Skip to content

Commit 51eedd1

Browse files
authored
Merge pull request #397 from code-dot-org/sl-31-refactor
Refactor repo after updating to React v16
2 parents 5c20bb9 + 07f089e commit 51eedd1

File tree

14 files changed

+1673
-1599
lines changed

14 files changed

+1673
-1599
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import React from 'react';
2+
import Radium from "radium";
3+
import PropTypes from "prop-types";
4+
5+
import guide from "@ml/oceans/models/guide";
6+
import soundLibrary from "@ml/oceans/models/soundLibrary";
7+
import styles from "@ml/oceans/styles";
8+
9+
const UnwrappedButton = class Button extends React.Component {
10+
static propTypes = {
11+
className: PropTypes.string,
12+
style: PropTypes.object,
13+
children: PropTypes.node,
14+
onClick: PropTypes.func,
15+
sound: PropTypes.string
16+
};
17+
18+
onClick = event => {
19+
guide.dismissCurrentGuide();
20+
const clickReturnValue = this.props.onClick(event);
21+
22+
if (clickReturnValue !== false) {
23+
const sound = this.props.sound || 'other';
24+
soundLibrary.playSound(sound);
25+
}
26+
};
27+
28+
render() {
29+
return (
30+
<button
31+
type="button"
32+
className={this.props.className}
33+
style={[styles.button, this.props.style]}
34+
onClick={this.onClick}
35+
>
36+
{this.props.children}
37+
</button>
38+
);
39+
}
40+
};
41+
42+
export default Radium(UnwrappedButton);
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
import Radium from "radium";
4+
5+
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
6+
import {faEraser} from "@fortawesome/free-solid-svg-icons";
7+
8+
import snail from "@public/images/snail-large.png";
9+
10+
import styles from "@ml/oceans/styles";
11+
import I18n from "@ml/oceans/i18n";
12+
import Button from "@ml/oceans/components/common/Button";
13+
14+
let UnwrappedConfirmationDialog = class ConfirmationDialog extends React.Component {
15+
static propTypes = {
16+
onYesClick: PropTypes.func.isRequired,
17+
onNoClick: PropTypes.func.isRequired
18+
};
19+
20+
render() {
21+
return (
22+
<div style={styles.confirmationDialogBackground}>
23+
<div style={styles.confirmationDialog}>
24+
<div style={styles.confirmationDialogContent}>
25+
<img src={snail} style={styles.confirmationDialogImg}/>
26+
<div>
27+
<div
28+
style={styles.confirmationHeader}
29+
className="confirmation-text"
30+
>
31+
{I18n.t('areYouSure')}
32+
</div>
33+
<div style={styles.confirmationText}>
34+
{I18n.t('eraseWarning')}
35+
</div>
36+
</div>
37+
</div>
38+
<div style={styles.confirmationButtons}>
39+
<Button
40+
onClick={this.props.onYesClick}
41+
style={styles.confirmationYesButton}
42+
className="dialog-button"
43+
>
44+
<FontAwesomeIcon icon={faEraser}/> {I18n.t('erase')}
45+
</Button>
46+
<Button
47+
onClick={this.props.onNoClick}
48+
style={styles.confirmationNoButton}
49+
className="dialog-button"
50+
>
51+
{I18n.t('cancel')}
52+
</Button>
53+
</div>
54+
</div>
55+
</div>
56+
);
57+
}
58+
};
59+
export default Radium(UnwrappedConfirmationDialog);
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import React from 'react'
2+
import Radium from "radium";
3+
import Typist from "react-typist";
4+
5+
import {getState, setState} from "@ml/oceans/state";
6+
import guide from "@ml/oceans/models/guide";
7+
import soundLibrary from "@ml/oceans/models/soundLibrary";
8+
import styles from "@ml/oceans/styles";
9+
import colors from "@ml/oceans/styles/colors";
10+
import I18n from "@ml/oceans/i18n";
11+
import {Button} from "@ml/oceans/components/common";
12+
import arrowDownImage from "@public/images/arrow-down.png";
13+
14+
let UnwrappedGuide = class Guide extends React.Component {
15+
onShowing() {
16+
clearInterval(getState().guideTypingTimer);
17+
setState({guideShowing: true, guideTypingTimer: null});
18+
}
19+
20+
dismissGuideClick() {
21+
const dismissed = guide.dismissCurrentGuide();
22+
if (dismissed) {
23+
soundLibrary.playSound('other');
24+
}
25+
}
26+
27+
render() {
28+
const state = getState();
29+
const currentGuide = guide.getCurrentGuide();
30+
31+
let guideBgStyle = [styles.guideBackground];
32+
if (currentGuide) {
33+
if (currentGuide.noDimBackground) {
34+
guideBgStyle = [styles.guideBackgroundHidden];
35+
}
36+
37+
// Info guides should have a darker background color.
38+
if (currentGuide.style === 'Info') {
39+
guideBgStyle.push({backgroundColor: colors.transparentBlack});
40+
}
41+
}
42+
43+
// Start playing the typing sounds.
44+
if (!state.guideShowing && !state.guideTypingTimer && currentGuide) {
45+
const guideTypingTimer = setInterval(() => {
46+
soundLibrary.playSound('no', 0.5);
47+
}, 1000 / 10);
48+
setState({guideTypingTimer});
49+
}
50+
51+
return (
52+
<div>
53+
{currentGuide && currentGuide.image && (
54+
<img
55+
src={currentGuide.image}
56+
style={[styles.guideImage, currentGuide.imageStyle || {}]}
57+
/>
58+
)}
59+
{!!currentGuide && (
60+
<div>
61+
<div
62+
key={currentGuide.id}
63+
style={guideBgStyle}
64+
onClick={this.dismissGuideClick}
65+
id="uitest-dismiss-guide"
66+
>
67+
<div
68+
style={{
69+
...styles.guide,
70+
...styles[`guide${currentGuide.style}`]
71+
}}
72+
>
73+
<div>
74+
{currentGuide.style === 'Info' && (
75+
<div style={styles.guideHeading}>
76+
{I18n.t('didYouKnow')}
77+
</div>
78+
)}
79+
<div style={styles.guideTypingText}>
80+
<Typist
81+
avgTypingDelay={35}
82+
stdTypingDelay={15}
83+
cursor={{show: false}}
84+
onTypingDone={this.onShowing}
85+
>
86+
{currentGuide.textFn(getState())}
87+
</Typist>
88+
</div>
89+
<div
90+
style={
91+
currentGuide.style === 'Info'
92+
? styles.guideFinalTextInfoContainer
93+
: styles.guideFinalTextContainer
94+
}
95+
>
96+
<div style={styles.guideFinalText}>
97+
{currentGuide.textFn(getState())}
98+
</div>
99+
</div>
100+
{currentGuide.style === 'Info' && (
101+
<Button style={styles.infoGuideButton} onClick={() => {}}>
102+
{I18n.t('continue')}
103+
</Button>
104+
)}
105+
</div>
106+
</div>
107+
</div>
108+
{currentGuide.arrow && (
109+
<img
110+
src={arrowDownImage}
111+
style={{
112+
...styles.guideArrow,
113+
...styles[`arrow${currentGuide.arrow}`]
114+
}}
115+
/>
116+
)}
117+
</div>
118+
)}
119+
</div>
120+
);
121+
}
122+
};
123+
export default Radium(UnwrappedGuide);
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import React from 'react'
2+
import PropTypes from 'prop-types'
3+
4+
import styles from "@ml/oceans/styles";
5+
6+
import Guide from "@ml/oceans/components/common/Guide";
7+
import Button from "@ml/oceans/components/common/Button";
8+
import ConfirmationDialog from "@ml/oceans/components/common/ConfirmationDialog";
9+
import loadingGif from "@public/images/loading.gif";
10+
11+
const Body = ({onClick, children}) => (
12+
<div style={styles.body} onClick={onClick}>
13+
{children}
14+
<Guide />
15+
</div>
16+
)
17+
Body.propTypes = {
18+
children: PropTypes.node,
19+
onClick: PropTypes.func
20+
}
21+
22+
const Content = ({children}) => (<div style={styles.content}>{children}</div>)
23+
Content.propTypes = {
24+
children: PropTypes.node
25+
};
26+
27+
const Loading = () => (
28+
<Body>
29+
<img src={loadingGif} style={styles.loading} />
30+
</Body>
31+
)
32+
33+
34+
export {Body, Content, Loading, Guide, Button, ConfirmationDialog}
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import React from "react";
2+
import {getState, setState} from "@ml/oceans/state";
3+
import styles from "@ml/oceans/styles";
4+
import I18n from "@ml/oceans/i18n";
5+
import Markdown from "@ml/utils/Markdown";
6+
7+
class PondPanel extends React.Component {
8+
onPondPanelClick = e => {
9+
setState({pondPanelShowing: false});
10+
e.stopPropagation();
11+
};
12+
13+
render() {
14+
const state = getState();
15+
16+
const maxExplainValue = state.showRecallFish
17+
? state.pondRecallFishMaxExplainValue
18+
: state.pondFishMaxExplainValue;
19+
20+
return (
21+
<div>
22+
{!state.pondClickedFish && (
23+
<div style={styles.pondPanelLeft} onClick={this.onPondPanelClick}>
24+
{state.pondExplainGeneralSummary && (
25+
<div>
26+
<div style={styles.pondPanelPreText}>
27+
{I18n.t('mostImportantParts')}
28+
</div>
29+
{state.pondExplainGeneralSummary.slice(0, 5).map((f, i) => (
30+
<div key={i}>
31+
{f.importance > 0 && (
32+
<div style={styles.pondPanelRow}>
33+
&nbsp;
34+
<div
35+
style={{
36+
...styles.pondPanelGeneralBar,
37+
width:
38+
(Math.abs(f.importance) /
39+
state.pondExplainGeneralSummary[0].importance) *
40+
100 +
41+
'%'
42+
}}
43+
>
44+
&nbsp;
45+
</div>
46+
<div style={styles.pondPanelGeneralBarText}>
47+
{I18n.t(f.partType)}
48+
</div>
49+
</div>
50+
)}
51+
</div>
52+
))}
53+
<div style={styles.pondPanelPostText}>
54+
{I18n.t('clickIndividualFish')}
55+
</div>
56+
</div>
57+
)}
58+
</div>
59+
)}
60+
{state.pondClickedFish && (
61+
<div
62+
style={
63+
state.pondPanelSide === 'left'
64+
? styles.pondPanelLeft
65+
: styles.pondPanelRight
66+
}
67+
onClick={e => this.onPondPanelClick(e)}
68+
>
69+
{state.pondExplainFishSummary && (
70+
<div>
71+
<div style={styles.pondPanelPreText} id="pondTextMarkdown">
72+
<Markdown
73+
markdown={I18n.t(
74+
'mostImportantPartsDescription',
75+
{
76+
word: state.word.toLowerCase(),
77+
notWord: I18n.t('notWord', {
78+
word: state.word
79+
}).toLowerCase()
80+
}
81+
)}
82+
/>
83+
</div>
84+
{state.pondExplainFishSummary.slice(0, 4).map((f, i) => (
85+
<div key={i}>
86+
{f.impact < 0 && (
87+
<div style={styles.pondPanelRow}>
88+
&nbsp;
89+
<div
90+
style={{
91+
...styles.pondPanelGreenBar,
92+
width:
93+
((Math.abs(f.impact) / maxExplainValue) * 100) /
94+
2 +
95+
'%'
96+
}}
97+
>
98+
&nbsp;
99+
</div>
100+
<div style={styles.pondPanelGreenBarText}>
101+
{I18n.t(f.partType)}
102+
</div>
103+
</div>
104+
)}
105+
{f.impact > 0 && (
106+
<div style={styles.pondPanelRow}>
107+
&nbsp;
108+
<div
109+
style={{
110+
...styles.pondPanelRedBar,
111+
width:
112+
((Math.abs(f.impact) / maxExplainValue) * 100) /
113+
2 +
114+
'%'
115+
}}
116+
>
117+
&nbsp;
118+
</div>
119+
<div style={styles.pondPanelRedBarText}>
120+
{I18n.t(f.partType)}
121+
</div>
122+
</div>
123+
)}
124+
</div>
125+
))}
126+
</div>
127+
)}
128+
</div>
129+
)}
130+
</div>
131+
);
132+
}
133+
}
134+
export default PondPanel;

0 commit comments

Comments
 (0)