Skip to content

Commit a342f72

Browse files
Merge pull request #2 from processing/develop
updating the fork
2 parents 0761cf9 + b7d17a0 commit a342f72

Some content is hidden

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

69 files changed

+1242
-596
lines changed

client/common/icons.jsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import Preferences from '../images/preferences.svg';
1414
import Play from '../images/triangle-arrow-right.svg';
1515
import More from '../images/more.svg';
1616
import Code from '../images/code.svg';
17+
import Save from '../images/save.svg';
1718
import Terminal from '../images/terminal.svg';
1819

1920
import Folder from '../images/folder-padded.svg';
@@ -87,6 +88,7 @@ export const PlayIcon = withLabel(Play);
8788
export const MoreIcon = withLabel(More);
8889
export const TerminalIcon = withLabel(Terminal);
8990
export const CodeIcon = withLabel(Code);
91+
export const SaveIcon = withLabel(Save);
9092

9193
export const FolderIcon = withLabel(Folder);
9294

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/Nav.jsx

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { withRouter } from 'react-router';
55
import { Link } from 'react-router';
66
import classNames from 'classnames';
77
import { withTranslation } from 'react-i18next';
8-
import i18next from 'i18next';
8+
import { languageKeyToLabel } from '../i18n';
99
import * as IDEActions from '../modules/IDE/actions/ide';
1010
import * as toastActions from '../modules/IDE/actions/toast';
1111
import * as projectActions from '../modules/IDE/actions/project';
@@ -549,7 +549,7 @@ class Nav extends React.PureComponent {
549549

550550
renderLanguageMenu(navDropdownState) {
551551
return (
552-
<ul className="nav__items-right" title="user-menu">
552+
<React.Fragment>
553553
<li className={navDropdownState.lang}>
554554
<button
555555
onClick={this.toggleDropdownForLang}
@@ -561,21 +561,11 @@ class Nav extends React.PureComponent {
561561
}
562562
}}
563563
>
564-
<span className="nav__item-header"> {this.props.t('Nav.Lang')}</span>
564+
<span className="nav__item-header"> {languageKeyToLabel(this.props.language)}</span>
565565
<TriangleIcon className="nav__item-header-triangle" focusable="false" aria-hidden="true" />
566566
</button>
567567
<ul className="nav__dropdown">
568568

569-
<li className="nav__dropdown-item">
570-
<button
571-
onFocus={this.handleFocusForLang}
572-
onBlur={this.handleBlur}
573-
value="it"
574-
onClick={e => this.handleLangSelection(e)}
575-
>
576-
Italian (Test Fallback)
577-
</button>
578-
</li>
579569
<li className="nav__dropdown-item">
580570
<button
581571
onFocus={this.handleFocusForLang}
@@ -597,14 +587,15 @@ class Nav extends React.PureComponent {
597587
</li>
598588
</ul>
599589
</li>
600-
</ul>
590+
</React.Fragment>
601591
);
602592
}
603593

604594

