Electron 环境下改用系统原生文件夹选择对话框替代自定义 FolderPicker 组件, 浏览器环境保留原有 FolderPicker 作为 fallback(浏览器沙箱无法获取绝对路径)。 - electron/main.ts: 新增 `dialog:open-folder` IPC handler,调用 `dialog.showOpenDialog` 并设置 openDirectory + createDirectory 属性, macOS 下支持在对话框内新建文件夹,对话框模态绑定 mainWindow - electron/preload.ts: 在 electronAPI 中暴露 `dialog.openFolder()` 方法 - src/types/electron.d.ts: 新建全局类型声明,统一定义 window.electronAPI 的完整类型,消除代码中散落的 `(window as any)` 类型断言 - src/hooks/useNativeFolderPicker.ts: 新建 hook 封装平台检测和原生对话框 调用逻辑,返回 isElectron 标志和 openNativePicker 方法 - src/components/layout/ChatListPanel.tsx: 新增 openFolderPicker() 统一入口, Electron 走原生对话框、浏览器走 setFolderPickerOpen(true);替换 handleNewChat 中 4 处及文件夹按钮 onClick 共 5 处调用点; handleFolderSelect 改为 useCallback 并调整声明顺序避免引用前使用; 清理 electronAPI 类型断言 - src/app/chat/[id]/page.tsx: 移除 `window as unknown as ...` 类型断言 - src/components/layout/ConnectionStatus.tsx: 移除 `(window as any)` 断言 - src/components/layout/InstallWizard.tsx: getInstallAPI() 简化为直接返回 window.electronAPI?.install,移除 10 行手动类型定义 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
29 lines
1.1 KiB
TypeScript
29 lines
1.1 KiB
TypeScript
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
const { contextBridge, ipcRenderer } = require('electron');
|
|
|
|
contextBridge.exposeInMainWorld('electronAPI', {
|
|
versions: {
|
|
electron: process.versions.electron,
|
|
node: process.versions.node,
|
|
chrome: process.versions.chrome,
|
|
},
|
|
shell: {
|
|
openPath: (folderPath: string) => ipcRenderer.invoke('shell:open-path', folderPath),
|
|
},
|
|
dialog: {
|
|
openFolder: (options?: { defaultPath?: string; title?: string }) =>
|
|
ipcRenderer.invoke('dialog:open-folder', options),
|
|
},
|
|
install: {
|
|
checkPrerequisites: () => ipcRenderer.invoke('install:check-prerequisites'),
|
|
start: (options?: { includeNode?: boolean }) => ipcRenderer.invoke('install:start', options),
|
|
cancel: () => ipcRenderer.invoke('install:cancel'),
|
|
getLogs: () => ipcRenderer.invoke('install:get-logs'),
|
|
onProgress: (callback: (data: unknown) => void) => {
|
|
const listener = (_event: unknown, data: unknown) => callback(data);
|
|
ipcRenderer.on('install:progress', listener);
|
|
return () => { ipcRenderer.removeListener('install:progress', listener); };
|
|
},
|
|
},
|
|
});
|