/** * lyroc 主程序文件 * 使用模块化结构,只负责应用的生命周期管理和组件集成 */ const { app, protocol, ipcMain } = require("electron"); const path = require("path"); const fs = require("fs"); const isDev = require("electron-is-dev"); // 导入自定义模块 const windowManager = require("./modules/window-manager"); const backendService = require("./modules/backend-service"); const logger = require("./modules/logger"); const searchWindowManager = require("./windows/search-window"); // 应用全局状态 global.appReady = false; /** * 初始化应用 */ async function initApp() { try { console.log("初始化应用..."); // 确保只有一个实例在运行 const gotTheLock = app.requestSingleInstanceLock(); if (!gotTheLock) { console.log("另一个实例已经在运行"); app.quit(); return; } // 创建加载窗口 const loadingWindow = windowManager.createLoadingWindow(); windowManager.updateLoadingProgress(10, "initializing"); // 注册文件协议处理器 protocol.registerFileProtocol("file", (request, callback) => { const url = request.url.replace("file://", ""); try { return callback(decodeURIComponent(url)); } catch (error) { console.error("协议处理器错误:", error); } }); // 检查系统环境 console.log("运行模式:", isDev ? "开发" : "生产"); // 清理可能运行的Python进程 await backendService.cleanupExistingProcesses(); // 检查端口可用性 await backendService.checkPort(); windowManager.updateLoadingProgress(30, "allocatingPorts"); // 获取前端随机端口 await backendService.getFrontendPort(); // 启动Deno后端 windowManager.updateLoadingProgress(40, "loadingBackend"); await backendService.startDenoBackend(isDev); // 更新加载进度 windowManager.updateLoadingProgress(60, "loadingFrontend"); // 初始化窗口配置 windowManager.initConfig(app.getPath("userData")); // 创建窗口 windowManager.updateLoadingProgress(70, "connecting"); const mainWindow = windowManager.createWindow( null, backendService.getFrontendPortNumber(), backendService.getBackendPort(), isDev ); // 更新加载进度 windowManager.updateLoadingProgress(80, "connecting"); // 设置窗口事件 windowManager.setupWindowEvents(); // 设置IPC通信 windowManager.setupIPC( backendService.getBackendPort(), backendService.getFrontendPortNumber() ); // 处理搜索窗口相关事件 ipcMain.on("open-search-window", () => { console.log("收到打开搜索窗口请求"); searchWindowManager.createWindow(); }); ipcMain.on("close-search-window", () => { console.log("收到关闭搜索窗口请求"); searchWindowManager.closeWindow(); }); // 处理发送数据到搜索窗口的请求 ipcMain.on("send-to-search-window", (_, data) => { console.log("收到发送到搜索窗口的数据:", data); searchWindowManager.receiveMainWindowData(data); }); // 处理搜索窗口请求主窗口数据 ipcMain.on("request-main-window-data", () => { console.log("收到搜索窗口数据请求"); // 获取主窗口数据并发送 const mainWindow = windowManager.mainWindow(); if (mainWindow && !mainWindow.isDestroyed()) { mainWindow.webContents.send("get-main-window-data"); } }); // 更新加载进度 windowManager.updateLoadingProgress(90, "loadingLyrics"); // 监听主窗口内容加载完成事件 mainWindow.webContents.once("did-finish-load", () => { windowManager.updateLoadingProgress(100, "ready"); // 短暂延迟后关闭加载窗口 setTimeout(() => { // 不需要在这里显示主窗口,动画结束时会自动显示 windowManager.closeLoadingWindow(); }, 500); // 设置应用就绪标志 global.appReady = true; }); } catch (err) { console.error("应用初始化失败:", err); app.quit(); } } // Electron 应用就绪时 app.on("ready", () => { // 设置日志记录 const logPath = logger.setupLogging(app.getPath("userData")); // 添加日志以显示Electron路径 console.log("Electron应用已准备就绪"); console.log("应用路径:", app.getAppPath()); console.log("__dirname:", __dirname); console.log("用户数据路径:", app.getPath("userData")); console.log("日志文件路径:", logPath); // 检查资源路径 const resourcePath = isDev ? path.join(__dirname, "..", "backend") : path.join(process.resourcesPath, "backend"); console.log("后端资源路径:", resourcePath); console.log("该路径存在:", fs.existsSync(resourcePath)); // 隐藏dock栏图标 if (process.platform === "darwin" && app.dock) { app.dock.hide(); console.log("已隐藏Dock图标"); } // 启动应用初始化 initApp() .then(() => { console.log("应用初始化完成"); }) .catch((err) => { console.error("初始化应用失败:", err); }); }); // 所有窗口关闭时退出应用 app.on("window-all-closed", function () { if (process.platform !== "darwin") { app.quit(); } }); // 应用激活时 app.on("activate", function () { if (!windowManager.mainWindow()) { // 初始化窗口配置 windowManager.initConfig(app.getPath("userData")); // 重新创建窗口 const mainWindow = windowManager.createWindow( null, backendService.getFrontendPortNumber(), backendService.getBackendPort(), isDev ); // 设置窗口事件 windowManager.setupWindowEvents(); } }); // 应用退出前 app.on("before-quit", () => { // 清理Python进程 backendService.stopPythonBackend(); }); // 监听第二实例启动事件 app.on("second-instance", (event, commandLine, workingDirectory) => { // 当尝试启动第二个实例时,让主窗口获得焦点 const mainWindow = windowManager.mainWindow(); if (mainWindow) { if (mainWindow.isMinimized()) mainWindow.restore(); mainWindow.focus(); console.log("已有实例在运行,已将其窗口聚焦"); } });