feat: add auto-update functionality with settings UI

- Implement electron-updater integration with IPC handlers for update operations
- Add Pinia store for managing update state and user preferences
- Create settings UI with version display, update controls, and auto-update toggles
- Update IPC constants and preload API for update-related communication
- Refactor preload invoke methods to use async IPC consistently
- Add rounded corners to settings page layout for better visual consistency
This commit is contained in:
DEV_DSW
2026-04-09 15:15:23 +08:00
parent a8bfbff0e9
commit 1aa28a7808
10 changed files with 411 additions and 96 deletions

View File

@@ -14,6 +14,7 @@ const http = require("http");
const child_process = require("child_process");
const events = require("events");
require("bytenode");
const electronUpdater = require("electron-updater");
function _interopNamespaceDefault(e) {
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
if (e) {
@@ -78,6 +79,11 @@ var IPC_EVENTS = /* @__PURE__ */ ((IPC_EVENTS2) => {
IPC_EVENTS2["THEME_MODE_UPDATED"] = "theme-mode-updated";
IPC_EVENTS2["EXECUTE_SCRIPT"] = "execute-script";
IPC_EVENTS2["OPEN_CHANNEL"] = "open-channel";
IPC_EVENTS2["UPDATE_CHECK"] = "update:check";
IPC_EVENTS2["UPDATE_DOWNLOAD"] = "update:download";
IPC_EVENTS2["UPDATE_INSTALL"] = "update:install";
IPC_EVENTS2["UPDATE_VERSION"] = "update:version";
IPC_EVENTS2["UPDATE_STATUS_CHANGED"] = "update:status-changed";
return IPC_EVENTS2;
})(IPC_EVENTS || {});
const MAIN_WIN_SIZE = {
@@ -101,6 +107,8 @@ var CONFIG_KEYS = /* @__PURE__ */ ((CONFIG_KEYS2) => {
CONFIG_KEYS2["MINIMIZE_TO_TRAY"] = "minimizeToTray";
CONFIG_KEYS2["PROVIDER"] = "provider";
CONFIG_KEYS2["DEFAULT_MODEL"] = "defaultModel";
CONFIG_KEYS2["AUTO_CHECK_UPDATE"] = "autoCheckUpdate";
CONFIG_KEYS2["AUTO_DOWNLOAD_UPDATE"] = "autoDownloadUpdate";
return CONFIG_KEYS2;
})(CONFIG_KEYS || {});
var MENU_IDS = /* @__PURE__ */ ((MENU_IDS2) => {
@@ -1548,6 +1556,74 @@ function runTaskOperationService() {
}
});
}
class AppUpdater {
mainWindow = null;
static _instance;
_initialized = false;
constructor() {
electronUpdater.autoUpdater.autoDownload = false;
}
init() {
if (this._initialized) return;
this._initialized = true;
this.setupListeners();
this.registerHandlers();
}
static getInstance() {
if (!this._instance) {
this._instance = new AppUpdater();
}
return this._instance;
}
setMainWindow(window2) {
this.mainWindow = window2;
}
setupListeners() {
electronUpdater.autoUpdater.on("checking-for-update", () => this.sendToRenderer(IPC_EVENTS.UPDATE_STATUS_CHANGED, { status: "checking" }));
electronUpdater.autoUpdater.on("update-available", (info) => this.sendToRenderer(IPC_EVENTS.UPDATE_STATUS_CHANGED, { status: "available", info }));
electronUpdater.autoUpdater.on("update-not-available", () => this.sendToRenderer(IPC_EVENTS.UPDATE_STATUS_CHANGED, { status: "not-available" }));
electronUpdater.autoUpdater.on("download-progress", (progress) => this.sendToRenderer(IPC_EVENTS.UPDATE_STATUS_CHANGED, { status: "downloading", progress }));
electronUpdater.autoUpdater.on("update-downloaded", (info) => this.sendToRenderer(IPC_EVENTS.UPDATE_STATUS_CHANGED, { status: "downloaded", info }));
electronUpdater.autoUpdater.on("error", (error) => this.sendToRenderer(IPC_EVENTS.UPDATE_STATUS_CHANGED, { status: "error", error: error.message }));
}
sendToRenderer(channel, data) {
electron.BrowserWindow.getAllWindows().forEach((win) => {
if (!win.isDestroyed()) {
win.webContents.send(channel, data);
}
});
}
registerHandlers() {
electron.ipcMain.handle(IPC_EVENTS.UPDATE_CHECK, () => {
if (electron.app.isPackaged) {
return electronUpdater.autoUpdater.checkForUpdates();
} else {
this.sendToRenderer(IPC_EVENTS.UPDATE_STATUS_CHANGED, { status: "checking" });
setTimeout(() => {
this.sendToRenderer(IPC_EVENTS.UPDATE_STATUS_CHANGED, { status: "not-available" });
}, 1500);
return null;
}
});
electron.ipcMain.handle(IPC_EVENTS.UPDATE_DOWNLOAD, () => {
if (electron.app.isPackaged) {
return electronUpdater.autoUpdater.downloadUpdate();
}
return null;
});
electron.ipcMain.handle(IPC_EVENTS.UPDATE_INSTALL, () => {
if (electron.app.isPackaged) {
return electronUpdater.autoUpdater.quitAndInstall();
}
return null;
});
electron.ipcMain.handle(IPC_EVENTS.UPDATE_VERSION, () => {
return electron.app.getVersion();
});
}
}
const appUpdater = AppUpdater.getInstance();
appUpdater.init();
if (started) {
electron.app.quit();
}