feat(phase1): architecture skeleton
- Electron 33 main process with frameless window, IPC, win-state persistence - Preload with contextBridge typed API (window, theme, dialog) - Vue 3 + Pinia + Element Plus + Vue Router renderer - Dark/light dual theme via CSS custom properties - TitleBar with window controls + theme toggle - StatusBar placeholder - Design spec document
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
// src/main/ipc-handlers.ts
|
||||
import { ipcMain, BrowserWindow, nativeTheme, dialog } from 'electron'
|
||||
|
||||
export function registerIpcHandlers(): void {
|
||||
ipcMain.on('window:minimize', () => {
|
||||
BrowserWindow.getFocusedWindow()?.minimize()
|
||||
})
|
||||
|
||||
ipcMain.on('window:maximize', () => {
|
||||
const win = BrowserWindow.getFocusedWindow()
|
||||
if (win) win.isMaximized() ? win.unmaximize() : win.maximize()
|
||||
})
|
||||
|
||||
ipcMain.on('window:close', () => {
|
||||
BrowserWindow.getFocusedWindow()?.close()
|
||||
})
|
||||
|
||||
ipcMain.handle('theme:get', () => nativeTheme.shouldUseDarkColors)
|
||||
|
||||
ipcMain.on('theme:set', (_event, theme: 'system' | 'dark' | 'light') => {
|
||||
nativeTheme.themeSource = theme
|
||||
})
|
||||
|
||||
ipcMain.handle('dialog:openFile', async (_event, options: Electron.OpenDialogOptions) => {
|
||||
const win = BrowserWindow.getFocusedWindow()
|
||||
if (!win) return null
|
||||
const result = await dialog.showOpenDialog(win, options)
|
||||
if (result.canceled || result.filePaths.length === 0) return null
|
||||
const fs = await import('fs')
|
||||
try {
|
||||
const content = fs.readFileSync(result.filePaths[0], 'utf-8')
|
||||
return { path: result.filePaths[0], content }
|
||||
} catch { return null }
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user