605595
renderUnauthenticatedUserMenu(navDropdownState) {
606596
return (
607597
<ul className="nav__items-right" title="user-menu">
598+
{getConfig('TRANSLATIONS_ENABLED') && this.renderLanguageMenu(navDropdownState)}
608599
<li className="nav__item">
609600
<Link to="/login" className="nav__auth-button">
610601
<span className="nav__item-header">{this.props.t('Nav.Login')}</span>
@@ -623,10 +614,7 @@ class Nav extends React.PureComponent {
623614
renderAuthenticatedUserMenu(navDropdownState) {
624615
return (
625616
<ul className="nav__items-right" title="user-menu">
626-
<li className="nav__item">
627-
<span>{this.props.t('Nav.Auth.Hello')}, {this.props.user.username}!</span>
628-
</li>
629-
<span className="nav__item-spacer">|</span>
617+
{getConfig('TRANSLATIONS_ENABLED') && this.renderLanguageMenu(navDropdownState)}
630618
<li className={navDropdownState.account}>
631619
<button
632620
className="nav__item-header"
@@ -639,7 +627,7 @@ class Nav extends React.PureComponent {
639627
}
640628
}}
641629
>
642-
{this.props.t('Nav.Auth.MyAccount')}
630+
<span>{this.props.t('Nav.Auth.Hello')}, {this.props.user.username}!</span>
643631
<TriangleIcon className="nav__item-header-triangle" focusable="false" aria-hidden="true" />
644632
</button>
645633
<ul className="nav__dropdown">
@@ -755,7 +743,6 @@ class Nav extends React.PureComponent {
755743
<header>
756744
<nav className="nav" title="main-navigation" ref={(node) => { this.node = node; }}>
757745
{this.renderLeftLayout(navDropdownState)}
758-
{getConfig('TRANSLATIONS_ENABLED') && this.renderLanguageMenu(navDropdownState)}
759746
{this.renderUserMenu(navDropdownState)}
760747
</nav>
761748
</header>
@@ -809,6 +796,7 @@ Nav.propTypes = {
809796
}),
810797
t: PropTypes.func.isRequired,
811798
setLanguage: PropTypes.func.isRequired,
799+
language: PropTypes.string.isRequired,
812800
};
813801

814802
Nav.defaultProps = {
@@ -829,7 +817,8 @@ function mapStateToProps(state) {
829817
project: state.project,
830818
user: state.user,
831819
unsavedChanges: state.ide.unsavedChanges,
832-
rootFile: state.files.filter(file => file.name === 'root')[0]
820+
rootFile: state.files.filter(file => file.name === 'root')[0],
821+
language: state.preferences.language
833822
};
834823
}
835824

client/components/NavBasic.jsx

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

45
import LogoIcon from '../images/p5js-logo-small.svg';
56
import ArrowIcon from '../images/triangle-arrow-left.svg';
@@ -14,7 +15,7 @@ class NavBasic extends React.PureComponent {
1415
<nav className="nav" title="main-navigation" ref={(node) => { this.node = node; }}>
1516
<ul className="nav__items-left">
1617
<li className="nav__item-logo">
17-
<LogoIcon role="img" aria-label="p5.js Logo" focusable="false" className="svg__logo" />
18+
<LogoIcon role="img" aria-label={this.props.t('Common.p5logoARIA')} focusable="false" className="svg__logo" />
1819
</li>
1920
{ this.props.onBack && (
2021
<li className="nav__item">
@@ -34,6 +35,7 @@ class NavBasic extends React.PureComponent {
3435

3536
NavBasic.propTypes = {
3637
onBack: PropTypes.func,
38+
t: PropTypes.func.isRequired
3739
};
3840

39-
export default NavBasic;
41+
export default withTranslation()(NavBasic);

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/__test__/Nav.test.jsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ describe('Nav', () => {
4646
id: 'root-file'
4747
},
4848
t: jest.fn(),
49-
setLanguage: jest.fn()
49+
setLanguage: jest.fn(),
50+
language: 'en-US'
5051
};
5152

5253
it('renders correctly', () => {
Lines changed: 23 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,16 @@
11
import React from 'react';
2-
import styled from 'styled-components';
32
import PropTypes from 'prop-types';
4-
import { bindActionCreators } from 'redux';
5-
import { useDispatch, useSelector } from 'react-redux';
3+
import styled from 'styled-components';
64
import { remSize, prop } from '../../theme';
75
import IconButton from './IconButton';
8-
import { TerminalIcon, FolderIcon } from '../../common/icons';
9-
import * as IDEActions from '../../modules/IDE/actions/ide';
106

117
const BottomBarContent = styled.div`
128
padding: ${remSize(8)};
13-
display: flex;
9+
display: grid;
10+
grid-template-columns: repeat(8,1fr);
1411
1512
svg {
1613
max-height: ${remSize(32)};
17-
1814
}
1915
2016
path { fill: ${prop('primaryTextColor')} !important }
@@ -25,42 +21,28 @@ const BottomBarContent = styled.div`
2521
}
2622
`;
2723

28-
// Maybe this component shouldn't be connected, and instead just receive the `actions` prop
29-
const ActionStrip = ({ toggleExplorer }) => {
30-
const { expandConsole, collapseConsole } = bindActionCreators(IDEActions, useDispatch());
31-
const { consoleIsExpanded } = useSelector(state => state.ide);
32-
33-
const actions = [
34-
{
35-
icon: TerminalIcon, inverted: true, aria: 'Open terminal console', action: consoleIsExpanded ? collapseConsole : expandConsole
36-
},
37-
{ icon: FolderIcon, aria: 'Open files explorer', action: toggleExplorer }
38-
];
39-
40-
return (
41-
<BottomBarContent>
42-
{actions.map(({
43-
icon, aria, action, inverted
44-
}) =>
45-
(
46-
<IconButton
47-
inverted={inverted}
48-
className={inverted && 'inverted'}
49-
icon={icon}
50-
aria-label={aria}
51-
key={`bottom-bar-${aria}`}
52-
onClick={() => action()}
53-
/>))}
54-
</BottomBarContent>
55-
);
56-
};
24+
const ActionStrip = ({ actions }) => (
25+
<BottomBarContent>
26+
{actions.map(({
27+
icon, aria, action, inverted
28+
}) =>
29+
(<IconButton
30+
inverted={inverted}
31+
className={inverted && 'inverted'}
32+
icon={icon}
33+
aria-label={aria}
34+
key={`bottom-bar-${aria}`}
35+
onClick={action}
36+
/>))}
37+
</BottomBarContent>);
5738

5839
ActionStrip.propTypes = {
59-
toggleExplorer: PropTypes.func
60-
};
61-
62-
ActionStrip.defaultProps = {
63-
toggleExplorer: () => {}
40+
actions: PropTypes.arrayOf(PropTypes.shape({
41+
icon: PropTypes.any,
42+
aria: PropTypes.string.isRequired,
43+
action: PropTypes.func.isRequired,
44+
inverted: PropTypes.bool
45+
})).isRequired
6446
};
6547

6648
export default ActionStrip;

client/components/mobile/Header.jsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ const HeaderDiv = styled.div`
3535
}
3636
3737
& svg path { fill: ${textColor} !important; }
38+
39+
.editor__unsaved-changes svg {
40+
width: ${remSize(16)};
41+
padding: 0;
42+
vertical-align: top
43+
}
3844
`;
3945

4046
const IconContainer = styled.div`
@@ -71,8 +77,9 @@ const Header = ({
7177
</HeaderDiv>
7278
);
7379

80+
7481
Header.propTypes = {
75-
title: PropTypes.string,
82+
title: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
7683
subtitle: PropTypes.string,
7784
leftButton: PropTypes.element,
7885
children: PropTypes.oneOfType([PropTypes.element, PropTypes.arrayOf(PropTypes.element)]),

0 commit comments

Comments
 (0)