template_0205
This commit is contained in:
87
RN_TEMPLATE/app/i18n/index.ts
Normal file
87
RN_TEMPLATE/app/i18n/index.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
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<Translations>
|
||||
|
||||
// via: https://stackoverflow.com/a/65333050
|
||||
type RecursiveKeyOf<TObj extends object> = {
|
||||
[TKey in keyof TObj & (string | number)]: RecursiveKeyOfHandleValue<TObj[TKey], `${TKey}`, true>
|
||||
}[keyof TObj & (string | number)]
|
||||
|
||||
type RecursiveKeyOfInner<TObj extends object> = {
|
||||
[TKey in keyof TObj & (string | number)]: RecursiveKeyOfHandleValue<TObj[TKey], `${TKey}`, false>
|
||||
}[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<TValue>}`
|
||||
: Text | `${Text}.${RecursiveKeyOfInner<TValue>}`
|
||||
: Text
|
||||
Reference in New Issue
Block a user