mirror of
https://github.com/DayuanJiang/next-ai-draw-io.git
synced 2026-10-12 20:49:53 +08:00
- delete electron/settings, the settings preload and window, the config-presets IPC channels, the Configuration menu and the preset watcher in scripts/electron-dev.mjs; config-manager.ts keeps only the user locale (still read from config-presets.json so the saved language survives) - electron/main/env-loader.ts parses .env with dotenv instead of a hand-written parser; electron:compile bundles dependencies - drop the unreachable development branches in port-manager.ts and next-server.ts, the duplicated locale normalisation in menu-i18n.ts, the unused electronAPI members, resources/entitlements.mac.plist - scripts/copy-dereferenced.cjs shared by afterPack and prepare-electron-build - CI: delete ci.yml, move type check and concurrency into test.yml, Node 24 everywhere, docker-build only on main - remove unused dependencies (@xmldom/xmldom, remark-gfm, @anthropic-ai/tokenizer, @testing-library/user-event, concurrently, wait-on, eslint, eslint-config-next, @vitest/coverage-v8, shx), .eslintrc.json and the vitest coverage block
116 lines
3.7 KiB
TypeScript
116 lines
3.7 KiB
TypeScript
import { app, type IpcMainInvokeEvent, ipcMain } from "electron"
|
|
import { buildAppMenu } from "./app-menu"
|
|
import { setUserLocale, USER_LOCALES, type UserLocale } from "./config-manager"
|
|
import { restartNextServer } from "./next-server"
|
|
import { noteNoChats, rememberChatPort } from "./port-manager"
|
|
import {
|
|
applyProxyToEnv,
|
|
getProxyConfig,
|
|
type ProxyConfig,
|
|
saveProxyConfig,
|
|
} from "./proxy-manager"
|
|
import { isAppUrl } from "./window-manager"
|
|
|
|
/**
|
|
* Register an IPC handler that only answers the app's own pages (on the app
|
|
* server). A main window that somehow ends up on an external site still
|
|
* gets the preload API, so its calls must be rejected here.
|
|
*/
|
|
function handle<Args extends unknown[]>(
|
|
channel: string,
|
|
listener: (event: IpcMainInvokeEvent, ...args: Args) => unknown,
|
|
): void {
|
|
ipcMain.handle(channel, (event, ...args) => {
|
|
const url = event.senderFrame?.url
|
|
if (!isAppUrl(url)) {
|
|
throw new Error(`Blocked "${channel}" from untrusted page: ${url}`)
|
|
}
|
|
return listener(event, ...(args as Args))
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Register all IPC handlers
|
|
*/
|
|
export function registerIpcHandlers(): void {
|
|
// ==================== Where the chats are ====================
|
|
|
|
// The page saved a chat, or loaded without any: decides which port
|
|
// (and so which origin's chats) the next launch opens
|
|
handle("chat-saved", () => rememberChatPort())
|
|
handle("chats-loaded", (_event, count: unknown) => {
|
|
if (count === 0) noteNoChats()
|
|
})
|
|
|
|
// ==================== Proxy Settings ====================
|
|
|
|
handle("get-proxy", () => {
|
|
return getProxyConfig()
|
|
})
|
|
|
|
handle("set-proxy", async (_event, config: ProxyConfig) => {
|
|
const isOptionalString = (value: unknown) =>
|
|
value === undefined || typeof value === "string"
|
|
if (
|
|
typeof config !== "object" ||
|
|
config === null ||
|
|
!isOptionalString(config.httpProxy) ||
|
|
!isOptionalString(config.httpsProxy)
|
|
) {
|
|
return { success: false, error: "Invalid proxy settings" }
|
|
}
|
|
|
|
try {
|
|
// Save config to file
|
|
saveProxyConfig({
|
|
httpProxy: config.httpProxy,
|
|
httpsProxy: config.httpsProxy,
|
|
})
|
|
|
|
// Apply to current process environment
|
|
applyProxyToEnv()
|
|
|
|
if (!app.isPackaged) {
|
|
// In development, env vars are already applied
|
|
// Next.js dev server may need manual restart
|
|
return { success: true }
|
|
}
|
|
|
|
// Production: restart Next.js server to pick up new env vars
|
|
await restartNextServer()
|
|
return { success: true }
|
|
} catch (error) {
|
|
return {
|
|
success: false,
|
|
error:
|
|
error instanceof Error
|
|
? error.message
|
|
: "Failed to apply proxy settings",
|
|
}
|
|
}
|
|
})
|
|
|
|
// ==================== User Locale ====================
|
|
|
|
handle("set-user-locale", (_event, locale: string) => {
|
|
if (!(USER_LOCALES as readonly string[]).includes(locale)) {
|
|
return { success: false, error: "Invalid locale" }
|
|
}
|
|
|
|
try {
|
|
setUserLocale(locale as UserLocale)
|
|
// Rebuild the menu to reflect the new locale
|
|
buildAppMenu()
|
|
return { success: true }
|
|
} catch (error) {
|
|
return {
|
|
success: false,
|
|
error:
|
|
error instanceof Error
|
|
? error.message
|
|
: "Failed to set locale",
|
|
}
|
|
}
|
|
})
|
|
}
|