import * as LocaleCurrencyMap from 'locale-currency/map'; import * as LocaleCurrency from 'locale-currency'; import {nativeCompare} from 'app/common/gutil'; import {localeCodes} from "app/common/LocaleCodes"; const DEFAULT_CURRENCY = "USD"; export interface Locale { name: string; code: string; } export let locales: Readonly; // Intl.DisplayNames is only supported on recent browsers, so proceed with caution. try { const regionDisplay = new Intl.DisplayNames('en', {type: 'region'}); const languageDisplay = new Intl.DisplayNames('en', {type: 'language'}); const display = (code: string) => { try { const locale = new Intl.Locale(code); const regionName = regionDisplay.of(locale.region!); const languageName = languageDisplay.of(locale.language); return `${regionName} (${languageName})`; } catch (ex) { return code; } }; // Leave only those that are supported by current system (can be translated to human readable form). // Though, this file is in common, it is safe to filter by current system // as the list should be already filtered by codes that are supported by the backend. locales = Intl.DisplayNames.supportedLocalesOf(localeCodes).map(code => { return {name: display(code), code}; }); } catch { // Fall back to using the locale code as the display name. locales = localeCodes.map(code => ({name: code, code})); } export interface Currency { name: string; code: string; } export let currencies: Readonly; // locale-currency package doesn't have South Sudanese pound currency or a default value for Kosovo LocaleCurrencyMap["SS"] = "SSP"; LocaleCurrencyMap["XK"] = "EUR"; const currenciesCodes = Object.values(LocaleCurrencyMap); export function getCurrency(code: string) { const currency = LocaleCurrency.getCurrency(code ?? 'en-US'); // Fallback to USD return currency ?? DEFAULT_CURRENCY; } // Intl.DisplayNames is only supported on recent browsers, so proceed with caution. try { const currencyDisplay = new Intl.DisplayNames('en', {type: 'currency'}); currencies = [...new Set(currenciesCodes)].map(code => { return {name: currencyDisplay.of(code)!, code}; }); } catch { // Fall back to using the currency code as the display name. currencies = [...new Set(currenciesCodes)].map(code => { return {name: code, code}; }); } currencies = [...currencies].sort((a, b) => nativeCompare(a.code, b.code)); export function getCountryCode(locale: string) { // We have some defaults defined. if (locale === 'en') { return 'US'; } let countryCode = locale.split(/[-_]/)[1]; if (countryCode) { return countryCode.toUpperCase(); } // Some defaults that we support and can't be read from language code. countryCode = { 'uk': 'UA', // Ukraine }[locale] ?? locale.toUpperCase(); // Test if we can use language as a country code. if (localeCodes.map(code => code.split(/[-_]/)[1]).includes(countryCode)) { return countryCode; } return null; }