import { I18nManager } from "react-native" import * as Localization from "expo-localization" import i18n from "i18next" import { initReactI18next } from "react-i18next" import "intl-pluralrules" // if English isn't your default language, move Translations to the appropriate language file. import ar from "./ar" import en, { Translations } from "./en" import es from "./es" import fr from "./fr" import hi from "./hi" import ja from "./ja" import ko from "./ko" import zh from "./zh" const fallbackLocale = "en-US" const systemLocales = Localization.getLocales() const resources = { ar, en, ko, es, fr, ja, hi, zh } const supportedTags = Object.keys(resources) // Checks to see if the device locale matches any of the supported locales // Device locale may be more specific and still match (e.g., en-US matches en) const systemTagMatchesSupportedTags = (deviceTag: string) => { const primaryTag = deviceTag.split("-")[0] return supportedTags.includes(primaryTag) } const pickSupportedLocale: () => Localization.Locale | undefined = () => { return systemLocales.find((locale) => systemTagMatchesSupportedTags(locale.languageTag)) } const locale = pickSupportedLocale() export let isRTL = false // Need to set RTL ASAP to ensure the app is rendered correctly. Waiting for i18n to init is too late. if (locale?.languageTag && locale?.textDirection === "rtl") { I18nManager.allowRTL(true) isRTL = true } else { I18nManager.allowRTL(false) } export const initI18n = async () => { i18n.use(initReactI18next) await i18n.init({ resources, lng: locale?.languageTag ?? fallbackLocale, fallbackLng: fallbackLocale, interpolation: { escapeValue: false, }, }) return i18n } /** * Builds up valid keypaths for translations. */ export type TxKeyPath = RecursiveKeyOf // via: https://stackoverflow.com/a/65333050 type RecursiveKeyOf = { [TKey in keyof TObj & (string | number)]: RecursiveKeyOfHandleValue }[keyof TObj & (string | number)] type RecursiveKeyOfInner = { [TKey in keyof TObj & (string | number)]: RecursiveKeyOfHandleValue }[keyof TObj & (string | number)] type RecursiveKeyOfHandleValue< TValue, Text extends string, IsFirstLevel extends boolean, > = TValue extends any[] ? Text : TValue extends object ? IsFirstLevel extends true ? Text | `${Text}:${RecursiveKeyOfInner}` : Text | `${Text}.${RecursiveKeyOfInner}` : Text