diff --git a/package.json b/package.json index e167285a307..4c7c179693d 100644 --- a/package.json +++ b/package.json @@ -62,9 +62,9 @@ "@expo/webpack-config": "^19.0.0", "@floating-ui/dom": "^1.6.3", "@floating-ui/react-dom": "^2.0.8", - "@formatjs/intl-locale": "^4.0.0", - "@formatjs/intl-numberformat": "^8.10.3", - "@formatjs/intl-pluralrules": "^5.2.14", + "@formatjs/intl-locale": "^4.2.8", + "@formatjs/intl-numberformat": "^8.15.1", + "@formatjs/intl-pluralrules": "^5.4.1", "@fortawesome/fontawesome-svg-core": "^6.1.1", "@fortawesome/free-regular-svg-icons": "^6.1.1", "@fortawesome/free-solid-svg-icons": "^6.1.1", diff --git a/src/view/com/util/numeric/__tests__/format-test.ts b/src/view/com/util/numeric/__tests__/format-test.ts deleted file mode 100644 index 74df4be4c9d..00000000000 --- a/src/view/com/util/numeric/__tests__/format-test.ts +++ /dev/null @@ -1,92 +0,0 @@ -import {describe, expect, it} from '@jest/globals' - -import {APP_LANGUAGES} from '#/locale/languages' -import {formatCount} from '../format' - -const formatCountRound = (locale: string, num: number) => { - const options: Intl.NumberFormatOptions = { - notation: 'compact', - maximumFractionDigits: 1, - } - return new Intl.NumberFormat(locale, options).format(num) -} - -const formatCountTrunc = (locale: string, num: number) => { - const options: Intl.NumberFormatOptions = { - notation: 'compact', - maximumFractionDigits: 1, - // @ts-ignore - roundingMode: 'trunc', - } - return new Intl.NumberFormat(locale, options).format(num) -} - -// prettier-ignore -const testNums = [ - 1, - 5, - 9, - 11, - 55, - 99, - 111, - 555, - 999, - 1111, - 5555, - 9999, - 11111, - 55555, - 99999, - 111111, - 555555, - 999999, - 1111111, - 5555555, - 9999999, - 11111111, - 55555555, - 99999999, - 111111111, - 555555555, - 999999999, - 1111111111, - 5555555555, - 9999999999, - 11111111111, - 55555555555, - 99999999999, - 111111111111, - 555555555555, - 999999999999, - 1111111111111, - 5555555555555, - 9999999999999, - 11111111111111, - 55555555555555, - 99999999999999, - 111111111111111, - 555555555555555, - 999999999999999, - 1111111111111111, - 5555555555555555, -] - -describe('formatCount', () => { - for (const appLanguage of APP_LANGUAGES) { - const locale = appLanguage.code2 - it('truncates for ' + locale, () => { - const mockI8nn = { - locale, - number(num: number) { - return formatCountRound(locale, num) - }, - } - for (const num of testNums) { - const formatManual = formatCount(mockI8nn as any, num) - const formatOriginal = formatCountTrunc(locale, num) - expect(formatManual).toEqual(formatOriginal) - } - }) - } -}) diff --git a/src/view/com/util/numeric/format.ts b/src/view/com/util/numeric/format.ts index 053b0069b51..8f3ebd0e71e 100644 --- a/src/view/com/util/numeric/format.ts +++ b/src/view/com/util/numeric/format.ts @@ -1,50 +1,10 @@ import {I18n} from '@lingui/core' -const truncateRounding = (num: number, factors: Array): number => { - for (let i = factors.length - 1; i >= 0; i--) { - let factor = factors[i] - if (num >= 10 ** factor) { - if (factor === 10) { - // CA and ES abruptly jump from "9999,9 M" to "10 mil M" - factor-- - } - const precision = 1 - const divisor = 10 ** (factor - precision) - return Math.floor(num / divisor) * divisor - } - } - return num -} - -const koFactors = [3, 4, 8, 12] -const hiFactors = [3, 5, 7, 9, 11, 13] -const esCaFactors = [3, 6, 10, 12] -const itDeFactors = [6, 9, 12] -const jaZhFactors = [4, 8, 12] -const glFactors = [6, 12] -const restFactors = [3, 6, 9, 12] - export const formatCount = (i18n: I18n, num: number) => { - const locale = i18n.locale - let truncatedNum: number - if (locale === 'hi') { - truncatedNum = truncateRounding(num, hiFactors) - } else if (locale === 'ko') { - truncatedNum = truncateRounding(num, koFactors) - } else if (locale === 'es' || locale === 'ca') { - truncatedNum = truncateRounding(num, esCaFactors) - } else if (locale === 'ja' || locale === 'zh-CN' || locale === 'zh-TW') { - truncatedNum = truncateRounding(num, jaZhFactors) - } else if (locale === 'it' || locale === 'de') { - truncatedNum = truncateRounding(num, itDeFactors) - } else if (locale === 'gl') { - truncatedNum = truncateRounding(num, glFactors) - } else { - truncatedNum = truncateRounding(num, restFactors) - } - return i18n.number(truncatedNum, { + return i18n.number(num, { notation: 'compact', maximumFractionDigits: 1, - // Ideally we'd use roundingMode: 'trunc' but it isn't supported on RN. + // @ts-expect-error - roundingMode not in the types + roundingMode: 'trunc', }) } diff --git a/yarn.lock b/yarn.lock index beea8f136b7..21fdb48c60d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4250,62 +4250,74 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.1.tgz#16308cea045f0fc777b6ff20a9f25474dd8293d2" integrity sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q== -"@formatjs/ecma402-abstract@2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-2.0.0.tgz#39197ab90b1c78b7342b129a56a7acdb8f512e17" - integrity sha512-rRqXOqdFmk7RYvj4khklyqzcfQl9vEL/usogncBHRZfZBDOwMGuSRNFl02fu5KGHXdbinju+YXyuR+Nk8xlr/g== +"@formatjs/ecma402-abstract@2.3.1": + version "2.3.1" + resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-2.3.1.tgz#cdeb3ffe1aeea9c4284b85b7e37e8e8615314c39" + integrity sha512-Ip9uV+/MpLXWRk03U/GzeJMuPeOXpJBSB5V1tjA6kJhvqssye5J5LoYLc7Z5IAHb7nR62sRoguzrFiVCP/hnzw== dependencies: - "@formatjs/intl-localematcher" "0.5.4" - tslib "^2.4.0" + "@formatjs/fast-memoize" "2.2.5" + "@formatjs/intl-localematcher" "0.5.9" + decimal.js "10" + tslib "2" -"@formatjs/intl-enumerator@1.4.7": - version "1.4.7" - resolved "https://registry.yarnpkg.com/@formatjs/intl-enumerator/-/intl-enumerator-1.4.7.tgz#6ab697f3f8f18cf0cc6a6b028cb9c40db6001f3d" - integrity sha512-03RHnFqfpB4H/jwCwlzC+wkTDk2Fi24JmVIY2PVGvTUpikN2bSr9+8oTXfOC+y7B7VxjCArUnqWXVoctkmy85w== +"@formatjs/fast-memoize@2.2.5": + version "2.2.5" + resolved "https://registry.yarnpkg.com/@formatjs/fast-memoize/-/fast-memoize-2.2.5.tgz#54a4a1793d773b72c372d3dcab3595149aee7880" + integrity sha512-6PoewUMrrcqxSoBXAOJDiW1m+AmkrAj0RiXnOMD59GRaswjXhm3MDhgepXPBgonc09oSirAJTsAggzAGQf6A6g== dependencies: - tslib "^2.4.0" + tslib "2" -"@formatjs/intl-getcanonicallocales@2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@formatjs/intl-getcanonicallocales/-/intl-getcanonicallocales-2.3.0.tgz#b6c6fa1c664e30a61f27fa6399a76159d82a5842" - integrity sha512-BOXbLwqQ7nKua/l7tKqDLRN84WupDXFDhGJQMFvsMVA2dKuOdRaWTxWpL3cJ7qPkoNw11Jf+Xpj4OSPBBvW0eQ== +"@formatjs/intl-enumerator@1.8.7": + version "1.8.7" + resolved "https://registry.yarnpkg.com/@formatjs/intl-enumerator/-/intl-enumerator-1.8.7.tgz#3f004753333f80cc468ae34046bd8416772a0412" + integrity sha512-qd7UlWUivKRJ073btssUqMSqzWW9yN3Ki6EqfCZ6uvIv19mONelE5q3GMmdPWBEjgqZikBzBE2qPTqfrgJ4TCA== dependencies: - tslib "^2.4.0" + "@formatjs/ecma402-abstract" "2.3.1" + tslib "2" -"@formatjs/intl-locale@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@formatjs/intl-locale/-/intl-locale-4.0.0.tgz#c111a33078413eba2011e82140466261eb1d67cd" - integrity sha512-+4dbMEGsp1bvB3JB3UHH6YTjMnFTifnfdaHp4ROrCCu50NedA69RBsDCG3eivcZkbj57X9ehGhMWjLxlP+gyVw== +"@formatjs/intl-getcanonicallocales@2.5.4": + version "2.5.4" + resolved "https://registry.yarnpkg.com/@formatjs/intl-getcanonicallocales/-/intl-getcanonicallocales-2.5.4.tgz#9b843e1891dea83405c51eb3d00c42ef9cb6cab9" + integrity sha512-vSDOsAcc3U+Kl/0b3de8wCQkb3W30H8LUuslyz67wTAHOPSQhPimZyquhwxXpJR+K5yy9CkzTgk5YE5kFT+PFg== dependencies: - "@formatjs/ecma402-abstract" "2.0.0" - "@formatjs/intl-enumerator" "1.4.7" - "@formatjs/intl-getcanonicallocales" "2.3.0" - tslib "^2.4.0" + tslib "2" -"@formatjs/intl-localematcher@0.5.4": - version "0.5.4" - resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.5.4.tgz#caa71f2e40d93e37d58be35cfffe57865f2b366f" - integrity sha512-zTwEpWOzZ2CiKcB93BLngUX59hQkuZjT2+SAQEscSm52peDW/getsawMcWF1rGRpMCX6D7nSJA3CzJ8gn13N/g== +"@formatjs/intl-locale@^4.2.8": + version "4.2.8" + resolved "https://registry.yarnpkg.com/@formatjs/intl-locale/-/intl-locale-4.2.8.tgz#571d44e92b6eb43b7410b37f25e280ec384a32cf" + integrity sha512-6RY/npeA0kyoZ8QW0JRAT+VBAFBT6+4ZVeGkKCNIDjbLX2LPuU73emGR35Mbwcc6pquVFrxyo6mXxKNzib0kEA== dependencies: - tslib "^2.4.0" + "@formatjs/ecma402-abstract" "2.3.1" + "@formatjs/intl-enumerator" "1.8.7" + "@formatjs/intl-getcanonicallocales" "2.5.4" + tslib "2" -"@formatjs/intl-numberformat@^8.10.3": - version "8.10.3" - resolved "https://registry.yarnpkg.com/@formatjs/intl-numberformat/-/intl-numberformat-8.10.3.tgz#abc97cc6a7b7f1b20da9f07a976b5589c1192ab8" - integrity sha512-lH3liLMeIjZ19Zxt8RRPnBcpPweS1YNSXRURDiFfvFmRlDZUOd8+GlcVyECcPZPkIoSH/p4lfGrnaUzepxJ92g== +"@formatjs/intl-localematcher@0.5.9": + version "0.5.9" + resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.5.9.tgz#43c6ee22be85b83340bcb09bdfed53657a2720db" + integrity sha512-8zkGu/sv5euxbjfZ/xmklqLyDGQSxsLqg8XOq88JW3cmJtzhCP8EtSJXlaKZnVO4beEaoiT9wj4eIoCQ9smwxA== dependencies: - "@formatjs/ecma402-abstract" "2.0.0" - "@formatjs/intl-localematcher" "0.5.4" - tslib "^2.4.0" + tslib "2" -"@formatjs/intl-pluralrules@^5.2.14": - version "5.2.14" - resolved "https://registry.yarnpkg.com/@formatjs/intl-pluralrules/-/intl-pluralrules-5.2.14.tgz#7477bd2aa9bfde9e543d839707eff5460eb08026" - integrity sha512-l6Ev7aOGXJSh5EPDEqzsbyufdCCKXZk993QXRQebLsB0TXRhIyF4alqjdMEatLwIigK/Mka8kiVIOLeFP5Cj9Q== +"@formatjs/intl-numberformat@^8.15.1": + version "8.15.1" + resolved "https://registry.yarnpkg.com/@formatjs/intl-numberformat/-/intl-numberformat-8.15.1.tgz#b2a5b00889ed31dbef9d4e5aeee1dea3d040b068" + integrity sha512-NIouSY50xpH/SMJrRbX1Q3hMsGyQmT5MQrta/bOYhpZda1bztOlEYZAKLytk8VGs10wkGz875602mCMhtg4/LA== dependencies: - "@formatjs/ecma402-abstract" "2.0.0" - "@formatjs/intl-localematcher" "0.5.4" - tslib "^2.4.0" + "@formatjs/ecma402-abstract" "2.3.1" + "@formatjs/intl-localematcher" "0.5.9" + decimal.js "10" + tslib "2" + +"@formatjs/intl-pluralrules@^5.4.1": + version "5.4.1" + resolved "https://registry.yarnpkg.com/@formatjs/intl-pluralrules/-/intl-pluralrules-5.4.1.tgz#1c03cd2da449e1871bb7c54ea36fec1de68b7e7e" + integrity sha512-kKK4ixTsfKAzyJIVRiJGuw4zd18nEHXiKloYBO9VmLpxrwJTgLQHv2+1hcbxQcwbbo2uc8moUFQuyvxeGEFOfw== + dependencies: + "@formatjs/ecma402-abstract" "2.3.1" + "@formatjs/intl-localematcher" "0.5.9" + decimal.js "10" + tslib "2" "@fortawesome/fontawesome-common-types@6.4.2": version "6.4.2" @@ -9372,7 +9384,7 @@ decamelize@^1.2.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== -decimal.js@^10.4.2: +decimal.js@10, decimal.js@^10.4.2: version "10.4.3" resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== @@ -18105,6 +18117,11 @@ ts-node@^10.9.1: v8-compile-cache-lib "^3.0.1" yn "3.1.1" +tslib@2: + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== + tslib@^1.11.1, tslib@^1.8.1, tslib@^1.9.0: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"