Language Detection implementation, bug fixes related to i18n and debugger helper added.

This commit is contained in:
romulo bordezani 2019-06-11 20:05:14 -03:00
parent fde6088cb1
commit 0c8cd3fbe9
11 changed files with 125 additions and 57 deletions

View File

@ -18,10 +18,10 @@
}, },
"peerDependencies": { "peerDependencies": {
"i18next": "^17.0.3", "i18next": "^17.0.3",
"i18next-browser-languagedetector": "^3.0.1",
"react": "^16.0.0", "react": "^16.0.0",
"react-dom": "^16.0.0", "react-dom": "^16.0.0",
"react-i18next": "^10.11.0", "react-i18next": "^10.11.0"
"i18next-browser-languagedetector": "^3.0.1"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.2.2", "@babel/core": "^7.2.2",
@ -39,6 +39,7 @@
"eslint-plugin-react": "^7.11.1", "eslint-plugin-react": "^7.11.1",
"husky": "^1.3.1", "husky": "^1.3.1",
"i18next": "^15.1.3", "i18next": "^15.1.3",
"i18next-browser-languagedetector": "^3.0.1",
"lint-staged": "^8.1.0", "lint-staged": "^8.1.0",
"prettier": "^1.15.3", "prettier": "^1.15.3",
"react": "^16.0.0", "react": "^16.0.0",
@ -52,8 +53,7 @@
"rollup-plugin-node-resolve": "^4.0.0", "rollup-plugin-node-resolve": "^4.0.0",
"rollup-plugin-peer-deps-external": "^2.2.0", "rollup-plugin-peer-deps-external": "^2.2.0",
"rollup-plugin-postcss": "^2.0.3", "rollup-plugin-postcss": "^2.0.3",
"rollup-plugin-url": "^2.1.0", "rollup-plugin-url": "^2.1.0"
"i18next-browser-languagedetector": "^3.0.1"
}, },
"husky": { "husky": {
"hooks": { "hooks": {
@ -80,6 +80,7 @@
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.2.0", "@babel/runtime": "^7.2.0",
"classnames": "^2.2.6" "classnames": "^2.2.6",
"rollup-plugin-json": "^4.0.0"
} }
} }

View File

