feat: 前端 UI 国际化,支持中/英/日三语切换
之前语言设置只影响后端 AI 行为,前端 UI 文字始终为中文。 新增轻量 i18n 模块(React Context + 翻译字典),切换语言后所有 UI 文字即时刷新。 - 新增 i18n 核心模块和 zh-CN/en-US/ja-JP 翻译文件(约 72 个 key) - App.tsx 拆分为 App(Provider)+ AppContent(业务),确保 Hook 可访问 Context - 所有组件通过 useI18n().t() 获取翻译文本 - errors.ts 改为接受翻译函数参数 - storage.ts saveConfig 时派发事件通知 locale 变化
This commit is contained in:
@@ -12,6 +12,7 @@ import { getErrorMessage } from "../lib/errors";
|
||||
import { TTSPlayer } from "../lib/ttsPlayer";
|
||||
import { showToast } from "../lib/toast";
|
||||
import { loadConfig, saveConfig } from "../lib/storage";
|
||||
import { useI18n } from "../lib/i18n";
|
||||
import { useCamera } from "../components/CameraManager";
|
||||
import { useMicrophone } from "../components/MicManager";
|
||||
import { useVAD, sampleFrame, compareFrames } from "../components/EdgeProcessor";
|
||||
@@ -29,6 +30,7 @@ export interface SessionStats {
|
||||
}
|
||||
|
||||
export function useVisionSession() {
|
||||
const { t } = useI18n();
|
||||
const [messages, setMessages] = useState<ChatMessage[]>([]);
|
||||
const [currentReply, setCurrentReply] = useState<string>("");
|
||||
const [isProcessing, setIsProcessing] = useState(false);
|
||||
@@ -84,7 +86,7 @@ export function useVisionSession() {
|
||||
...prev,
|
||||
{
|
||||
role: "user",
|
||||
content: "👁️ 画面变化检测",
|
||||
content: t("session.changeDetected"),
|
||||
timestamp: Date.now(),
|
||||
},
|
||||
]);
|
||||
@@ -199,7 +201,7 @@ export function useVisionSession() {
|
||||
// 添加用户消息(STT 流式结果会逐步更新文本)
|
||||
setMessages((prev) => [
|
||||
...prev,
|
||||
{ role: "user", content: "(语音识别中...)", timestamp: Date.now() },
|
||||
{ role: "user", content: t("session.recognizing"), timestamp: Date.now() },
|
||||
]);
|
||||
setIsProcessing(true);
|
||||
},
|
||||
@@ -219,7 +221,7 @@ export function useVisionSession() {
|
||||
if (lastUserIdx >= 0) {
|
||||
updated[lastUserIdx] = {
|
||||
...updated[lastUserIdx],
|
||||
content: msg.text || "(未识别到语音)",
|
||||
content: msg.text || t("session.noSpeech"),
|
||||
};
|
||||
}
|
||||
return updated;
|
||||
@@ -271,7 +273,7 @@ export function useVisionSession() {
|
||||
|
||||
case "error":
|
||||
console.error("[Session] 服务端错误:", msg.code, msg.message);
|
||||
showToast(getErrorMessage(msg.code), "error");
|
||||
showToast(getErrorMessage(msg.code, t), "error");
|
||||
setIsProcessing(false);
|
||||
break;
|
||||
}
|
||||
@@ -359,7 +361,7 @@ export function useVisionSession() {
|
||||
setIsAudioPlaying(false);
|
||||
// 将未完成的流式内容保存为最终消息
|
||||
if (currentReply) {
|
||||
const interrupted = currentReply + "(已打断)";
|
||||
const interrupted = currentReply + t("session.interrupted");
|
||||
historyRef.current.push({ role: "assistant", content: interrupted });
|
||||
setMessages((prev) => [
|
||||
...prev,
|
||||
|
||||
Reference in New Issue
Block a user