添加主题切换、多语言支持
This commit is contained in:
55
i18n/index.ts
Normal file
55
i18n/index.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
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);
|
||||
}
|
||||
};
|
||||
28
i18n/locales/en.json
Normal file
28
i18n/locales/en.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"welcome": "Welcome!",
|
||||
"tabs": {
|
||||
"all": "All",
|
||||
"live": "Live",
|
||||
"upcoming": "Upcoming",
|
||||
"finished": "Finished",
|
||||
"fav": "Favorites"
|
||||
},
|
||||
"settings": {
|
||||
"title": "Settings",
|
||||
"theme": "Theme",
|
||||
"language": "Language",
|
||||
"light": "Light",
|
||||
"dark": "Dark",
|
||||
"system": "System",
|
||||
"english": "English",
|
||||
"chinese": "Chinese"
|
||||
},
|
||||
"home": {
|
||||
"title": "Physical"
|
||||
},
|
||||
"profile": {
|
||||
"title": "My Profile",
|
||||
"name": "User Name",
|
||||
"settings": "Settings"
|
||||
}
|
||||
}
|
||||
28
i18n/locales/zh.json
Normal file
28
i18n/locales/zh.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"welcome": "欢迎!",
|
||||
"tabs": {
|
||||
"all": "全部",
|
||||
"live": "直播",
|
||||
"upcoming": "即将到来",
|
||||
"finished": "已完成",
|
||||
"fav": "收藏"
|
||||
},
|
||||
"settings": {
|
||||
"title": "设置",
|
||||
"theme": "主题",
|
||||
"language": "语言",
|
||||
"light": "浅色",
|
||||
"dark": "深色",
|
||||
"system": "跟随系统",
|
||||
"english": "英文",
|
||||
"chinese": "中文"
|
||||
},
|
||||
"home": {
|
||||
"title": "Physical"
|
||||
},
|
||||
"profile": {
|
||||
"title": "我的",
|
||||
"name": "用户名",
|
||||
"settings": "设置"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user