@ -8,6 +8,7 @@ import pkg from './package.json';
// Deal with https://github.com/rollup/rollup-plugin-commonjs/issues/297 // Deal with https://github.com/rollup/rollup-plugin-commonjs/issues/297
import builtins from 'rollup-plugin-node-builtins'; import builtins from 'rollup-plugin-node-builtins';
import copy from 'rollup-plugin-copy'; import copy from 'rollup-plugin-copy';
import json from 'rollup-plugin-json';
const globals = { const globals = {
react: 'React', react: 'React',
@ -17,6 +18,7 @@ const globals = {
'prop-types': 'PropTypes', 'prop-types': 'PropTypes',
'i18next': 'i18next', 'i18next': 'i18next',
'react-i18next': 'react-i18next', 'react-i18next': 'react-i18next',
'i18next-browser-languagedetector': 'LngDetector'
}; };
export default { export default {
@ -48,6 +50,13 @@ export default {
targets: ['src/locales'], targets: ['src/locales'],
outputFolder: 'dist', outputFolder: 'dist',
}), }),
json({
// ignores indent and generates the smallest code
compact: true, // Default: false
// generate a named export for every property of the JSON object
namedExports: true // Default: true
}),
url(), url(),
babel({ babel({
exclude: 'node_modules/**', exclude: 'node_modules/**',

View File

@ -0,0 +1,24 @@
const debugMode = !!(
process.env.NODE_ENV !== 'production' && process.env.REACT_APP_I18N_DEBUG
);
const detectionOptions = {
// order and from where user language should be detected
order: ['querystring', 'cookie', 'localStorage', 'navigator', 'htmlTag', 'path', 'subdomain'],
// keys or params to lookup language from
lookupQuerystring: 'lng',
lookupCookie: 'i18next',
lookupLocalStorage: 'i18nextLng',
lookupFromPathIndex: 0,
lookupFromSubdomainIndex: 0,
// cache user language on
caches: ['localStorage', 'cookie'],
excludeCacheFor: ['cimode'], // languages to not persist (cookie, localStorage)
// optional htmlTag with lang attribute, the default is:
htmlTag: document.documentElement
};
export { debugMode, detectionOptions };

View File

@ -0,0 +1,8 @@
import { debugMode } from './config';
export default (message, level = 'log') => {
if (debugMode) {
// eslint-disable-next-line
console[level](message);
}
};

View File

@ -1,16 +1,11 @@
import i18n from 'i18next'; import i18n from 'i18next';
import { initReactI18next } from 'react-i18next'; import { initReactI18next } from 'react-i18next';
import LngDetector from 'i18next-browser-languagedetector'; import LngDetector from 'i18next-browser-languagedetector';
import customDebug from './debugger';
import pkg from '../package.json';
import { debugMode, detectionOptions } from './config';
const currentLanguage = process.env.REACT_APP_LANG || 'en-US'; let translate;
const debugMode = !!(
process.env.NODE_ENV !== 'production' && process.env.REACT_APP_I18N_DEBUG
);
function getDefaultLanguage() {
const mainLanguage = currentLanguage.match(/(.*.)(-)/);
return mainLanguage !== null ? mainLanguage[1] : null;
}
function getNameSpaceString(key) { function getNameSpaceString(key) {
const nameSpaceMatcher = key.match(/[^/]+$/g); const nameSpaceMatcher = key.match(/[^/]+$/g);
@ -23,7 +18,7 @@ function getNameSpaceString(key) {
return finalNameSpace; return finalNameSpace;
} }
function getCleanKeyForNameSpaces(key) { function getKeyForNameSpaces(key) {
const cleanedKey = key.match(/[/\\].+(?=[/\\])/); const cleanedKey = key.match(/[/\\].+(?=[/\\])/);
let finalKey; let finalKey;
@ -40,8 +35,8 @@ function getLocales() {
const locales = {}; const locales = {};
context.keys().forEach(key => { context.keys().forEach(key => {
locales[getCleanKeyForNameSpaces(key)] = { locales[getKeyForNameSpaces(key)] = {
...locales[getCleanKeyForNameSpaces(key)], ...locales[getKeyForNameSpaces(key)],
[getNameSpaceString(key)]: context(key), [getNameSpaceString(key)]: context(key),
}; };
}); });
@ -52,43 +47,48 @@ function getLocales() {
function addLocales(context) { function addLocales(context) {
context.keys().forEach(key => { context.keys().forEach(key => {
i18n.addResourceBundle( i18n.addResourceBundle(
getCleanKeyForNameSpaces(key), getKeyForNameSpaces(key),
getNameSpaceString(key), getNameSpaceString(key),
context(key), context(key),
true, true,
true true
); );
}); });
customDebug(`Locales added successfully`, 'info');
} }
let translate; function initI18n(detection = detectionOptions) {
i18n
.use(LngDetector)
.use(initReactI18next)
.init({
resources: getLocales(),
debug: debugMode,
keySeparator: false,
interpolation: {
escapeValue: false,
},
detection,
fallbackNS: ['common'],
defaultNS: 'common',
react: {
wait: true,
},
})
.then(function(t) {
translate = t;
customDebug(`t function available.`, 'info');
});
}
i18n customDebug(`@ohif/i18n version ${pkg.version} loaded.`, 'info');
.use(LngDetector)
.use(initReactI18next)
.init({
resources: getLocales(),
fallbackLng: getDefaultLanguage(),
lng: currentLanguage, initI18n();
debug: debugMode,
// have a common namespace used around the full app export {
keySeparator: false, // uses content as keys translate as t,
interpolation: { addLocales,
escapeValue: false, initI18n
}, };
fallbackNS: ['common'],
defaultNS: 'common',
react: {
wait: true,
},
})
.then(function(t) {
translate = t;
});
export { translate as t, addLocales };
export default i18n; export default i18n;

View File

@ -4430,6 +4430,13 @@ rollup-plugin-copy@^2.0.1:
fs-extra "^7.0.1" fs-extra "^7.0.1"
is-plain-object "^3.0.0" is-plain-object "^3.0.0"
rollup-plugin-json@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/rollup-plugin-json/-/rollup-plugin-json-4.0.0.tgz#a18da0a4b30bf5ca1ee76ddb1422afbb84ae2b9e"
integrity sha512-hgb8N7Cgfw5SZAkb3jf0QXii6QX/FOkiIq2M7BAQIEydjHvTyxXHQiIzZaTFgx1GK0cRCHOCBHIyEkkLdWKxow==
dependencies:
rollup-pluginutils "^2.5.0"
rollup-plugin-node-builtins@^2.1.2: rollup-plugin-node-builtins@^2.1.2:
version "2.1.2" version "2.1.2"
resolved "https://registry.yarnpkg.com/rollup-plugin-node-builtins/-/rollup-plugin-node-builtins-2.1.2.tgz#24a1fed4a43257b6b64371d8abc6ce1ab14597e9" resolved "https://registry.yarnpkg.com/rollup-plugin-node-builtins/-/rollup-plugin-node-builtins-2.1.2.tgz#24a1fed4a43257b6b64371d8abc6ce1ab14597e9"
@ -4491,6 +4498,13 @@ rollup-pluginutils@^2.0.1, rollup-pluginutils@^2.3.0, rollup-pluginutils@^2.3.3,
dependencies: dependencies:
estree-walker "^0.6.1" estree-walker "^0.6.1"
rollup-pluginutils@^2.5.0:
version "2.8.1"
resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.8.1.tgz#8fa6dd0697344938ef26c2c09d2488ce9e33ce97"
integrity sha512-J5oAoysWar6GuZo0s+3bZ6sVZAC0pfqKz68De7ZgDi5z63jOVZn1uJL/+z1jeKHNbGII8kAyHF5q8LnxSX5lQg==
dependencies:
estree-walker "^0.6.1"
rollup@^1.1.2: rollup@^1.1.2:
version "1.13.1" version "1.13.1"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-1.13.1.tgz#86a474c29df0f303ed31e4c8be5d81c1038beae8" resolved "https://registry.yarnpkg.com/rollup/-/rollup-1.13.1.tgz#86a474c29df0f303ed31e4c8be5d81c1038beae8"

View File

@ -93,6 +93,7 @@
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.2.0", "@babel/runtime": "^7.2.0",
"@ohif/i18n": "file:.yalc/@ohif/i18n",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"react-vtkjs-viewport": "^0.0.7" "react-vtkjs-viewport": "^0.0.7"
} }

View File

@ -727,6 +727,12 @@
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b"
integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==
"@ohif/i18n@file:.yalc/@ohif/i18n":
version "0.0.1-rc-003-62f0a044"
dependencies:
"@babel/runtime" "^7.2.0"
classnames "^2.2.6"
"@samverschueren/stream-to-observable@^0.3.0": "@samverschueren/stream-to-observable@^0.3.0":
version "0.3.0" version "0.3.0"
resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f"

View File

@ -70,7 +70,7 @@
"@ohif/extension-cornerstone": "0.0.34", "@ohif/extension-cornerstone": "0.0.34",
"@ohif/extension-dicom-microscopy": "0.0.6", "@ohif/extension-dicom-microscopy": "0.0.6",
"@ohif/extension-vtk": "file:.yalc/@ohif/extension-vtk", "@ohif/extension-vtk": "file:.yalc/@ohif/extension-vtk",
"@ohif/i18n": "0.0.1-rc-001", "@ohif/i18n": "file:.yalc/@ohif/i18n",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"cornerstone-core": "^2.2.8", "cornerstone-core": "^2.2.8",
"cornerstone-math": "^0.1.8", "cornerstone-math": "^0.1.8",
@ -81,6 +81,7 @@
"dicomweb-client": "^0.4.2", "dicomweb-client": "^0.4.2",
"hammerjs": "^2.0.8", "hammerjs": "^2.0.8",
"i18next": "^17.0.3", "i18next": "^17.0.3",
"i18next-browser-languagedetector": "^3.0.1",
"lodash.isequal": "4.5.0", "lodash.isequal": "4.5.0",
"moment": "^2.24.0", "moment": "^2.24.0",
"ohif-core": "0.5.6", "ohif-core": "0.5.6",

View File

@ -24,7 +24,7 @@ import WhiteLabellingContext from './WhiteLabellingContext';
import setupTools from './setupTools'; import setupTools from './setupTools';
import ui from './redux/ui.js'; import ui from './redux/ui.js';
import i18n from '@ohif/i18n'; import i18n from '@ohif/i18n';
import { I18nextProvider } from 'react-i18next'; import { I18nextProvider } from 'react-i18next';
const { ExtensionManager } = OHIF.extensions; const { ExtensionManager } = OHIF.extensions;
const { reducers, localStorage } = OHIF.redux; const { reducers, localStorage } = OHIF.redux;

View File

@ -1033,17 +1033,17 @@
classnames "^2.2.6" classnames "^2.2.6"
dicom-microscopy-viewer "^0.4.3" dicom-microscopy-viewer "^0.4.3"
"@ohif/extension-vtk@file:.yalc/@ohif/extension-vtk": "@ohif/extension-vtk@0.0.2":
version "0.0.3-3bee9176" version "0.0.2"
resolved "https://registry.yarnpkg.com/@ohif/extension-vtk/-/extension-vtk-0.0.2.tgz#99f0ea796ddae14d7e64cff958c0656b5d964f4e"
integrity sha512-WDuQVwK4RlHgXwbmKIECZrP90x8cVOwESQz8bJOeNG2eVPDBVlNWx/zOXShAhn6J62QG6Sn1RnHQWLedgGnhyA==
dependencies: dependencies:
"@babel/runtime" "^7.2.0" "@babel/runtime" "^7.2.0"
classnames "^2.2.6" classnames "^2.2.6"
react-vtkjs-viewport "^0.0.7" react-vtkjs-viewport "^0.0.7"
"@ohif/i18n@0.0.1-rc-001": "@ohif/i18n@file:.yalc/@ohif/i18n":
version "0.0.1-rc-001" version "0.0.1-rc-003-18e6caf4"
resolved "https://registry.yarnpkg.com/@ohif/i18n/-/i18n-0.0.1-rc-001.tgz#47286daa1411efb5f0219f0310484c8919bfe607"
integrity sha512-CJ9wqd15DpJ6adVMyXkyqQqcRZgSnMWJ7L3WyUpMqf66CvAFKzCUuckyiFeCupIq8ZGv7w4jaADSYKrLcpviUw==
dependencies: dependencies:
"@babel/runtime" "^7.2.0" "@babel/runtime" "^7.2.0"
classnames "^2.2.6" classnames "^2.2.6"
@ -6335,6 +6335,11 @@ husky@1.3.x:
run-node "^1.0.0" run-node "^1.0.0"
slash "^2.0.0" slash "^2.0.0"
i18next-browser-languagedetector@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/i18next-browser-languagedetector/-/i18next-browser-languagedetector-3.0.1.tgz#a47c43176e8412c91e808afb7c6eb5367649aa8e"
integrity sha512-WFjPLNPWl62uu07AHY2g+KsC9qz0tyMq+OZEB/H7N58YKL/JLiCz9U709gaR20Mule/Ppn+uyfVx5REJJjn1HA==
i18next@^17.0.3: i18next@^17.0.3:
version "17.0.3" version "17.0.3"
resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.3.tgz#82d67826d13e8ca2cd2a3c87871533414e952d03" resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.3.tgz#82d67826d13e8ca2cd2a3c87871533414e952d03"
@ -11788,13 +11793,13 @@ react-transition-group@^2.0.0, react-transition-group@^2.2.0:
prop-types "^15.6.2" prop-types "^15.6.2"
react-lifecycles-compat "^3.0.4" react-lifecycles-compat "^3.0.4"
"react-viewerbase@file:.yalc/react-viewerbase": react-viewerbase@^0.7.0:
version "0.2.17-a5956254" version "0.7.0"
resolved "https://registry.yarnpkg.com/react-viewerbase/-/react-viewerbase-0.7.0.tgz#b0f48a0f003b849c280b8ca67927d4780c68b0dc"
integrity sha512-1VQXREKSsqxtOSSHRou0gjBODrSOjE8SBJ6/dHG0gPgdmeotOg68xPMKYf9K7fYyGZ6CDA7oVCAmdTE4SVYP5Q==
dependencies: dependencies:
"@babel/runtime" "7.2.0" "@babel/runtime" "7.2.0"
"@ohif/i18n" "0.0.1-rc-001"
classnames "2.2.6" classnames "2.2.6"
i18next "^17.0.3"
lodash.isequal "4.5.0" lodash.isequal "4.5.0"
moment "2.24.0" moment "2.24.0"
prop-types "15.6.2" prop-types "15.6.2"
@ -11802,7 +11807,6 @@ react-transition-group@^2.0.0, react-transition-group@^2.2.0:
react-dates "18.4.1" react-dates "18.4.1"
react-dnd "7.0.2" react-dnd "7.0.2"
react-dnd-html5-backend "7.0.2" react-dnd-html5-backend "7.0.2"
react-i18next "^10.11.0"
react-with-direction "1.3.0" react-with-direction "1.3.0"
react-vtkjs-viewport@^0.0.7: react-vtkjs-viewport@^0.0.7: