From 9a4600c5fb9bdd21e5d035181bfc7fbdb9340497 Mon Sep 17 00:00:00 2001 From: Brooklyn Nicholson Date: Wed, 24 Jun 2026 19:20:38 -0500 Subject: [PATCH] fix(desktop): stop the update overlay looking frozen while it works MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two ways the update overlay read as stuck even though the update was streaming progress underneath: - In-app (macOS/Linux) UpdatesOverlay: runStreamedUpdate forwards every stdout line as a progress event with percent: null, and ingestProgress wrote that straight through — clobbering the milestone percents (10/60) so the bar fell back to indeterminate on every log line. Keep the last percent when a line carries null. - Staged install/update overlay: the bar is completedCount / totalCount, which counts only *finished* stages, so a long first stage pinned it at "0 of 2" / 0% until the stage ended. Count the running stage as half a unit so the bar advances during the stage (the per-stage spinner already shows which step is live). Both are display-only; no stage/event semantics change. (The Windows hermes-setup Tauri progress UI in apps/bootstrap-installer has the same counter-only-on-completion logic — parity follow-up.) --- apps/desktop/src/components/desktop-install-overlay.tsx | 6 +++++- apps/desktop/src/store/updates.ts | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/desktop/src/components/desktop-install-overlay.tsx b/apps/desktop/src/components/desktop-install-overlay.tsx index 0213a93b7d2..0341dc5675f 100644 --- a/apps/desktop/src/components/desktop-install-overlay.tsx +++ b/apps/desktop/src/components/desktop-install-overlay.tsx @@ -407,7 +407,11 @@ export function DesktopInstallOverlay({ enabled = true }: DesktopInstallOverlayP const totalCount = stages.length const failed = Boolean(state.error) - const progressPct = totalCount > 0 ? Math.round((completedCount / totalCount) * 100) : 0 + // Count the running stage as half-done so the bar advances *during* a long + // stage instead of sitting frozen at the last completed step while its logs + // stream (e.g. "0 of 2" pinned at 0% for the whole first stage). + const progressUnits = completedCount + (!failed && currentStage ? 0.5 : 0) + const progressPct = totalCount > 0 ? Math.round((progressUnits / totalCount) * 100) : 0 const currentStartedAt = currentStage ? state.stages[currentStage]?.startedAt : null const currentElapsed = typeof currentStartedAt === 'number' ? formatElapsed(now - currentStartedAt) : '' diff --git a/apps/desktop/src/store/updates.ts b/apps/desktop/src/store/updates.ts index 6b6aae9bea1..3297b6e9a90 100644 --- a/apps/desktop/src/store/updates.ts +++ b/apps/desktop/src/store/updates.ts @@ -531,7 +531,9 @@ function ingestProgress(payload: DesktopUpdateProgress): void { applying: !terminal, stage: payload.stage, message: payload.message, - percent: payload.percent, + // Streamed log lines carry percent: null; keep the last milestone percent + // (10/60/…) instead of resetting the bar to indeterminate on every line. + percent: payload.percent ?? current.percent, error: payload.error, // 'manual' carries the command to run in its message field. command: payload.stage === 'manual' ? payload.message : current.command,