From eca70425cf9a6c74bc4070f3e7860d60b5e9d0c6 Mon Sep 17 00:00:00 2001 From: DEV_DSW <562304744@qq.com> Date: Fri, 17 Apr 2026 17:16:18 +0800 Subject: [PATCH] feat(i18n): integrate internationalization into sidebar, title bar, and settings components - Added useI18n hook to Sidebar and TitleBar components for translation support. - Updated sidebar navigation items to use translation keys instead of hardcoded labels. - Enhanced TitleBar buttons with localized titles for minimize, maximize, and close actions. - Expanded i18n constants to include new namespaces for sidebar and login. - Implemented translation messages for sidebar, settings, and login components in English, Chinese, and Japanese. - Refactored Knowledge and Skills pages to utilize useLocale for locale management. - Updated Login page to display localized text for form labels, placeholders, and error messages. - Enhanced Account and General settings panels with localized titles and descriptions. - Modified SettingMenu to use translation keys for menu items. --- dist-electron/main/main.js | 9 +- dist-electron/preload/preload.js | 138 +++++++++++- dist/index.html | 2 +- src/App.tsx | 3 + src/components/layout/Sidebar.tsx | 4 +- src/components/layout/TitleBar.tsx | 9 +- src/i18n/constants.ts | 4 +- src/i18n/index.ts | 21 ++ src/i18n/messages.ts | 204 +++++++++++++++++- src/pages/Knowledge/copy.ts | 7 +- src/pages/Login/index.tsx | 66 +++--- .../components/AccountSettingsPanel.tsx | 35 +-- .../components/GeneralSettingsPanel.tsx | 116 +++++----- src/pages/Setting/components/SettingMenu.tsx | 25 ++- src/pages/Skills/copy.ts | 7 +- src/router/routes.ts | 24 ++- 16 files changed, 533 insertions(+), 141 deletions(-) diff --git a/dist-electron/main/main.js b/dist-electron/main/main.js index a8c04dd..86f81e5 100644 --- a/dist-electron/main/main.js +++ b/dist-electron/main/main.js @@ -1,2 +1,7 @@ -require('bytenode') -require('./main.jsc') \ No newline at end of file +"use strict"; +require("electron"); +require("./main-B0AKNiSn.js"); +require("electron-squirrel-startup"); +require("electron-log"); +require("bytenode"); +require("axios"); diff --git a/dist-electron/preload/preload.js b/dist-electron/preload/preload.js index 956f473..c4f6639 100644 --- a/dist-electron/preload/preload.js +++ b/dist-electron/preload/preload.js @@ -1 +1,137 @@ -"use strict";const r=require("electron");var i=(e=>(e.EXTERNAL_OPEN="external-open",e.APP_SET_FRAMELESS="app:set-frameless",e.APP_LOAD_PAGE="app:load-page",e.TAB_CREATE="tab:create",e.TAB_LIST="tab:list",e.TAB_NAVIGATE="tab:navigate",e.TAB_RELOAD="tab:reload",e.TAB_BACK="tab:back",e.TAB_FORWARD="tab:forward",e.TAB_SWITCH="tab:switch",e.TAB_CLOSE="tab:close",e.LOG_TO_MAIN="log-to-main",e.READ_FILE="read-file",e.INVOKE="ipc:invoke",e.INVOKE_ASYNC="ipc:invokeAsync",e.APP_MINIMIZE="app:minimize",e.APP_MAXIMIZE="app:maximize",e.APP_QUIT="app:quit",e.FILE_READ="file:read",e.FILE_WRITE="file:write",e.GET_WINDOW_ID="get-window-id",e.CUSTOM_EVENT="custom:event",e.TIME_UPDATE="time:update",e.RENDERER_IS_READY="renderer-ready",e.SHOW_CONTEXT_MENU="show-context-menu",e.START_A_DIALOGUE="start-a-dialogue",e.OPEN_WINDOW="open-window",e.LOG_DEBUG="log-debug",e.LOG_INFO="log-info",e.LOG_WARN="log-warn",e.LOG_ERROR="log-error",e.CONFIG_UPDATED="config-updated",e.SET_CONFIG="set-config",e.GET_CONFIG="get-config",e.UPDATE_CONFIG="update-config",e.SET_THEME_MODE="set-theme-mode",e.GET_THEME_MODE="get-theme-mode",e.IS_DARK_THEME="is-dark-theme",e.THEME_MODE_UPDATED="theme-mode-updated",e.EXECUTE_SCRIPT="execute-script",e.TASK_PROGRESS="task:progress",e.TASK_STARTED="task:started",e.TASK_COMPLETED="task:completed",e.OPEN_CHANNEL="open-channel",e.SCRIPT_LIST="script:list",e.SCRIPT_GET="script:get",e.SCRIPT_SAVE="script:save",e.SCRIPT_DELETE="script:delete",e.SCRIPT_TOGGLE="script:toggle",e.SCRIPT_RUN="script:run",e.SCRIPT_RECORD_START="script:record-start",e.SCRIPT_RECORD_STOP="script:record-stop",e.SCRIPT_CODEGEN="script:codegen",e.GATEWAY_RPC="gateway:rpc",e.GATEWAY_EVENT="gateway:event",e.UPDATE_CHECK="update:check",e.UPDATE_DOWNLOAD="update:download",e.UPDATE_INSTALL="update:install",e.UPDATE_VERSION="update:version",e.UPDATE_STATUS_CHANGED="update:status-changed",e))(i||{});const d={versions:process.versions,external:{open:e=>r.ipcRenderer.invoke("external-open",e)},platform:process.platform,windowMinimize:()=>r.ipcRenderer.invoke("window:minimize"),windowMaximize:()=>r.ipcRenderer.invoke("window:maximize"),windowClose:()=>r.ipcRenderer.invoke("window:close"),windowIsMaximized:()=>r.ipcRenderer.invoke("window:isMaximized"),viewIsReady:()=>r.ipcRenderer.send(i.RENDERER_IS_READY),app:{setFrameless:e=>r.ipcRenderer.invoke(i.APP_SET_FRAMELESS,e),loadPage:e=>r.ipcRenderer.invoke(i.APP_LOAD_PAGE,e)},readFile:e=>r.ipcRenderer.invoke(i.READ_FILE,e),invoke:(e,...n)=>r.ipcRenderer.invoke(e,...n),invokeAsync:(e,...n)=>r.ipcRenderer.invoke(e,...n),on:(e,n)=>{const t=(o,...R)=>n(...R);return r.ipcRenderer.on(e,t),()=>r.ipcRenderer.removeListener(e,t)},send:(e,...n)=>r.ipcRenderer.send(e,...n),getCurrentWindowId:()=>r.ipcRenderer.sendSync(i.GET_WINDOW_ID),logger:{debug:(e,...n)=>r.ipcRenderer.send(i.LOG_DEBUG,e,...n),info:(e,...n)=>r.ipcRenderer.send(i.LOG_INFO,e,...n),warn:(e,...n)=>r.ipcRenderer.send(i.LOG_WARN,e,...n),error:(e,...n)=>r.ipcRenderer.send(i.LOG_ERROR,e,...n)},executeScript:e=>r.ipcRenderer.invoke(i.EXECUTE_SCRIPT,e),onTaskProgress:e=>{const n=(t,o)=>e(o);return r.ipcRenderer.on(i.TASK_PROGRESS,n),()=>r.ipcRenderer.removeListener(i.TASK_PROGRESS,n)},onTaskStarted:e=>{const n=(t,o)=>e(o);return r.ipcRenderer.on(i.TASK_STARTED,n),()=>r.ipcRenderer.removeListener(i.TASK_STARTED,n)},onTaskCompleted:e=>{const n=(t,o)=>e(o);return r.ipcRenderer.on(i.TASK_COMPLETED,n),()=>r.ipcRenderer.removeListener(i.TASK_COMPLETED,n)},openChannel:e=>r.ipcRenderer.invoke(i.OPEN_CHANNEL,e),scriptApi:{list:()=>r.ipcRenderer.invoke(i.SCRIPT_LIST),get:e=>r.ipcRenderer.invoke(i.SCRIPT_GET,e),save:e=>r.ipcRenderer.invoke(i.SCRIPT_SAVE,e),delete:e=>r.ipcRenderer.invoke(i.SCRIPT_DELETE,e),toggle:(e,n)=>r.ipcRenderer.invoke(i.SCRIPT_TOGGLE,e,n),run:e=>r.ipcRenderer.invoke(i.SCRIPT_RUN,e),startRecording:e=>r.ipcRenderer.invoke(i.SCRIPT_RECORD_START,e),stopRecording:()=>r.ipcRenderer.invoke(i.SCRIPT_RECORD_STOP),codegen:(e,n)=>r.ipcRenderer.invoke(i.SCRIPT_CODEGEN,e,n)}};r.contextBridge.exposeInMainWorld("api",d); +"use strict"; +const electron = require("electron"); +var IPC_EVENTS = /* @__PURE__ */ ((IPC_EVENTS2) => { + IPC_EVENTS2["EXTERNAL_OPEN"] = "external-open"; + IPC_EVENTS2["APP_SET_FRAMELESS"] = "app:set-frameless"; + IPC_EVENTS2["APP_LOAD_PAGE"] = "app:load-page"; + IPC_EVENTS2["TAB_CREATE"] = "tab:create"; + IPC_EVENTS2["TAB_LIST"] = "tab:list"; + IPC_EVENTS2["TAB_NAVIGATE"] = "tab:navigate"; + IPC_EVENTS2["TAB_RELOAD"] = "tab:reload"; + IPC_EVENTS2["TAB_BACK"] = "tab:back"; + IPC_EVENTS2["TAB_FORWARD"] = "tab:forward"; + IPC_EVENTS2["TAB_SWITCH"] = "tab:switch"; + IPC_EVENTS2["TAB_CLOSE"] = "tab:close"; + IPC_EVENTS2["LOG_TO_MAIN"] = "log-to-main"; + IPC_EVENTS2["READ_FILE"] = "read-file"; + IPC_EVENTS2["INVOKE"] = "ipc:invoke"; + IPC_EVENTS2["INVOKE_ASYNC"] = "ipc:invokeAsync"; + IPC_EVENTS2["APP_MINIMIZE"] = "app:minimize"; + IPC_EVENTS2["APP_MAXIMIZE"] = "app:maximize"; + IPC_EVENTS2["APP_QUIT"] = "app:quit"; + IPC_EVENTS2["FILE_READ"] = "file:read"; + IPC_EVENTS2["FILE_WRITE"] = "file:write"; + IPC_EVENTS2["GET_WINDOW_ID"] = "get-window-id"; + IPC_EVENTS2["CUSTOM_EVENT"] = "custom:event"; + IPC_EVENTS2["TIME_UPDATE"] = "time:update"; + IPC_EVENTS2["RENDERER_IS_READY"] = "renderer-ready"; + IPC_EVENTS2["SHOW_CONTEXT_MENU"] = "show-context-menu"; + IPC_EVENTS2["START_A_DIALOGUE"] = "start-a-dialogue"; + IPC_EVENTS2["OPEN_WINDOW"] = "open-window"; + IPC_EVENTS2["LOG_DEBUG"] = "log-debug"; + IPC_EVENTS2["LOG_INFO"] = "log-info"; + IPC_EVENTS2["LOG_WARN"] = "log-warn"; + IPC_EVENTS2["LOG_ERROR"] = "log-error"; + IPC_EVENTS2["CONFIG_UPDATED"] = "config-updated"; + IPC_EVENTS2["SET_CONFIG"] = "set-config"; + IPC_EVENTS2["GET_CONFIG"] = "get-config"; + IPC_EVENTS2["UPDATE_CONFIG"] = "update-config"; + IPC_EVENTS2["SET_THEME_MODE"] = "set-theme-mode"; + IPC_EVENTS2["GET_THEME_MODE"] = "get-theme-mode"; + IPC_EVENTS2["IS_DARK_THEME"] = "is-dark-theme"; + IPC_EVENTS2["THEME_MODE_UPDATED"] = "theme-mode-updated"; + IPC_EVENTS2["EXECUTE_SCRIPT"] = "execute-script"; + IPC_EVENTS2["TASK_PROGRESS"] = "task:progress"; + IPC_EVENTS2["TASK_STARTED"] = "task:started"; + IPC_EVENTS2["TASK_COMPLETED"] = "task:completed"; + IPC_EVENTS2["OPEN_CHANNEL"] = "open-channel"; + IPC_EVENTS2["SCRIPT_LIST"] = "script:list"; + IPC_EVENTS2["SCRIPT_GET"] = "script:get"; + IPC_EVENTS2["SCRIPT_SAVE"] = "script:save"; + IPC_EVENTS2["SCRIPT_DELETE"] = "script:delete"; + IPC_EVENTS2["SCRIPT_TOGGLE"] = "script:toggle"; + IPC_EVENTS2["SCRIPT_RUN"] = "script:run"; + IPC_EVENTS2["SCRIPT_RECORD_START"] = "script:record-start"; + IPC_EVENTS2["SCRIPT_RECORD_STOP"] = "script:record-stop"; + IPC_EVENTS2["SCRIPT_CODEGEN"] = "script:codegen"; + IPC_EVENTS2["GATEWAY_RPC"] = "gateway:rpc"; + IPC_EVENTS2["GATEWAY_EVENT"] = "gateway:event"; + IPC_EVENTS2["UPDATE_CHECK"] = "update:check"; + IPC_EVENTS2["UPDATE_DOWNLOAD"] = "update:download"; + IPC_EVENTS2["UPDATE_INSTALL"] = "update:install"; + IPC_EVENTS2["UPDATE_VERSION"] = "update:version"; + IPC_EVENTS2["UPDATE_STATUS_CHANGED"] = "update:status-changed"; + return IPC_EVENTS2; +})(IPC_EVENTS || {}); +const api = { + versions: process.versions, + external: { + open: (url) => electron.ipcRenderer.invoke("external-open", url) + }, + platform: process.platform, + windowMinimize: () => electron.ipcRenderer.invoke("window:minimize"), + windowMaximize: () => electron.ipcRenderer.invoke("window:maximize"), + windowClose: () => electron.ipcRenderer.invoke("window:close"), + windowIsMaximized: () => electron.ipcRenderer.invoke("window:isMaximized"), + viewIsReady: () => electron.ipcRenderer.send(IPC_EVENTS.RENDERER_IS_READY), + app: { + setFrameless: (route) => electron.ipcRenderer.invoke(IPC_EVENTS.APP_SET_FRAMELESS, route), + loadPage: (page) => electron.ipcRenderer.invoke(IPC_EVENTS.APP_LOAD_PAGE, page) + }, + // 通过 IPC 调用主进程 + readFile: (filePath) => electron.ipcRenderer.invoke(IPC_EVENTS.READ_FILE, filePath), + // 异步调用(映射为 electron 的 invoke) + invoke: (channel, ...args) => electron.ipcRenderer.invoke(channel, ...args), + // 异步调用(为了兼容老代码) + invokeAsync: (channel, ...args) => electron.ipcRenderer.invoke(channel, ...args), + // 监听主进程消息 + on: (event, callback) => { + const subscription = (_event, ...args) => callback(...args); + electron.ipcRenderer.on(event, subscription); + return () => electron.ipcRenderer.removeListener(event, subscription); + }, + // 发送消息到主进程 + send: (channel, ...args) => electron.ipcRenderer.send(channel, ...args), + // 获取窗口ID + getCurrentWindowId: () => electron.ipcRenderer.sendSync(IPC_EVENTS.GET_WINDOW_ID), + // 发送日志 + logger: { + debug: (message, ...meta) => electron.ipcRenderer.send(IPC_EVENTS.LOG_DEBUG, message, ...meta), + info: (message, ...meta) => electron.ipcRenderer.send(IPC_EVENTS.LOG_INFO, message, ...meta), + warn: (message, ...meta) => electron.ipcRenderer.send(IPC_EVENTS.LOG_WARN, message, ...meta), + error: (message, ...meta) => electron.ipcRenderer.send(IPC_EVENTS.LOG_ERROR, message, ...meta) + }, + // 执行脚本 + executeScript: (params) => electron.ipcRenderer.invoke(IPC_EVENTS.EXECUTE_SCRIPT, params), + // 任务事件 + onTaskProgress: (cb) => { + const subscription = (_event, payload) => cb(payload); + electron.ipcRenderer.on(IPC_EVENTS.TASK_PROGRESS, subscription); + return () => electron.ipcRenderer.removeListener(IPC_EVENTS.TASK_PROGRESS, subscription); + }, + onTaskStarted: (cb) => { + const subscription = (_event, payload) => cb(payload); + electron.ipcRenderer.on(IPC_EVENTS.TASK_STARTED, subscription); + return () => electron.ipcRenderer.removeListener(IPC_EVENTS.TASK_STARTED, subscription); + }, + onTaskCompleted: (cb) => { + const subscription = (_event, payload) => cb(payload); + electron.ipcRenderer.on(IPC_EVENTS.TASK_COMPLETED, subscription); + return () => electron.ipcRenderer.removeListener(IPC_EVENTS.TASK_COMPLETED, subscription); + }, + // 打开渠道 + openChannel: (channels) => electron.ipcRenderer.invoke(IPC_EVENTS.OPEN_CHANNEL, channels), + // 脚本管理 + scriptApi: { + list: () => electron.ipcRenderer.invoke(IPC_EVENTS.SCRIPT_LIST), + get: (id) => electron.ipcRenderer.invoke(IPC_EVENTS.SCRIPT_GET, id), + save: (input) => electron.ipcRenderer.invoke(IPC_EVENTS.SCRIPT_SAVE, input), + delete: (id) => electron.ipcRenderer.invoke(IPC_EVENTS.SCRIPT_DELETE, id), + toggle: (id, enabled) => electron.ipcRenderer.invoke(IPC_EVENTS.SCRIPT_TOGGLE, id, enabled), + run: (id) => electron.ipcRenderer.invoke(IPC_EVENTS.SCRIPT_RUN, id), + startRecording: (url) => electron.ipcRenderer.invoke(IPC_EVENTS.SCRIPT_RECORD_START, url), + stopRecording: () => electron.ipcRenderer.invoke(IPC_EVENTS.SCRIPT_RECORD_STOP), + codegen: (id, url) => electron.ipcRenderer.invoke(IPC_EVENTS.SCRIPT_CODEGEN, id, url) + } +}; +electron.contextBridge.exposeInMainWorld("api", api); diff --git a/dist/index.html b/dist/index.html index 96432eb..a7a7ccb 100644 --- a/dist/index.html +++ b/dist/index.html @@ -8,7 +8,7 @@ http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: http://8.138.234.141 https://one-feel-bucket.oss-cn-guangzhou.aliyuncs.com; connect-src 'self' http://8.138.234.141 https://api.iconify.design wss://onefeel.brother7.cn" /> - +
diff --git a/src/App.tsx b/src/App.tsx index ed0af8a..99fd971 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,9 +1,12 @@ import { useEffect } from 'react'; import { HashRouter } from 'react-router-dom'; +import { useLocale } from './i18n'; import { AppRouter } from './router'; import { initSettingsStore } from './stores'; export default function App() { + useLocale(); + useEffect(() => { void initSettingsStore(); }, []); diff --git a/src/components/layout/Sidebar.tsx b/src/components/layout/Sidebar.tsx index 506c643..df70ea6 100644 --- a/src/components/layout/Sidebar.tsx +++ b/src/components/layout/Sidebar.tsx @@ -1,5 +1,6 @@ import { useLocation, useNavigate } from 'react-router-dom'; import { Book, Clock, Code, Cpu, House, Puzzle, Settings } from 'lucide-react'; +import { useI18n } from '../../i18n'; import { NAV_ITEMS, normalizeWorkspacePath } from '../../router/routes'; const MENU_MARKS: Record