From 0e10ae9e3558f43496769476269835db4c4f743e Mon Sep 17 00:00:00 2001 From: DEV_DSW <562304744@qq.com> Date: Tue, 21 Apr 2026 11:42:40 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AF=B9=E8=AF=9D=E5=9B=BD=E9=99=85?= =?UTF-8?q?=E5=8C=96=E6=A0=B7=E5=BC=8F=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist-electron/main/main.js | 9 +- dist-electron/preload/preload.js | 138 ++++++++++++++++++++++++++- src/components/chat/ChatComposer.tsx | 22 +++-- src/i18n/messages.ts | 12 +++ 4 files changed, 168 insertions(+), 13 deletions(-) diff --git a/dist-electron/main/main.js b/dist-electron/main/main.js index a8c04dd..a2ff5f7 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-Bm7LE7mJ.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/src/components/chat/ChatComposer.tsx b/src/components/chat/ChatComposer.tsx index 842a1ee..5b19570 100644 --- a/src/components/chat/ChatComposer.tsx +++ b/src/components/chat/ChatComposer.tsx @@ -1,6 +1,7 @@ import { useRef } from 'react'; import { SendHorizontal, Square, X, Paperclip, FileText, Film, Music, FileArchive, File, Loader2, AtSign } from 'lucide-react'; import type { AttachedFileMeta } from '../../shared/chat-model'; +import { useI18n } from '../../i18n'; type ChatComposerProps = { value: string; @@ -28,10 +29,11 @@ export default function ChatComposer({ onDismissError, }: ChatComposerProps) { const fileInputRef = useRef(null); + const { t } = useI18n(); return ( -
-
+
+
{error ? ( @@ -39,14 +41,14 @@ export default function ChatComposer({ {error} {onDismissError ? ( ) : null}
) : null}