import electron from 'electron'; import path from 'path'; import fs from 'fs'; const { contextBridge, ipcRenderer } = electron; const MIME_MAP: Record = { '.png': 'image/png', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.webp': 'image/webp', '.gif': 'image/gif', '.bmp': 'image/bmp', }; function getFileAsDataUrl(filePath: string): string | null { try { const buffer = fs.readFileSync(filePath); const ext = path.extname(filePath).toLowerCase(); const mime = MIME_MAP[ext] || 'image/png'; return `data:${mime};base64,${buffer.toString('base64')}`; } catch { return null; } } contextBridge.exposeInMainWorld('electronAPI', { // Generic IPC invoke: (channel: string, ...args: unknown[]) => ipcRenderer.invoke(channel, ...args), on: (channel: string, callback: (...args: unknown[]) => void) => { const handler = (_event: Electron.IpcRendererEvent, ...args: unknown[]) => callback(...args); ipcRenderer.on(channel, handler); return () => ipcRenderer.removeListener(channel, handler); }, send: (channel: string, ...args: unknown[]) => ipcRenderer.send(channel, ...args), // Window controls minimize: () => ipcRenderer.invoke('window:minimize'), maximize: () => ipcRenderer.invoke('window:maximize'), close: () => ipcRenderer.invoke('window:close'), isMaximized: () => ipcRenderer.invoke('window:isMaximized'), onResized: (callback: () => void) => { const handler = () => callback(); ipcRenderer.on('window:resized', handler); return () => ipcRenderer.removeListener('window:resized', handler); }, // Theme getTheme: () => ipcRenderer.invoke('window:getTheme'), // Background image — pick file, copy to userData, return base64 data URL pickBackgroundImage: async (): Promise => { const result = await ipcRenderer.invoke('dialog:openFile', { filters: [{ name: '图片', extensions: ['png', 'jpg', 'jpeg', 'webp', 'gif', 'bmp'] }], }); if (!result) return null; const { srcPath, ext } = result as { srcPath: string; ext: string }; // Copy to userData via main process const destPath = await ipcRenderer.invoke('background:copyToUserData', srcPath, ext); if (!destPath) return null; return getFileAsDataUrl(destPath); }, // Get cached background as base64 data URL getBackgroundDataUrl: async (): Promise => { const filePath = await ipcRenderer.invoke('background:getCachedPath'); if (!filePath) return null; return getFileAsDataUrl(filePath); }, // Open external URL in system browser openExternal: (url: string) => ipcRenderer.invoke('shell:openExternal', url), });