From 4aab045867ea8e0d28f111ab12b762f48549857a Mon Sep 17 00:00:00 2001 From: ridait Date: Wed, 26 Aug 2020 22:42:40 +0200 Subject: [PATCH 1/5] #1559 Internationalize mobile text using i18n --- client/components/mobile/Explorer.jsx | 14 +++++--- .../Preferences/PreferenceCreators.jsx | 21 +++++++----- client/modules/IDE/pages/MobileIDEView.jsx | 25 ++++++++------ client/modules/Mobile/MobileDashboardView.jsx | 23 +++++++++---- client/modules/Mobile/MobilePreferences.jsx | 34 ++++++++++++------- translations/locales/en-US/translations.json | 21 ++++++++++++ translations/locales/es-419/translations.json | 21 ++++++++++++ 7 files changed, 116 insertions(+), 43 deletions(-) diff --git a/client/components/mobile/Explorer.jsx b/client/components/mobile/Explorer.jsx index 40455e242a..d090553495 100644 --- a/client/components/mobile/Explorer.jsx +++ b/client/components/mobile/Explorer.jsx @@ -1,15 +1,19 @@ import React from 'react'; +import { useTranslation } from 'react-i18next'; import styled from 'styled-components'; import PropTypes from 'prop-types'; import Sidebar from './Sidebar'; import ConnectedFileNode from '../../modules/IDE/components/FileNode'; -const Explorer = ({ id, canEdit, onPressClose }) => ( - - onPressClose()} /> - -); +const Explorer = ({ id, canEdit, onPressClose }) => { + const { t, i18n } = useTranslation(); + return ( + + onPressClose()} /> + + ); +}; Explorer.propTypes = { id: PropTypes.number.isRequired, diff --git a/client/modules/IDE/components/Preferences/PreferenceCreators.jsx b/client/modules/IDE/components/Preferences/PreferenceCreators.jsx index 9b977e0975..dd5ef2ff1d 100644 --- a/client/modules/IDE/components/Preferences/PreferenceCreators.jsx +++ b/client/modules/IDE/components/Preferences/PreferenceCreators.jsx @@ -1,11 +1,16 @@ -export const optionsOnOff = (name, onLabel = 'On', offLabel = 'Off') => [ - { - value: true, label: onLabel, ariaLabel: `${name} on`, name: `${name}`, id: `${name}-on`.replace(' ', '-') - }, - { - value: false, label: offLabel, ariaLabel: `${name} off`, name: `${name}`, id: `${name}-off`.replace(' ', '-') - }, -]; +import { useTranslation } from 'react-i18next'; + +export const optionsOnOff = (name) => { + const { t, i18n } = useTranslation(); + return [ + { + value: true, label: t('Preferences.On'), ariaLabel: `${name} on`, name: `${name}`, id: `${name}-on`.replace(' ', '-') + }, + { + value: false, label: t('Preferences.Off'), ariaLabel: `${name} off`, name: `${name}`, id: `${name}-off`.replace(' ', '-') + } + ]; +}; export const optionsPickOne = (name, ...options) => options.map(option => ({ value: option, diff --git a/client/modules/IDE/pages/MobileIDEView.jsx b/client/modules/IDE/pages/MobileIDEView.jsx index 842cd8c78c..28524f2bb6 100644 --- a/client/modules/IDE/pages/MobileIDEView.jsx +++ b/client/modules/IDE/pages/MobileIDEView.jsx @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { withRouter } from 'react-router'; import { useState } from 'react'; +import { useTranslation } from 'react-i18next'; import styled from 'styled-components'; // Imports to be Refactored @@ -63,22 +64,24 @@ const NavItem = styled.li` position: relative; `; -const getNavOptions = (username = undefined, logoutUser = () => {}, toggleForceDesktop = () => {}) => - (username +const getNavOptions = (username = undefined, logoutUser = () => {}, toggleForceDesktop = () => {}) => { + const { t, i18n } = useTranslation(); + return (username ? [ - { icon: PreferencesIcon, title: 'Preferences', href: '/preferences', }, - { icon: PreferencesIcon, title: 'My Stuff', href: `/${username}/sketches` }, - { icon: PreferencesIcon, title: 'Examples', href: '/p5/sketches' }, - { icon: PreferencesIcon, title: 'Original Editor', action: toggleForceDesktop, }, - { icon: PreferencesIcon, title: 'Logout', action: logoutUser, }, + { icon: PreferencesIcon, title: t('MobileNav.Preferences'), href: '/preferences', }, + { icon: PreferencesIcon, title: t('MobileNav.MyStuff'), href: `/${username}/sketches` }, + { icon: PreferencesIcon, title: t('MobileNav.Examples'), href: '/p5/sketches' }, + { icon: PreferencesIcon, title: t('MobileNav.OriginalEditor'), action: toggleForceDesktop, }, + { icon: PreferencesIcon, title: t('MobileNav.Logout'), action: logoutUser, }, ] : [ - { icon: PreferencesIcon, title: 'Preferences', href: '/preferences', }, - { icon: PreferencesIcon, title: 'Examples', href: '/p5/sketches' }, - { icon: PreferencesIcon, title: 'Original Editor', action: toggleForceDesktop, }, - { icon: PreferencesIcon, title: 'Login', href: '/login', }, + { icon: PreferencesIcon, title: t('MobileNav.Preferences'), href: '/preferences', }, + { icon: PreferencesIcon, title: t('MobileNav.Examples'), href: '/p5/sketches' }, + { icon: PreferencesIcon, title: t('MobileNav.OriginalEditor'), action: toggleForceDesktop, }, + { icon: PreferencesIcon, title: t('MobileNav.Login'), href: '/login', }, ] ); +}; const MobileIDEView = (props) => { const { diff --git a/client/modules/Mobile/MobileDashboardView.jsx b/client/modules/Mobile/MobileDashboardView.jsx index 0fd7cfe41b..c2df71886d 100644 --- a/client/modules/Mobile/MobileDashboardView.jsx +++ b/client/modules/Mobile/MobileDashboardView.jsx @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import styled from 'styled-components'; import { useSelector } from 'react-redux'; import { withRouter } from 'react-router'; +import { useTranslation } from 'react-i18next'; import Screen from '../../components/mobile/MobileScreen'; import Header from '../../components/mobile/Header'; @@ -137,10 +138,13 @@ const Panels = { }; -const navOptions = username => [ - { title: 'Create Sketch', href: '/' }, - { title: 'Create Collection', href: `/${username}/collections/create` } -]; +const navOptions = (username) => { + const { t, i18n } = useTranslation(); + return [ + { title: t('MobileDashboardView.CreateSketch'), href: '/' }, + { title: t('MobileDashboardView.CreateCollection'), href: `/${username}/collections/create` } + ]; +}; const getPanel = (pathname) => { @@ -162,8 +166,14 @@ const MobileDashboard = ({ params, location }) => { const user = useSelector(state => state.user); const { username: paramsUsername } = params; const { pathname } = location; + const { t, i18n } = useTranslation(); const Tabs = Object.keys(Panels); + const TabLabels = { + sketches: t('MobileDashboardView.Sketches'), + collections: t('MobileDashboardView.Collections'), + assets: t('MobileDashboardView.Assets') + }; const isExamples = paramsUsername === EXAMPLE_USERNAME; const panel = getPanel(pathname); @@ -173,9 +183,10 @@ const MobileDashboard = ({ params, location }) => { align="right" />); + return ( -
+
{ selected={tab === panel} to={pathname.replace(panel, tab)} > -

{(isExamples && tab === 'Sketches') ? 'Examples' : tab}

+

{(isExamples && tab === 'Sketches') ? t('MobileDashboardView.Examples') : (TabLabels[tab] || tab)}

)) } diff --git a/client/modules/Mobile/MobilePreferences.jsx b/client/modules/Mobile/MobilePreferences.jsx index 69ad737b03..0efd4b4604 100644 --- a/client/modules/Mobile/MobilePreferences.jsx +++ b/client/modules/Mobile/MobilePreferences.jsx @@ -2,6 +2,8 @@ import React from 'react'; import { bindActionCreators } from 'redux'; import { connect, useSelector, useDispatch } from 'react-redux'; import { withRouter } from 'react-router'; +import { useTranslation } from 'react-i18next'; + import PropTypes from 'prop-types'; import styled from 'styled-components'; @@ -42,27 +44,33 @@ const MobilePreferences = () => { setTheme, setAutosave, setLinewrap, setTextOutput, setGridOutput, setSoundOutput, setLineNumbers, setLintWarning, } = bindActionCreators({ ...PreferencesActions, ...IdeActions }, useDispatch()); + const { t, i18n } = useTranslation(); const generalSettings = [ { - title: 'Theme', + title: t('Preferences.Theme'), value: theme, - options: optionsPickOne('theme', 'light', 'dark', 'contrast'), + options: optionsPickOne( + t('Preferences.Theme'), + t('Preferences.LightTheme'), + t('Preferences.DarkTheme'), + t('Preferences.HighContrastTheme') + ), onSelect: x => setTheme(x) // setTheme }, - preferenceOnOff('Autosave', autosave, setAutosave, 'autosave'), - preferenceOnOff('Word Wrap', linewrap, setLinewrap, 'linewrap') + preferenceOnOff(t('Preferences.Autosave'), autosave, setAutosave, 'autosave'), + preferenceOnOff(t('Preferences.WordWrap'), linewrap, setLinewrap, 'linewrap') ]; const outputSettings = [ - preferenceOnOff('Plain-text', textOutput, setTextOutput, 'text output'), - preferenceOnOff('Table-text', gridOutput, setGridOutput, 'table output'), - preferenceOnOff('Lint Warning Sound', soundOutput, setSoundOutput, 'sound output') + preferenceOnOff(t('Preferences.PlainText'), textOutput, setTextOutput, 'text output'), + preferenceOnOff(t('Preferences.TableText'), gridOutput, setGridOutput, 'table output'), + preferenceOnOff(t('Preferences.Sound'), soundOutput, setSoundOutput, 'sound output') ]; const accessibilitySettings = [ - preferenceOnOff('Line Numbers', lineNumbers, setLineNumbers), - preferenceOnOff('Lint Warning Sound', lintWarning, setLintWarning) + preferenceOnOff(t('Preferences.LineNumbers'), lineNumbers, setLineNumbers), + preferenceOnOff(t('Preferences.LintWarningSound'), lintWarning, setLintWarning) ]; return ( @@ -73,14 +81,14 @@ const MobilePreferences = () => {
- General Settings + {t('Preferences.GeneralSettings')} { generalSettings.map(option => ) } - Accessibility + {t('Preferences.Accessibility')} { accessibilitySettings.map(option => ) } - Accessible Output - Used with screen reader + {t('Preferences.AccessibleOutput')} + {t('Preferences.UsedScreenReader')} { outputSettings.map(option => ) } diff --git a/translations/locales/en-US/translations.json b/translations/locales/en-US/translations.json index ab64c317eb..0157b77137 100644 --- a/translations/locales/en-US/translations.json +++ b/translations/locales/en-US/translations.json @@ -114,6 +114,7 @@ "Settings": "Settings", "GeneralSettings": "General settings", "Accessibility": "Accessibility", + "AccessibleOutput": "Accessible Output", "Theme": "Theme", "LightTheme": "Light", "LightThemeARIA": "light theme on", @@ -531,5 +532,25 @@ "PreviewNav": { "EditSketchARIA": "Edit Sketch", "ByUser": "by" + }, + "MobileNav":{ + "Preferences": "Preferences", + "MyStuff": "My Stuff", + "Examples": "Examples", + "OriginalEditor": "Original Editor", + "Login": "Login", + "Logout": "Logout" + }, + "MobileDashboardView": { + "Examples": "Examples", + "Sketches": "Sketches", + "Collections": "Collections", + "Assets": "Assets", + "MyStuff": "My Stuff", + "CreateSketch": "Create Sketch", + "CreateCollection": "Create Collection" + }, + "MobileSideBar": { + "Files": "Files" } } diff --git a/translations/locales/es-419/translations.json b/translations/locales/es-419/translations.json index 08d9778ad5..979b483721 100644 --- a/translations/locales/es-419/translations.json +++ b/translations/locales/es-419/translations.json @@ -114,6 +114,7 @@ "Settings": "Configuración", "GeneralSettings": "Configuración general", "Accessibility": "Accesibilidad", + "AccessibleOutput": "Salida accesible", "Theme": "Modo de visualización", "LightTheme": "Claro", "LightThemeARIA": "Modo de visualización claro activado", @@ -531,5 +532,25 @@ "PreviewNav": { "EditSketchARIA": "Editar Bosquejo", "ByUser": "por" + }, + "MobileNav":{ + "Preferences": "Preferencias", + "MyStuff": "Mis cosas", + "Examples": "Ejemplos", + "OriginalEditor": "Editor Original", + "Login": "Ingresa", + "Logout": "Cerrar sesión" + }, + "MobileDashboardView": { + "Examples": "Ejemplos", + "Sketches": "Bosquejos", + "Collections": "Colecciones", + "Assets": "Assets", + "MyStuff": "Mis cosas", + "CreateSketch": "Crear bosquejo", + "CreateCollection": "Crear colección" + }, + "MobileSideBar": { + "Files": "Archivos" } } From 533aff6b837c3c84799941327dd1e910834e5123 Mon Sep 17 00:00:00 2001 From: ridait Date: Wed, 26 Aug 2020 19:15:21 +0200 Subject: [PATCH 2/5] Fix capture and display rejected promises in web editor console --- client/utils/consoleUtils.js | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/client/utils/consoleUtils.js b/client/utils/consoleUtils.js index a6013924c3..19e942e838 100644 --- a/client/utils/consoleUtils.js +++ b/client/utils/consoleUtils.js @@ -38,6 +38,22 @@ export const hijackConsoleErrorsScript = (offs) => { }], '*'); return false; }; + // catch rejected promises + window.onunhandledrejection = function (event) { + if (event.reason && event.reason.message && event.reason.stack){ + var errorNum = event.reason.stack.split('about:srcdoc:')[1].split(':')[0]; + var fileInfo = getScriptOff(errorNum); + var data = event.reason.message + ' (' + fileInfo[1] + ': line ' + fileInfo[0] + ')'; + window.parent.postMessage([{ + log: [{ + method: 'error', + data: [data], + id: Date.now().toString() + }], + source: fileInfo[1] + }], '*'); + } + }; `; return s; }; @@ -46,7 +62,7 @@ export const startTag = '@fs-'; export const getAllScriptOffsets = (htmlFile) => { const offs = []; - const hijackConsoleErrorsScriptLength = 36; + const hijackConsoleErrorsScriptLength = 52; const embeddedJSStart = 'script crossorigin=""'; let foundJSScript = true; let foundEmbeddedJS = true; From da294b221e1243725a42b3f3fc50bc03b2fa355a Mon Sep 17 00:00:00 2001 From: ov Date: Thu, 27 Aug 2020 16:00:04 +0100 Subject: [PATCH 3/5] Language UI Dropdown new location (#1582) * New language selector design * Adjust authenticated nav to consolidate Account dropdown * Adding language in NavTest Co-authored-by: Cassie Tarakajian --- client/components/Nav.jsx | 21 ++++++++++----------- client/components/__test__/Nav.test.jsx | 3 ++- client/i18n.js | 8 ++++++++ 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/client/components/Nav.jsx b/client/components/Nav.jsx index 4056607f31..1aff392709 100644 --- a/client/components/Nav.jsx +++ b/client/components/Nav.jsx @@ -5,7 +5,7 @@ import { withRouter } from 'react-router'; import { Link } from 'react-router'; import classNames from 'classnames'; import { withTranslation } from 'react-i18next'; -import i18next from 'i18next'; +import { languageKeyToLabel } from '../i18n'; import * as IDEActions from '../modules/IDE/actions/ide'; import * as toastActions from '../modules/IDE/actions/toast'; import * as projectActions from '../modules/IDE/actions/project'; @@ -549,7 +549,7 @@ class Nav extends React.PureComponent { renderLanguageMenu(navDropdownState) { return ( -
    +
    • @@ -597,7 +597,7 @@ class Nav extends React.PureComponent {
  • -
+ ); } @@ -605,6 +605,7 @@ class Nav extends React.PureComponent { renderUnauthenticatedUserMenu(navDropdownState) { return (
    + {getConfig('TRANSLATIONS_ENABLED') && this.renderLanguageMenu(navDropdownState)}
  • {this.props.t('Nav.Login')} @@ -623,10 +624,7 @@ class Nav extends React.PureComponent { renderAuthenticatedUserMenu(navDropdownState) { return (
      -
    • - {this.props.t('Nav.Auth.Hello')}, {this.props.user.username}! -
    • - | + {getConfig('TRANSLATIONS_ENABLED') && this.renderLanguageMenu(navDropdownState)}
      • @@ -755,7 +753,6 @@ class Nav extends React.PureComponent {
        @@ -809,6 +806,7 @@ Nav.propTypes = { }), t: PropTypes.func.isRequired, setLanguage: PropTypes.func.isRequired, + language: PropTypes.string.isRequired, }; Nav.defaultProps = { @@ -829,7 +827,8 @@ function mapStateToProps(state) { project: state.project, user: state.user, unsavedChanges: state.ide.unsavedChanges, - rootFile: state.files.filter(file => file.name === 'root')[0] + rootFile: state.files.filter(file => file.name === 'root')[0], + language: state.preferences.language }; } diff --git a/client/components/__test__/Nav.test.jsx b/client/components/__test__/Nav.test.jsx index ee175fe7df..791db4902c 100644 --- a/client/components/__test__/Nav.test.jsx +++ b/client/components/__test__/Nav.test.jsx @@ -46,7 +46,8 @@ describe('Nav', () => { id: 'root-file' }, t: jest.fn(), - setLanguage: jest.fn() + setLanguage: jest.fn(), + language: 'en-US' }; it('renders correctly', () => { diff --git a/client/i18n.js b/client/i18n.js index 66131bab04..4871e50063 100644 --- a/client/i18n.js +++ b/client/i18n.js @@ -6,6 +6,14 @@ import Backend from 'i18next-http-backend'; const fallbackLng = ['en-US']; const availableLanguages = ['en-US', 'es-419']; +export function languageKeyToLabel(lang) { + const languageMap = { + 'en-US': 'English', + 'es-419': 'Español' + }; + return languageMap[lang]; +} + const options = { loadPath: '/locales/{{lng}}/translations.json', requestOptions: { // used for fetch, can also be a function (payload) => ({ method: 'GET' }) From 762716835a4f7ff42bea59c601a852fc0f55d65b Mon Sep 17 00:00:00 2001 From: ridait Date: Wed, 26 Aug 2020 22:42:40 +0200 Subject: [PATCH 4/5] #1559 Internationalize mobile text using i18n --- client/components/mobile/Explorer.jsx | 14 +++++--- .../Preferences/PreferenceCreators.jsx | 21 +++++++----- client/modules/IDE/pages/MobileIDEView.jsx | 25 ++++++++------ client/modules/Mobile/MobileDashboardView.jsx | 23 +++++++++---- client/modules/Mobile/MobilePreferences.jsx | 34 ++++++++++++------- translations/locales/en-US/translations.json | 21 ++++++++++++ translations/locales/es-419/translations.json | 21 ++++++++++++ 7 files changed, 116 insertions(+), 43 deletions(-) diff --git a/client/components/mobile/Explorer.jsx b/client/components/mobile/Explorer.jsx index 40455e242a..d090553495 100644 --- a/client/components/mobile/Explorer.jsx +++ b/client/components/mobile/Explorer.jsx @@ -1,15 +1,19 @@ import React from 'react'; +import { useTranslation } from 'react-i18next'; import styled from 'styled-components'; import PropTypes from 'prop-types'; import Sidebar from './Sidebar'; import ConnectedFileNode from '../../modules/IDE/components/FileNode'; -const Explorer = ({ id, canEdit, onPressClose }) => ( - - onPressClose()} /> - -); +const Explorer = ({ id, canEdit, onPressClose }) => { + const { t, i18n } = useTranslation(); + return ( + + onPressClose()} /> + + ); +}; Explorer.propTypes = { id: PropTypes.number.isRequired, diff --git a/client/modules/IDE/components/Preferences/PreferenceCreators.jsx b/client/modules/IDE/components/Preferences/PreferenceCreators.jsx index 9b977e0975..dd5ef2ff1d 100644 --- a/client/modules/IDE/components/Preferences/PreferenceCreators.jsx +++ b/client/modules/IDE/components/Preferences/PreferenceCreators.jsx @@ -1,11 +1,16 @@ -export const optionsOnOff = (name, onLabel = 'On', offLabel = 'Off') => [ - { - value: true, label: onLabel, ariaLabel: `${name} on`, name: `${name}`, id: `${name}-on`.replace(' ', '-') - }, - { - value: false, label: offLabel, ariaLabel: `${name} off`, name: `${name}`, id: `${name}-off`.replace(' ', '-') - }, -]; +import { useTranslation } from 'react-i18next'; + +export const optionsOnOff = (name) => { + const { t, i18n } = useTranslation(); + return [ + { + value: true, label: t('Preferences.On'), ariaLabel: `${name} on`, name: `${name}`, id: `${name}-on`.replace(' ', '-') + }, + { + value: false, label: t('Preferences.Off'), ariaLabel: `${name} off`, name: `${name}`, id: `${name}-off`.replace(' ', '-') + } + ]; +}; export const optionsPickOne = (name, ...options) => options.map(option => ({ value: option, diff --git a/client/modules/IDE/pages/MobileIDEView.jsx b/client/modules/IDE/pages/MobileIDEView.jsx index 842cd8c78c..28524f2bb6 100644 --- a/client/modules/IDE/pages/MobileIDEView.jsx +++ b/client/modules/IDE/pages/MobileIDEView.jsx @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { withRouter } from 'react-router'; import { useState } from 'react'; +import { useTranslation } from 'react-i18next'; import styled from 'styled-components'; // Imports to be Refactored @@ -63,22 +64,24 @@ const NavItem = styled.li` position: relative; `; -const getNavOptions = (username = undefined, logoutUser = () => {}, toggleForceDesktop = () => {}) => - (username +const getNavOptions = (username = undefined, logoutUser = () => {}, toggleForceDesktop = () => {}) => { + const { t, i18n } = useTranslation(); + return (username ? [ - { icon: PreferencesIcon, title: 'Preferences', href: '/preferences', }, - { icon: PreferencesIcon, title: 'My Stuff', href: `/${username}/sketches` }, - { icon: PreferencesIcon, title: 'Examples', href: '/p5/sketches' }, - { icon: PreferencesIcon, title: 'Original Editor', action: toggleForceDesktop, }, - { icon: PreferencesIcon, title: 'Logout', action: logoutUser, }, + { icon: PreferencesIcon, title: t('MobileNav.Preferences'), href: '/preferences', }, + { icon: PreferencesIcon, title: t('MobileNav.MyStuff'), href: `/${username}/sketches` }, + { icon: PreferencesIcon, title: t('MobileNav.Examples'), href: '/p5/sketches' }, + { icon: PreferencesIcon, title: t('MobileNav.OriginalEditor'), action: toggleForceDesktop, }, + { icon: PreferencesIcon, title: t('MobileNav.Logout'), action: logoutUser, }, ] : [ - { icon: PreferencesIcon, title: 'Preferences', href: '/preferences', }, - { icon: PreferencesIcon, title: 'Examples', href: '/p5/sketches' }, - { icon: PreferencesIcon, title: 'Original Editor', action: toggleForceDesktop, }, - { icon: PreferencesIcon, title: 'Login', href: '/login', }, + { icon: PreferencesIcon, title: t('MobileNav.Preferences'), href: '/preferences', }, + { icon: PreferencesIcon, title: t('MobileNav.Examples'), href: '/p5/sketches' }, + { icon: PreferencesIcon, title: t('MobileNav.OriginalEditor'), action: toggleForceDesktop, }, + { icon: PreferencesIcon, title: t('MobileNav.Login'), href: '/login', }, ] ); +}; const MobileIDEView = (props) => { const { diff --git a/client/modules/Mobile/MobileDashboardView.jsx b/client/modules/Mobile/MobileDashboardView.jsx index 0fd7cfe41b..c2df71886d 100644 --- a/client/modules/Mobile/MobileDashboardView.jsx +++ b/client/modules/Mobile/MobileDashboardView.jsx @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import styled from 'styled-components'; import { useSelector } from 'react-redux'; import { withRouter } from 'react-router'; +import { useTranslation } from 'react-i18next'; import Screen from '../../components/mobile/MobileScreen'; import Header from '../../components/mobile/Header'; @@ -137,10 +138,13 @@ const Panels = { }; -const navOptions = username => [ - { title: 'Create Sketch', href: '/' }, - { title: 'Create Collection', href: `/${username}/collections/create` } -]; +const navOptions = (username) => { + const { t, i18n } = useTranslation(); + return [ + { title: t('MobileDashboardView.CreateSketch'), href: '/' }, + { title: t('MobileDashboardView.CreateCollection'), href: `/${username}/collections/create` } + ]; +}; const getPanel = (pathname) => { @@ -162,8 +166,14 @@ const MobileDashboard = ({ params, location }) => { const user = useSelector(state => state.user); const { username: paramsUsername } = params; const { pathname } = location; + const { t, i18n } = useTranslation(); const Tabs = Object.keys(Panels); + const TabLabels = { + sketches: t('MobileDashboardView.Sketches'), + collections: t('MobileDashboardView.Collections'), + assets: t('MobileDashboardView.Assets') + }; const isExamples = paramsUsername === EXAMPLE_USERNAME; const panel = getPanel(pathname); @@ -173,9 +183,10 @@ const MobileDashboard = ({ params, location }) => { align="right" />); + return ( -
        +
        { selected={tab === panel} to={pathname.replace(panel, tab)} > -

        {(isExamples && tab === 'Sketches') ? 'Examples' : tab}

        +

        {(isExamples && tab === 'Sketches') ? t('MobileDashboardView.Examples') : (TabLabels[tab] || tab)}

        )) } diff --git a/client/modules/Mobile/MobilePreferences.jsx b/client/modules/Mobile/MobilePreferences.jsx index 69ad737b03..0efd4b4604 100644 --- a/client/modules/Mobile/MobilePreferences.jsx +++ b/client/modules/Mobile/MobilePreferences.jsx @@ -2,6 +2,8 @@ import React from 'react'; import { bindActionCreators } from 'redux'; import { connect, useSelector, useDispatch } from 'react-redux'; import { withRouter } from 'react-router'; +import { useTranslation } from 'react-i18next'; + import PropTypes from 'prop-types'; import styled from 'styled-components'; @@ -42,27 +44,33 @@ const MobilePreferences = () => { setTheme, setAutosave, setLinewrap, setTextOutput, setGridOutput, setSoundOutput, setLineNumbers, setLintWarning, } = bindActionCreators({ ...PreferencesActions, ...IdeActions }, useDispatch()); + const { t, i18n } = useTranslation(); const generalSettings = [ { - title: 'Theme', + title: t('Preferences.Theme'), value: theme, - options: optionsPickOne('theme', 'light', 'dark', 'contrast'), + options: optionsPickOne( + t('Preferences.Theme'), + t('Preferences.LightTheme'), + t('Preferences.DarkTheme'), + t('Preferences.HighContrastTheme') + ), onSelect: x => setTheme(x) // setTheme }, - preferenceOnOff('Autosave', autosave, setAutosave, 'autosave'), - preferenceOnOff('Word Wrap', linewrap, setLinewrap, 'linewrap') + preferenceOnOff(t('Preferences.Autosave'), autosave, setAutosave, 'autosave'), + preferenceOnOff(t('Preferences.WordWrap'), linewrap, setLinewrap, 'linewrap') ]; const outputSettings = [ - preferenceOnOff('Plain-text', textOutput, setTextOutput, 'text output'), - preferenceOnOff('Table-text', gridOutput, setGridOutput, 'table output'), - preferenceOnOff('Lint Warning Sound', soundOutput, setSoundOutput, 'sound output') + preferenceOnOff(t('Preferences.PlainText'), textOutput, setTextOutput, 'text output'), + preferenceOnOff(t('Preferences.TableText'), gridOutput, setGridOutput, 'table output'), + preferenceOnOff(t('Preferences.Sound'), soundOutput, setSoundOutput, 'sound output') ]; const accessibilitySettings = [ - preferenceOnOff('Line Numbers', lineNumbers, setLineNumbers), - preferenceOnOff('Lint Warning Sound', lintWarning, setLintWarning) + preferenceOnOff(t('Preferences.LineNumbers'), lineNumbers, setLineNumbers), + preferenceOnOff(t('Preferences.LintWarningSound'), lintWarning, setLintWarning) ]; return ( @@ -73,14 +81,14 @@ const MobilePreferences = () => {
        - General Settings + {t('Preferences.GeneralSettings')} { generalSettings.map(option => ) } - Accessibility + {t('Preferences.Accessibility')} { accessibilitySettings.map(option => ) } - Accessible Output - Used with screen reader + {t('Preferences.AccessibleOutput')} + {t('Preferences.UsedScreenReader')} { outputSettings.map(option => ) } diff --git a/translations/locales/en-US/translations.json b/translations/locales/en-US/translations.json index ab64c317eb..0157b77137 100644 --- a/translations/locales/en-US/translations.json +++ b/translations/locales/en-US/translations.json @@ -114,6 +114,7 @@ "Settings": "Settings", "GeneralSettings": "General settings", "Accessibility": "Accessibility", + "AccessibleOutput": "Accessible Output", "Theme": "Theme", "LightTheme": "Light", "LightThemeARIA": "light theme on", @@ -531,5 +532,25 @@ "PreviewNav": { "EditSketchARIA": "Edit Sketch", "ByUser": "by" + }, + "MobileNav":{ + "Preferences": "Preferences", + "MyStuff": "My Stuff", + "Examples": "Examples", + "OriginalEditor": "Original Editor", + "Login": "Login", + "Logout": "Logout" + }, + "MobileDashboardView": { + "Examples": "Examples", + "Sketches": "Sketches", + "Collections": "Collections", + "Assets": "Assets", + "MyStuff": "My Stuff", + "CreateSketch": "Create Sketch", + "CreateCollection": "Create Collection" + }, + "MobileSideBar": { + "Files": "Files" } } diff --git a/translations/locales/es-419/translations.json b/translations/locales/es-419/translations.json index 08d9778ad5..979b483721 100644 --- a/translations/locales/es-419/translations.json +++ b/translations/locales/es-419/translations.json @@ -114,6 +114,7 @@ "Settings": "Configuración", "GeneralSettings": "Configuración general", "Accessibility": "Accesibilidad", + "AccessibleOutput": "Salida accesible", "Theme": "Modo de visualización", "LightTheme": "Claro", "LightThemeARIA": "Modo de visualización claro activado", @@ -531,5 +532,25 @@ "PreviewNav": { "EditSketchARIA": "Editar Bosquejo", "ByUser": "por" + }, + "MobileNav":{ + "Preferences": "Preferencias", + "MyStuff": "Mis cosas", + "Examples": "Ejemplos", + "OriginalEditor": "Editor Original", + "Login": "Ingresa", + "Logout": "Cerrar sesión" + }, + "MobileDashboardView": { + "Examples": "Ejemplos", + "Sketches": "Bosquejos", + "Collections": "Colecciones", + "Assets": "Assets", + "MyStuff": "Mis cosas", + "CreateSketch": "Crear bosquejo", + "CreateCollection": "Crear colección" + }, + "MobileSideBar": { + "Files": "Archivos" } } From e8d277cdab18188aab2d693256de1bf60be30d61 Mon Sep 17 00:00:00 2001 From: ridait Date: Fri, 28 Aug 2020 18:52:38 +0200 Subject: [PATCH 5/5] remove unused var & improve keys naming --- client/components/mobile/Explorer.jsx | 4 +-- .../Preferences/PreferenceCreators.jsx | 6 ++-- client/modules/IDE/pages/MobileIDEView.jsx | 20 +++++------ client/modules/Mobile/MobileDashboardView.jsx | 4 +-- client/modules/Mobile/MobilePreferences.jsx | 34 +++++++++---------- translations/locales/en-US/translations.json | 27 +++++++++++++-- translations/locales/es-419/translations.json | 27 +++++++++++++-- 7 files changed, 82 insertions(+), 40 deletions(-) diff --git a/client/components/mobile/Explorer.jsx b/client/components/mobile/Explorer.jsx index d090553495..f4d501ceb0 100644 --- a/client/components/mobile/Explorer.jsx +++ b/client/components/mobile/Explorer.jsx @@ -7,9 +7,9 @@ import ConnectedFileNode from '../../modules/IDE/components/FileNode'; const Explorer = ({ id, canEdit, onPressClose }) => { - const { t, i18n } = useTranslation(); + const { t } = useTranslation(); return ( - + onPressClose()} /> ); diff --git a/client/modules/IDE/components/Preferences/PreferenceCreators.jsx b/client/modules/IDE/components/Preferences/PreferenceCreators.jsx index dd5ef2ff1d..4a946ac2bf 100644 --- a/client/modules/IDE/components/Preferences/PreferenceCreators.jsx +++ b/client/modules/IDE/components/Preferences/PreferenceCreators.jsx @@ -1,13 +1,13 @@ import { useTranslation } from 'react-i18next'; export const optionsOnOff = (name) => { - const { t, i18n } = useTranslation(); + const { t } = useTranslation(); return [ { - value: true, label: t('Preferences.On'), ariaLabel: `${name} on`, name: `${name}`, id: `${name}-on`.replace(' ', '-') + value: true, label: t('PreferenceCreators.On'), ariaLabel: `${name} on`, name: `${name}`, id: `${name}-on`.replace(' ', '-') }, { - value: false, label: t('Preferences.Off'), ariaLabel: `${name} off`, name: `${name}`, id: `${name}-off`.replace(' ', '-') + value: false, label: t('PreferenceCreators.Off'), ariaLabel: `${name} off`, name: `${name}`, id: `${name}-off`.replace(' ', '-') } ]; }; diff --git a/client/modules/IDE/pages/MobileIDEView.jsx b/client/modules/IDE/pages/MobileIDEView.jsx index 28524f2bb6..ae690f09ab 100644 --- a/client/modules/IDE/pages/MobileIDEView.jsx +++ b/client/modules/IDE/pages/MobileIDEView.jsx @@ -65,20 +65,20 @@ const NavItem = styled.li` `; const getNavOptions = (username = undefined, logoutUser = () => {}, toggleForceDesktop = () => {}) => { - const { t, i18n } = useTranslation(); + const { t } = useTranslation(); return (username ? [ - { icon: PreferencesIcon, title: t('MobileNav.Preferences'), href: '/preferences', }, - { icon: PreferencesIcon, title: t('MobileNav.MyStuff'), href: `/${username}/sketches` }, - { icon: PreferencesIcon, title: t('MobileNav.Examples'), href: '/p5/sketches' }, - { icon: PreferencesIcon, title: t('MobileNav.OriginalEditor'), action: toggleForceDesktop, }, - { icon: PreferencesIcon, title: t('MobileNav.Logout'), action: logoutUser, }, + { icon: PreferencesIcon, title: t('MobileIDEView.Preferences'), href: '/preferences', }, + { icon: PreferencesIcon, title: t('MobileIDEView.MyStuff'), href: `/${username}/sketches` }, + { icon: PreferencesIcon, title: t('MobileIDEView.Examples'), href: '/p5/sketches' }, + { icon: PreferencesIcon, title: t('MobileIDEView.OriginalEditor'), action: toggleForceDesktop, }, + { icon: PreferencesIcon, title: t('MobileIDEView.Logout'), action: logoutUser, }, ] : [ - { icon: PreferencesIcon, title: t('MobileNav.Preferences'), href: '/preferences', }, - { icon: PreferencesIcon, title: t('MobileNav.Examples'), href: '/p5/sketches' }, - { icon: PreferencesIcon, title: t('MobileNav.OriginalEditor'), action: toggleForceDesktop, }, - { icon: PreferencesIcon, title: t('MobileNav.Login'), href: '/login', }, + { icon: PreferencesIcon, title: t('MobileIDEView.Preferences'), href: '/preferences', }, + { icon: PreferencesIcon, title: t('MobileIDEView.Examples'), href: '/p5/sketches' }, + { icon: PreferencesIcon, title: t('MobileIDEView.OriginalEditor'), action: toggleForceDesktop, }, + { icon: PreferencesIcon, title: t('MobileIDEView.Login'), href: '/login', }, ] ); }; diff --git a/client/modules/Mobile/MobileDashboardView.jsx b/client/modules/Mobile/MobileDashboardView.jsx index c2df71886d..51f074fb9a 100644 --- a/client/modules/Mobile/MobileDashboardView.jsx +++ b/client/modules/Mobile/MobileDashboardView.jsx @@ -139,7 +139,7 @@ const Panels = { const navOptions = (username) => { - const { t, i18n } = useTranslation(); + const { t } = useTranslation(); return [ { title: t('MobileDashboardView.CreateSketch'), href: '/' }, { title: t('MobileDashboardView.CreateCollection'), href: `/${username}/collections/create` } @@ -166,7 +166,7 @@ const MobileDashboard = ({ params, location }) => { const user = useSelector(state => state.user); const { username: paramsUsername } = params; const { pathname } = location; - const { t, i18n } = useTranslation(); + const { t } = useTranslation(); const Tabs = Object.keys(Panels); const TabLabels = { diff --git a/client/modules/Mobile/MobilePreferences.jsx b/client/modules/Mobile/MobilePreferences.jsx index 0efd4b4604..07701e2684 100644 --- a/client/modules/Mobile/MobilePreferences.jsx +++ b/client/modules/Mobile/MobilePreferences.jsx @@ -44,33 +44,33 @@ const MobilePreferences = () => { setTheme, setAutosave, setLinewrap, setTextOutput, setGridOutput, setSoundOutput, setLineNumbers, setLintWarning, } = bindActionCreators({ ...PreferencesActions, ...IdeActions }, useDispatch()); - const { t, i18n } = useTranslation(); + const { t } = useTranslation(); const generalSettings = [ { - title: t('Preferences.Theme'), + title: t('MobilePreferences.Theme'), value: theme, options: optionsPickOne( - t('Preferences.Theme'), - t('Preferences.LightTheme'), - t('Preferences.DarkTheme'), - t('Preferences.HighContrastTheme') + t('MobilePreferences.Theme'), + t('MobilePreferences.LightTheme'), + t('MobilePreferences.DarkTheme'), + t('MobilePreferences.HighContrastTheme') ), onSelect: x => setTheme(x) // setTheme }, - preferenceOnOff(t('Preferences.Autosave'), autosave, setAutosave, 'autosave'), - preferenceOnOff(t('Preferences.WordWrap'), linewrap, setLinewrap, 'linewrap') + preferenceOnOff(t('MobilePreferences.Autosave'), autosave, setAutosave, 'autosave'), + preferenceOnOff(t('MobilePreferences.WordWrap'), linewrap, setLinewrap, 'linewrap') ]; const outputSettings = [ - preferenceOnOff(t('Preferences.PlainText'), textOutput, setTextOutput, 'text output'), - preferenceOnOff(t('Preferences.TableText'), gridOutput, setGridOutput, 'table output'), - preferenceOnOff(t('Preferences.Sound'), soundOutput, setSoundOutput, 'sound output') + preferenceOnOff(t('MobilePreferences.PlainText'), textOutput, setTextOutput, 'text output'), + preferenceOnOff(t('MobilePreferences.TableText'), gridOutput, setGridOutput, 'table output'), + preferenceOnOff(t('MobilePreferences.Sound'), soundOutput, setSoundOutput, 'sound output') ]; const accessibilitySettings = [ - preferenceOnOff(t('Preferences.LineNumbers'), lineNumbers, setLineNumbers), - preferenceOnOff(t('Preferences.LintWarningSound'), lintWarning, setLintWarning) + preferenceOnOff(t('MobilePreferences.LineNumbers'), lineNumbers, setLineNumbers), + preferenceOnOff(t('MobilePreferences.LintWarningSound'), lintWarning, setLintWarning) ]; return ( @@ -81,14 +81,14 @@ const MobilePreferences = () => {
        - {t('Preferences.GeneralSettings')} + {t('MobilePreferences.GeneralSettings')} { generalSettings.map(option => ) } - {t('Preferences.Accessibility')} + {t('MobilePreferences.Accessibility')} { accessibilitySettings.map(option => ) } - {t('Preferences.AccessibleOutput')} - {t('Preferences.UsedScreenReader')} + {t('MobilePreferences.AccessibleOutput')} + {t('MobilePreferences.UsedScreenReader')} { outputSettings.map(option => ) } diff --git a/translations/locales/en-US/translations.json b/translations/locales/en-US/translations.json index 0157b77137..65e32fd6b4 100644 --- a/translations/locales/en-US/translations.json +++ b/translations/locales/en-US/translations.json @@ -114,7 +114,6 @@ "Settings": "Settings", "GeneralSettings": "General settings", "Accessibility": "Accessibility", - "AccessibleOutput": "Accessible Output", "Theme": "Theme", "LightTheme": "Light", "LightThemeARIA": "light theme on", @@ -533,7 +532,29 @@ "EditSketchARIA": "Edit Sketch", "ByUser": "by" }, - "MobileNav":{ + "MobilePreferences": { + "Settings": "Settings", + "GeneralSettings": "General settings", + "Accessibility": "Accessibility", + "AccessibleOutput": "Accessible Output", + "Theme": "Theme", + "LightTheme": "Light", + "DarkTheme": "Dark", + "HighContrastTheme": "High Contrast", + "Autosave": "Autosave", + "WordWrap": "Word Wrap", + "LineNumbers": "Line numbers", + "LintWarningSound": "Lint warning sound", + "UsedScreenReader": "Used with screen reader", + "PlainText": "Plain-text", + "TableText": "Table-text", + "Sound": "Sound" + }, + "PreferenceCreators": { + "On": "On", + "Off": "Off" + }, + "MobileIDEView":{ "Preferences": "Preferences", "MyStuff": "My Stuff", "Examples": "Examples", @@ -550,7 +571,7 @@ "CreateSketch": "Create Sketch", "CreateCollection": "Create Collection" }, - "MobileSideBar": { + "Explorer": { "Files": "Files" } } diff --git a/translations/locales/es-419/translations.json b/translations/locales/es-419/translations.json index 979b483721..997334a35a 100644 --- a/translations/locales/es-419/translations.json +++ b/translations/locales/es-419/translations.json @@ -114,7 +114,6 @@ "Settings": "Configuración", "GeneralSettings": "Configuración general", "Accessibility": "Accesibilidad", - "AccessibleOutput": "Salida accesible", "Theme": "Modo de visualización", "LightTheme": "Claro", "LightThemeARIA": "Modo de visualización claro activado", @@ -533,7 +532,29 @@ "EditSketchARIA": "Editar Bosquejo", "ByUser": "por" }, - "MobileNav":{ + "MobilePreferences": { + "Settings": "Configuración", + "GeneralSettings": "Configuración general", + "Accessibility": "Accesibilidad", + "AccessibleOutput": "Salida accesible", + "Theme": "Modo de visualización", + "LightTheme": "Claro", + "DarkTheme": "Oscuro", + "HighContrastTheme": "Alto contraste", + "Autosave": "Grabar automáticamente", + "WordWrap": "Ajuste automático de línea", + "LineNumbers": "Número de línea", + "LintWarningSound": "Sonido de alarma Lint", + "UsedScreenReader": "Uso con screen reader", + "PlainText": "Texto sin formato", + "TableText": "Tablero de texto", + "Sound": "Sonido" + }, + "PreferenceCreators": { + "On": "Activar", + "Off": "Desactivar" + }, + "MobileIDEView":{ "Preferences": "Preferencias", "MyStuff": "Mis cosas", "Examples": "Ejemplos", @@ -550,7 +571,7 @@ "CreateSketch": "Crear bosquejo", "CreateCollection": "Crear colección" }, - "MobileSideBar": { + "Explorer": { "Files": "Archivos" } }