memowake-front/i18n/index.ts

117 lines
3.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import i18n from 'i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import { initReactI18next } from 'react-i18next';
import { Platform } from 'react-native';
// Conditionally import expo-secure-store only on native platforms
let customStorage: any;
if (Platform.OS !== 'web') {
try {
const SecureStore = require('expo-secure-store');
customStorage = {
getItem: (key: string) => SecureStore.getItemAsync(key),
setItem: (key: string, value: string) => SecureStore.setItemAsync(key, value),
};
} catch (e) {
console.error('Failed to load expo-secure-store', e);
}
}
// 自动生成的导入
import translations from './translations-generated';
// 初始化i18next
i18n
// 检测用户语言
.use(LanguageDetector)
// 将i18n实例传递给react-i18next
.use(initReactI18next)
// 初始化i18next
.init({
// 初始不加载任何资源
resources: translations,
// 支持命名空间
ns: ['common', 'example', 'download', 'permission'],
defaultNS: 'common',
// 设置默认语言为中文
lng: 'en',
fallbackLng: 'en',
debug: process.env.NODE_ENV === 'development',
interpolation: {
escapeValue: false, // 不需要转义React已经处理了
},
detection: {
order: Platform.OS === 'web' ? ['localStorage', 'navigator'] : ['customStorage', 'device'],
caches: Platform.OS === 'web' ? ['localStorage'] : ['customStorage'],
lookupLocalStorage: 'i18nextLng',
...(customStorage && { lookupCustomStorage: customStorage }),
}
});
// 按需加载翻译资源的函数
export const loadNamespaceForLanguage = async (lng: string, ns: string) => {
// 如果已经加载过该命名空间,则不重复加载
if (i18n.hasResourceBundle(lng, ns)) {
return;
}
try {
const langTranslations = translations[lng as keyof typeof translations];
if (!langTranslations) {
console.warn(`No translations found for language: ${lng}`);
return;
}
const resource = langTranslations[ns as keyof typeof langTranslations];
if (resource) {
i18n.addResourceBundle(lng, ns, resource, true, true);
} else {
console.warn(`No translations found for ${lng}/${ns}`);
}
} catch (error) {
console.error(`Failed to load translations for ${lng}/${ns}:`, error);
}
};
// 加载指定命名空间及其备用语言的翻译
export const loadNamespaceWithFallback = async (ns: string, language?: string) => {
const currentLng = language || i18n.language || 'en';
// 加载当前语言的翻译
await loadNamespaceForLanguage(currentLng, ns);
// 如果当前语言不是英语,也加载英语作为备用
if (currentLng !== 'en') {
await loadNamespaceForLanguage('en', ns);
}
};
// 预加载公共翻译资源
export const preloadCommonTranslations = async () => {
const currentLng = i18n.language || 'en';
// 预加载 common 和 example 命名空间
await Promise.all([
loadNamespaceForLanguage(currentLng, 'common'),
loadNamespaceForLanguage(currentLng, 'example'),
loadNamespaceForLanguage(currentLng, 'permission')
]);
// 如果当前语言不是英语,也预加载英语作为备用
if (currentLng !== 'en') {
await Promise.all([
loadNamespaceForLanguage('en', 'common'),
loadNamespaceForLanguage('en', 'example'),
loadNamespaceForLanguage('en', 'permission')
]);
}
};
// 初始加载公共翻译
preloadCommonTranslations();
export default i18n;