diff --git a/main.js b/main.js index 80f428c..f759b3f 100644 --- a/main.js +++ b/main.js @@ -4,7 +4,7 @@ const path = require('path'); const packageJson = require('./package.json'); const updateState = { - status: 'idle', // idle | checking | available | downloading | downloaded | not-available | error + status: 'idle', // idle | checking | available | downloading | downloaded | installing | not-available | error info: null, error: null, }; @@ -24,6 +24,7 @@ function isNewerVersionAvailable(info) { } let updateCheckInProgress = false; +let installInProgress = false; function resolveBackendUrl() { const configuredUrl = (process.env.CHATTZ_URL || process.env.APP_BASE_URL || '').trim(); @@ -49,6 +50,10 @@ function webContentsOrigin(webContents) { } async function runUpdateCheck(reason = 'manual') { + if (installInProgress) { + console.log(`Update check skipped (${reason}): install already in progress`); + return; + } if (updateCheckInProgress) { console.log(`Update check skipped (${reason}): another check is already in progress`); return; @@ -78,6 +83,47 @@ async function runUpdateCheck(reason = 'manual') { } } +function installDownloadedUpdate() { + if (installInProgress) { + console.log('Update install already in progress'); + return; + } + + installInProgress = true; + updateState.status = 'installing'; + updateState.error = null; + broadcastUpdateState(); + + const wins = BrowserWindow.getAllWindows(); + for (const win of wins) { + if (win.isDestroyed()) continue; + try { + win.removeAllListeners('close'); + win.destroy(); + } catch (err) { + console.warn('Failed to destroy window before update install', err); + } + } + + setImmediate(() => { + try { + autoUpdater.quitAndInstall(false, true); + } catch (err) { + installInProgress = false; + updateState.status = 'error'; + updateState.error = err && err.message ? err.message : String(err); + broadcastUpdateState(); + console.error('quitAndInstall failed', err); + } + }); + + setTimeout(() => { + if (installInProgress) { + console.warn('Update install is still waiting for app shutdown'); + } + }, 15000); +} + function createWindow() { const sess = session.fromPartition('persist:chattz'); const backendUrl = resolveBackendUrl(); @@ -209,6 +255,7 @@ app.whenReady().then(() => { }); ipcMain.on('download-update', () => { + if (installInProgress) return; updateState.status = 'downloading'; updateState.error = null; broadcastUpdateState(); @@ -216,7 +263,7 @@ app.whenReady().then(() => { }); ipcMain.on('quit-and-install', () => { - autoUpdater.quitAndInstall(); + installDownloadedUpdate(); }); // Check once on startup