Skip to content

Commit b05d1b1

Browse files
authored
Prototype with proposed i18n architecture (#1478)
* Branch with i18n functionality * Translation files with new entries * includes Loader in index.jsx * Uses WithTranslation In Nav * New Namespace * Shortcuts Modal Complete * Preferences complete * About overlay title translated
1 parent 69bd6cb commit b05d1b1

File tree

16 files changed

+542
-150
lines changed

16 files changed

+542
-150
lines changed

Diff for: client/components/Nav.jsx

+111-36
Large diffs are not rendered by default.

Diff for: client/components/__test__/Nav.test.jsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ describe('Nav', () => {
4444
setToastText: jest.fn(),
4545
rootFile: {
4646
id: 'root-file'
47-
}
47+
},
48+
t: jest.fn()
4849
};
4950
const getWrapper = () => shallow(<NavComponent {...props} />);
5051

Diff for: client/components/__test__/__snapshots__/Nav.test.jsx.snap

+14-48
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@ exports[`Nav renders correctly 1`] = `
3030
>
3131
<span
3232
className="nav__item-header"
33-
>
34-
File
35-
</span>
33+
/>
3634
<test-file-stub
3735
aria-hidden="true"
3836
className="nav__item-header-triangle"
@@ -49,9 +47,7 @@ exports[`Nav renders correctly 1`] = `
4947
onBlur={[Function]}
5048
onClick={[Function]}
5149
onFocus={[Function]}
52-
>
53-
New
54-
</button>
50+
/>
5551
</li>
5652
<li
5753
className="nav__dropdown-item"
@@ -60,9 +56,7 @@ exports[`Nav renders correctly 1`] = `
6056
onBlur={[Function]}
6157
onClick={[Function]}
6258
onFocus={[Function]}
63-
>
64-
Duplicate
65-
</button>
59+
/>
6660
</li>
6761
<li
6862
className="nav__dropdown-item"
@@ -71,9 +65,7 @@ exports[`Nav renders correctly 1`] = `
7165
onBlur={[Function]}
7266
onClick={[Function]}
7367
onFocus={[Function]}
74-
>
75-
Share
76-
</button>
68+
/>
7769
</li>
7870
<li
7971
className="nav__dropdown-item"
@@ -82,9 +74,7 @@ exports[`Nav renders correctly 1`] = `
8274
onBlur={[Function]}
8375
onClick={[Function]}
8476
onFocus={[Function]}
85-
>
86-
Download
87-
</button>
77+
/>
8878
</li>
8979
<li
9080
className="nav__dropdown-item"
@@ -94,9 +84,7 @@ exports[`Nav renders correctly 1`] = `
9484
onClick={[Function]}
9585
onFocus={[Function]}
9686
style={Object {}}
97-
>
98-
Open
99-
</a>
87+
/>
10088
</li>
10189
</ul>
10290
</li>
@@ -111,9 +99,7 @@ exports[`Nav renders correctly 1`] = `
11199
>
112100
<span
113101
className="nav__item-header"
114-
>
115-
Edit
116-
</span>
102+
/>
117103
<test-file-stub
118104
aria-hidden="true"
119105
className="nav__item-header-triangle"
@@ -131,7 +117,6 @@ exports[`Nav renders correctly 1`] = `
131117
onClick={[Function]}
132118
onFocus={[Function]}
133119
>
134-
Tidy Code
135120
<span
136121
className="nav__keyboard-shortcut"
137122
>
@@ -148,7 +133,6 @@ exports[`Nav renders correctly 1`] = `
148133
onClick={[Function]}
149134
onFocus={[Function]}
150135
>
151-
Find
152136
<span
153137
className="nav__keyboard-shortcut"
154138
>
@@ -165,7 +149,6 @@ exports[`Nav renders correctly 1`] = `
165149
onClick={[Function]}
166150
onFocus={[Function]}
167151
>
168-
Find Next
169152
<span
170153
className="nav__keyboard-shortcut"
171154
>
@@ -182,7 +165,6 @@ exports[`Nav renders correctly 1`] = `
182165
onClick={[Function]}
183166
onFocus={[Function]}
184167
>
185-
Find Previous
186168
<span
187169
className="nav__keyboard-shortcut"
188170
>
@@ -206,9 +188,7 @@ exports[`Nav renders correctly 1`] = `
206188
>
207189
<span
208190
className="nav__item-header"
209-
>
210-
Sketch
211-
</span>
191+
/>
212192
<test-file-stub
213193
aria-hidden="true"
214194
className="nav__item-header-triangle"
@@ -225,9 +205,7 @@ exports[`Nav renders correctly 1`] = `
225205
onBlur={[Function]}
226206
onClick={[Function]}
227207
onFocus={[Function]}
228-
>
229-
Add File
230-
</button>
208+
/>
231209
</li>
232210
<li
233211
className="nav__dropdown-item"
@@ -236,9 +214,7 @@ exports[`Nav renders correctly 1`] = `
236214
onBlur={[Function]}
237215
onClick={[Function]}
238216
onFocus={[Function]}
239-
>
240-
Add Folder
241-
</button>
217+
/>
242218
</li>
243219
<li
244220
className="nav__dropdown-item"
@@ -248,7 +224,6 @@ exports[`Nav renders correctly 1`] = `
248224
onClick={[Function]}
249225
onFocus={[Function]}
250226
>
251-
Run
252227
<span
253228
className="nav__keyboard-shortcut"
254229
>
@@ -265,7 +240,6 @@ exports[`Nav renders correctly 1`] = `
265240
onClick={[Function]}
266241
onFocus={[Function]}
267242
>
268-
Stop
269243
<span
270244
className="nav__keyboard-shortcut"
271245
>
@@ -289,9 +263,7 @@ exports[`Nav renders correctly 1`] = `
289263
>
290264
<span
291265
className="nav__item-header"
292-
>
293-
Help
294-
</span>
266+
/>
295267
<test-file-stub
296268
aria-hidden="true"
297269
className="nav__item-header-triangle"
@@ -308,9 +280,7 @@ exports[`Nav renders correctly 1`] = `
308280
onBlur={[Function]}
309281
onClick={[Function]}
310282
onFocus={[Function]}
311-
>
312-
Keyboard Shortcuts
313-
</button>
283+
/>
314284
</li>
315285
<li
316286
className="nav__dropdown-item"
@@ -322,9 +292,7 @@ exports[`Nav renders correctly 1`] = `
322292
onFocus={[Function]}
323293
rel="noopener noreferrer"
324294
target="_blank"
325-
>
326-
Reference
327-
</a>
295+
/>
328296
</li>
329297
<li
330298
className="nav__dropdown-item"
@@ -334,9 +302,7 @@ exports[`Nav renders correctly 1`] = `
334302
onClick={[Function]}
335303
onFocus={[Function]}
336304
style={Object {}}
337-
>
338-
About
339-
</a>
305+
/>
340306
</li>
341307
</ul>
342308
</li>

Diff for: client/i18n.js

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import i18n from 'i18next';
2+
import { initReactI18next } from 'react-i18next';
3+
import LanguageDetector from 'i18next-browser-languagedetector';
4+
import Backend from 'i18next-http-backend';
5+
6+
const fallbackLng = ['en-US'];
7+
const availableLanguages = ['en-US', 'es-419'];
8+
9+
const options = {
10+
loadPath: '/translations/{{lng}}/translations.json',
11+
requestOptions: { // used for fetch, can also be a function (payload) => ({ method: 'GET' })
12+
mode: 'no-cors'
13+
},
14+
allowMultiLoading: false, // set loadPath: '/locales/resources.json?lng={{lng}}&ns={{ns}}' to adapt to multiLoading
15+
};
16+
17+
i18n
18+
.use(initReactI18next) // pass the i18n instance to react-i18next.
19+
.use(LanguageDetector)// to detect the language from currentBrowser
20+
.use(Backend) // to fetch the data from server
21+
.init({
22+
lng: 'en-US',
23+
defaultNS: 'WebEditor',
24+
fallbackLng, // if user computer language is not on the list of available languages, than we will be using the fallback language specified earlier
25+
debug: false,
26+
backend: options,
27+
getAsync: false,
28+
initImmediate: false,
29+
useSuspense: true,
30+
whitelist: availableLanguages,
31+
interpolation: {
32+
escapeValue: false, // react already safes from xss
33+
},
34+
saveMissing: false, // if a key is not found AND this flag is set to true, i18next will call the handler missingKeyHandler
35+
missingKeyHandler: false // function(lng, ns, key, fallbackValue) { } custom logic about how to handle the missing keys
36+
});
37+
38+
export default i18n;

Diff for: client/index.jsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import React, { Suspense } from 'react';
22
import { render } from 'react-dom';
33
import { hot } from 'react-hot-loader/root';
44
import { Provider } from 'react-redux';
@@ -7,6 +7,8 @@ import { Router, browserHistory } from 'react-router';
77
import configureStore from './store';
88
import routes from './routes';
99
import ThemeProvider from './modules/App/components/ThemeProvider';
10+
import Loader from './modules/App/components/loader';
11+
import i18n from './i18n';
1012

1113
require('./styles/main.scss');
1214

@@ -29,6 +31,8 @@ const App = () => (
2931
const HotApp = hot(App);
3032

3133
render(
32-
<HotApp />,
34+
<Suspense fallback={(<Loader />)}>
35+
<HotApp />
36+
</Suspense>,
3337
document.getElementById('root')
3438
);

Diff for: client/modules/IDE/components/About.jsx

+12-11
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import React from 'react';
22
import { Helmet } from 'react-helmet';
3-
3+
import { useTranslation } from 'react-i18next';
44
import SquareLogoIcon from '../../../images/p5js-square-logo.svg';
55
// import PlayIcon from '../../../images/play.svg';
66
import AsteriskIcon from '../../../images/p5-asterisk.svg';
77

88
function About(props) {
9+
const { t } = useTranslation();
910
return (
1011
<div className="about__content">
1112
<Helmet>
12-
<title>p5.js Web Editor | About</title>
13+
<title>p5.js Web Editor | About </title>
1314
</Helmet>
1415
<div className="about__content-column">
1516
<SquareLogoIcon className="about__logo" role="img" aria-label="p5.js Logo" focusable="false" />
@@ -25,15 +26,15 @@ function About(props) {
2526
</p> */}
2627
</div>
2728
<div className="about__content-column">
28-
<h3 className="about__content-column-title">New to p5.js?</h3>
29+
<h3 className="about__content-column-title">{t('NewP5')}</h3>
2930
<p className="about__content-column-list">
3031
<a
3132
href="https://p5js.org/examples/"
3233
target="_blank"
3334
rel="noopener noreferrer"
3435
>
3536
<AsteriskIcon className="about__content-column-asterisk" aria-hidden="true" focusable="false" />
36-
Examples
37+
{t('Examples')}
3738
</a>
3839
</p>
3940
<p className="about__content-column-list">
@@ -43,20 +44,20 @@ function About(props) {
4344
rel="noopener noreferrer"
4445
>
4546
<AsteriskIcon className="about__content-column-asterisk" aria-hidden="true" focusable="false" />
46-
Learn
47+
{t('Learn')}
4748
</a>
4849
</p>
4950
</div>
5051
<div className="about__content-column">
51-
<h3 className="about__content-column-title">Resources</h3>
52+
<h3 className="about__content-column-title">{t('Resources')}</h3>
5253
<p className="about__content-column-list">
5354
<a
5455
href="https://p5js.org/libraries/"
5556
target="_blank"
5657
rel="noopener noreferrer"
5758
>
5859
<AsteriskIcon className="about__content-column-asterisk" aria-hidden="true" focusable="false" />
59-
Libraries
60+
{t('Libraries')}
6061
</a>
6162
</p>
6263
<p className="about__content-column-list">
@@ -66,7 +67,7 @@ function About(props) {
6667
rel="noopener noreferrer"
6768
>
6869
<AsteriskIcon className="about__content-column-asterisk" aria-hidden="true" focusable="false" />
69-
Reference
70+
{t('Reference')}
7071
</a>
7172
</p>
7273
<p className="about__content-column-list">
@@ -76,7 +77,7 @@ function About(props) {
7677
rel="noopener noreferrer"
7778
>
7879
<AsteriskIcon className="about__content-column-asterisk" aria-hidden="true" focusable="false" />
79-
Forum
80+
{t('Forum')}
8081
</a>
8182
</p>
8283
</div>
@@ -86,15 +87,15 @@ function About(props) {
8687
href="https://github.com/processing/p5.js-web-editor"
8788
target="_blank"
8889
rel="noopener noreferrer"
89-
>Contribute
90+
>{t('Contribute')}
9091
</a>
9192
</p>
9293
<p className="about__footer-list">
9394
<a
9495
href="https://github.com/processing/p5.js-web-editor/issues/new"
9596
target="_blank"
9697
rel="noopener noreferrer"
97-
>Report a bug
98+
>{t('Report')}
9899
</a>
99100
</p>
100101
<p className="about__footer-list">

0 commit comments

Comments
 (0)