desktop: v0.1.19 — reliable auto-update for close-to-tray users

The app closes to tray, so it kept running on the old version and only checked on a fresh launch.
Now: (1) check for updates on EVERY window show (X-to-tray then reopen, taskbar, relaunch via
second-instance) via win.on('show'), throttled 1/10min; (2) explicit autoInstallOnAppQuit=true so
a downloaded update installs on the next real quit / PC restart even if the user never clicks
"Restart now"; (3) native notification when an update finishes downloading while hidden in the
tray. The existing 6-hour background timer is unchanged and still runs regardless of window state.
Also carries the 0.1.18 downloads-to-Downloads-folder change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-19 15:38:01 +05:30
parent 3f44e2b285
commit 30eaf37773
2 changed files with 30 additions and 5 deletions
+29 -4
View File
@@ -35,6 +35,19 @@ ipcMain.on('get-install-info', (e) => {
// on the next restart. No-op in dev (unpackaged).
let autoUpdater = null;
try { ({ autoUpdater } = require('electron-updater')); } catch (_) { /* not installed in dev */ }
let _lastUpdateCheck = 0;
// Background update check — called on launch, on a timer, AND whenever the window is revealed from the tray
// (so re-opening the app actually looks for a new version instead of waiting up to 6h). Throttled so rapid
// tray open/close doesn't spam the feed. Combined with autoInstallOnAppQuit=true (set in whenReady), a
// downloaded update installs the next time the app truly quits — e.g. a normal PC restart — so close-to-tray
// users get updated even if they never pick "Quit" from the tray icon.
function bgUpdateCheck() {
if (!app.isPackaged || !autoUpdater) return;
const now = Date.now();
if (now - _lastUpdateCheck < 10 * 60 * 1000) return; // at most once / 10 min
_lastUpdateCheck = now;
autoUpdater.checkForUpdates().catch(() => {});
}
// #12: manual "Check for updates" from Settings. Returns the current status; the background updater
// (configured in app.whenReady) downloads and prompts to restart when a build is ready.
ipcMain.handle('check-updates', async () => {
@@ -268,6 +281,10 @@ function createWindow() {
const reveal = () => { closeSplash(); if (win && !win.isVisible()) { win.show(); win.focus(); } };
win.once('ready-to-show', reveal);
setTimeout(reveal, 12000);
// Every time the window is shown — X-to-tray then reopened, taskbar click, relaunch (second-instance),
// tray icon — check for a new version. This is the catch-all that covers ALL reveal paths (closing the
// window with the X and opening it again included), not just minimize/restore. Throttled to 1/10 min.
win.on('show', () => bgUpdateCheck());
// The menu bar is hidden, so the usual reload accelerators don't exist — wire them by hand. Without
// these there was literally no way to force the app off a stale page.
@@ -481,13 +498,21 @@ app.whenReady().then(() => {
// When an update finishes downloading, tell the web UI so it can show a BRANDED "Update ready —
// Restart now" banner (restartToUpdate IPC does the install). No native dialog — that was
// unbranded. It still installs on next launch if the user never clicks Restart.
autoUpdater.on('update-downloaded', (info) => sendUpdate({ phase: 'ready', version: info && info.version }));
autoUpdater.on('update-downloaded', (info) => {
sendUpdate({ phase: 'ready', version: info && info.version });
// If the window is hidden in the tray, the branded in-app banner isn't visible — nudge with a native
// notification so tray users know an update is waiting (it also installs automatically on next quit).
try { if ((!win || !win.isVisible()) && Notification.isSupported()) new Notification({ title: 'Biz Connect update ready', body: 'Version ' + ((info && info.version) || '') + ' installs when you restart. Open Biz Connect to restart now.' }).show(); } catch (_) {}
});
// Install a downloaded update on the next real quit (PC restart / tray-Quit) even if the user never
// clicks "Restart now" — so close-to-tray users don't get stuck on an old version. (This is the
// electron-updater default; set explicitly to be safe.)
autoUpdater.autoInstallOnAppQuit = true;
// checkForUpdates (NOT ...AndNotify): ...AndNotify pops electron-updater's OWN native "Update ready
// — Restart/Later" toast on download, which duplicated our branded in-app banner (the user saw TWO
// restart prompts). Plain checkForUpdates still auto-downloads and fires 'update-downloaded'.
const check = () => autoUpdater.checkForUpdates().catch(() => {});
check();
setInterval(check, 6 * 60 * 60 * 1000);
bgUpdateCheck();
setInterval(bgUpdateCheck, 6 * 60 * 60 * 1000);
}
});
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "biz-connect-desktop",
"version": "0.1.18",
"version": "0.1.19",
"description": "Biz Connect technician desktop client — loads the Connect web UI with native screen capture",
"author": {
"name": "BizGaze",