Skip to content

Commit 46f62e3

Browse files
authored
Merge branch 'develop' into feature-2/interactive-console
2 parents dbaa8a5 + 67ef2d3 commit 46f62e3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+890
-281
lines changed

client/components/AddRemoveButton.jsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
3+
import { withTranslation } from 'react-i18next';
4+
35

46
import AddIcon from '../images/plus.svg';
57
import RemoveIcon from '../images/minus.svg';
68

7-
const AddRemoveButton = ({ type, onClick }) => {
8-
const alt = type === 'add' ? 'Add to collection' : 'Remove from collection';
9+
const AddRemoveButton = ({ type, onClick, t }) => {
10+
const alt = type === 'add' ? t('AddRemoveButton.AltAddARIA') : t('AddRemoveButton.AltRemoveARIA');
911
const Icon = type === 'add' ? AddIcon : RemoveIcon;
1012

1113
return (
@@ -22,6 +24,7 @@ const AddRemoveButton = ({ type, onClick }) => {
2224
AddRemoveButton.propTypes = {
2325
type: PropTypes.oneOf(['add', 'remove']).isRequired,
2426
onClick: PropTypes.func.isRequired,
27+
t: PropTypes.func.isRequired
2528
};
2629

27-
export default AddRemoveButton;
30+
export default withTranslation()(AddRemoveButton);

client/components/Dropdown.jsx

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,7 @@ const DropdownWrapper = styled.ul`
3636
background-color: ${prop('Button.hover.background')};
3737
color: ${prop('Button.hover.foreground')};
3838
39-
& button, & a {
40-
color: ${prop('Button.hover.foreground')};
41-
}
39+
* { color: ${prop('Button.hover.foreground')}; }
4240
}
4341
4442
li {
@@ -48,12 +46,21 @@ const DropdownWrapper = styled.ul`
4846
align-items: center;
4947
5048
& button,
49+
& button span,
5150
& a {
51+
padding: ${remSize(8)} ${remSize(16)};
52+
}
53+
54+
* {
55+
text-align: left;
56+
justify-content: left;
57+
5258
color: ${prop('primaryTextColor')};
5359
width: 100%;
54-
text-align: left;
55-
padding: ${remSize(8)} ${remSize(16)};
60+
justify-content: flex-start;
5661
}
62+
63+
& button span { padding: 0px }
5764
}
5865
`;
5966

@@ -63,24 +70,29 @@ const DropdownWrapper = styled.ul`
6370
const Dropdown = ({ items, align }) => (
6471
<DropdownWrapper align={align} >
6572
{/* className="nav__items-left" */}
66-
{items && items.map(({ title, icon, href }) => (
73+
{items && items.map(({
74+
title, icon, href, action
75+
}) => (
6776
<li key={`nav-${title && title.toLowerCase()}`}>
68-
<Link to={href}>
69-
{/* {MaybeIcon(icon, `Navigate to ${title}`)} */}
70-
{title}
71-
</Link>
77+
{/* {MaybeIcon(icon, `Navigate to ${title}`)} */}
78+
{href
79+
? <IconButton to={href}>{title}</IconButton>
80+
: <IconButton onClick={() => action()}>{title}</IconButton>}
81+
7282
</li>
7383
))
7484
}
7585
</DropdownWrapper>
7686
);
7787

88+
7889
Dropdown.propTypes = {
7990
align: PropTypes.oneOf(['left', 'right']),
8091
items: PropTypes.arrayOf(PropTypes.shape({
8192
action: PropTypes.func,
8293
icon: PropTypes.func,
83-
href: PropTypes.string
94+
href: PropTypes.string,
95+
title: PropTypes.string
8496
})),
8597
};
8698

client/components/PreviewNav.jsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
11
import PropTypes from 'prop-types';
22
import React from 'react';
33
import { Link } from 'react-router';
4+
import { withTranslation } from 'react-i18next';
45

56
import LogoIcon from '../images/p5js-logo-small.svg';
67
import CodeIcon from '../images/code.svg';
78

8-
const PreviewNav = ({ owner, project }) => (
9+
const PreviewNav = ({ owner, project, t }) => (
910
<nav className="nav preview-nav">
1011
<div className="nav__items-left">
1112
<div className="nav__item-logo">
12-
<LogoIcon role="img" aria-label="p5.js Logo" focusable="false" className="svg__logo" />
13+
<LogoIcon role="img" aria-label={t('Common.p5logoARIA')} focusable="false" className="svg__logo" />
1314
</div>
1415
<Link className="nav__item" to={`/${owner.username}/sketches/${project.id}`}>{project.name}</Link>
15-
<p className="toolbar__project-owner">by</p>
16+
<p className="toolbar__project-owner">{t('PreviewNav.ByUser')}</p>
1617
<Link className="nav__item" to={`/${owner.username}/sketches/`}>{owner.username}</Link>
1718
</div>
1819
<div className="nav__items-right">
19-
<Link to={`/${owner.username}/sketches/${project.id}`} aria-label="Edit Sketch" >
20+
<Link to={`/${owner.username}/sketches/${project.id}`} aria-label={t('PreviewNav.EditSketchARIA')} >
2021
<CodeIcon className="preview-nav__editor-svg" focusable="false" aria-hidden="true" />
2122
</Link>
2223
</div>
@@ -31,6 +32,7 @@ PreviewNav.propTypes = {
3132
name: PropTypes.string.isRequired,
3233
id: PropTypes.string.isRequired,
3334
}).isRequired,
35+
t: PropTypes.func.isRequired
3436
};
3537

36-
export default PreviewNav;
38+
export default withTranslation()(PreviewNav);

client/components/mobile/IconButton.jsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,19 @@ const IconButton = (props) => {
1717
const Icon = icon;
1818

1919
return (<ButtonWrapper
20-
iconBefore={<Icon />}
20+
iconBefore={icon && <Icon />}
2121
kind={Button.kinds.inline}
2222
focusable="false"
2323
{...otherProps}
2424
/>);
2525
};
2626

2727
IconButton.propTypes = {
28-
icon: PropTypes.func.isRequired
28+
icon: PropTypes.func
29+
};
30+
31+
IconButton.defaultProps = {
32+
icon: null
2933
};
3034

3135
export default IconButton;

client/constants.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export const COLLAPSE_CONSOLE = 'COLLAPSE_CONSOLE';
6262

6363
export const UPDATE_LINT_MESSAGE = 'UPDATE_LINT_MESSAGE';
6464
export const CLEAR_LINT_MESSAGE = 'CLEAR_LINT_MESSAGE';
65+
export const TOGGLE_FORCE_DESKTOP = 'TOGGLE_FORCE_DESKTOP';
6566

6667
export const UPDATE_FILE_NAME = 'UPDATE_FILE_NAME';
6768
export const DELETE_FILE = 'DELETE_FILE';

client/i18n-test.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import i18n from 'i18next';
2+
import { initReactI18next } from 'react-i18next';
3+
4+
import translations from '../translations/locales/en-US/translations.json';
5+
6+
i18n
7+
.use(initReactI18next)
8+
.init({
9+
lng: 'en-US',
10+
fallbackLng: 'en-US',
11+
12+
// have a common namespace used around the full app
13+
ns: ['translations'],
14+
defaultNS: 'translations',
15+
16+
debug: false,
17+
18+
interpolation: {
19+
escapeValue: false, // not needed for react!!
20+
},
21+
22+
resources: { 'en-US': { translations } },
23+
});
24+
25+
26+
export default i18n;

client/jest.setup.js

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,3 @@ import '@babel/polyfill';
33
// See: https://github.com/testing-library/jest-dom
44
// eslint-disable-next-line import/no-extraneous-dependencies
55
import '@testing-library/jest-dom';
6-
7-
import lodash from 'lodash';
8-
9-
// For testing, we use en-US and provide a mock implementation
10-
// of t() that finds the correct translation
11-
import translations from '../translations/locales/en-US/translations.json';
12-
13-
// This function name needs to be prefixed with "mock" so that Jest doesn't
14-
// complain that it's out-of-scope in the mock below
15-
const mockTranslate = key => lodash.get(translations, key);
16-
17-
jest.mock('react-i18next', () => ({
18-
// this mock makes sure any components using the translate HoC receive the t function as a prop
19-
withTranslation: () => (Component) => {
20-
Component.defaultProps = { ...Component.defaultProps, t: mockTranslate };
21-
return Component;
22-
},
23-
}));

client/modules/App/components/Overlay.jsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import PropTypes from 'prop-types';
22
import React from 'react';
33
import { browserHistory } from 'react-router';
4+
import { withTranslation } from 'react-i18next';
45

56
import ExitIcon from '../../../images/exit.svg';
67

@@ -80,7 +81,7 @@ class Overlay extends React.Component {
8081
<h2 className="overlay__title">{title}</h2>
8182
<div className="overlay__actions">
8283
{actions}
83-
<button className="overlay__close-button" onClick={this.close} aria-label={`Close ${title} overlay`} >
84+
<button className="overlay__close-button" onClick={this.close} aria-label={this.props.t('Overlay.AriaLabel', { title })}>
8485
<ExitIcon focusable="false" aria-hidden="true" />
8586
</button>
8687
</div>
@@ -101,6 +102,7 @@ Overlay.propTypes = {
101102
ariaLabel: PropTypes.string,
102103
previousPath: PropTypes.string,
103104
isFixedHeight: PropTypes.bool,
105+
t: PropTypes.func.isRequired
104106
};
105107

106108
Overlay.defaultProps = {
@@ -113,4 +115,4 @@ Overlay.defaultProps = {
113115
isFixedHeight: false,
114116
};
115117

116-
export default Overlay;
118+
export default withTranslation()(Overlay);

client/modules/IDE/actions/editorAccessibility.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,9 @@ export function clearLintMessage() {
1414
type: ActionTypes.CLEAR_LINT_MESSAGE
1515
};
1616
}
17+
18+
export function toggleForceDesktop() {
19+
return {
20+
type: ActionTypes.TOGGLE_FORCE_DESKTOP
21+
};
22+
}

client/modules/IDE/components/AddToCollectionList.jsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import React from 'react';
33
import { Helmet } from 'react-helmet';
44
import { connect } from 'react-redux';
55
import { bindActionCreators } from 'redux';
6+
import { withTranslation } from 'react-i18next';
67

78
import * as ProjectActions from '../actions/project';
89
import * as ProjectsActions from '../actions/projects';
@@ -42,9 +43,9 @@ class CollectionList extends React.Component {
4243

4344
getTitle() {
4445
if (this.props.username === this.props.user.username) {
45-
return 'p5.js Web Editor | My collections';
46+
return this.props.t('AddToCollectionList.Title');
4647
}
47-
return `p5.js Web Editor | ${this.props.username}'s collections`;
48+
return this.props.t('AddToCollectionList.AnothersTitle', { anotheruser: this.props.username });
4849
}
4950

5051
handleCollectionAdd = (collection) => {
@@ -74,10 +75,11 @@ class CollectionList extends React.Component {
7475
items={collectionWithSketchStatus}
7576
onAdd={this.handleCollectionAdd}
7677
onRemove={this.handleCollectionRemove}
78+
t={this.props.t}
7779
/>
7880
);
7981
} else {
80-
content = 'No collections';
82+
content = this.props.t('AddToCollectionList.Empty');
8183
}
8284

8385
return (
@@ -135,7 +137,8 @@ CollectionList.propTypes = {
135137
owner: PropTypes.shape({
136138
id: PropTypes.string
137139
})
138-
})
140+
}),
141+
t: PropTypes.func.isRequired
139142
};
140143

141144
CollectionList.defaultProps = {
@@ -164,4 +167,4 @@ function mapDispatchToProps(dispatch) {
164167
);
165168
}
166169

167-
export default connect(mapStateToProps, mapDispatchToProps)(CollectionList);
170+
export default withTranslation()(connect(mapStateToProps, mapDispatchToProps)(CollectionList));

0 commit comments

Comments
 (0)