From f5d4ab1cc19fdfe0a1eacc5efd42dba814a57168 Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Thu, 2 Jul 2020 21:34:48 -0300 Subject: [PATCH] Include relative time polyfill locale data (#8896) We were including the polyfill for the `Intl.RelativeTimeFormat` API, but we weren't including any locale data. This polyfill doesn't work without the locale data for whichever locale you're formatting. The data for all locales we support is now included. The locale data is loaded from disk as-needed (during app startup, and upon each change in locale). --- development/build/static.js | 16 ++++++++++++++++ ui/app/helpers/utils/i18n-helper.js | 18 ++++++++++++++++++ ui/app/store/actions.js | 5 +++-- ui/index.js | 7 ++++++- 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/development/build/static.js b/development/build/static.js index de206d1f1..62dbeaa62 100644 --- a/development/build/static.js +++ b/development/build/static.js @@ -3,6 +3,8 @@ const path = require('path') const watch = require('gulp-watch') const glob = require('fast-glob') +const locales = require('../../app/_locales/index.json') + const { createTask, composeSeries } = require('./task') module.exports = createStaticAssetTasks @@ -45,6 +47,20 @@ const copyTargets = [ }, ] +const languageTags = new Set() +for (const locale of locales) { + const { code } = locale + const tag = code.split('_')[0] + languageTags.add(tag) +} + +for (const tag of languageTags) { + copyTargets.push({ + src: `./node_modules/@formatjs/intl-relativetimeformat/dist/locale-data/${tag}.json`, + dest: `intl/${tag}/relative-time-format-data.json`, + }) +} + const copyTargetsDev = [ ...copyTargets, { diff --git a/ui/app/helpers/utils/i18n-helper.js b/ui/app/helpers/utils/i18n-helper.js index a88995425..01a369229 100644 --- a/ui/app/helpers/utils/i18n-helper.js +++ b/ui/app/helpers/utils/i18n-helper.js @@ -79,3 +79,21 @@ export async function fetchLocale (localeCode) { } } +const relativeTimeFormatLocaleData = new Set() + +export async function loadRelativeTimeFormatLocaleData (localeCode) { + const languageTag = localeCode.split('_')[0] + if ( + Intl.RelativeTimeFormat && + typeof Intl.RelativeTimeFormat.__addLocaleData === 'function' && + !relativeTimeFormatLocaleData.has(languageTag) + ) { + const localeData = await fetchRelativeTimeFormatData(languageTag) + Intl.RelativeTimeFormat.__addLocaleData(localeData) + } +} + +async function fetchRelativeTimeFormatData (languageTag) { + const response = await window.fetch(`./intl/${languageTag}/relative-time-format-data.json`) + return await response.json() +} diff --git a/ui/app/store/actions.js b/ui/app/store/actions.js index d05b03214..dd9188687 100644 --- a/ui/app/store/actions.js +++ b/ui/app/store/actions.js @@ -4,7 +4,7 @@ import getBuyEthUrl from '../../../app/scripts/lib/buy-eth-url' import { checksumAddress } from '../helpers/utils/util' import { calcTokenBalance, estimateGas } from '../pages/send/send.utils' import ethUtil from 'ethereumjs-util' -import { fetchLocale } from '../helpers/utils/i18n-helper' +import { fetchLocale, loadRelativeTimeFormatLocaleData } from '../helpers/utils/i18n-helper' import { getMethodDataAsync } from '../helpers/utils/transactions.util' import { fetchSymbolAndDecimals } from '../helpers/utils/token-util' import switchDirection from '../helpers/utils/switch-direction' @@ -2012,8 +2012,9 @@ export function setIpfsGateway (val) { } export function updateCurrentLocale (key) { - return (dispatch) => { + return async (dispatch) => { dispatch(showLoadingIndication()) + await loadRelativeTimeFormatLocaleData(key) return fetchLocale(key) .then((localeMessages) => { log.debug(`background.setCurrentLocale`) diff --git a/ui/index.js b/ui/index.js index 8f868f317..44f5fd500 100644 --- a/ui/index.js +++ b/ui/index.js @@ -10,7 +10,7 @@ import txHelper from './lib/tx-helper' import { getEnvironmentType } from '../app/scripts/lib/util' import { ALERT_TYPES } from '../app/scripts/controllers/alert' import { ENVIRONMENT_TYPE_POPUP } from '../app/scripts/lib/enums' -import { fetchLocale } from './app/helpers/utils/i18n-helper' +import { fetchLocale, loadRelativeTimeFormatLocaleData } from './app/helpers/utils/i18n-helper' import switchDirection from './app/helpers/utils/switch-direction' import { getPermittedAccountsForCurrentTab, getSelectedAddress } from './app/selectors' import { ALERT_STATE } from './app/ducks/alerts/unconnected-account' @@ -48,6 +48,11 @@ async function startApp (metamaskState, backgroundConnection, opts) { : {} const enLocaleMessages = await fetchLocale('en') + await loadRelativeTimeFormatLocaleData('en') + if (metamaskState.currentLocale) { + await loadRelativeTimeFormatLocaleData(metamaskState.currentLocale) + } + if (metamaskState.textDirection === 'rtl') { await switchDirection('rtl') }