import { Menu, app, BrowserWindow, WebContentsView, ipcMain } from "electron"; import { fileURLToPath } from "node:url"; import path from "node:path"; import fs from "node:fs"; const __dirname$1 = path.dirname(fileURLToPath(import.meta.url)); process.env.APP_ROOT = path.join(__dirname$1, ".."); const VITE_DEV_SERVER_URL = process.env["VITE_DEV_SERVER_URL"]; const MAIN_DIST = path.join(process.env.APP_ROOT, "dist-electron"); const RENDERER_DIST = path.join(process.env.APP_ROOT, "dist"); process.env.VITE_PUBLIC = VITE_DEV_SERVER_URL ? path.join(process.env.APP_ROOT, "public") : RENDERER_DIST; let mainWindow; let childView; let isSideOpen = true; let childViewAspectRatio = 0; const SIDE_WIDTH = 250; const EXPAND_VIEW_SIZE = 40; const LOADING_VIEW_WIDTH = 150; const LOADING_VIEW_HEIGHT = 100; function loadWindowPage(window, subPath) { if (VITE_DEV_SERVER_URL) { window.loadURL(VITE_DEV_SERVER_URL + "#" + subPath); } else { window.loadFile(path.join(RENDERER_DIST, "index.html") + "#" + subPath); } } function loadViewUrl(view, subPath) { if (!mainWindow) { return; } if (VITE_DEV_SERVER_URL) { view.webContents.loadURL(VITE_DEV_SERVER_URL + "#" + subPath); } else { view.webContents.loadFile(path.join(RENDERER_DIST, "index.html") + "#" + subPath); } } Menu.setApplicationMenu(null); function createWindow() { mainWindow = new BrowserWindow({ icon: path.join(process.env.VITE_PUBLIC, "icon.ico"), webPreferences: { preload: path.join(__dirname$1, "preload.mjs"), contextIsolation: true, allowRunningInsecureContent: true, partition: "persist:minnan-demo-app" }, width: 1200, height: 800 }); childView = new WebContentsView({ webPreferences: { partition: "persist:minnan-demo-app", allowRunningInsecureContent: true, enableBlinkFeatures: "PasswordManager" } }); const expandButtonView = new WebContentsView({ webPreferences: { preload: path.join(__dirname$1, "preload.mjs"), contextIsolation: true } }); const loadingView = new BrowserWindow({ skipTaskbar: true, width: LOADING_VIEW_WIDTH, height: LOADING_VIEW_HEIGHT, parent: mainWindow, thickFrame: true, titleBarStyle: "hidden", webPreferences: { preload: path.join(__dirname$1, "preload.mjs"), contextIsolation: true } }); mainWindow.contentView.addChildView(childView); mainWindow.contentView.addChildView(expandButtonView); expandButtonView.setVisible(false); childView.webContents.on("did-start-loading", () => { loadingView.show(); }); childView.webContents.on("did-stop-loading", () => { loadingView.hide(); }); childView.webContents.on("did-fail-load", (_, errorCode, errorDescription) => { loadingView.hide(); loadWindowPage(loadingView, "/error?code=" + errorCode + "&message=" + errorDescription); }); function updateChildWindowBounds() { const bounds = mainWindow.getBounds(); expandButtonView.setBounds({ x: 0, y: bounds.height - 100, width: EXPAND_VIEW_SIZE, height: EXPAND_VIEW_SIZE }); loadingView.setBounds({ x: bounds.x + (bounds.width - LOADING_VIEW_WIDTH) / 2, y: bounds.y + (bounds.height - LOADING_VIEW_HEIGHT) / 2, width: LOADING_VIEW_WIDTH, height: LOADING_VIEW_HEIGHT }); if (childViewAspectRatio) { const rect = { x: isSideOpen ? SIDE_WIDTH : 0, y: 0, width: bounds.width - (isSideOpen ? SIDE_WIDTH : 0), height: bounds.height }; const availableRatio = rect.width / rect.height; let childWidth, childHeight; if (availableRatio > childViewAspectRatio) { childHeight = rect.height; childWidth = childHeight * childViewAspectRatio; } else { childWidth = rect.width; childHeight = childWidth / childViewAspectRatio; } const childX = rect.x + (rect.width - childWidth) / 2; const childY = rect.y + (rect.height - childHeight) / 2; childView.setBounds({ x: Math.round(childX), y: Math.round(childY), width: Math.round(childWidth), height: Math.round(childHeight) }); } else { childView.setBounds({ x: isSideOpen ? SIDE_WIDTH : 0, y: 0, width: bounds.width - (isSideOpen ? SIDE_WIDTH : 0), height: bounds.height }); } } loadWindowPage(mainWindow, "/"); loadWindowPage(loadingView, "/loading"); loadViewUrl(childView, "/hello"); loadViewUrl(expandButtonView, "/expand"); updateChildWindowBounds(); mainWindow.on("resize", () => { updateChildWindowBounds(); }); mainWindow.webContents.on("did-finish-load", () => { mainWindow == null ? void 0 : mainWindow.webContents.send("main-process-message", (/* @__PURE__ */ new Date()).toLocaleString()); }); function handleWindowFullScreenKeys(event, input) { if (input.key === "F11" && input.type === "keyDown") { event.preventDefault(); mainWindow == null ? void 0 : mainWindow.setFullScreen(!(mainWindow == null ? void 0 : mainWindow.isFullScreen())); } else if (input.key === "F12" && input.type === "keyDown") { event.preventDefault(); mainWindow == null ? void 0 : mainWindow.webContents.toggleDevTools(); } } mainWindow.webContents.on("before-input-event", (event, input) => { handleWindowFullScreenKeys(event, input); }); childView.webContents.on("before-input-event", (event, input) => { handleWindowFullScreenKeys(event, input); }); ipcMain.on("exit-app", () => { app.quit(); }); ipcMain.on("toggle-fullscreen", (_event, isFullScreen) => { if (mainWindow) { if (isFullScreen) { mainWindow.setFullScreen(true); } else { mainWindow.setFullScreen(false); } } }); ipcMain.on("load-child-url", (_event, url, aspectRatio) => { if (childView) childView.webContents.loadURL(url); childViewAspectRatio = aspectRatio; updateChildWindowBounds(); }); ipcMain.on("toggle-child-side", (_event, value) => { isSideOpen = value; expandButtonView.setVisible(!isSideOpen); mainWindow == null ? void 0 : mainWindow.webContents.send("main-side-state-changed", isSideOpen); updateChildWindowBounds(); }); ipcMain.handle("get-app-path", () => { return app.getAppPath(); }); ipcMain.on("open-window", (_event, url) => { const newWin = new BrowserWindow({ icon: path.join(process.env.VITE_PUBLIC, "icon.ico"), webPreferences: { preload: path.join(__dirname$1, "preload.mjs"), contextIsolation: true, allowRunningInsecureContent: true }, fullscreenable: true, maximizable: true, width: 1200, height: 800 }); newWin.loadURL(url); newWin.maximize(); newWin.webContents.on("before-input-event", (event, input) => { if (input.key === "F11" && input.type === "keyDown") { event.preventDefault(); newWin == null ? void 0 : newWin.setFullScreen(!(newWin == null ? void 0 : newWin.fullScreen)); } else if (input.key === "F12" && input.type === "keyDown") { event.preventDefault(); newWin == null ? void 0 : newWin.webContents.toggleDevTools(); } }); }); ipcMain.handle("load-apps-json", async () => { const appPath = process.cwd(); const appsJsonPath = path.join(appPath, "apps.json"); try { if (fs.existsSync(appsJsonPath)) { const data = fs.readFileSync(appsJsonPath, "utf8"); return JSON.parse(data); } else { const devAppsJsonPath = path.join(process.env.VITE_PUBLIC || "", "apps.json"); if (fs.existsSync(devAppsJsonPath)) { const data = fs.readFileSync(devAppsJsonPath, "utf8"); return JSON.parse(data); } throw new Error("apps.json not found"); } } catch (error) { console.error("Error loading apps.json:", error); throw error; } }); ipcMain.handle("load-default-apps-json", async () => { const devAppsJsonPath = path.join(process.env.VITE_PUBLIC || "", "apps.json"); if (fs.existsSync(devAppsJsonPath)) { const data = fs.readFileSync(devAppsJsonPath, "utf8"); return JSON.parse(data); } throw new Error("apps.json not found"); }); ipcMain.on("show-config", () => { const configWindow = new BrowserWindow({ icon: path.join(process.env.VITE_PUBLIC, "icon.ico"), webPreferences: { preload: path.join(__dirname$1, "preload.mjs"), contextIsolation: true, allowRunningInsecureContent: true }, title: "列表配置", parent: mainWindow || void 0, skipTaskbar: true, minimizable: false, maximizable: false, modal: true, width: 800, height: 600 }); loadWindowPage(configWindow, "/config"); }); ipcMain.on("save-apps-json", (_event, appsJson) => { const appPath = process.cwd(); const appsJsonPath = path.join(appPath, "apps.json"); try { fs.writeFileSync(appsJsonPath, appsJson); mainWindow == null ? void 0 : mainWindow.webContents.send("main-config-changed"); } catch (error) { console.error("Error saving apps.json:", error); throw error; } }); ipcMain.on("show-about", () => { const aboutWindow = new BrowserWindow({ icon: path.join(process.env.VITE_PUBLIC, "icon.ico"), webPreferences: { preload: path.join(__dirname$1, "preload.mjs"), contextIsolation: true, allowRunningInsecureContent: true }, parent: mainWindow || void 0, title: "关于程序", skipTaskbar: true, maximizable: false, minimizable: false, modal: true, width: 450, height: 470 }); loadWindowPage(aboutWindow, "/about"); }); } app.on("window-all-closed", () => { if (process.platform !== "darwin") { app.quit(); mainWindow = null; } }); app.on("activate", () => { if (BrowserWindow.getAllWindows().length === 0) { createWindow(); } }); app.whenReady().then(createWindow); export { MAIN_DIST, RENDERER_DIST, VITE_DEV_SERVER_URL };