i18n.js 1.88 KB
Newer Older
fisherdaddy's avatar
fisherdaddy committed
1 2
import { useState, useEffect } from 'react';

3
let currentLanguage = localStorage.getItem('language') || 'zh';
fisherdaddy's avatar
fisherdaddy committed
4
let listeners = [];
5
let translations = {};
fisherdaddy's avatar
fisherdaddy committed
6

7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
// 动态加载翻译文件
async function loadTranslations(lang) {
  try {
    const [common, tools, aiproducts] = await Promise.all([
      import(`../locales/${lang}/common.json`),
      import(`../locales/${lang}/tools.json`),
      import(`../locales/${lang}/aiproducts.json`)
    ]);
    
    translations[lang] = {
      ...common.default,
      tools: tools.default,
      aiproducts: aiproducts.default
    };
    
    return true;
  } catch (error) {
    console.error(`Failed to load translations for ${lang}:`, error);
    return false;
  }
}

// 初始加载默认语言的翻译
const initPromise = loadTranslations(currentLanguage);

export async function setLanguage(lang) {
  if (!translations[lang]) {
    const loaded = await loadTranslations(lang);
    if (!loaded) return;
fisherdaddy's avatar
fisherdaddy committed
36
  }
37 38 39 40
  
  currentLanguage = lang;
  localStorage.setItem('language', lang);
  listeners.forEach(listener => listener(currentLanguage));
fisherdaddy's avatar
fisherdaddy committed
41 42 43 44 45 46 47
}

export function getLanguage() {
  return currentLanguage;
}

export function t(key) {
48 49 50 51
  if (!translations[currentLanguage]) {
    return key;
  }

fisherdaddy's avatar
fisherdaddy committed
52
  const keys = key.split('.');
53 54
  let value = translations[currentLanguage];
  
fisherdaddy's avatar
fisherdaddy committed
55 56
  for (const k of keys) {
    if (value[k] === undefined) {
57
      return key;
fisherdaddy's avatar
fisherdaddy committed
58 59 60 61 62 63 64 65
    }
    value = value[k];
  }
  return value;
}

export function useTranslation() {
  const [lang, setLang] = useState(currentLanguage);
66
  const [isLoading, setIsLoading] = useState(true);
fisherdaddy's avatar
fisherdaddy committed
67 68

  useEffect(() => {
69 70 71 72 73
    // 等待初始翻译加载完成
    initPromise.then(() => {
      setIsLoading(false);
    });

fisherdaddy's avatar
fisherdaddy committed
74 75 76 77 78 79 80
    const listener = (newLang) => setLang(newLang);
    listeners.push(listener);
    return () => {
      listeners = listeners.filter(l => l !== listener);
    };
  }, []);

81
  return { t, lang, setLanguage, isLoading };
fisherdaddy's avatar
fisherdaddy committed
82
}