feat: 添加国际化支持,优化语言切换器和登录界面,增强用户体验
Some checks failed
lotteryfront CI / build (push) Has been cancelled

This commit is contained in:
2026-06-29 15:27:37 +08:00
parent 1a43e81fb4
commit ebc6f4d349
8 changed files with 181 additions and 100 deletions

46
src/i18n/hydration-t.ts Normal file
View File

@@ -0,0 +1,46 @@
"use client";
import type { TFunction } from "i18next";
import { useMemo } from "react";
import { useTranslation } from "react-i18next";
import { useI18nHydrated } from "@/components/i18n-hydration-provider";
import { DEFAULT_LANGUAGE, type AppLanguage } from "@/i18n/language";
import enEntry from "@/i18n/locales/en/entry.json";
import neEntry from "@/i18n/locales/ne/entry.json";
import zhEntry from "@/i18n/locales/zh/entry.json";
const STATIC_ENTRY: Record<AppLanguage, typeof zhEntry> = {
zh: zhEntry,
en: enEntry,
ne: neEntry,
};
function getStaticValue(obj: Record<string, unknown>, key: string): string {
const parts = key.split(".");
let cur: unknown = obj;
for (const part of parts) {
if (cur == null || typeof cur !== "object") return key;
cur = (cur as Record<string, unknown>)[part];
}
return typeof cur === "string" ? cur : key;
}
function createStaticEntryT(): TFunction<"entry"> {
const fn = ((key: string) =>
getStaticValue(STATIC_ENTRY[DEFAULT_LANGUAGE] as Record<string, unknown>, key)) as TFunction<
"entry"
>;
return fn;
}
/** entry 命名空间hydration 前固定 DEFAULT_LANGUAGE 文案,避免 SSR/客户端首屏不一致。 */
export function useHydrationSafeEntryT(): TFunction<"entry"> {
const hydrated = useI18nHydrated();
const { t } = useTranslation("entry");
return useMemo(
() => (hydrated ? t : createStaticEntryT()),
[hydrated, t],
);
}