From 04b58b715a339acda1210479a73614dc50104ee9 Mon Sep 17 00:00:00 2001 From: Ivan Vershigora Date: Fri, 6 Dec 2024 12:39:33 +0000 Subject: [PATCH] fix: load intl polyfill locale data --- shim.js | 5 +- src/utils/i18n/index.ts | 30 ++++++++++-- src/utils/i18n/locales/index.ts | 82 +++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 6 deletions(-) diff --git a/shim.js b/shim.js index b1c11ceb1..152de6976 100644 --- a/shim.js +++ b/shim.js @@ -9,23 +9,22 @@ require('./src/polyfills/textdecoder-polyfill'); // RN still doesn't support full spec of Intl API // Don't remove -force from these because detection is VERY slow on low-end Android. // https://github.com/formatjs/formatjs/issues/4463#issuecomment-2176070577 +// we only load english locale data by default, other locales should be loaded after i18next initialized if (!Intl.Locale) { require('@formatjs/intl-locale/polyfill-force'); } if (!NumberFormat.formatToParts) { require('@formatjs/intl-numberformat/polyfill-force'); require('@formatjs/intl-numberformat/locale-data/en'); - require('@formatjs/intl-numberformat/locale-data/ru'); + NumberFormat.polyfilled = true; } if (!Intl.PluralRules) { require('@formatjs/intl-pluralrules/polyfill-force'); require('@formatjs/intl-pluralrules/locale-data/en'); - require('@formatjs/intl-pluralrules/locale-data/ru'); } if (!Intl.RelativeTimeFormat) { require('@formatjs/intl-relativetimeformat/polyfill-force'); require('@formatjs/intl-relativetimeformat/locale-data/en'); - require('@formatjs/intl-relativetimeformat/locale-data/ru'); } if (!Symbol.asyncIterator) { diff --git a/src/utils/i18n/index.ts b/src/utils/i18n/index.ts index 717301dcc..be332e9e2 100644 --- a/src/utils/i18n/index.ts +++ b/src/utils/i18n/index.ts @@ -1,13 +1,17 @@ import i18n from 'i18next'; -import { initReactI18next } from 'react-i18next'; import ICU from 'i18next-icu'; +import { initReactI18next } from 'react-i18next'; import * as RNLocalize from 'react-native-localize'; import { __ENABLE_I18NEXT_DEBUGGER__ } from '../../constants/env'; -import locales from './locales'; import { dispatch } from '../../store/helpers'; import { updateUi } from '../../store/slices/ui'; import convert from './convert'; +import locales, { + numberFormatPolyfills, + pluralRulesPolyfills, + relativeTimeFormatPolyfills, +} from './locales'; const getDeviceLanguage = (): string => { const lang = @@ -58,7 +62,27 @@ i18nICU } } - dispatch(updateUi({ timeZone, language: i18n.language })); + dispatch(updateUi({ timeZone, language: i18nICU.language })); + }) + .then(async () => { + // we need to load language related polyfill data + const lang = i18nICU.language; + try { + // @ts-ignore + if (NumberFormat.polyfilled) { + await numberFormatPolyfills[lang]?.(); + } + // @ts-ignore + if (Intl.PluralRules.polyfilled) { + await pluralRulesPolyfills[lang]?.(); + } + // @ts-ignore + if (Intl.RelativeTimeFormat.polyfilled) { + await relativeTimeFormatPolyfills[lang]?.(); + } + } catch (e) { + console.warn('Error loading polyfill for language: ', lang); + } }); export default i18nICU; diff --git a/src/utils/i18n/locales/index.ts b/src/utils/i18n/locales/index.ts index 536fdab75..3b0e6b154 100644 --- a/src/utils/i18n/locales/index.ts +++ b/src/utils/i18n/locales/index.ts @@ -48,3 +48,85 @@ export default { uk, yo, } as const; + +export const numberFormatPolyfills = { + arb: (): any => import('@formatjs/intl-numberformat/locale-data/ar'), + ca: (): any => import('@formatjs/intl-numberformat/locale-data/ca'), + cs: (): any => import('@formatjs/intl-numberformat/locale-data/cs'), + de: (): any => import('@formatjs/intl-numberformat/locale-data/de'), + el: (): any => import('@formatjs/intl-numberformat/locale-data/el'), + es: (): any => import('@formatjs/intl-numberformat/locale-data/es'), + 'es-ES': (): any => import('@formatjs/intl-numberformat/locale-data/es'), + 'es-419': (): any => import('@formatjs/intl-numberformat/locale-data/es-419'), + fa: (): any => import('@formatjs/intl-numberformat/locale-data/fa'), + fr: (): any => import('@formatjs/intl-numberformat/locale-data/fr'), + it: (): any => import('@formatjs/intl-numberformat/locale-data/it'), + ja: (): any => import('@formatjs/intl-numberformat/locale-data/ja'), + ko: (): any => import('@formatjs/intl-numberformat/locale-data/ko'), + nl: (): any => import('@formatjs/intl-numberformat/locale-data/nl'), + no: (): any => import('@formatjs/intl-numberformat/locale-data/no'), + pl: (): any => import('@formatjs/intl-numberformat/locale-data/pl'), + pt: (): any => import('@formatjs/intl-numberformat/locale-data/pt'), + 'pt-BR': (): any => import('@formatjs/intl-numberformat/locale-data/pt'), + 'pt-PT': (): any => import('@formatjs/intl-numberformat/locale-data/pt-PT'), + ro: (): any => import('@formatjs/intl-numberformat/locale-data/ro'), + ru: (): any => import('@formatjs/intl-numberformat/locale-data/ru'), + uk: (): any => import('@formatjs/intl-numberformat/locale-data/uk'), + yo: (): any => import('@formatjs/intl-numberformat/locale-data/yo'), +}; + +export const pluralRulesPolyfills = { + arb: (): any => import('@formatjs/intl-pluralrules/locale-data/ar'), + ca: (): any => import('@formatjs/intl-pluralrules/locale-data/ca'), + cs: (): any => import('@formatjs/intl-pluralrules/locale-data/cs'), + de: (): any => import('@formatjs/intl-pluralrules/locale-data/de'), + el: (): any => import('@formatjs/intl-pluralrules/locale-data/el'), + es: (): any => import('@formatjs/intl-pluralrules/locale-data/es'), + 'es-ES': (): any => import('@formatjs/intl-pluralrules/locale-data/es'), + 'es-419': (): any => import('@formatjs/intl-pluralrules/locale-data/es'), + fa: (): any => import('@formatjs/intl-pluralrules/locale-data/fa'), + fr: (): any => import('@formatjs/intl-pluralrules/locale-data/fr'), + it: (): any => import('@formatjs/intl-pluralrules/locale-data/it'), + ja: (): any => import('@formatjs/intl-pluralrules/locale-data/ja'), + ko: (): any => import('@formatjs/intl-pluralrules/locale-data/ko'), + nl: (): any => import('@formatjs/intl-pluralrules/locale-data/nl'), + no: (): any => import('@formatjs/intl-pluralrules/locale-data/no'), + pl: (): any => import('@formatjs/intl-pluralrules/locale-data/pl'), + pt: (): any => import('@formatjs/intl-pluralrules/locale-data/pt'), + 'pt-BR': (): any => import('@formatjs/intl-pluralrules/locale-data/pt'), + 'pt-PT': (): any => import('@formatjs/intl-pluralrules/locale-data/pt-PT'), + ro: (): any => import('@formatjs/intl-pluralrules/locale-data/ro'), + ru: (): any => import('@formatjs/intl-pluralrules/locale-data/ru'), + uk: (): any => import('@formatjs/intl-pluralrules/locale-data/uk'), + yo: (): any => import('@formatjs/intl-pluralrules/locale-data/yo'), +}; + +export const relativeTimeFormatPolyfills = { + arb: (): any => import('@formatjs/intl-relativetimeformat/locale-data/ar'), + ca: (): any => import('@formatjs/intl-relativetimeformat/locale-data/ca'), + cs: (): any => import('@formatjs/intl-relativetimeformat/locale-data/cs'), + de: (): any => import('@formatjs/intl-relativetimeformat/locale-data/de'), + el: (): any => import('@formatjs/intl-relativetimeformat/locale-data/el'), + es: (): any => import('@formatjs/intl-relativetimeformat/locale-data/es'), + 'es-ES': (): any => + import('@formatjs/intl-relativetimeformat/locale-data/es'), + 'es-419': (): any => + import('@formatjs/intl-relativetimeformat/locale-data/es-419'), + fa: (): any => import('@formatjs/intl-relativetimeformat/locale-data/fa'), + fr: (): any => import('@formatjs/intl-relativetimeformat/locale-data/fr'), + it: (): any => import('@formatjs/intl-relativetimeformat/locale-data/it'), + ja: (): any => import('@formatjs/intl-relativetimeformat/locale-data/ja'), + ko: (): any => import('@formatjs/intl-relativetimeformat/locale-data/ko'), + nl: (): any => import('@formatjs/intl-relativetimeformat/locale-data/nl'), + no: (): any => import('@formatjs/intl-relativetimeformat/locale-data/no'), + pl: (): any => import('@formatjs/intl-relativetimeformat/locale-data/pl'), + pt: (): any => import('@formatjs/intl-relativetimeformat/locale-data/pt'), + 'pt-BR': (): any => + import('@formatjs/intl-relativetimeformat/locale-data/pt'), + 'pt-PT': (): any => + import('@formatjs/intl-relativetimeformat/locale-data/pt-PT'), + ro: (): any => import('@formatjs/intl-relativetimeformat/locale-data/ro'), + ru: (): any => import('@formatjs/intl-relativetimeformat/locale-data/ru'), + uk: (): any => import('@formatjs/intl-relativetimeformat/locale-data/uk'), + yo: (): any => import('@formatjs/intl-relativetimeformat/locale-data/yo'), +};