56 lines
1.4 KiB
TypeScript
56 lines
1.4 KiB
TypeScript
import AsyncStorage from "@react-native-async-storage/async-storage";
|
|
import * as Localization from "expo-localization";
|
|
import i18n from "i18next";
|
|
import { initReactI18next } from "react-i18next";
|
|
|
|
import en from "./locales/en.json";
|
|
import zh from "./locales/zh.json";
|
|
|
|
const RESOURCES = {
|
|
en: { translation: en },
|
|
zh: { translation: zh },
|
|
};
|
|
|
|
const LANGUAGE_STORAGE_KEY = "user_language_preference";
|
|
|
|
const initI18n = async () => {
|
|
let savedLanguage = null;
|
|
try {
|
|
savedLanguage = await AsyncStorage.getItem(LANGUAGE_STORAGE_KEY);
|
|
} catch (error) {
|
|
console.warn("Failed to load language preference", error);
|
|
}
|
|
|
|
// Get device language (e.g. "en-US" -> "en")
|
|
// Prefer Localization.getLocales()[0].languageCode; fall back to 'en'
|
|
const locales = Localization.getLocales?.() ?? [];
|
|
const deviceLanguageCode = locales[0]?.languageCode ?? "en";
|
|
|
|
const languageToUse = savedLanguage || deviceLanguageCode || "en";
|
|
|
|
i18n.use(initReactI18next).init({
|
|
resources: RESOURCES,
|
|
lng: languageToUse,
|
|
fallbackLng: "en",
|
|
interpolation: {
|
|
escapeValue: false,
|
|
},
|
|
react: {
|
|
useSuspense: false, // For React Native compatibility
|
|
},
|
|
});
|
|
};
|
|
|
|
initI18n();
|
|
|
|
export default i18n;
|
|
|
|
export const changeLanguage = async (lang: string) => {
|
|
try {
|
|
await i18n.changeLanguage(lang);
|
|
await AsyncStorage.setItem(LANGUAGE_STORAGE_KEY, lang);
|
|
} catch (error) {
|
|
console.warn("Failed to change/save language", error);
|
|
}
|
|
};
|