🔀 merge from feature/mobile-header-dropdown-menu

This commit is contained in:
ghalestrilo 2020-07-31 10:49:19 -03:00
commit d42f10e114
20 changed files with 476 additions and 372 deletions

View file

@ -16,6 +16,9 @@ const DropdownWrapper = styled.ul`
right: ${props => (props.right ? 0 : 'initial')}; right: ${props => (props.right ? 0 : 'initial')};
left: ${props => (props.left ? 0 : 'initial')}; left: ${props => (props.left ? 0 : 'initial')};
${props => (props.align === 'right' && 'right: 0;')}
${props => (props.align === 'left' && 'left: 0;')}
text-align: left; text-align: left;
width: ${remSize(180)}; width: ${remSize(180)};
@ -57,8 +60,8 @@ const DropdownWrapper = styled.ul`
// TODO: Add Icon to the left of the items in the menu // TODO: Add Icon to the left of the items in the menu
// const MaybeIcon = (Element, label) => Element && <Element aria-label={label} />; // const MaybeIcon = (Element, label) => Element && <Element aria-label={label} />;
const Dropdown = ({ items, right, left }) => ( const Dropdown = ({ items, align }) => (
<DropdownWrapper right={right} left={left}> <DropdownWrapper align={align} >
{/* className="nav__items-left" */} {/* className="nav__items-left" */}
{items && items.map(({ title, icon, href }) => ( {items && items.map(({ title, icon, href }) => (
<li key={`nav-${title && title.toLowerCase()}`}> <li key={`nav-${title && title.toLowerCase()}`}>
@ -73,8 +76,7 @@ const Dropdown = ({ items, right, left }) => (
); );
Dropdown.propTypes = { Dropdown.propTypes = {
right: PropTypes.bool, align: PropTypes.oneOf(['left', 'right']),
left: PropTypes.bool,
items: PropTypes.arrayOf(PropTypes.shape({ items: PropTypes.arrayOf(PropTypes.shape({
action: PropTypes.func, action: PropTypes.func,
icon: PropTypes.func, icon: PropTypes.func,
@ -84,8 +86,7 @@ Dropdown.propTypes = {
Dropdown.defaultProps = { Dropdown.defaultProps = {
items: [], items: [],
right: false, align: null
left: false,
}; };
export default Dropdown; export default Dropdown;

View file

@ -100,11 +100,11 @@ class Nav extends React.PureComponent {
const { unsavedChanges, warnIfUnsavedChanges } = this.props; const { unsavedChanges, warnIfUnsavedChanges } = this.props;
if (!unsavedChanges) { if (!unsavedChanges) {
this.props.showToast(1500); this.props.showToast(1500);
this.props.setToastText('Opened new sketch.'); this.props.setToastText('Toast.OpenedNewSketch');
this.props.newProject(); this.props.newProject();
} else if (warnIfUnsavedChanges && warnIfUnsavedChanges()) { } else if (warnIfUnsavedChanges && warnIfUnsavedChanges()) {
this.props.showToast(1500); this.props.showToast(1500);
this.props.setToastText('Opened new sketch.'); this.props.setToastText('Toast.OpenedNewSketch');
this.props.newProject(); this.props.newProject();
} }
this.setDropdown('none'); this.setDropdown('none');
@ -172,7 +172,7 @@ class Nav extends React.PureComponent {
handleLangSelection(event) { handleLangSelection(event) {
i18next.changeLanguage(event.target.value); i18next.changeLanguage(event.target.value);
this.props.showToast(1500); this.props.showToast(1500);
this.props.setToastText('LangChange'); this.props.setToastText('Toast.LangChange');
this.setDropdown('none'); this.setDropdown('none');
} }
@ -240,13 +240,13 @@ class Nav extends React.PureComponent {
return ( return (
<ul className="nav__items-left"> <ul className="nav__items-left">
<li className="nav__item-logo"> <li className="nav__item-logo">
<LogoIcon role="img" aria-label="p5.js Logo" focusable="false" className="svg__logo" /> <LogoIcon role="img" aria-label={this.props.t('Common.p5logoARIA')} focusable="false" className="svg__logo" />
</li> </li>
<li className="nav__item nav__item--no-icon"> <li className="nav__item nav__item--no-icon">
<Link to="/" className="nav__back-link"> <Link to="/" className="nav__back-link">
<CaretLeftIcon className="nav__back-icon" focusable="false" aria-hidden="true" /> <CaretLeftIcon className="nav__back-icon" focusable="false" aria-hidden="true" />
<span className="nav__item-header"> <span className="nav__item-header">
{this.props.t('BackEditor')} {this.props.t('Nav.BackEditor')}
</span> </span>
</Link> </Link>
</li> </li>
@ -258,7 +258,7 @@ class Nav extends React.PureComponent {
return ( return (
<ul className="nav__items-left"> <ul className="nav__items-left">
<li className="nav__item-logo"> <li className="nav__item-logo">
<LogoIcon role="img" aria-label="p5.js Logo" focusable="false" className="svg__logo" /> <LogoIcon role="img" aria-label={this.props.t('Common.p5logoARIA')} focusable="false" className="svg__logo" />
</li> </li>
<li className={navDropdownState.file}> <li className={navDropdownState.file}>
<button <button
@ -271,7 +271,7 @@ class Nav extends React.PureComponent {
} }
}} }}
> >
<span className="nav__item-header">{this.props.t('File')}</span> <span className="nav__item-header">{this.props.t('Nav.File.Title')}</span>
<TriangleIcon className="nav__item-header-triangle" focusable="false" aria-hidden="true" /> <TriangleIcon className="nav__item-header-triangle" focusable="false" aria-hidden="true" />
</button> </button>
<ul className="nav__dropdown"> <ul className="nav__dropdown">
@ -281,7 +281,7 @@ class Nav extends React.PureComponent {
onFocus={this.handleFocusForFile} onFocus={this.handleFocusForFile}
onBlur={this.handleBlur} onBlur={this.handleBlur}
> >
{this.props.t('New')} {this.props.t('Nav.File.New')}
</button> </button>
</li> </li>
{ getConfig('LOGIN_ENABLED') && (!this.props.project.owner || this.isUserOwner()) && { getConfig('LOGIN_ENABLED') && (!this.props.project.owner || this.isUserOwner()) &&
@ -291,7 +291,7 @@ class Nav extends React.PureComponent {
onFocus={this.handleFocusForFile} onFocus={this.handleFocusForFile}
onBlur={this.handleBlur} onBlur={this.handleBlur}
> >
{this.props.t('Save')} {this.props.t('Common.Save')}
<span className="nav__keyboard-shortcut">{metaKeyName}+S</span> <span className="nav__keyboard-shortcut">{metaKeyName}+S</span>
</button> </button>
</li> } </li> }
@ -302,7 +302,7 @@ class Nav extends React.PureComponent {
onFocus={this.handleFocusForFile} onFocus={this.handleFocusForFile}
onBlur={this.handleBlur} onBlur={this.handleBlur}
> >
{this.props.t('Duplicate')} {this.props.t('Nav.File.Duplicate')}
</button> </button>
</li> } </li> }
{ this.props.project.id && { this.props.project.id &&
@ -312,7 +312,7 @@ class Nav extends React.PureComponent {
onFocus={this.handleFocusForFile} onFocus={this.handleFocusForFile}
onBlur={this.handleBlur} onBlur={this.handleBlur}
> >
{this.props.t('Share')} {this.props.t('Nav.File.Share')}
</button> </button>
</li> } </li> }
{ this.props.project.id && { this.props.project.id &&
@ -322,7 +322,7 @@ class Nav extends React.PureComponent {
onFocus={this.handleFocusForFile} onFocus={this.handleFocusForFile}
onBlur={this.handleBlur} onBlur={this.handleBlur}
> >
{this.props.t('Download')} {this.props.t('Nav.File.Download')}
</button> </button>
</li> } </li> }
{ this.props.user.authenticated && { this.props.user.authenticated &&
@ -333,7 +333,7 @@ class Nav extends React.PureComponent {
onBlur={this.handleBlur} onBlur={this.handleBlur}
onClick={this.setDropdownForNone} onClick={this.setDropdownForNone}
> >
{this.props.t('Open')} {this.props.t('Nav.File.Open')}
</Link> </Link>
</li> } </li> }
{getConfig('UI_COLLECTIONS_ENABLED') && {getConfig('UI_COLLECTIONS_ENABLED') &&
@ -346,7 +346,7 @@ class Nav extends React.PureComponent {
onBlur={this.handleBlur} onBlur={this.handleBlur}
onClick={this.setDropdownForNone} onClick={this.setDropdownForNone}
> >
{this.props.t('AddToCollection')} {this.props.t('Nav.File.AddToCollection')}
</Link> </Link>
</li>} </li>}
{ getConfig('EXAMPLES_ENABLED') && { getConfig('EXAMPLES_ENABLED') &&
@ -357,7 +357,7 @@ class Nav extends React.PureComponent {
onBlur={this.handleBlur} onBlur={this.handleBlur}
onClick={this.setDropdownForNone} onClick={this.setDropdownForNone}
> >
{this.props.t('Examples')} {this.props.t('Nav.File.Examples')}
</Link> </Link>
</li> } </li> }
</ul> </ul>
@ -373,7 +373,7 @@ class Nav extends React.PureComponent {
} }
}} }}
> >
<span className="nav__item-header">{this.props.t('Edit')}</span> <span className="nav__item-header">{this.props.t('Nav.Edit.Title')}</span>
<TriangleIcon className="nav__item-header-triangle" focusable="false" aria-hidden="true" /> <TriangleIcon className="nav__item-header-triangle" focusable="false" aria-hidden="true" />
</button> </button>
<ul className="nav__dropdown" > <ul className="nav__dropdown" >
@ -386,7 +386,7 @@ class Nav extends React.PureComponent {
onFocus={this.handleFocusForEdit} onFocus={this.handleFocusForEdit}
onBlur={this.handleBlur} onBlur={this.handleBlur}
> >
{this.props.t('TidyCode')} {this.props.t('Nav.Edit.TidyCode')}
<span className="nav__keyboard-shortcut">{'\u21E7'}+Tab</span> <span className="nav__keyboard-shortcut">{'\u21E7'}+Tab</span>
</button> </button>
</li> </li>
@ -396,7 +396,7 @@ class Nav extends React.PureComponent {
onFocus={this.handleFocusForEdit} onFocus={this.handleFocusForEdit}
onBlur={this.handleBlur} onBlur={this.handleBlur}
> >
{this.props.t('Find')} {this.props.t('Nav.Edit.Find')}
<span className="nav__keyboard-shortcut">{metaKeyName}+F</span> <span className="nav__keyboard-shortcut">{metaKeyName}+F</span>
</button> </button>
</li> </li>
@ -406,7 +406,7 @@ class Nav extends React.PureComponent {
onFocus={this.handleFocusForEdit} onFocus={this.handleFocusForEdit}
onBlur={this.handleBlur} onBlur={this.handleBlur}
> >
{this.props.t('FindNext')} {this.props.t('Nav.Edit.FindNext')}
<span className="nav__keyboard-shortcut">{metaKeyName}+G</span> <span className="nav__keyboard-shortcut">{metaKeyName}+G</span>
</button> </button>
</li> </li>
@ -416,7 +416,7 @@ class Nav extends React.PureComponent {
onFocus={this.handleFocusForEdit} onFocus={this.handleFocusForEdit}
onBlur={this.handleBlur} onBlur={this.handleBlur}
> >
{this.props.t('FindPrevious')} {this.props.t('Nav.Edit.FindPrevious')}
<span className="nav__keyboard-shortcut">{'\u21E7'}+{metaKeyName}+G</span> <span className="nav__keyboard-shortcut">{'\u21E7'}+{metaKeyName}+G</span>
</button> </button>
</li> </li>
@ -433,7 +433,7 @@ class Nav extends React.PureComponent {
} }
}} }}
> >
<span className="nav__item-header">{this.props.t('Sketch')}</span> <span className="nav__item-header">{this.props.t('Nav.Sketch.Title')}</span>
<TriangleIcon className="nav__item-header-triangle" focusable="false" aria-hidden="true" /> <TriangleIcon className="nav__item-header-triangle" focusable="false" aria-hidden="true" />
</button> </button>
<ul className="nav__dropdown"> <ul className="nav__dropdown">
@ -443,7 +443,7 @@ class Nav extends React.PureComponent {
onFocus={this.handleFocusForSketch} onFocus={this.handleFocusForSketch}
onBlur={this.handleBlur} onBlur={this.handleBlur}
> >
{this.props.t('AddFile')} {this.props.t('Nav.Sketch.AddFile')}
</button> </button>
</li> </li>
<li className="nav__dropdown-item"> <li className="nav__dropdown-item">
@ -452,7 +452,7 @@ class Nav extends React.PureComponent {
onFocus={this.handleFocusForSketch} onFocus={this.handleFocusForSketch}
onBlur={this.handleBlur} onBlur={this.handleBlur}
> >
{this.props.t('AddFolder')} {this.props.t('Nav.Sketch.AddFolder')}
</button> </button>
</li> </li>
<li className="nav__dropdown-item"> <li className="nav__dropdown-item">
@ -461,7 +461,7 @@ class Nav extends React.PureComponent {
onFocus={this.handleFocusForSketch} onFocus={this.handleFocusForSketch}
onBlur={this.handleBlur} onBlur={this.handleBlur}
> >
{this.props.t('Run')} {this.props.t('Nav.Sketch.Run')}
<span className="nav__keyboard-shortcut">{metaKeyName}+Enter</span> <span className="nav__keyboard-shortcut">{metaKeyName}+Enter</span>
</button> </button>
</li> </li>
@ -471,7 +471,7 @@ class Nav extends React.PureComponent {
onFocus={this.handleFocusForSketch} onFocus={this.handleFocusForSketch}
onBlur={this.handleBlur} onBlur={this.handleBlur}
> >
{this.props.t('Stop')} {this.props.t('Nav.Sketch.Stop')}
<span className="nav__keyboard-shortcut">{'\u21E7'}+{metaKeyName}+Enter</span> <span className="nav__keyboard-shortcut">{'\u21E7'}+{metaKeyName}+Enter</span>
</button> </button>
</li> </li>
@ -508,7 +508,7 @@ class Nav extends React.PureComponent {
} }
}} }}
> >
<span className="nav__item-header">{this.props.t('Help')}</span> <span className="nav__item-header">{this.props.t('Nav.Help.Title')}</span>
<TriangleIcon className="nav__item-header-triangle" focusable="false" aria-hidden="true" /> <TriangleIcon className="nav__item-header-triangle" focusable="false" aria-hidden="true" />
</button> </button>
<ul className="nav__dropdown"> <ul className="nav__dropdown">
@ -518,7 +518,7 @@ class Nav extends React.PureComponent {
onBlur={this.handleBlur} onBlur={this.handleBlur}
onClick={this.handleKeyboardShortcuts} onClick={this.handleKeyboardShortcuts}
> >
{this.props.t('KeyboardShortcuts')} {this.props.t('Nav.Help.KeyboardShortcuts')}
</button> </button>
</li> </li>
<li className="nav__dropdown-item"> <li className="nav__dropdown-item">
@ -529,7 +529,7 @@ class Nav extends React.PureComponent {
onFocus={this.handleFocusForHelp} onFocus={this.handleFocusForHelp}
onBlur={this.handleBlur} onBlur={this.handleBlur}
onClick={this.setDropdownForNone} onClick={this.setDropdownForNone}
>{this.props.t('Reference')} >{this.props.t('Nav.Help.Reference')}
</a> </a>
</li> </li>
<li className="nav__dropdown-item"> <li className="nav__dropdown-item">
@ -539,7 +539,7 @@ class Nav extends React.PureComponent {
onBlur={this.handleBlur} onBlur={this.handleBlur}
onClick={this.setDropdownForNone} onClick={this.setDropdownForNone}
> >
{this.props.t('About')} {this.props.t('Nav.Help.About')}
</Link> </Link>
</li> </li>
</ul> </ul>
@ -562,7 +562,7 @@ class Nav extends React.PureComponent {
} }
}} }}
> >
<span className="nav__item-header"> {this.props.t('Lang')}</span> <span className="nav__item-header"> {this.props.t('Nav.Lang')}</span>
<TriangleIcon className="nav__item-header-triangle" focusable="false" aria-hidden="true" /> <TriangleIcon className="nav__item-header-triangle" focusable="false" aria-hidden="true" />
</button> </button>
<ul className="nav__dropdown"> <ul className="nav__dropdown">
@ -608,13 +608,13 @@ class Nav extends React.PureComponent {
<ul className="nav__items-right" title="user-menu"> <ul className="nav__items-right" title="user-menu">
<li className="nav__item"> <li className="nav__item">
<Link to="/login" className="nav__auth-button"> <Link to="/login" className="nav__auth-button">
<span className="nav__item-header">{this.props.t('Login')}</span> <span className="nav__item-header">{this.props.t('Nav.Login.Login')}</span>
</Link> </Link>
</li> </li>
<span className="nav__item-or">{this.props.t('LoginOr')}</span> <span className="nav__item-or">{this.props.t('Nav.Login.LoginOr')}</span>
<li className="nav__item"> <li className="nav__item">
<Link to="/signup" className="nav__auth-button"> <Link to="/signup" className="nav__auth-button">
<span className="nav__item-header">{this.props.t('SignUp')}</span> <span className="nav__item-header">{this.props.t('Nav.Login.SignUp')}</span>
</Link> </Link>
</li> </li>
</ul> </ul>
@ -625,7 +625,7 @@ class Nav extends React.PureComponent {
return ( return (
<ul className="nav__items-right" title="user-menu"> <ul className="nav__items-right" title="user-menu">
<li className="nav__item"> <li className="nav__item">
<span>{this.props.t('Hello')}, {this.props.user.username}!</span> <span>{this.props.t('Nav.Auth.Hello')}, {this.props.user.username}!</span>
</li> </li>
<span className="nav__item-spacer">|</span> <span className="nav__item-spacer">|</span>
<li className={navDropdownState.account}> <li className={navDropdownState.account}>
@ -640,7 +640,7 @@ class Nav extends React.PureComponent {
} }
}} }}
> >
{this.props.t('MyAccount')} {this.props.t('Nav.Auth.MyAccount')}
<TriangleIcon className="nav__item-header-triangle" focusable="false" aria-hidden="true" /> <TriangleIcon className="nav__item-header-triangle" focusable="false" aria-hidden="true" />
</button> </button>
<ul className="nav__dropdown"> <ul className="nav__dropdown">
@ -651,7 +651,7 @@ class Nav extends React.PureComponent {
onBlur={this.handleBlur} onBlur={this.handleBlur}
onClick={this.setDropdownForNone} onClick={this.setDropdownForNone}
> >
{this.props.t('MySketches')} {this.props.t('Nav.Auth.MySketches')}
</Link> </Link>
</li> </li>
{getConfig('UI_COLLECTIONS_ENABLED') && {getConfig('UI_COLLECTIONS_ENABLED') &&
@ -662,7 +662,7 @@ class Nav extends React.PureComponent {
onBlur={this.handleBlur} onBlur={this.handleBlur}
onClick={this.setDropdownForNone} onClick={this.setDropdownForNone}
> >
{this.props.t('MyCollections')} {this.props.t('Nav.Auth.MyCollections')}
</Link> </Link>
</li> </li>
} }
@ -673,7 +673,7 @@ class Nav extends React.PureComponent {
onBlur={this.handleBlur} onBlur={this.handleBlur}
onClick={this.setDropdownForNone} onClick={this.setDropdownForNone}
> >
{this.props.t('MyAssets')} {this.props.t('Nav.Auth.MyAssets')}
</Link> </Link>
</li> </li>
<li className="nav__dropdown-item"> <li className="nav__dropdown-item">
@ -683,7 +683,7 @@ class Nav extends React.PureComponent {
onBlur={this.handleBlur} onBlur={this.handleBlur}
onClick={this.setDropdownForNone} onClick={this.setDropdownForNone}
> >
{this.props.t('Settings')} {this.props.t('Preferences.Settings')}
</Link> </Link>
</li> </li>
<li className="nav__dropdown-item"> <li className="nav__dropdown-item">
@ -692,7 +692,7 @@ class Nav extends React.PureComponent {
onFocus={this.handleFocusForAccount} onFocus={this.handleFocusForAccount}
onBlur={this.handleBlur} onBlur={this.handleBlur}
> >
{this.props.t('LogOut')} {this.props.t('Nav.Auth.LogOut')}
</button> </button>
</li> </li>
</ul> </ul>
@ -842,5 +842,5 @@ const mapDispatchToProps = {
setAllAccessibleOutput setAllAccessibleOutput
}; };
export default withTranslation('WebEditor')(withRouter(connect(mapStateToProps, mapDispatchToProps)(Nav))); export default withTranslation()(withRouter(connect(mapStateToProps, mapDispatchToProps)(Nav)));
export { Nav as NavComponent }; export { Nav as NavComponent };

View file

@ -14,7 +14,6 @@ exports[`Nav renders correctly 1`] = `
class="nav__item-logo" class="nav__item-logo"
> >
<test-file-stub <test-file-stub
aria-label="p5.js Logo"
classname="svg__logo" classname="svg__logo"
focusable="false" focusable="false"
role="img" role="img"

View file

@ -0,0 +1,10 @@
import React from 'react';
import { useModalBehavior } from '../utils/custom-hooks';
export default (component) => {
const [visible, trigger, setRef] = useModalBehavior();
const wrapper = () => <div ref={setRef}> {visible && component} </div>; // eslint-disable-line
return [trigger, wrapper];
};

View file

@ -16,11 +16,10 @@ const options = {
i18n i18n
.use(initReactI18next) // pass the i18n instance to react-i18next. .use(initReactI18next) // pass the i18n instance to react-i18next.
.use(LanguageDetector)// to detect the language from currentBrowser // .use(LanguageDetector)// to detect the language from currentBrowser
.use(Backend) // to fetch the data from server .use(Backend) // to fetch the data from server
.init({ .init({
lng: 'en-US', lng: 'en-US',
defaultNS: 'WebEditor',
fallbackLng, // if user computer language is not on the list of available languages, than we will be using the fallback language specified earlier fallbackLng, // if user computer language is not on the list of available languages, than we will be using the fallback language specified earlier
debug: false, debug: false,
backend: options, backend: options,

View file

@ -157,19 +157,19 @@ export function saveProject(selectedFile = null, autosave = false) {
if (!autosave) { if (!autosave) {
if (state.ide.justOpenedProject && state.preferences.autosave) { if (state.ide.justOpenedProject && state.preferences.autosave) {
dispatch(showToast(5500)); dispatch(showToast(5500));
dispatch(setToastText('Sketch saved.')); dispatch(setToastText('Toast.SketchSaved'));
setTimeout(() => dispatch(setToastText('Autosave enabled.')), 1500); setTimeout(() => dispatch(setToastText('Toast.AutosaveEnabled')), 1500);
dispatch(resetJustOpenedProject()); dispatch(resetJustOpenedProject());
} else { } else {
dispatch(showToast(1500)); dispatch(showToast(1500));
dispatch(setToastText('Sketch saved.')); dispatch(setToastText('Toast.SketchSaved'));
} }
} }
}) })
.catch((error) => { .catch((error) => {
const { response } = error; const { response } = error;
dispatch(endSavingProject()); dispatch(endSavingProject());
dispatch(setToastText('Failed to save sketch.')); dispatch(setToastText('Toast.SketchFailedSave'));
dispatch(showToast(1500)); dispatch(showToast(1500));
if (response.status === 403) { if (response.status === 403) {
dispatch(showErrorModal('staleSession')); dispatch(showErrorModal('staleSession'));
@ -199,19 +199,19 @@ export function saveProject(selectedFile = null, autosave = false) {
if (!autosave) { if (!autosave) {
if (state.preferences.autosave) { if (state.preferences.autosave) {
dispatch(showToast(5500)); dispatch(showToast(5500));
dispatch(setToastText('Sketch saved.')); dispatch(setToastText('Toast.SketchSaved'));
setTimeout(() => dispatch(setToastText('Autosave enabled.')), 1500); setTimeout(() => dispatch(setToastText('Toast.AutosaveEnabled')), 1500);
dispatch(resetJustOpenedProject()); dispatch(resetJustOpenedProject());
} else { } else {
dispatch(showToast(1500)); dispatch(showToast(1500));
dispatch(setToastText('Sketch saved.')); dispatch(setToastText('Toast.SketchSaved'));
} }
} }
}) })
.catch((error) => { .catch((error) => {
const { response } = error; const { response } = error;
dispatch(endSavingProject()); dispatch(endSavingProject());
dispatch(setToastText('Failed to save sketch.')); dispatch(setToastText('Toast.SketchFailedSave'));
dispatch(showToast(1500)); dispatch(showToast(1500));
if (response.status === 403) { if (response.status === 403) {
dispatch(showErrorModal('staleSession')); dispatch(showErrorModal('staleSession'));

View file

@ -10,23 +10,13 @@ function About(props) {
return ( return (
<div className="about__content"> <div className="about__content">
<Helmet> <Helmet>
<title>p5.js Web Editor | About </title> <title> {t('About.TitleHelmet')} </title>
</Helmet> </Helmet>
<div className="about__content-column"> <div className="about__content-column">
<SquareLogoIcon className="about__logo" role="img" aria-label="p5.js Logo" focusable="false" /> <SquareLogoIcon className="about__logo" role="img" aria-label={t('Common.p5logoARIA')} focusable="false" />
{/* Video button to hello p5 video page */}
{/* <p className="about__play-video">
<a
href="http://hello.p5js.org/"
target="_blank"
rel="noopener noreferrer"
>
<PlayIcon className="about__play-video-button" title="Play Hello Video" />
Play hello! video</a>
</p> */}
</div> </div>
<div className="about__content-column"> <div className="about__content-column">
<h3 className="about__content-column-title">{t('NewP5')}</h3> <h3 className="about__content-column-title">{t('About.NewP5')}</h3>
<p className="about__content-column-list"> <p className="about__content-column-list">
<a <a
href="https://p5js.org/examples/" href="https://p5js.org/examples/"
@ -34,7 +24,7 @@ function About(props) {
rel="noopener noreferrer" rel="noopener noreferrer"
> >
<AsteriskIcon className="about__content-column-asterisk" aria-hidden="true" focusable="false" /> <AsteriskIcon className="about__content-column-asterisk" aria-hidden="true" focusable="false" />
{t('Examples')} {t('About.Examples')}
</a> </a>
</p> </p>
<p className="about__content-column-list"> <p className="about__content-column-list">
@ -44,12 +34,12 @@ function About(props) {
rel="noopener noreferrer" rel="noopener noreferrer"
> >
<AsteriskIcon className="about__content-column-asterisk" aria-hidden="true" focusable="false" /> <AsteriskIcon className="about__content-column-asterisk" aria-hidden="true" focusable="false" />
{t('Learn')} {t('About.Learn')}
</a> </a>
</p> </p>
</div> </div>
<div className="about__content-column"> <div className="about__content-column">
<h3 className="about__content-column-title">{t('Resources')}</h3> <h3 className="about__content-column-title">{t('About.Resources')}</h3>
<p className="about__content-column-list"> <p className="about__content-column-list">
<a <a
href="https://p5js.org/libraries/" href="https://p5js.org/libraries/"
@ -57,7 +47,7 @@ function About(props) {
rel="noopener noreferrer" rel="noopener noreferrer"
> >
<AsteriskIcon className="about__content-column-asterisk" aria-hidden="true" focusable="false" /> <AsteriskIcon className="about__content-column-asterisk" aria-hidden="true" focusable="false" />
{t('Libraries')} {t('About.Libraries')}
</a> </a>
</p> </p>
<p className="about__content-column-list"> <p className="about__content-column-list">
@ -67,7 +57,7 @@ function About(props) {
rel="noopener noreferrer" rel="noopener noreferrer"
> >
<AsteriskIcon className="about__content-column-asterisk" aria-hidden="true" focusable="false" /> <AsteriskIcon className="about__content-column-asterisk" aria-hidden="true" focusable="false" />
{t('Reference')} {t('Nav.Help.Reference')}
</a> </a>
</p> </p>
<p className="about__content-column-list"> <p className="about__content-column-list">
@ -77,7 +67,7 @@ function About(props) {
rel="noopener noreferrer" rel="noopener noreferrer"
> >
<AsteriskIcon className="about__content-column-asterisk" aria-hidden="true" focusable="false" /> <AsteriskIcon className="about__content-column-asterisk" aria-hidden="true" focusable="false" />
{t('Forum')} {t('About.Forum')}
</a> </a>
</p> </p>
</div> </div>
@ -87,7 +77,7 @@ function About(props) {
href="https://github.com/processing/p5.js-web-editor" href="https://github.com/processing/p5.js-web-editor"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
>{t('Contribute')} >{t('About.Contribute')}
</a> </a>
</p> </p>
<p className="about__footer-list"> <p className="about__footer-list">
@ -95,7 +85,7 @@ function About(props) {
href="https://github.com/processing/p5.js-web-editor/issues/new" href="https://github.com/processing/p5.js-web-editor/issues/new"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
>{t('Report')} >{t('About.Report')}
</a> </a>
</p> </p>
<p className="about__footer-list"> <p className="about__footer-list">

View file

@ -6,50 +6,50 @@ function KeyboardShortcutModal() {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<div className="keyboard-shortcuts"> <div className="keyboard-shortcuts">
<h3 className="keyboard-shortcuts__title">{t('CodeEditing')}</h3> <h3 className="keyboard-shortcuts__title">{t('KeyboardShortcuts.CodeEditing.CodeEditing')}</h3>
<p className="keyboard-shortcuts__description"> <p className="keyboard-shortcuts__description">
{t('Code editing keyboard shortcuts follow')} <a href="https://shortcuts.design/toolspage-sublimetext.html" target="_blank" rel="noopener noreferrer">{t('Sublime Text shortcuts')}</a>. {t('KeyboardShortcuts.ShortcutsFollow')} <a href="https://shortcuts.design/toolspage-sublimetext.html" target="_blank" rel="noopener noreferrer">{t('KeyboardShortcuts.SublimeText')}</a>.
</p> </p>
<ul className="keyboard-shortcuts__list"> <ul className="keyboard-shortcuts__list">
<li className="keyboard-shortcut-item"> <li className="keyboard-shortcut-item">
<span className="keyboard-shortcut__command">{'\u21E7'} + Tab</span> <span className="keyboard-shortcut__command">{'\u21E7'} + Tab</span>
<span>{t('Tidy')}</span> <span>{t('KeyboardShortcuts.CodeEditing.Tidy')}</span>
</li> </li>
<li className="keyboard-shortcut-item"> <li className="keyboard-shortcut-item">
<span className="keyboard-shortcut__command"> <span className="keyboard-shortcut__command">
{metaKeyName} + F {metaKeyName} + F
</span> </span>
<span>{t('FindText')}</span> <span>{t('KeyboardShortcuts.CodeEditing.FindText')}</span>
</li> </li>
<li className="keyboard-shortcut-item"> <li className="keyboard-shortcut-item">
<span className="keyboard-shortcut__command"> <span className="keyboard-shortcut__command">
{metaKeyName} + G {metaKeyName} + G
</span> </span>
<span>{t('FindNextTextMatch')}</span> <span>{t('KeyboardShortcuts.CodeEditing.FindNextTextMatch')}</span>
</li> </li>
<li className="keyboard-shortcut-item"> <li className="keyboard-shortcut-item">
<span className="keyboard-shortcut__command"> <span className="keyboard-shortcut__command">
{metaKeyName} + {'\u21E7'} + G {metaKeyName} + {'\u21E7'} + G
</span> </span>
<span>{t('FindPreviousTextMatch')}</span> <span>{t('KeyboardShortcuts.CodeEditing.FindPreviousTextMatch')}</span>
</li> </li>
<li className="keyboard-shortcut-item"> <li className="keyboard-shortcut-item">
<span className="keyboard-shortcut__command"> <span className="keyboard-shortcut__command">
{metaKeyName} + [ {metaKeyName} + [
</span> </span>
<span>{t('IndentCodeLeft')}</span> <span>{t('KeyboardShortcuts.CodeEditing.IndentCodeLeft')}</span>
</li> </li>
<li className="keyboard-shortcut-item"> <li className="keyboard-shortcut-item">
<span className="keyboard-shortcut__command"> <span className="keyboard-shortcut__command">
{metaKeyName} + ] {metaKeyName} + ]
</span> </span>
<span>{t('IndentCodeRight')}</span> <span>{t('KeyboardShortcuts.CodeEditing.IndentCodeRight')}</span>
</li> </li>
<li className="keyboard-shortcut-item"> <li className="keyboard-shortcut-item">
<span className="keyboard-shortcut__command"> <span className="keyboard-shortcut__command">
{metaKeyName} + / {metaKeyName} + /
</span> </span>
<span>{t('CommentLine')}</span> <span>{t('KeyboardShortcuts.CodeEditing.CommentLine')}</span>
</li> </li>
</ul> </ul>
<h3 className="keyboard-shortcuts__title">General</h3> <h3 className="keyboard-shortcuts__title">General</h3>
@ -58,31 +58,31 @@ function KeyboardShortcutModal() {
<span className="keyboard-shortcut__command"> <span className="keyboard-shortcut__command">
{metaKeyName} + S {metaKeyName} + S
</span> </span>
<span>{t('Save')}</span> <span>{t('Common.Save')}</span>
</li> </li>
<li className="keyboard-shortcut-item"> <li className="keyboard-shortcut-item">
<span className="keyboard-shortcut__command"> <span className="keyboard-shortcut__command">
{metaKeyName} + Enter {metaKeyName} + Enter
</span> </span>
<span>{t('StartSketch')}</span> <span>{t('KeyboardShortcuts.General.StartSketch')}</span>
</li> </li>
<li className="keyboard-shortcut-item"> <li className="keyboard-shortcut-item">
<span className="keyboard-shortcut__command"> <span className="keyboard-shortcut__command">
{metaKeyName} + {'\u21E7'} + Enter {metaKeyName} + {'\u21E7'} + Enter
</span> </span>
<span>{t('StopSketch')}</span> <span>{t('KeyboardShortcuts.General.StopSketch')}</span>
</li> </li>
<li className="keyboard-shortcut-item"> <li className="keyboard-shortcut-item">
<span className="keyboard-shortcut__command"> <span className="keyboard-shortcut__command">
{metaKeyName} + {'\u21E7'} + 1 {metaKeyName} + {'\u21E7'} + 1
</span> </span>
<span>{t('TurnOnAccessibleOutput')}</span> <span>{t('KeyboardShortcuts.General.TurnOnAccessibleOutput')}</span>
</li> </li>
<li className="keyboard-shortcut-item"> <li className="keyboard-shortcut-item">
<span className="keyboard-shortcut__command"> <span className="keyboard-shortcut__command">
{metaKeyName} + {'\u21E7'} + 2 {metaKeyName} + {'\u21E7'} + 2
</span> </span>
<span>{t('TurnOffAccessibleOutput')}</span> <span>{t('KeyboardShortcuts.General.TurnOffAccessibleOutput')}</span>
</li> </li>
</ul> </ul>
</div> </div>

View file

@ -99,59 +99,59 @@ class Preferences extends React.Component {
<Tabs> <Tabs>
<TabList> <TabList>
<div className="tabs__titles"> <div className="tabs__titles">
<Tab><h4 className="tabs__title">{this.props.t('GeneralSettings')}</h4></Tab> <Tab><h4 className="tabs__title">{this.props.t('Preferences.GeneralSettings')}</h4></Tab>
<Tab><h4 className="tabs__title">{this.props.t('Accessibility')}</h4></Tab> <Tab><h4 className="tabs__title">{this.props.t('Preferences.Accessibility')}</h4></Tab>
</div> </div>
</TabList> </TabList>
<TabPanel> <TabPanel>
<div className="preference"> <div className="preference">
<h4 className="preference__title">{this.props.t('Theme')}</h4> <h4 className="preference__title">{this.props.t('Preferences.Theme')}</h4>
<div className="preference__options"> <div className="preference__options">
<input <input
type="radio" type="radio"
onChange={() => this.props.setTheme('light')} onChange={() => this.props.setTheme('light')}
aria-label="light theme on" aria-label={this.props.t('Preferences.LightThemeARIA')}
name="light theme" name="light theme"
id="light-theme-on" id="light-theme-on"
className="preference__radio-button" className="preference__radio-button"
value="light" value="light"
checked={this.props.theme === 'light'} checked={this.props.theme === 'light'}
/> />
<label htmlFor="light-theme-on" className="preference__option">{this.props.t('Light')}</label> <label htmlFor="light-theme-on" className="preference__option">{this.props.t('Preferences.LightTheme')}</label>
<input <input
type="radio" type="radio"
onChange={() => this.props.setTheme('dark')} onChange={() => this.props.setTheme('dark')}
aria-label="dark theme on" aria-label={this.props.t('Preferences.DarkThemeARIA')}
name="dark theme" name="dark theme"
id="dark-theme-on" id="dark-theme-on"
className="preference__radio-button" className="preference__radio-button"
value="dark" value="dark"
checked={this.props.theme === 'dark'} checked={this.props.theme === 'dark'}
/> />
<label htmlFor="dark-theme-on" className="preference__option">{this.props.t('Dark')}</label> <label htmlFor="dark-theme-on" className="preference__option">{this.props.t('Preferences.DarkTheme')}</label>
<input <input
type="radio" type="radio"
onChange={() => this.props.setTheme('contrast')} onChange={() => this.props.setTheme('contrast')}
aria-label="high contrast theme on" aria-label={this.props.t('Preferences.HighContrastThemeARIA')}
name="high contrast theme" name="high contrast theme"
id="high-contrast-theme-on" id="high-contrast-theme-on"
className="preference__radio-button" className="preference__radio-button"
value="contrast" value="contrast"
checked={this.props.theme === 'contrast'} checked={this.props.theme === 'contrast'}
/> />
<label htmlFor="high-contrast-theme-on" className="preference__option">{this.props.t('HighContrast')}</label> <label htmlFor="high-contrast-theme-on" className="preference__option">{this.props.t('Preferences.HighContrastTheme')}</label>
</div> </div>
</div> </div>
<div className="preference"> <div className="preference">
<h4 className="preference__title">{this.props.t('TextSize')}</h4> <h4 className="preference__title">{this.props.t('Preferences.TextSize')}</h4>
<button <button
className="preference__minus-button" className="preference__minus-button"
onClick={this.decreaseFontSize} onClick={this.decreaseFontSize}
aria-label="decrease font size" aria-label={this.props.t('Preferences.DecreaseFontARIA')}
disabled={this.state.fontSize <= 8} disabled={this.state.fontSize <= 8}
> >
<MinusIcon focusable="false" aria-hidden="true" /> <MinusIcon focusable="false" aria-hidden="true" />
<h6 className="preference__label">{this.props.t('Decrease')}</h6> <h6 className="preference__label">{this.props.t('Preferences.DecreaseFont')}</h6>
</button> </button>
<form onSubmit={this.onFontInputSubmit}> <form onSubmit={this.onFontInputSubmit}>
<input <input
@ -168,133 +168,133 @@ class Preferences extends React.Component {
<button <button
className="preference__plus-button" className="preference__plus-button"
onClick={this.increaseFontSize} onClick={this.increaseFontSize}
aria-label="increase font size" aria-label={this.props.t('Preferences.IncreaseFontARIA')}
disabled={this.state.fontSize >= 36} disabled={this.state.fontSize >= 36}
> >
<PlusIcon focusable="false" aria-hidden="true" /> <PlusIcon focusable="false" aria-hidden="true" />
<h6 className="preference__label">{this.props.t('Increase')}</h6> <h6 className="preference__label">{this.props.t('Preferences.IncreaseFont')}</h6>
</button> </button>
</div> </div>
<div className="preference"> <div className="preference">
<h4 className="preference__title">{this.props.t('Autosave')}</h4> <h4 className="preference__title">{this.props.t('Preferences.Autosave')}</h4>
<div className="preference__options"> <div className="preference__options">
<input <input
type="radio" type="radio"
onChange={() => this.props.setAutosave(true)} onChange={() => this.props.setAutosave(true)}
aria-label="autosave on" aria-label={this.props.t('Preferences.AutosaveOnARIA')}
name="autosave" name="autosave"
id="autosave-on" id="autosave-on"
className="preference__radio-button" className="preference__radio-button"
value="On" value="On"
checked={this.props.autosave} checked={this.props.autosave}
/> />
<label htmlFor="autosave-on" className="preference__option">{this.props.t('On')}</label> <label htmlFor="autosave-on" className="preference__option">{this.props.t('Preferences.On')}</label>
<input <input
type="radio" type="radio"
onChange={() => this.props.setAutosave(false)} onChange={() => this.props.setAutosave(false)}
aria-label="autosave off" aria-label={this.props.t('Preferences.AutosaveOffARIA')}
name="autosave" name="autosave"
id="autosave-off" id="autosave-off"
className="preference__radio-button" className="preference__radio-button"
value="Off" value="Off"
checked={!this.props.autosave} checked={!this.props.autosave}
/> />
<label htmlFor="autosave-off" className="preference__option">{this.props.t('Off')}</label> <label htmlFor="autosave-off" className="preference__option">{this.props.t('Preferences.Off')}</label>
</div> </div>
</div> </div>
<div className="preference"> <div className="preference">
<h4 className="preference__title">{this.props.t('WordWrap')}</h4> <h4 className="preference__title">{this.props.t('Preferences.WordWrap')}</h4>
<div className="preference__options"> <div className="preference__options">
<input <input
type="radio" type="radio"
onChange={() => this.props.setLinewrap(true)} onChange={() => this.props.setLinewrap(true)}
aria-label="linewrap on" aria-label={this.props.t('Preferences.LineWrapOnARIA')}
name="linewrap" name="linewrap"
id="linewrap-on" id="linewrap-on"
className="preference__radio-button" className="preference__radio-button"
value="On" value="On"
checked={this.props.linewrap} checked={this.props.linewrap}
/> />
<label htmlFor="linewrap-on" className="preference__option">{this.props.t('On')}</label> <label htmlFor="linewrap-on" className="preference__option">{this.props.t('Preferences.On')}</label>
<input <input
type="radio" type="radio"
onChange={() => this.props.setLinewrap(false)} onChange={() => this.props.setLinewrap(false)}
aria-label="linewrap off" aria-label={this.props.t('Preferences.LineWrapOffARIA')}
name="linewrap" name="linewrap"
id="linewrap-off" id="linewrap-off"
className="preference__radio-button" className="preference__radio-button"
value="Off" value="Off"
checked={!this.props.linewrap} checked={!this.props.linewrap}
/> />
<label htmlFor="linewrap-off" className="preference__option">{this.props.t('Off')}</label> <label htmlFor="linewrap-off" className="preference__option">{this.props.t('Preferences.Off')}</label>
</div> </div>
</div> </div>
</TabPanel> </TabPanel>
<TabPanel> <TabPanel>
<div className="preference"> <div className="preference">
<h4 className="preference__title">{this.props.t('LineNumbers')}</h4> <h4 className="preference__title">{this.props.t('Preferences.LineNumbers')}</h4>
<div className="preference__options"> <div className="preference__options">
<input <input
type="radio" type="radio"
onChange={() => this.props.setLineNumbers(true)} onChange={() => this.props.setLineNumbers(true)}
aria-label="line numbers on" aria-label={this.props.t('Preferences.LineNumbersOnARIA')}
name="line numbers" name="line numbers"
id="line-numbers-on" id="line-numbers-on"
className="preference__radio-button" className="preference__radio-button"
value="On" value="On"
checked={this.props.lineNumbers} checked={this.props.lineNumbers}
/> />
<label htmlFor="line-numbers-on" className="preference__option">{this.props.t('On')}</label> <label htmlFor="line-numbers-on" className="preference__option">{this.props.t('Preferences.On')}</label>
<input <input
type="radio" type="radio"
onChange={() => this.props.setLineNumbers(false)} onChange={() => this.props.setLineNumbers(false)}
aria-label="line numbers off" aria-label={this.props.t('Preferences.LineNumbersOffARIA')}
name="line numbers" name="line numbers"
id="line-numbers-off" id="line-numbers-off"
className="preference__radio-button" className="preference__radio-button"
value="Off" value="Off"
checked={!this.props.lineNumbers} checked={!this.props.lineNumbers}
/> />
<label htmlFor="line-numbers-off" className="preference__option">{this.props.t('Off')}</label> <label htmlFor="line-numbers-off" className="preference__option">{this.props.t('Preferences.Off')}</label>
</div> </div>
</div> </div>
<div className="preference"> <div className="preference">
<h4 className="preference__title">{this.props.t('LintWarningSound')}</h4> <h4 className="preference__title">{this.props.t('Preferences.LintWarningSound')}</h4>
<div className="preference__options"> <div className="preference__options">
<input <input
type="radio" type="radio"
onChange={() => this.props.setLintWarning(true)} onChange={() => this.props.setLintWarning(true)}
aria-label="lint warning on" aria-label={this.props.t('Preferences.LintWarningOnARIA')}
name="lint warning" name="lint warning"
id="lint-warning-on" id="lint-warning-on"
className="preference__radio-button" className="preference__radio-button"
value="On" value="On"
checked={this.props.lintWarning} checked={this.props.lintWarning}
/> />
<label htmlFor="lint-warning-on" className="preference__option">{this.props.t('On')}</label> <label htmlFor="lint-warning-on" className="preference__option">{this.props.t('Preferences.On')}</label>
<input <input
type="radio" type="radio"
onChange={() => this.props.setLintWarning(false)} onChange={() => this.props.setLintWarning(false)}
aria-label="lint warning off" aria-label={this.props.t('Preferences.LintWarningOffARIA')}
name="lint warning" name="lint warning"
id="lint-warning-off" id="lint-warning-off"
className="preference__radio-button" className="preference__radio-button"
value="Off" value="Off"
checked={!this.props.lintWarning} checked={!this.props.lintWarning}
/> />
<label htmlFor="lint-warning-off" className="preference__option">{this.props.t('Off')}</label> <label htmlFor="lint-warning-off" className="preference__option">{this.props.t('Preferences.Off')}</label>
<button <button
className="preference__preview-button" className="preference__preview-button"
onClick={() => beep.play()} onClick={() => beep.play()}
aria-label="preview sound" aria-label={this.props.t('Preferences.PreviewSoundARIA')}
> >
{this.props.t('PreviewSound')} {this.props.t('Preferences.PreviewSound')}
</button> </button>
</div> </div>
</div> </div>
<div className="preference"> <div className="preference">
<h4 className="preference__title">{this.props.t('AccessibleTextBasedCanvas')}</h4> <h4 className="preference__title">{this.props.t('Preferences.AccessibleTextBasedCanvas')}</h4>
<h6 className="preference__subtitle">{this.props.t('UsedScreenReader')}</h6> <h6 className="preference__subtitle">{this.props.t('Preferences.UsedScreenReader')}</h6>
<div className="preference__options"> <div className="preference__options">
<input <input
@ -302,37 +302,37 @@ class Preferences extends React.Component {
onChange={(event) => { onChange={(event) => {
this.props.setTextOutput(event.target.checked); this.props.setTextOutput(event.target.checked);
}} }}
aria-label="text output on" aria-label={this.props.t('Preferences.TextOutputARIA')}
name="text output" name="text output"
id="text-output-on" id="text-output-on"
value="On" value="On"
checked={(this.props.textOutput)} checked={(this.props.textOutput)}
/> />
<label htmlFor="text-output-on" className="preference__option preference__canvas">{this.props.t('PlainText')}</label> <label htmlFor="text-output-on" className="preference__option preference__canvas">{this.props.t('Preferences.PlainText')}</label>
<input <input
type="checkbox" type="checkbox"
onChange={(event) => { onChange={(event) => {
this.props.setGridOutput(event.target.checked); this.props.setGridOutput(event.target.checked);
}} }}
aria-label="table output on" aria-label={this.props.t('Preferences.TableOutputARIA')}
name="table output" name="table output"
id="table-output-on" id="table-output-on"
value="On" value="On"
checked={(this.props.gridOutput)} checked={(this.props.gridOutput)}
/> />
<label htmlFor="table-output-on" className="preference__option preference__canvas">{this.props.t('TableText')}</label> <label htmlFor="table-output-on" className="preference__option preference__canvas">{this.props.t('Preferences.TableText')}</label>
<input <input
type="checkbox" type="checkbox"
onChange={(event) => { onChange={(event) => {
this.props.setSoundOutput(event.target.checked); this.props.setSoundOutput(event.target.checked);
}} }}
aria-label="sound output on" aria-label={this.props.t('Preferences.SoundOutputARIA')}
name="sound output" name="sound output"
id="sound-output-on" id="sound-output-on"
value="On" value="On"
checked={(this.props.soundOutput)} checked={(this.props.soundOutput)}
/> />
<label htmlFor="sound-output-on" className="preference__option preference__canvas">{this.props.t('Sound')}</label> <label htmlFor="sound-output-on" className="preference__option preference__canvas">{this.props.t('Preferences.Sound')}</label>
</div> </div>
</div> </div>
</TabPanel> </TabPanel>
@ -364,4 +364,4 @@ Preferences.propTypes = {
t: PropTypes.func.isRequired, t: PropTypes.func.isRequired,
}; };
export default withTranslation('WebEditor')(Preferences); export default withTranslation()(Preferences);

View file

@ -8,7 +8,7 @@ import * as ToastActions from '../actions/toast';
import ExitIcon from '../../../images/exit.svg'; import ExitIcon from '../../../images/exit.svg';
function Toast(props) { function Toast(props) {
const { t } = useTranslation('WebEditor'); const { t } = useTranslation();
return ( return (
<section className="toast"> <section className="toast">
<p> <p>

View file

@ -3,6 +3,7 @@ import React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { Link } from 'react-router'; import { Link } from 'react-router';
import classNames from 'classnames'; import classNames from 'classnames';
import { withTranslation } from 'react-i18next';
import * as IDEActions from '../actions/ide'; import * as IDEActions from '../actions/ide';
import * as preferenceActions from '../actions/preferences'; import * as preferenceActions from '../actions/preferences';
import * as projectActions from '../actions/project'; import * as projectActions from '../actions/project';
@ -115,7 +116,7 @@ class Toolbar extends React.Component {
}} }}
/> />
<label htmlFor="autorefresh" className="toolbar__autorefresh-label"> <label htmlFor="autorefresh" className="toolbar__autorefresh-label">
Auto-refresh {this.props.t('Toolbar.Auto-refresh')}
</label> </label>
</div> </div>
<div className={nameContainerClass}> <div className={nameContainerClass}>
@ -197,7 +198,8 @@ Toolbar.propTypes = {
startSketch: PropTypes.func.isRequired, startSketch: PropTypes.func.isRequired,
startAccessibleSketch: PropTypes.func.isRequired, startAccessibleSketch: PropTypes.func.isRequired,
saveProject: PropTypes.func.isRequired, saveProject: PropTypes.func.isRequired,
currentUser: PropTypes.string currentUser: PropTypes.string,
t: PropTypes.func.isRequired
}; };
Toolbar.defaultProps = { Toolbar.defaultProps = {
@ -224,4 +226,5 @@ const mapDispatchToProps = {
}; };
export const ToolbarComponent = Toolbar; export const ToolbarComponent = Toolbar;
export default connect(mapStateToProps, mapDispatchToProps)(Toolbar); // export default connect(mapStateToProps, mapDispatchToProps)(Toolbar);
export default withTranslation()(connect(mapStateToProps, mapDispatchToProps)(Toolbar));

View file

@ -33,6 +33,7 @@ const renderComponent = (extraProps = {}) => {
isEditingName: false, isEditingName: false,
id: 'id', id: 'id',
}, },
t: jest.fn()
}, extraProps); }, extraProps);
render(<ToolbarComponent {...props} />); render(<ToolbarComponent {...props} />);

View file

@ -64,7 +64,7 @@ function warnIfUnsavedChanges(props) {
props.persistState(); props.persistState();
window.onbeforeunload = null; window.onbeforeunload = null;
} else if (props.ide.unsavedChanges) { } else if (props.ide.unsavedChanges) {
if (!window.confirm(props.t('WarningUnsavedChanges'))) { if (!window.confirm(props.t('Nav.WarningUnsavedChanges'))) {
return false; return false;
} }
props.setUnsavedChanges(false); props.setUnsavedChanges(false);
@ -268,8 +268,8 @@ class IDEView extends React.Component {
<Toolbar key={this.props.project.id} /> <Toolbar key={this.props.project.id} />
{this.props.ide.preferencesIsVisible && ( {this.props.ide.preferencesIsVisible && (
<Overlay <Overlay
title={this.props.t('Settings')} title={this.props.t('Preferences.Settings')}
ariaLabel="settings" ariaLabel={this.props.t('Preferences.Settings')}
closeOverlay={this.props.closePreferences} closeOverlay={this.props.closePreferences}
> >
<Preferences <Preferences
@ -388,9 +388,7 @@ class IDEView extends React.Component {
</SplitPane> </SplitPane>
<section className="preview-frame-holder"> <section className="preview-frame-holder">
<header className="preview-frame__header"> <header className="preview-frame__header">
<h2 className="preview-frame__title"> <h2 className="preview-frame__title">{this.props.t('Toolbar.Preview')}</h2>
{this.props.t('Preview')}
</h2>
</header> </header>
<div className="preview-frame__content"> <div className="preview-frame__content">
<div <div
@ -448,16 +446,16 @@ class IDEView extends React.Component {
)} )}
{this.props.location.pathname === '/about' && ( {this.props.location.pathname === '/about' && (
<Overlay <Overlay
title={this.props.t('About')} title={this.props.t('About.Title')}
previousPath={this.props.ide.previousPath} previousPath={this.props.ide.previousPath}
ariaLabel="about" ariaLabel={this.props.t('About.Title')}
> >
<About previousPath={this.props.ide.previousPath} /> <About previousPath={this.props.ide.previousPath} />
</Overlay> </Overlay>
)} )}
{this.props.location.pathname === '/feedback' && ( {this.props.location.pathname === '/feedback' && (
<Overlay <Overlay
title="Submit Feedback" title={this.props.t('IDEView.SubmitFeedback')}
previousPath={this.props.ide.previousPath} previousPath={this.props.ide.previousPath}
ariaLabel="submit-feedback" ariaLabel="submit-feedback"
> >
@ -494,8 +492,8 @@ class IDEView extends React.Component {
)} )}
{this.props.ide.keyboardShortcutVisible && ( {this.props.ide.keyboardShortcutVisible && (
<Overlay <Overlay
title={this.props.t('KeyboardShortcuts')} title={this.props.t('KeyboardShortcuts.Title')}
ariaLabel="keyboard shortcuts" ariaLabel={this.props.t('KeyboardShortcuts.Title')}
closeOverlay={this.props.closeKeyboardShortcutModal} closeOverlay={this.props.closeKeyboardShortcutModal}
> >
<KeyboardShortcutModal /> <KeyboardShortcutModal />
@ -504,7 +502,7 @@ class IDEView extends React.Component {
{this.props.ide.errorType && ( {this.props.ide.errorType && (
<Overlay <Overlay
title="Error" title="Error"
ariaLabel="error" ariaLabel={this.props.t('Common.Error')}
closeOverlay={this.props.hideErrorModal} closeOverlay={this.props.hideErrorModal}
> >
<ErrorModal <ErrorModal
@ -700,4 +698,5 @@ function mapDispatchToProps(dispatch) {
); );
} }
export default withTranslation('WebEditor')(withRouter(connect(mapStateToProps, mapDispatchToProps)(IDEView)));
export default withTranslation()(withRouter(connect(mapStateToProps, mapDispatchToProps)(IDEView)));

View file

@ -31,7 +31,7 @@ import Console from '../components/Console';
import { remSize } from '../../../theme'; import { remSize } from '../../../theme';
// import OverlayManager from '../../../components/OverlayManager'; // import OverlayManager from '../../../components/OverlayManager';
import ActionStrip from '../../../components/mobile/ActionStrip'; import ActionStrip from '../../../components/mobile/ActionStrip';
import { useAsModal } from '../../../utils/custom-hooks'; import useAsModal from '../../../components/useAsModal';
import { PreferencesIcon } from '../../../common/icons'; import { PreferencesIcon } from '../../../common/icons';
import Dropdown from '../../../components/Dropdown'; import Dropdown from '../../../components/Dropdown';
@ -48,27 +48,11 @@ const NavItem = styled.li`
const MobileIDEView = (props) => { const MobileIDEView = (props) => {
const { const {
preferences, preferences, ide, editorAccessibility, project, updateLintMessage, clearLintMessage,
ide, selectedFile, updateFileContent, files, user,
editorAccessibility, closeEditorOptions, showEditorOptions,
project, startRefreshSketch, stopSketch, expandSidebar, collapseSidebar, clearConsole, console,
updateLintMessage, showRuntimeErrorWarning, hideRuntimeErrorWarning, startSketch
clearLintMessage,
selectedFile,
updateFileContent,
files,
closeEditorOptions,
showEditorOptions,
startRefreshSketch,
stopSketch,
expandSidebar,
collapseSidebar,
clearConsole,
console,
showRuntimeErrorWarning,
hideRuntimeErrorWarning,
startSketch,
user
} = props; } = props;
const [tmController, setTmController] = useState(null); // eslint-disable-line const [tmController, setTmController] = useState(null); // eslint-disable-line
@ -90,7 +74,7 @@ const MobileIDEView = (props) => {
const [triggerNavDropdown, NavDropDown] = useAsModal(<Dropdown const [triggerNavDropdown, NavDropDown] = useAsModal(<Dropdown
items={username ? navOptionsLoggedIn : navOptionsLoggedOut} items={username ? navOptionsLoggedIn : navOptionsLoggedOut}
right align="right"
/>); />);
return ( return (

View file

@ -13,8 +13,8 @@ const defaultHTML =
`<!DOCTYPE html> `<!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/p5.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/addons/p5.sound.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/addons/p5.sound.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css"> <link rel="stylesheet" type="text/css" href="style.css">
<meta charset="utf-8" /> <meta charset="utf-8" />

View file

@ -1,4 +1,4 @@
import React, { useEffect, useRef, useMemo, useState } from 'react'; import React, { useEffect, useRef, useState } from 'react';
export const noop = () => {}; export const noop = () => {};
@ -22,7 +22,7 @@ export const useModalBehavior = (hideOverlay) => {
// Return values // Return values
const setRef = (r) => { ref.current = r; }; const setRef = (r) => { ref.current = r; };
const [visible, setVisible] = useState(true); const [visible, setVisible] = useState(true);
const trigger = () => setVisible(true); const trigger = () => setVisible(!visible);
const hide = () => setVisible(false); const hide = () => setVisible(false);
@ -40,12 +40,3 @@ export const useModalBehavior = (hideOverlay) => {
return [visible, trigger, setRef]; return [visible, trigger, setRef];
}; };
// TODO: This is HOC, not a hook. Where do we put it?
export const useAsModal = (component) => {
const [visible, trigger, setRef] = useModalBehavior();
const wrapper = () => (<div ref={setRef}> {visible && component} </div>); // eslint-disable-line
return [trigger, wrapper];
};

View file

@ -10,9 +10,8 @@ const defaultHTML =
`<!DOCTYPE html> `<!DOCTYPE html>
<html> <html>
<head> <head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/p5.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/addons/p5.dom.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/addons/p5.sound.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/addons/p5.sound.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css"> <link rel="stylesheet" type="text/css" href="style.css">
<meta charset="utf-8" /> <meta charset="utf-8" />

View file

@ -11,8 +11,8 @@ const defaultHTML =
`<!DOCTYPE html> `<!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/p5.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/addons/p5.sound.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/addons/p5.sound.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css"> <link rel="stylesheet" type="text/css" href="style.css">
<meta charset="utf-8" /> <meta charset="utf-8" />
</head> </head>

View file

@ -1,76 +1,39 @@
{ {
"Contribute": "Contribute", "Nav": {
"NewP5": "New to p5.js?", "File": {
"Report": "Report a bug", "Title": "File",
"Learn": "Learn",
"About": "About",
"Resources": "Resources",
"Libraries": "Libraries",
"Forum": "Forum",
"File": "File",
"New": "New", "New": "New",
"Save": "Save",
"Share": "Share", "Share": "Share",
"Duplicate": "Duplicate", "Duplicate": "Duplicate",
"Examples": "Examples", "Open": "Open",
"Edit": "Edit", "Download": "Download",
"AddToCollection": "Add to Collection",
"Examples": "Examples"
},
"Edit": {
"Title": "Edit",
"TidyCode": "Tidy Code", "TidyCode": "Tidy Code",
"Find": "Find", "Find": "Find",
"AddToCollection": "Add to Collection",
"FindNext": "Find Next", "FindNext": "Find Next",
"FindPrevious": "Find Previous", "FindPrevious": "Find Previous"
"Sketch": "Sketch", },
"Sketch": {
"Title": "Sketch",
"AddFile": "Add File", "AddFile": "Add File",
"AddFolder": "Add Folder", "AddFolder": "Add Folder",
"Run": "Run", "Run": "Run",
"Stop": "Stop", "Stop": "Stop"
"Help": "Help", },
"Help": {
"Title": "Help",
"KeyboardShortcuts": "Keyboard Shortcuts", "KeyboardShortcuts": "Keyboard Shortcuts",
"Reference": "Reference", "Reference": "Reference",
"Tidy": "Tidy", "About": "About"
},
"Lang": "Language", "Lang": "Language",
"FindNextMatch": "Find Next Match", "BackEditor": "Back to Editor",
"FindPrevMatch": "Find Previous Match", "WarningUnsavedChanges": "Are you sure you want to leave this page? You have unsaved changes.",
"IndentCodeLeft": "Indent Code Left", "Login": {
"IndentCodeRight": "Indent Code Right",
"CommentLine": "Comment Line",
"StartSketch": "Start Sketch",
"StopSketch": "StopSketch",
"TurnOnAccessibleOutput": "Turn On Accessible Output",
"TurnOffAccessibleOutput": "Turn Off Accessible Output",
"ToogleSidebar": "Toogle Sidebar",
"ToogleConsole": "Toogle Console",
"Preview": "Preview",
"Auto-refresh": "Auto-refresh",
"Console": "Console",
"Settings": "Settings",
"GeneralSettings": "General settings",
"Theme": "Theme",
"Light": "Light",
"Dark": "Dark",
"HighContrast": "High Contrast",
"TextSize": "Text Size",
"Decrease": "Decrease",
"Increase": "Increase",
"IndentationAmount": "Indentation amount",
"Autosave": "Autosave",
"On": "On",
"Off": "Off",
"SketchSettings": "Sketch Settings",
"SecurityProtocol": "Security Protocol",
"ServeOverHTTPS": "Serve over HTTPS",
"Accessibility": "Accessibility",
"LintWarningSound": "Lint warning sound",
"PreviewSound": "Preview sound",
"AccessibleTextBasedCanvas": "Accessible text-based canvas",
"UsedScreenReader": "Used with screen reader",
"PlainText": "Plain-text",
"TableText": "Table-text",
"Sound": "Sound",
"WordWrap": "Word Wrap",
"LineNumbers": "Line numbers",
"LangChange": "Language changed",
"Welcome": "Welcome",
"Login": "Log in", "Login": "Log in",
"LoginOr": "or", "LoginOr": "or",
"SignUp": "Sign up", "SignUp": "Sign up",
@ -80,37 +43,135 @@
"LoginGoogle": "Login with Google", "LoginGoogle": "Login with Google",
"DontHaveAccount": "Don't have an account?", "DontHaveAccount": "Don't have an account?",
"ForgotPassword": "Forgot your password?", "ForgotPassword": "Forgot your password?",
"ResetPassword": "Reset your password", "ResetPassword": "Reset your password"
"BackEditor": "Back to Editor", },
"UsernameSplit": "User Name", "Auth": {
"Password": "Password", "Welcome": "Welcome",
"ConfirmPassword": "Confirm Password",
"OpenedNewSketch": "Opened new sketch.",
"Hello": "Hello", "Hello": "Hello",
"MyAccount": "My Account", "MyAccount": "My Account",
"My":"My", "My": "My",
"MySketches": "My Sketches", "MySketches": "My Sketches",
"MyCollections": "My Collections", "MyCollections": "My Collections",
"Asset": "Asset", "Asset": "Asset",
"MyAssets": "My Assets", "MyAssets": "My Assets",
"TitleAbout": "p5.js Web Editor | About", "LogOut": "Log Out"
"CodeEditing": "Code Editing", }
"Error": "Error", },
"In order to save": "In order to save", "About": {
"you must be logged in": "you must be logged in", "Title": "About",
"Please": "please", "TitleHelmet": "p5.js Web Editor | About",
"Find in files": "Find in files", "Contribute": "Contribute",
"Create": "Create", "NewP5": "New to p5.js?",
"enter a name": "enter a name", "Report": "Report a bug",
"Add": "Add", "Learn": "Learn",
"Folder": "Folder", "Resources": "Resources",
"Libraries": "Libraries",
"Forum": "Forum",
"Examples": "Examples"
},
"Toast": {
"OpenedNewSketch": "Opened new sketch.",
"SketchSaved": "Sketch saved.",
"SketchFailedSave": "Failed to save sketch.",
"AutosaveEnabled": "Autosave enabled.",
"LangChange": "Language changed"
},
"Toolbar": {
"Preview": "Preview",
"Auto-refresh": "Auto-refresh",
"OpenPreferencesARIA": "Open Preferences",
"PlaySketchARIA": "Play sketch",
"PlayOnlyVisualSketchARIA": "Play only visual sketch",
"StopSketchARIA": "Stop sketch",
"EditSketchARIA": "Edit sketch name",
"NewSketchNameARIA": "New sketch name"
},
"Console": {
"Title": "Console",
"Clear": "Clear",
"ClearARIA": "Clear console",
"Close": "Close",
"CloseARIA": "Close console",
"Open": "Open",
"OpenARIA": "Open console"
},
"Preferences": {
"Settings": "Settings",
"GeneralSettings": "General settings",
"Accessibility": "Accessibility",
"Theme": "Theme",
"LightTheme": "Light",
"LightThemeARIA": "light theme on",
"DarkTheme": "Dark",
"DarkThemeARIA": "dark theme on",
"HighContrastTheme": "High Contrast",
"HighContrastThemeARIA": "high contrast theme on",
"TextSize": "Text Size",
"DecreaseFont": "Decrease",
"DecreaseFontARIA": "decrease font size",
"IncreaseFont": "Increase",
"IncreaseFontARIA": "increase font size",
"Autosave": "Autosave",
"On": "On",
"AutosaveOnARIA": "autosave on",
"Off": "Off",
"AutosaveOffARIA": "autosave off",
"WordWrap": "Word Wrap",
"LineWrapOnARIA": "linewrap on",
"LineWrapOffARIA": "linewrap off",
"LineNumbers": "Line numbers",
"LineNumbersOnARIA": "line numbers on",
"LineNumbersOffARIA": "line numbers off",
"LintWarningSound": "Lint warning sound",
"LintWarningOnARIA": "lint warning on",
"LintWarningOffARIA": "lint warning off",
"PreviewSound": "Preview sound",
"PreviewSoundARIA": "preview sound",
"AccessibleTextBasedCanvas": "Accessible text-based canvas",
"UsedScreenReader": "Used with screen reader",
"PlainText": "Plain-text",
"TextOutputARIA": "text output on",
"TableText": "Table-text",
"TableOutputARIA": "table output on",
"Sound": "Sound",
"SoundOutputARIA": "sound output on"
},
"KeyboardShortcuts": {
"Title": " Keyboard Shortcuts",
"ShortcutsFollow": "Code editing keyboard shortcuts follow",
"SublimeText": "Sublime Text shortcuts",
"CodeEditing": {
"Tidy": "Tidy",
"FindText": "Find Text", "FindText": "Find Text",
"FindNextMatch": "Find Next Match",
"FindPrevMatch": "Find Previous Match",
"IndentCodeLeft": "Indent Code Left",
"IndentCodeRight": "Indent Code Right",
"CommentLine": "Comment Line",
"FindNextTextMatch": "Find Next Text Match", "FindNextTextMatch": "Find Next Text Match",
"FindPreviousTextMatch": "Find Previous Text Match", "FindPreviousTextMatch": "Find Previous Text Match",
"Code editing keyboard shortcuts follow": "Code editing keyboard shortcuts follow", "CodeEditing": "Code Editing"
"Sublime Text shortcuts": "Sublime Text shortcuts", },
"WarningUnsavedChanges": "Are you sure you want to leave this page? You have unsaved changes.", "General": {
"LogOut": "Log Out" "StartSketch": "Start Sketch",
"StopSketch": "Stop Sketch",
"TurnOnAccessibleOutput": "Turn On Accessible Output",
"TurnOffAccessibleOutput": "Turn Off Accessible Output"
}
},
"Sidebar": {
"Create": "Create",
"EnterName": "enter a name",
"Add": "Add",
"Folder": "Folder"
},
"Common": {
"Error": "Error",
"Save": "Save",
"p5logoARIA": "p5.js Logo"
},
"IDEView": {
"SubmitFeedback": "Submit Feedback"
}
} }

View file

@ -1,113 +1,180 @@
{ {
"Contribute": "Contribuir", "Nav": {
"NewP5": "¿Empezando con p5.js?", "File": {
"Report": "Reporta un error", "Title": "Archivo",
"Learn": "Aprende",
"About": "Acerca de",
"Resources": "Recursos",
"Libraries": "Bibliotecas",
"Forum": "Foro",
"File": "Archivo",
"New": "Nuevo", "New": "Nuevo",
"Save": "Guardar",
"Share": "Compartir", "Share": "Compartir",
"Duplicate": "Duplicar", "Duplicate": "Duplicar",
"Examples": "Ejemplos", "Open": "Abrir",
"Edit": "Editar", "Download": "Descargar",
"AddToCollection": "Agregar a colección",
"Examples": "Ejemplos"
},
"Edit": {
"Title": "Editar",
"TidyCode": "Ordenar código", "TidyCode": "Ordenar código",
"Find": "Buscar", "Find": "Buscar",
"AddToCollection": "Agregar a colección",
"FindNext": "Buscar siguiente", "FindNext": "Buscar siguiente",
"FindPrevious": "Buscar anterior", "FindPrevious": "Buscar anterior"
"Sketch": "Bosquejo", },
"Sketch": {
"Title": "Bosquejo",
"AddFile": "Agregar archivo", "AddFile": "Agregar archivo",
"AddFolder": "Agregar directorio", "AddFolder": "Agregar directorio",
"Run": "Ejecutar", "Run": "Ejecutar",
"Stop": "Detener", "Stop": "Detener"
"Help": "Ayuda", },
"Help": {
"Title": "Ayuda",
"KeyboardShortcuts": "Atajos", "KeyboardShortcuts": "Atajos",
"Reference": "Referencia", "Reference": "Referencia",
"Tidy": "Ordenar", "About": "Acerca de"
},
"Lang": "Lenguaje", "Lang": "Lenguaje",
"BackEditor": "Regresa al editor",
"WarningUnsavedChanges": "¿Realmente quieres salir de la página? Tienes cambios sin guardar.",
"Login": {
"Login": "Ingresa",
"LoginOr": "o",
"SignUp": "registráte",
"Email": "correo electrónico",
"Username": "Identificación",
"LoginGithub": "Ingresa con Github",
"LoginGoogle": "Ingresa con Google",
"DontHaveAccount": "¿No tienes cuenta?",
"ForgotPassword": "¿Olvidaste tu contraseña?",
"ResetPassword": "Regenera tu contraseña"
},
"Auth": {
"Welcome": "Hola",
"Hello": "Hola",
"MyAccount": "Mi Cuenta",
"My": "Mi",
"MySketches": "Mis bosquejos",
"MyCollections": "Mis colecciones",
"Asset": "Asset",
"MyAssets": "Mis assets",
"LogOut": "Cerrar sesión"
}
},
"About": {
"Title": "Acerca de",
"TitleHelmet": "Editor Web p5.js | Acerca de",
"Contribute": "Contribuir",
"NewP5": "¿Empezando con p5.js?",
"Report": "Reporta un error",
"Learn": "Aprender",
"Resources": "Recursos",
"Libraries": "Bibliotecas",
"Forum": "Foro",
"Examples": "Ejemplos"
},
"Toast": {
"OpenedNewSketch": "Abriste un nuevo bosquejo.",
"SketchSaved": "Bosquejo guardado.",
"SketchFailedSave": "Fallo al guardar el bosquejo.",
"AutosaveEnabled": "Grabado automático activado.",
"LangChange": "Lenguaje cambiado"
},
"Toolbar": {
"Preview": "Vista previa",
"Auto-refresh": "Auto-refrescar",
"OpenPreferencesARIA": "Abrir Preferencias",
"PlaySketchARIA": "Ejecutar bosquejo",
"PlayOnlyVisualSketchARIA": "Ejecutar bosquejo visual",
"StopSketchARIA": "Detener bosquejo",
"EditSketchARIA": "Editar nombre de bosquejo",
"NewSketchNameARIA": "Nuevo nombre de bosquejo"
},
"Console": {
"Title": "Consola",
"Clear": "Limpiar",
"ClearARIA": "limpiar consola",
"Close": "Cerrar",
"CloseARIA": "cerrar consola",
"Open": "Abrir",
"OpenARIA": "Abrir consola"
},
"Preferences": {
"Settings": "Configuración",
"GeneralSettings": "Configuración general",
"Accessibility": "Accesibilidad",
"Theme": "Modo de visualización",
"LightTheme": "Claro",
"LightThemeARIA": "Modo de visualización claro activado",
"DarkTheme": "Oscuro",
"DarkThemeARIA": "Modo de visualización oscuro activado",
"HighContrastTheme": "Alto contraste",
"HighContrastThemeARIA": "Modo de visualización de alto contraste activado",
"TextSize": "Tamaño del texto",
"DecreaseFont": "Disminuir",
"DecreaseFontARIA": "Disminuir tamaño del texto",
"IncreaseFont": "Aumentar",
"IncreaseFontARIA": "Aumentar tamaño del texto",
"Autosave": "Grabar automáticamente",
"On": "Activar",
"AutosaveOnARIA": "Grabado automático activado",
"Off": "Desactivar",
"AutosaveOffARIA": "Grabado automático desactivado",
"WordWrap": "Ajuste automático de línea",
"LineWrapOnARIA": "Ajuste automático de línea activado",
"LineWrapOffARIA": "Ajuste automático de línea desactivado",
"LineNumbers": "Número de línea",
"LineNumbersOnARIA": "Número de línea activado",
"LineNumbersOffARIA": "Número de línea desactivado",
"LintWarningSound": "Sonido de alarma Lint",
"LintWarningOnARIA": "Sonido de alarma Lint activado",
"LintWarningOffARIA": "Sonido de alarma Lint desactivado",
"PreviewSound": "Probar sonido",
"PreviewSoundARIA": "Probar sonido",
"AccessibleTextBasedCanvas": "Lienzo accesible por texto",
"UsedScreenReader": "Uso con screen reader",
"PlainText": "Texto sin formato",
"TextOutputARIA": "Salida de texto activado",
"TableText": "Tablero de texto",
"TableOutputARIA": "Salida de tablero activado",
"Sound": "Sonido",
"SoundOutputARIA": "Salida de sonido activado"
},
"KeyboardShortcuts": {
"Title": " Atajos de teclado",
"ShortcutsFollow": "Los atajos para edición son como",
"SublimeText": "los atajos de Sublime Text ",
"CodeEditing": {
"Tidy": "Ordenar",
"FindText": "Encontrar texto",
"FindNextMatch": "Encontrar siguiente ocurrencia", "FindNextMatch": "Encontrar siguiente ocurrencia",
"FindPrevMatch": "Encontrar ocurrencia previa", "FindPrevMatch": "Encontrar ocurrencia previa",
"IndentCodeLeft": "Indentar código a la izquierda", "IndentCodeLeft": "Indentar código a la izquierda",
"IndentCodeRight": "Indentar código a la derecha", "IndentCodeRight": "Indentar código a la derecha",
"CommentLine": "Comentar línea de código", "CommentLine": "Comentar línea de código",
"FindNextTextMatch": "Encontrar la siguiente ocurrencia de texto",
"FindPreviousTextMatch": "Encontrar la ocurrencia previa de texto",
"CodeEditing": "Editando Código"
},
"General": {
"StartSketch": "Iniciar bosquejo", "StartSketch": "Iniciar bosquejo",
"StopSketch": "Detener bosquejo", "StopSketch": "Detener bosquejo",
"TurnOnAccessibleOutput": "Activar salida accesible", "TurnOnAccessibleOutput": "Activar salida accesible",
"TurnOffAccessibleOutput": "Desactivar salida accesible", "TurnOffAccessibleOutput": "Desactivar salida accesible"
"ToogleSidebar": "Alternar barra de deslizamiento",
"ToogleConsole": "Alternar consola",
"Preview": "Vista previa",
"Auto-refresh": "Auto-refrescar",
"Console": "Consola",
"Settings": "Configuración",
"GeneralSettings": "Configuración general",
"Theme": "Modo de visualización",
"Light": "Claro",
"Dark": "Oscuro",
"HighContrast": "Alto contraste",
"TextSize": "Tamaño del texto",
"Decrease": "Disminuir",
"Increase": "Aumentar",
"IndentationAmount": "Cantidad de indentación",
"Autosave": "Grabar automáticamente",
"On": "Activar",
"Off": "Desactivar",
"SketchSettings": "Configuración del bosquejo",
"SecurityProtocol": "Protocolo de seguridad",
"ServeOverHTTPS": "Usar HTTPS",
"Accessibility": "Accesibilidad",
"LintWarningSound": "Sonido de alarma Lint",
"PreviewSound": "Probar sonido",
"AccessibleTextBasedCanvas": "Lienzo accesible por texto",
"UsedScreenReader": "Uso con screen reader",
"PlainText": "Texto sin formato",
"TableText": "Tablero de texto",
"Sound": "Sonido",
"WordWrap": "Ajuste automático de línea",
"LineNumbers": "Número de línea",
"LangChange": "Lenguaje cambiado",
"Welcome": "Bienvenida",
"Login": "Ingresa",
"LoginOr": "o",
"SignUp": "registráte",
"email": "correo electrónico",
"username": "nombre de usuario",
"LoginGithub": "Ingresa con Github",
"LoginGoogle": "Ingresa con Google",
"DontHaveAccount": "No tienes cuenta?",
"ForgotPassword": "¿Olvidaste tu contraseña?",
"ResetPassword": "Regenera tu contraseña",
"BackEditor": "Regresa al editor",
"UsernameSplit": "Nombre de usuario",
"Password": "Contraseña",
"ConfirmPassword": "Confirma la contraseña",
"OpenedNewSketch": "Creaste nuevo bosquejo.",
"Hello": "Hola",
"MyAccount": "Mi Cuenta",
"My": "Mi",
"MySketches": "Mis bosquejos",
"MyCollections":"Mis colecciones",
"Asset": "Asset",
"MyAssets": "Mis assets",
"TitleAbout": "Editor Web p5.js | Acerca de",
"CodeEditing": "Editando Código",
"Error": "Error",
"In order to save": "Para guardar",
"you must be logged in": "debes ingresar a tu cuenta",
"Please": "Por favor",
"Find in files": "Encontrar en archivos",
"Create": "Create",
"enter a name": "enter a name",
"Add": "Add",
"Folder": "Directorio",
"FindText": "Encontrar texto",
"FindNextTextMatch": "Encontrar la siguiente ocurrencia de texto",
"FindPreviousTextMatch": "Encontrar la ocurrencia previa de texto",
"Code editing keyboard shortcuts follow": "Los atajos para edición son como",
"Sublime Text shortcuts": "los atajos de Sublime Text ",
"WarningUnsavedChanges": "¿Estás seguro de que quieres salir de la página? Tienes cambios sin guardar."
} }
},
"Sidebar": {
"Create": "Crear",
"EnterName": "Introduce un nombre",
"Add": "Agregar",
"Folder": "Directorio"
},
"Common": {
"Error": "Error",
"Save": "Guardar",
"p5logoARIA": "Logo p5.js "
},
"IDEView": {
"SubmitFeedback": "Enviar retroalimentación"
}
}