mirror of
https://gitee.com/wanwujie/deer-flow
synced 2026-04-22 05:34:45 +08:00
feat: implement i18n
This commit is contained in:
57
frontend/src/core/i18n/hooks.ts
Normal file
57
frontend/src/core/i18n/hooks.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
import { enUS } from "./locales/en-US";
|
||||
import { zhCN } from "./locales/zh-CN";
|
||||
|
||||
import { detectLocale, type Locale, type Translations } from "./index";
|
||||
|
||||
const translations: Record<Locale, Translations> = {
|
||||
"en-US": enUS,
|
||||
"zh-CN": zhCN,
|
||||
};
|
||||
|
||||
export function useI18n() {
|
||||
const [locale, setLocale] = useState<Locale>(() => {
|
||||
if (typeof window === "undefined") {
|
||||
return "en-US";
|
||||
}
|
||||
|
||||
// Try to get from localStorage first
|
||||
const saved = localStorage.getItem("locale") as Locale | null;
|
||||
if (saved && (saved === "en-US" || saved === "zh-CN")) {
|
||||
return saved;
|
||||
}
|
||||
|
||||
// Otherwise detect from browser
|
||||
return detectLocale();
|
||||
});
|
||||
|
||||
const t = translations[locale];
|
||||
|
||||
const changeLocale = (newLocale: Locale) => {
|
||||
setLocale(newLocale);
|
||||
if (typeof window !== "undefined") {
|
||||
localStorage.setItem("locale", newLocale);
|
||||
}
|
||||
};
|
||||
|
||||
// Initialize locale on mount
|
||||
useEffect(() => {
|
||||
if (typeof window !== "undefined") {
|
||||
const saved = localStorage.getItem("locale") as Locale | null;
|
||||
if (!saved) {
|
||||
const detected = detectLocale();
|
||||
setLocale(detected);
|
||||
localStorage.setItem("locale", detected);
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
return {
|
||||
locale,
|
||||
t,
|
||||
changeLocale,
|
||||
};
|
||||
}
|
||||
23
frontend/src/core/i18n/index.ts
Normal file
23
frontend/src/core/i18n/index.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
export { enUS } from "./locales/en-US";
|
||||
export { zhCN } from "./locales/zh-CN";
|
||||
export type { Translations } from "./locales/types";
|
||||
|
||||
export type Locale = "en-US" | "zh-CN";
|
||||
|
||||
// Helper function to detect browser locale
|
||||
export function detectLocale(): Locale {
|
||||
// if (typeof window === "undefined") {
|
||||
// return "en-US";
|
||||
// }
|
||||
|
||||
// const browserLang =
|
||||
// navigator.language ||
|
||||
// (navigator as unknown as { userLanguage: string }).userLanguage;
|
||||
|
||||
// // Check if browser language is Chinese (zh, zh-CN, zh-TW, etc.)
|
||||
// if (browserLang.toLowerCase().startsWith("zh")) {
|
||||
// return "zh-CN";
|
||||
// }
|
||||
|
||||
return "en-US";
|
||||
}
|
||||
86
frontend/src/core/i18n/locales/en-US.ts
Normal file
86
frontend/src/core/i18n/locales/en-US.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
import type { Translations } from "./types";
|
||||
|
||||
export const enUS: Translations = {
|
||||
// Common
|
||||
common: {
|
||||
home: "Home",
|
||||
settings: "Settings",
|
||||
delete: "Delete",
|
||||
openInNewWindow: "Open in new window",
|
||||
close: "Close",
|
||||
more: "More",
|
||||
search: "Search",
|
||||
download: "Download",
|
||||
thinking: "Thinking",
|
||||
artifacts: "Artifacts",
|
||||
},
|
||||
|
||||
// Welcome
|
||||
welcome: {
|
||||
greeting: "👋 Hello, again!",
|
||||
description:
|
||||
"Welcome to 🦌 DeerFlow, an open source super agent. With built-in and custom skills, DeerFlow helps you search on the web, analyze data, and generate artifacts like slides, web pages and do almost anything.",
|
||||
},
|
||||
|
||||
// Clipboard
|
||||
clipboard: {
|
||||
copyToClipboard: "Copy to clipboard",
|
||||
copiedToClipboard: "Copied to clipboard",
|
||||
failedToCopyToClipboard: "Failed to copy to clipboard",
|
||||
},
|
||||
|
||||
// Input Box
|
||||
inputBox: {
|
||||
placeholder: "How can I assist you today?",
|
||||
thinkingEnabled: "Thinking is enabled",
|
||||
thinkingDisabled: "Thinking is disabled",
|
||||
clickToDisableThinking: "Click to disable thinking",
|
||||
clickToEnableThinking: "Click to enable thinking",
|
||||
searchModels: "Search models...",
|
||||
},
|
||||
|
||||
// Sidebar
|
||||
sidebar: {
|
||||
newChat: "New chat",
|
||||
chats: "Chats",
|
||||
recentChats: "Recent chats",
|
||||
},
|
||||
|
||||
// Breadcrumb
|
||||
breadcrumb: {
|
||||
workspace: "Workspace",
|
||||
chats: "Chats",
|
||||
},
|
||||
|
||||
// Workspace
|
||||
workspace: {
|
||||
githubTooltip: "DeerFlow on Github",
|
||||
},
|
||||
|
||||
// Conversation
|
||||
conversation: {
|
||||
noMessages: "No messages yet",
|
||||
startConversation: "Start a conversation to see messages here",
|
||||
},
|
||||
|
||||
// Chats
|
||||
chats: {
|
||||
searchChats: "Search chats",
|
||||
},
|
||||
|
||||
// Tool calls
|
||||
toolCalls: {
|
||||
moreSteps: (count: number) => `${count} more step${count === 1 ? "" : "s"}`,
|
||||
lessSteps: "Less steps",
|
||||
executeCommand: "Execute command",
|
||||
presentFiles: "Present files",
|
||||
needYourHelp: "Need your help",
|
||||
useTool: (toolName: string) => `Use "${toolName}" tool`,
|
||||
searchForRelatedInfo: "Search for related information",
|
||||
searchOnWebFor: (query: string) => `Search on the web for "${query}"`,
|
||||
viewWebPage: "View web page",
|
||||
listFolder: "List folder",
|
||||
readFile: "Read file",
|
||||
writeFile: "Write file",
|
||||
},
|
||||
};
|
||||
3
frontend/src/core/i18n/locales/index.ts
Normal file
3
frontend/src/core/i18n/locales/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export { enUS } from "./en-US";
|
||||
export { zhCN } from "./zh-CN";
|
||||
export type { Translations } from "./types";
|
||||
83
frontend/src/core/i18n/locales/types.ts
Normal file
83
frontend/src/core/i18n/locales/types.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
export interface Translations {
|
||||
// Common
|
||||
common: {
|
||||
home: string;
|
||||
settings: string;
|
||||
delete: string;
|
||||
openInNewWindow: string;
|
||||
close: string;
|
||||
more: string;
|
||||
search: string;
|
||||
download: string;
|
||||
thinking: string;
|
||||
artifacts: string;
|
||||
};
|
||||
|
||||
// Welcome
|
||||
welcome: {
|
||||
greeting: string;
|
||||
description: string;
|
||||
};
|
||||
|
||||
// Clipboard
|
||||
clipboard: {
|
||||
copyToClipboard: string;
|
||||
copiedToClipboard: string;
|
||||
failedToCopyToClipboard: string;
|
||||
};
|
||||
|
||||
// Input Box
|
||||
inputBox: {
|
||||
placeholder: string;
|
||||
thinkingEnabled: string;
|
||||
thinkingDisabled: string;
|
||||
clickToDisableThinking: string;
|
||||
clickToEnableThinking: string;
|
||||
searchModels: string;
|
||||
};
|
||||
|
||||
// Sidebar
|
||||
sidebar: {
|
||||
recentChats: string;
|
||||
newChat: string;
|
||||
chats: string;
|
||||
};
|
||||
|
||||
// Breadcrumb
|
||||
breadcrumb: {
|
||||
workspace: string;
|
||||
chats: string;
|
||||
};
|
||||
|
||||
// Workspace
|
||||
workspace: {
|
||||
githubTooltip: string;
|
||||
};
|
||||
|
||||
// Conversation
|
||||
conversation: {
|
||||
noMessages: string;
|
||||
startConversation: string;
|
||||
};
|
||||
|
||||
// Chats
|
||||
chats: {
|
||||
searchChats: string;
|
||||
};
|
||||
|
||||
// Tool calls
|
||||
toolCalls: {
|
||||
moreSteps: (count: number) => string;
|
||||
lessSteps: string;
|
||||
executeCommand: string;
|
||||
presentFiles: string;
|
||||
needYourHelp: string;
|
||||
useTool: (toolName: string) => string;
|
||||
searchForRelatedInfo: string;
|
||||
searchOnWebFor: (query: string) => string;
|
||||
viewWebPage: string;
|
||||
listFolder: string;
|
||||
readFile: string;
|
||||
writeFile: string;
|
||||
};
|
||||
}
|
||||
86
frontend/src/core/i18n/locales/zh-CN.ts
Normal file
86
frontend/src/core/i18n/locales/zh-CN.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
import type { Translations } from "./types";
|
||||
|
||||
export const zhCN: Translations = {
|
||||
// Common
|
||||
common: {
|
||||
home: "首页",
|
||||
settings: "设置",
|
||||
delete: "删除",
|
||||
openInNewWindow: "在新窗口打开",
|
||||
close: "关闭",
|
||||
more: "更多",
|
||||
search: "搜索",
|
||||
download: "下载",
|
||||
thinking: "思考",
|
||||
artifacts: "文件",
|
||||
},
|
||||
|
||||
// Welcome
|
||||
welcome: {
|
||||
greeting: "👋 你好,欢迎回来!",
|
||||
description:
|
||||
"欢迎使用 🦌 DeerFlow,一个完全开源的超级智能体。通过内置和\n自定义的 Skills,DeerFlow 可以帮你搜索网络、分析数据,\n还能为你生成幻灯片、网页等作品,几乎可以做任何事情。",
|
||||
},
|
||||
|
||||
// Clipboard
|
||||
clipboard: {
|
||||
copyToClipboard: "复制到剪贴板",
|
||||
copiedToClipboard: "已复制到剪贴板",
|
||||
failedToCopyToClipboard: "复制到剪贴板失败",
|
||||
},
|
||||
|
||||
// Input Box
|
||||
inputBox: {
|
||||
placeholder: "今天我能为你做些什么?",
|
||||
thinkingEnabled: "思考功能已启用",
|
||||
thinkingDisabled: "思考功能已禁用",
|
||||
clickToDisableThinking: "点击禁用思考功能",
|
||||
clickToEnableThinking: "点击启用思考功能",
|
||||
searchModels: "搜索模型...",
|
||||
},
|
||||
|
||||
// Sidebar
|
||||
sidebar: {
|
||||
newChat: "新对话",
|
||||
chats: "对话",
|
||||
recentChats: "最近的聊天",
|
||||
},
|
||||
|
||||
// Breadcrumb
|
||||
breadcrumb: {
|
||||
workspace: "工作区",
|
||||
chats: "对话",
|
||||
},
|
||||
|
||||
// Workspace
|
||||
workspace: {
|
||||
githubTooltip: "DeerFlow 在 Github",
|
||||
},
|
||||
|
||||
// Conversation
|
||||
conversation: {
|
||||
noMessages: "还没有消息",
|
||||
startConversation: "开始新的对话以查看消息",
|
||||
},
|
||||
|
||||
// Chats
|
||||
chats: {
|
||||
searchChats: "搜索对话",
|
||||
},
|
||||
|
||||
// Tool calls
|
||||
toolCalls: {
|
||||
moreSteps: (count: number) => `查看其他 ${count} 个步骤`,
|
||||
lessSteps: "隐藏步骤",
|
||||
executeCommand: "执行命令",
|
||||
presentFiles: "展示文件",
|
||||
needYourHelp: "需要你的协助",
|
||||
useTool: (toolName: string) => `使用 “${toolName}” 工具`,
|
||||
searchForRelatedInfo: "搜索相关信息",
|
||||
searchOnWebFor: (query: string) => `在网络上搜索 “${query}”`,
|
||||
viewWebPage: "查看网页",
|
||||
listFolder: "列出文件夹",
|
||||
readFile: "读取文件",
|
||||
writeFile: "写入文件",
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user