mirror of
https://github.com/DayuanJiang/next-ai-draw-io.git
synced 2026-01-02 14:22:28 +08:00
* feat(electron): add desktop application support with electron - implement complete Electron main process architecture with window management, app menu, IPC handlers, and settings window - integrate Next.js server for production builds with embedded standalone server - add configuration management with persistent storage and env file support - create preload scripts with secure context bridge for renderer communication - set up electron-builder configuration for multi-platform packaging (macOS, Windows, Linux) - add GitHub Actions workflow for automated release builds - include development scripts for hot-reload during Electron development * feat(electron): enhance security and stability - encrypt API keys using Electron safeStorage API before persisting to disk - add error handling and rollback for preset switching failures - extract inline styles to external CSS file and remove unsafe-inline from CSP - implement dynamic port allocation with automatic fallback for production builds * fix(electron): add maintainer field for Linux .deb package - add maintainer email to linux configuration in electron-builder.yml - required for building .deb packages * fix(electron): use shx for cross-platform file copying - replace Unix-only cp -r with npx shx cp -r - add shx as devDependency for Windows compatibility * fix(electron): fix runtime icon path for all platforms - use icon.png directly instead of platform-specific formats - electron-builder handles icon conversion during packaging - macOS uses embedded icon from app bundle, no explicit path needed - add icon.png to extraResources for Windows/Linux runtime access * fix(electron): add security warning for plaintext API key storage - warn user when safeStorage is unavailable (Linux without keyring) - fail secure: throw error if encryption fails instead of storing plaintext - prevent duplicate warnings with hasWarnedAboutPlaintext flag * fix(electron): add remaining review fixes - Add Windows ARM64 architecture support - Add IPC input validation with config key whitelist - Add server.js existence check before starting Next.js server - Make afterPack throw error on missing directories - Add workflow permissions for release job --------- Co-authored-by: dayuan.jiang <jdy.toh@gmail.com>
85 lines
2.2 KiB
TypeScript
85 lines
2.2 KiB
TypeScript
import path from "node:path"
|
|
import { app, BrowserWindow, screen } from "electron"
|
|
|
|
let mainWindow: BrowserWindow | null = null
|
|
|
|
/**
|
|
* Get the icon path based on platform
|
|
* Note: electron-builder converts icon.png during packaging,
|
|
* but at runtime we use PNG directly - Electron handles it
|
|
*/
|
|
function getIconPath(): string | undefined {
|
|
// macOS doesn't need explicit icon - it's embedded in the app bundle
|
|
if (process.platform === "darwin" && app.isPackaged) {
|
|
return undefined
|
|
}
|
|
|
|
const iconName = "icon.png"
|
|
|
|
if (app.isPackaged) {
|
|
return path.join(process.resourcesPath, iconName)
|
|
}
|
|
|
|
// Development: use icon.png from resources
|
|
return path.join(__dirname, "../../resources/icon.png")
|
|
}
|
|
|
|
/**
|
|
* Create the main application window
|
|
*/
|
|
export function createWindow(serverUrl: string): BrowserWindow {
|
|
const { width, height } = screen.getPrimaryDisplay().workAreaSize
|
|
|
|
mainWindow = new BrowserWindow({
|
|
width: Math.min(1400, Math.floor(width * 0.9)),
|
|
height: Math.min(900, Math.floor(height * 0.9)),
|
|
minWidth: 800,
|
|
minHeight: 600,
|
|
title: "Next AI Draw.io",
|
|
icon: getIconPath(),
|
|
show: false, // Don't show until ready
|
|
webPreferences: {
|
|
preload: path.join(__dirname, "../preload/index.js"),
|
|
contextIsolation: true,
|
|
nodeIntegration: false,
|
|
sandbox: true,
|
|
webSecurity: true,
|
|
},
|
|
})
|
|
|
|
// Load the Next.js application
|
|
mainWindow.loadURL(serverUrl)
|
|
|
|
// Show window when ready to prevent flashing
|
|
mainWindow.once("ready-to-show", () => {
|
|
mainWindow?.show()
|
|
})
|
|
|
|
// Open DevTools in development
|
|
if (process.env.NODE_ENV === "development") {
|
|
mainWindow.webContents.openDevTools()
|
|
}
|
|
|
|
mainWindow.on("closed", () => {
|
|
mainWindow = null
|
|
})
|
|
|
|
// Handle page title updates
|
|
mainWindow.webContents.on("page-title-updated", (event, title) => {
|
|
if (title && !title.includes("localhost")) {
|
|
mainWindow?.setTitle(title)
|
|
} else {
|
|
event.preventDefault()
|
|
}
|
|
})
|
|
|
|
return mainWindow
|
|
}
|
|
|
|
/**
|
|
* Get the main window instance
|
|
*/
|
|
export function getMainWindow(): BrowserWindow | null {
|
|
return mainWindow
|
|
}
|