Skip to content

Commit

Permalink
lazy load json language source to i18n
Browse files Browse the repository at this point in the history
  • Loading branch information
oskar-binary committed Dec 18, 2019
1 parent 2d6531c commit dda74ad
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 76 deletions.
2 changes: 1 addition & 1 deletion packages/core/build/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const copyConfig = (base) => ([
{ from: path.resolve(__dirname, '../node_modules/deriv-trader/dist/js/trader.*.js'), to: 'js', flatten: true },
{ from: path.resolve(__dirname, '../node_modules/deriv-trader/dist/css/**'), to: 'css', flatten: true },
{ from: path.resolve(__dirname, '../node_modules/deriv-trader/dist/*.*'), to: 'js', flatten: true },
{ from: path.resolve(__dirname, '../node_modules/deriv-translations/lib/languages/*.*'), to: 'public/i18n', flatten: true },
{ from: path.resolve(__dirname, '../node_modules/deriv-translations/lib/public/i18n/*.*'), to: 'public/i18n', flatten: true },
{ from: path.resolve(__dirname, '../scripts/CNAME'), to: 'CNAME', toType: 'file' },
{ from: path.resolve(__dirname, '../src/root_files/404.html'), to: '404.html', toType: 'file' },
{ from: path.resolve(__dirname, '../src/root_files/robots.txt'), to: 'robots.txt', toType: 'file' },
Expand Down
5 changes: 3 additions & 2 deletions packages/core/src/App/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Prompt } from 'react-router';
import { BrowserRouter as Router } from 'react-router-dom';
// Initialize i18n by importing it here
// eslint-disable-next-line no-unused-vars
import { i18n,
import { initializeTranslations,
loadIncontextTranslation } from 'deriv-translations';
import Client from '_common/base/client_base';
import WS from 'Services/ws-methods';
Expand All @@ -32,8 +32,9 @@ const App = ({ root_store }) => {
const has_base = /^\/(br_)/.test(l.pathname);
const url_params = new URLSearchParams(l.search);

initializeTranslations();
const is_staging = /staging\.deriv\.app/i.test(l.hostname);
if (true) {
if (is_staging) {
loadIncontextTranslation();
}

Expand Down
8 changes: 5 additions & 3 deletions packages/translations/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@
* This project uses [react-i18next](https://react.i18next.com)

### Setup
* initialize translations in root app.jsx by importing i18n.js
* in `app.jsx`
* initialize translations in root app.jsx by importing and calling initializeTranslations
* in `app.jsx`:
```jsx
import { i18n } from 'deriv-translations';
import { initializeTranslations } from 'deriv-translations';
...
initializeTranslations()
```
### Usage
* For strings use either `localize(...)` or `<Localize />`
Expand Down
2 changes: 1 addition & 1 deletion packages/translations/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "Deriv translations",
"author": "Deriv",
"license": "Apache-2.0",
"main": "lib/main.js",
"main": "lib/translations.main.js",
"repository": {
"type": "git",
"url": "git+https://github.com/binary-com/deriv-app.git"
Expand Down
120 changes: 54 additions & 66 deletions packages/translations/src/i18next/i18next.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,7 @@
/* eslint-disable */
import { str as crc32 } from 'crc-32';
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import withI18n from '../components'
// TODO: lazy load these: with i18n.addResourceBundle
// import ach from '../translations/ach.json';
// import es from '../translations/es.json';
// import fr from '../translations/fr.json';
// import id from '../translations/id.json';
// import it from '../translations/it.json';
// import pl from '../translations/pl.json';
// import pt from '../translations/pt.json';
// import ru from '../translations/ru.json';
// import vi from '../translations/ru.json';
// import zh_cn from '../translations/zh_cn.json';
// import zh_tw from '../translations/zh_tw.json';
import withI18n from '../components';

const LANGUAGE_KEY = 'i18n_language';
const DEFAULT_LANGUAGE = 'EN';
Expand All @@ -33,7 +20,15 @@ const ALL_LANGUAGES = Object.freeze({
ZH_TW: '繁體中文',
});

const hasLanguage = lang => {
const getUrlBase = (path = '') => {
const l = window.location;

if (!/^\/(br_)/.test(l.pathname)) return path;

return `/${l.pathname.split('/')[1]}${/^\//.test(path) ? path : `/${path}`}`;
};

const hasLanguage = (lang) => {
if (!lang) return false;
return Object.keys(ALL_LANGUAGES).includes(lang.toUpperCase());
};
Expand Down Expand Up @@ -64,65 +59,50 @@ const getInitialLanguage = () => {
return DEFAULT_LANGUAGE;
};

const loadLanguageJson = async (lang) => {
if (!i18n.hasResourceBundle(lang, 'translations') && lang !== DEFAULT_LANGUAGE) {
const response = await fetch(getUrlBase(`/public/i18n/${lang.toLowerCase()}.json`));
const lang_json = await response.text();

i18n.addResourceBundle(lang, 'translations', JSON.parse(lang_json));
}
};

const initial_language = getInitialLanguage();
const i18n_config = {
resources: {
// ACH : { translations: {...ach } },
// ES : { translations: { ...es } },
// FR : { translations: { ...fr } },
// ID : { translations: { ...id } },
// IT : { translations: { ...it } },
// PL : { translations: { ...pl } },
// PT : { translations: { ...pt } },
// RU : { translations: { ...ru } },
// VI : { translations: { ...vi } },
// ZH_CN: { translations: { ...zh_cn } },
// ZH_TW: { translations: { ...zh_tw } },
},
react: {
hashTransKey(defaultValue) {
return crc32(defaultValue);
},
},
lng: initial_language,
lng : initial_language,
fallbackLng: 'EN',
ns: ['translations'],
defaultNS: 'translations',
ns : ['translations'],
defaultNS : 'translations',
};

i18n
.use(initReactI18next) // passes i18n down to react-i18next
.init(i18n_config);

loadLanguageJson(initial_language);

function loadLanguageJson(lang) {
return new Promise((resolve) => {
if (!i18n.hasResourceBundle(lang, 'translations') && lang !== DEFAULT_LANGUAGE) {
import(`public/i18n/${lang.toLowerCase()}.json`).then(({default: lang_json}) => {
console.log('lang_json ', lang_json);
i18n.addResourceBundle(lang, 'translations', { ...lang_json })
resolve();
})
} else {
resolve()
}
})
}

const changeLanguage = (lang, cb) => {
// TODO: uncomment this when translations are ready
// if (hasLanguage(lang)) {
// i18n.changeLanguage(lang, () => {
// localStorage.setItem(LANGUAGE_KEY, lang);
// loadLanguageJson(lang).then(() => {
// cb();
// })
// })
// }
}

const getLanguage = () => i18n.language;
const initializeTranslations = async () => {
await loadLanguageJson(initial_language);
};

const changeLanguage = async (lang, cb) => {
if (hasLanguage(lang)) {
await loadLanguageJson(lang);
i18n.changeLanguage(lang, () => {
localStorage.setItem(LANGUAGE_KEY, lang);
cb();
});
}
};

const getLanguage = () => {
const lang = i18n.language || initial_language;
return lang;
};

// <Localize /> component wrapped with i18n
const Localize = withI18n(i18n);
Expand All @@ -136,16 +116,24 @@ const localize = (string, values) => {
const loadIncontextTranslation = () => {
const is_ach = i18n.language === 'ACH';
if (is_ach) {
const jipt = document.createElement('script')
jipt.type = 'text/javascript'
const jipt = document.createElement('script');
jipt.type = 'text/javascript';
jipt.text = `
var _jipt = []; _jipt.push(['project', 'deriv-app']);
var crowdin = document.createElement("script");
crowdin.setAttribute('src', '//cdn.crowdin.com/jipt/jipt.js');
document.head.appendChild(crowdin);
`
document.head.appendChild(jipt)
`;
document.head.appendChild(jipt);
}
}
};

export default { i18n, localize, Localize, changeLanguage, getLanguage, getAllLanguages, loadIncontextTranslation };
export default {
changeLanguage,
getAllLanguages,
getLanguage,
initializeTranslations,
loadIncontextTranslation,
localize,
Localize,
};
11 changes: 8 additions & 3 deletions packages/translations/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,16 @@ module.exports = {
entry : path.resolve(__dirname, 'src', 'i18next/index.js'),
output: {
path : path.resolve(__dirname, 'lib'),
filename : '[name].js',
filename : 'translations.main.js',
libraryExport: 'default',
library : ['deriv-translations', '[name]'],
library : 'deriv-translations',
libraryTarget: 'umd',
},
resolve: {
alias: {
'public/i18n': path.resolve(__dirname, 'lib', 'languages'),
},
},
optimization: {
minimize: true,
// TODO enable splitChunks
Expand Down Expand Up @@ -45,7 +50,7 @@ module.exports = {
},
plugins: [
new CopyWebpackPlugin([
{ from: 'src/translations', to: 'languages/' },
{ from: 'src/translations', to: 'public/i18n/' },
]),
],
externals: {
Expand Down

0 comments on commit dda74ad

Please sign in to comment.