feat: TypeScript + Electron v2 重构 - 纯桌面版
- 全面迁移到 TypeScript,严格类型定义 - 放弃 Web 版,专注 Electron 桌面应用 - 主进程模块化:main.ts, preload.ts, menu.ts, tray.ts, ipc.ts, utils.ts - 渲染进程完整迁移所有功能组件 - 删除 PWA 相关文件 (sw.js, manifest.json) - 删除 Web 版降级逻辑 - 保留所有核心功能:流式对话、多模型、Think推理、多模态、RAG知识库、Agent预设、历史管理 - 保留 Windows 11 Fluent Design 暗色主题样式
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Metona Ollama Desktop - IPC 处理器
|
||||
*/
|
||||
|
||||
import { ipcMain, dialog, shell } from 'electron';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { mainWindow } from './main.js';
|
||||
import { showNotification } from './utils.js';
|
||||
|
||||
export function setupIPC(): void {
|
||||
ipcMain.handle('dialog:openFile', async (_, options?: { filters?: Array<{ name: string; extensions: string[] }> }) => {
|
||||
const result = await dialog.showOpenDialog(mainWindow!, {
|
||||
properties: ['openFile', 'multiSelections'],
|
||||
filters: options?.filters || [{ name: '所有文件', extensions: ['*'] }]
|
||||
});
|
||||
if (result.canceled) return null;
|
||||
return result.filePaths;
|
||||
});
|
||||
|
||||
ipcMain.handle('dialog:saveFile', async (_, options?: { defaultPath?: string; filters?: Array<{ name: string; extensions: string[] }> }) => {
|
||||
const result = await dialog.showSaveDialog(mainWindow!, {
|
||||
defaultPath: options?.defaultPath || 'export',
|
||||
filters: options?.filters || [{ name: '所有文件', extensions: ['*'] }]
|
||||
});
|
||||
if (result.canceled) return null;
|
||||
return result.filePath;
|
||||
});
|
||||
|
||||
ipcMain.handle('fs:readFile', async (_, filePath: string) => {
|
||||
try {
|
||||
const content = await fs.promises.readFile(filePath, 'utf-8');
|
||||
return { success: true, content, name: path.basename(filePath) };
|
||||
} catch (err) {
|
||||
return { success: false, error: (err as Error).message };
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle('fs:writeFile', async (_, filePath: string, content: string) => {
|
||||
try {
|
||||
await fs.promises.writeFile(filePath, content, 'utf-8');
|
||||
return { success: true };
|
||||
} catch (err) {
|
||||
return { success: false, error: (err as Error).message };
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle('notify', (_: unknown, title: string, body: string) => {
|
||||
showNotification(title, body);
|
||||
});
|
||||
|
||||
ipcMain.handle('app:info', () => ({
|
||||
version: require('electron').app.getVersion(),
|
||||
platform: process.platform,
|
||||
arch: process.arch,
|
||||
electronVersion: process.versions.electron,
|
||||
userDataPath: require('electron').app.getPath('userData')
|
||||
}));
|
||||
|
||||
ipcMain.handle('window:minimize', () => mainWindow?.minimize());
|
||||
ipcMain.handle('window:maximize', () => {
|
||||
if (mainWindow?.isMaximized()) mainWindow.unmaximize();
|
||||
else mainWindow?.maximize();
|
||||
});
|
||||
ipcMain.handle('window:close', () => mainWindow?.close());
|
||||
|
||||
ipcMain.handle('shell:openExternal', (_, url: string) => {
|
||||
if (url.startsWith('http://') || url.startsWith('https://') || url.startsWith('mailto:')) {
|
||||
shell.openExternal(url);
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user