Files
lyroc/electron-app/main.js
2025-11-05 14:24:15 +08:00

212 lines
6.0 KiB
JavaScript

/**
* 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("second-instance", (event, commandLine, workingDirectory) => {
// 当尝试启动第二个实例时,让主窗口获得焦点
const mainWindow = windowManager.mainWindow();
if (mainWindow) {
if (mainWindow.isMinimized()) mainWindow.restore();
mainWindow.focus();
console.log("已有实例在运行,已将其窗口聚焦");
}
});