diff --git a/client/src/javascript/app.tsx b/client/src/javascript/app.tsx index 5927daf9..d7f295c1 100644 --- a/client/src/javascript/app.tsx +++ b/client/src/javascript/app.tsx @@ -75,7 +75,7 @@ const FloodApp: FC = observer(() => { return ( }> - + diff --git a/client/src/javascript/i18n/languages.tsx b/client/src/javascript/i18n/languages.tsx index c79e261c..c0255cc7 100644 --- a/client/src/javascript/i18n/languages.tsx +++ b/client/src/javascript/i18n/languages.tsx @@ -8,6 +8,7 @@ import EN from './strings.compiled.json'; import Languages from '../constants/Languages'; import type {Language} from '../constants/Languages'; +import type {LocaleConfig} from '../util/detectLocale'; const messagesCache: Partial, Record>> = {en: EN}; @@ -45,28 +46,31 @@ function getMessages(locale: Exclude) { } interface AsyncIntlProviderProps { - locale?: Language; + language?: Language; children: React.ReactNode; } -const AsyncIntlProvider: React.FC = ({locale, children}: AsyncIntlProviderProps) => { - let validatedLocale: Exclude; - if (locale == null || locale === 'auto' || !Object.prototype.hasOwnProperty.call(Languages, locale)) { +const AsyncIntlProvider: React.FC = ({language, children}: AsyncIntlProviderProps) => { + let validatedLocale: LocaleConfig; + if (language == null || language === 'auto' || !Object.prototype.hasOwnProperty.call(Languages, language)) { validatedLocale = detectLocale(); } else { - validatedLocale = locale; + validatedLocale = { + locale: language, + language, + }; } - const messages = getMessages(validatedLocale); + const messages = getMessages(validatedLocale.language); return ( - + {children} ); }; AsyncIntlProvider.defaultProps = { - locale: 'en', + language: 'en', }; export default AsyncIntlProvider; diff --git a/client/src/javascript/util/detectLocale.ts b/client/src/javascript/util/detectLocale.ts index ed4792f3..14bdece4 100644 --- a/client/src/javascript/util/detectLocale.ts +++ b/client/src/javascript/util/detectLocale.ts @@ -3,43 +3,54 @@ import Languages from '../constants/Languages'; import type {Language} from '../constants/Languages'; -let detectedLocale: Exclude = 'en'; +export interface LocaleConfig { + locale: string; + language: Exclude; +} + +const detectedLocales: LocaleConfig = { + locale: 'en', + language: 'en', +}; + let localeDetected = false; -function detectLocale(): Exclude { +const detectLocale = (): LocaleConfig => { if (localeDetected) { - return detectedLocale; + return detectedLocales; } + // Reverse loop to respect language priority of user getUserLocales() .reverse() .forEach((userLocale): void => { - let locale = userLocale; - switch (locale) { + detectedLocales.locale = userLocale; + switch (detectedLocales.locale) { // Special handlings for languages with variants case 'zh': case 'zh-CN': case 'zh-SG': case 'zh-MY': - locale = 'zh-Hans'; + detectedLocales.locale = 'zh-Hans'; break; case 'zh-TW': case 'zh-HK': case 'zh-MO': - locale = 'zh-Hant'; + detectedLocales.locale = 'zh-Hant'; break; default: break; } - if (Object.prototype.hasOwnProperty.call(Languages, locale)) { - detectedLocale = locale as Exclude; - } else if (Object.prototype.hasOwnProperty.call(Languages, locale.substr(0, 2))) { + if (Object.prototype.hasOwnProperty.call(Languages, detectedLocales.locale)) { + detectedLocales.language = detectedLocales.locale as Exclude; + } else if (Object.prototype.hasOwnProperty.call(Languages, detectedLocales.locale.substr(0, 2))) { // In rare cases, user provides a locale (eg. en-US) without fallback (eg. en) - detectedLocale = locale.substr(0, 2) as Exclude; + detectedLocales.language = detectedLocales.locale.substr(0, 2) as Exclude; } }); + localeDetected = true; - return detectedLocale; -} + return detectedLocales; +}; export default detectLocale;