@ibm-adw/skill-toolkit
Version:
Developing your own skills with IBM Automation Digital Worker Skill Toolkit
155 lines (133 loc) • 6.26 kB
JavaScript
/*
Licensed Materials - Property of IBM
5737-I23
Copyright IBM Corp. 2019, 2020. All Rights Reserved.
U.S. Government Users Restricted Rights:
Use, duplication or disclosure restricted by GSA ADP Schedule
Contract with IBM Corp.
*/
import React, { useContext, useEffect, useState } from 'react';
import intl from 'react-intl-universal';
import { useHistory, useLocation } from 'react-router-dom';
import acceptLanguage from 'accept-language';
import bcp47 from 'bcp47';
// Supported locales data
const SUPPORTED_LOCALES = process.env.REACT_APP_SUPPORTED_LOCALES.split(',').map(item => item.trim());
const DEFAULT_LOCALE = process.env.REACT_APP_DEFAULT_LOCALE;
const LocaleContext = React.createContext({
enforcedLocale: false,
currentLocale: '',
fallbackLocale: '',
initialized: false,
});
const useLocale = (nlsModules) => {
const localeContext = useContext(LocaleContext);
const [ nlsLoaded, setNlsLoaded ] = useState(false);
useEffect(() => {
if (localeContext.initialized) {
const currentLocale = intl.options.currentLocale;
const fallbackLocale = intl.options.fallbackLocale;
Promise.all(nlsModules()).then(nls => {
intl.load({
[currentLocale]: nls[0].default,
[fallbackLocale]: nls[1].default
});
setNlsLoaded(true);
}).catch((e) => {
// TODO We need to decide what we want to do when a specific language file is not found
// Could not load nls modules
});
}
}, [ localeContext, nlsModules ]);
return nlsLoaded;
};
const LocaleProvider = ({ supportedLocalesArray = SUPPORTED_LOCALES, defaultLocale = DEFAULT_LOCALE, children }) => {
const history = useHistory();
const searchLocation = new URLSearchParams(useLocation().search);
const queryParamsLocale = searchLocation.get('locale');
// Get valid supported locale for queryParamsLocale
// Define supported languages. The first language is default language.
acceptLanguage.languages([ defaultLocale ].concat(supportedLocalesArray));
// Get matching language. If no match, default language will be returned.
const matchingLocale = acceptLanguage.get(queryParamsLocale);
// Setting fallback locale
const tmpParsedLocale = bcp47.parse(matchingLocale);
const fallbackLocale = (tmpParsedLocale.langtag.region ? tmpParsedLocale.langtag.language.language : defaultLocale);
// if needed, update URL with valid locale
if (queryParamsLocale && matchingLocale !== queryParamsLocale) {
searchLocation.set('locale', matchingLocale);
history.replace({ search: searchLocation.toString() });
}
const [ state, setState ] = useState({
enforcedLocale: !!queryParamsLocale,
currentLocale: matchingLocale,
fallbackLocale: fallbackLocale,
initialized: false
});
useEffect(() => {
async function loadLocales() {
const browserLocale = intl.determineLocale();
let cuLocale = state.currentLocale;
let fbLocale = state.fallbackLocale;
if (browserLocale && !queryParamsLocale) {
// Get matching language. If no match, default language will be returned.
const matchingBrowserLocale = acceptLanguage.get(browserLocale);
// Setting current locale
cuLocale = matchingBrowserLocale;
// Setting fallback locale
const tmpParsedLocale = bcp47.parse(matchingBrowserLocale);
fbLocale = (tmpParsedLocale.langtag.region ? tmpParsedLocale.langtag.language.language : defaultLocale);
}
// TODO We need to decide what we want to do when a specific language file is not found
const cuLocaleData = await import(/* webpackChunkName: "nls" */ `./nls/${cuLocale}.json`).then(module => module.default).catch(() => { return {}; });
const fallbackLocaleData = await import(/* webpackChunkName: "nls" */ `./nls/${fbLocale}.json`).then(module => module.default).catch(() => { return {}; });
intl.init({
currentLocale: cuLocale,
locales: {
[cuLocale]: cuLocaleData,
[fbLocale]: fallbackLocaleData
},
commonLocaleDataUrls: {
en: '/locales/locale-data/1.0.0/en.js',
zh: '/locales/locale-data/1.0.0/zh.js',
fr: '/locales/locale-data/1.0.0/fr.js',
fa: '/locales/locale-data/1.0.0/fa.js',
ja: '/locales/locale-data/1.0.0/ja.js',
de: '/locales/locale-data/1.0.0/de.js',
es: '/locales/locale-data/1.0.0/es.js',
ko: '/locales/locale-data/1.0.0/ko.js',
pt: '/locales/locale-data/1.0.0/pt.js',
it: '/locales/locale-data/1.0.0/it.js',
ru: '/locales/locale-data/1.0.0/ru.js',
pl: '/locales/locale-data/1.0.0/pl.js',
nl: '/locales/locale-data/1.0.0/nl.js',
sv: '/locales/locale-data/1.0.0/sv.js',
tr: '/locales/locale-data/1.0.0/tr.js'
},
fallbackLocale: fbLocale
});
// Update state
setState({
enforcedLocale: state.enforcedLocale,
currentLocale: cuLocale,
fallbackLocale: fbLocale,
initialized: true
});
}
if (!state.initialized) {
loadLocales();
}
}, [ queryParamsLocale, matchingLocale, state, defaultLocale ]); // Only re-run the effect if localesLoaded changes
return (
<LocaleContext.Provider
value={{
enforcedLocale: state.enforcedLocale,
currentLocale: state.currentLocale,
fallbackLocale: state.fallbackLocale,
initialized: state.initialized,
}}>
{children}
</LocaleContext.Provider>
);
};
export { LocaleContext, LocaleProvider, useLocale };