Skip to content

fix(web): redesign app update button - #128

Merged
incognitojam merged 1 commit into
mainfrom
t3code/fix-immediate-update-download
Aug 14, 2026
Merged

fix(web): redesign app update button#128
incognitojam merged 1 commit into
mainfrom
t3code/fix-immediate-update-download

Conversation

@incognitojam

@incognitojam incognitojam commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

Background update downloads landed in #110, but the sidebar control still treated downloading as a call to action: it shared the isUpdateState styling branch with the states that want a click, so an automatic download lit the button and its changelog tooltip in update blue while needing no input at all. The downloaded state then offered a circular-arrow icon — the same metaphor this app uses for refresh and retry everywhere else, including the check-for-updates state of this very button.

This splits the tone decision into resolveDesktopUpdateButtonTone ("cta" | "quiet" | "idle"), so call-to-action colour is reserved for states that actually want a click: install, or retry a failed download. The intended flow is now visually staged:

  1. Check for updates in the background (existing pollers, unchanged)
  2. Update available → download starts automatically (feat(desktop): download updates in background #110, unchanged)
  3. Downloading → muted progress ring around a download glyph, no CTA colour
  4. Downloaded → CTA colour with an upward arrow, matching the update glyph in provider settings
Downloading Downloaded — ready to restart
Before Before: downloading rendered as a blue CTA with a spinning refresh icon Before: downloaded rendered as a blue CTA with a circular rotate arrow
After After: downloading rendered as a muted progress ring around a download glyph After: downloaded rendered as a blue CTA with an upward circle arrow

Full motion — indeterminate spin before the first progress event, gliding through the 10% progress broadcasts, then flipping to the CTA on completion:

ring.mp4

Implementation notes:

  • The ring follows the ContextWindowMeter construct (track + dash-offset arc, -rotate-90 transform-gpu, motion-reduce:transition-none), with its stroke transitioned over 500ms so the 10%-step broadcasts from the main process glide instead of jumping.
  • reduceDesktopUpdateStateOnDownloadStart reports downloadPercent: 0 until the first progress event, which would draw a zero-length arc, so 0 renders as an indeterminate spinning arc instead.
  • A manual retry keeps the button natively disabled for the whole download; the quiet branch omits the disabled: dimming so background and manual downloads render identically.
  • The changelog tooltip stays available while downloading, just without the update-tinted glass treatment.
  • Tone is decided in desktopUpdate.logic.ts and covered by tests, so a regression to the always-CTA behaviour would now fail the suite.

Tests:

  • vp test run apps/web/src/components/desktopUpdate.logic.test.ts apps/web/src/state/desktopUpdate.test.ts apps/web/src/components/desktopUpdate.toast.test.tsx apps/desktop/src/updates/DesktopUpdates.test.ts
  • vp run --filter @t3tools/web typecheck
  • Targeted lint for the changed TypeScript files

Written by an agent (T3 Code, claude-fable-5).

@incognitojam
incognitojam force-pushed the t3code/fix-immediate-update-download branch from f4acfb2 to 09509ec Compare August 14, 2026 12:44
@incognitojam
incognitojam enabled auto-merge (squash) August 14, 2026 12:48
@incognitojam
incognitojam disabled auto-merge August 14, 2026 12:52
@incognitojam
incognitojam force-pushed the t3code/fix-immediate-update-download branch from 09509ec to dc9cd78 Compare August 14, 2026 12:53
@incognitojam incognitojam changed the title fix(web): keep the update download quiet until it needs a click fix(web): quiet update downloads, loud restart button Aug 14, 2026
@incognitojam
incognitojam force-pushed the t3code/fix-immediate-update-download branch from dc9cd78 to 15252b5 Compare August 14, 2026 12:54
@incognitojam incognitojam changed the title fix(web): quiet update downloads, loud restart button fix(web): give the update button a progress ring and a restart arrow Aug 14, 2026
Background update downloads landed in #110, but the sidebar control still
treated downloading as a call to action: it shared the `isUpdateState`
branch with the states that want a click, so an automatic download lit the
button and its tooltip in update blue while needing no input at all. The
downloaded state then offered a circular-arrow icon, the same metaphor this
app uses for refresh and retry everywhere else.

Split the tone decision out into `resolveDesktopUpdateButtonTone`, so call-to-
action colour is reserved for states that actually want a click — install, or
retry a failed download. Downloading now renders a muted progress ring around
a download glyph, driven by `downloadPercent`, and the downloaded state uses
an upward arrow, matching the update glyph the provider settings already use.

The main process only broadcasts progress every 10%, so the ring transitions
its stroke to glide between steps, and treats the initial 0 as indeterminate
rather than drawing a zero-length arc for the first tenth of the download. A
manual retry keeps the button natively disabled for the whole download, so
the quiet branch omits the disabled dimming to stop the same state rendering
two different ways.

Tests:

- `vp test run apps/web/src/components/desktopUpdate.logic.test.ts
apps/web/src/state/desktopUpdate.test.ts
apps/web/src/components/desktopUpdate.toast.test.tsx
apps/desktop/src/updates/DesktopUpdates.test.ts`
- `vp run --filter @t3tools/web typecheck`
- Targeted lint for the changed TypeScript files
@incognitojam incognitojam changed the title fix(web): give the update button a progress ring and a restart arrow fix(web): redesign app update button Aug 14, 2026
@incognitojam
incognitojam force-pushed the t3code/fix-immediate-update-download branch from 15252b5 to 7ea0e98 Compare August 14, 2026 12:55
@incognitojam
incognitojam enabled auto-merge (squash) August 14, 2026 12:55
@incognitojam
incognitojam merged commit 4e6c0fa into main Aug 14, 2026
8 checks passed
@incognitojam
incognitojam deleted the t3code/fix-immediate-update-download branch August 14, 2026 13:05
yngatech-nightly Bot pushed a commit that referenced this pull request Aug 14, 2026
Background update downloads landed in #110, but the sidebar control
still treated downloading as a call to action: it shared the
`isUpdateState` styling branch with the states that want a click, so an
automatic download lit the button and its changelog tooltip in update
blue while needing no input at all. The downloaded state then offered a
circular-arrow icon — the same metaphor this app uses for refresh and
retry everywhere else, including the check-for-updates state of this
very button.

This splits the tone decision into `resolveDesktopUpdateButtonTone`
(`"cta" | "quiet" | "idle"`), so call-to-action colour is reserved for
states that actually want a click: install, or retry a failed download.
The intended flow is now visually staged:

1. Check for updates in the background (existing pollers, unchanged)
2. Update available → download starts automatically (#110, unchanged)
3. **Downloading → muted progress ring around a download glyph, no CTA
colour**
4. **Downloaded → CTA colour with an upward arrow, matching the update
glyph in provider settings**

| | Downloading | Downloaded — ready to restart |
| --- | --- | --- |
| Before | ![Before: downloading rendered as a blue CTA with a spinning
refresh
icon](https://raw.githubusercontent.com/yngatech/t3code/assets/pr-update-pill-quiet-download/before-downloading.png)
| ![Before: downloaded rendered as a blue CTA with a circular rotate
arrow](https://raw.githubusercontent.com/yngatech/t3code/assets/pr-update-pill-quiet-download/before-downloaded.png)
|
| After | ![After: downloading rendered as a muted progress ring around
a download
glyph](https://raw.githubusercontent.com/yngatech/t3code/assets/pr-update-pill-quiet-download/after-downloading.png)
| ![After: downloaded rendered as a blue CTA with an upward circle
arrow](https://raw.githubusercontent.com/yngatech/t3code/assets/pr-update-pill-quiet-download/after-downloaded.png)
|

Full motion — indeterminate spin before the first progress event,
gliding through the 10% progress broadcasts, then flipping to the CTA on
completion:

https://github.com/user-attachments/assets/80d64f3c-06d3-4f9e-aace-bfa2e29f1be8

Implementation notes:

- The ring follows the `ContextWindowMeter` construct (track +
dash-offset arc, `-rotate-90 transform-gpu`,
`motion-reduce:transition-none`), with its stroke transitioned over
500ms so the 10%-step broadcasts from the main process glide instead of
jumping.
- `reduceDesktopUpdateStateOnDownloadStart` reports `downloadPercent: 0`
until the first progress event, which would draw a zero-length arc, so
`0` renders as an indeterminate spinning arc instead.
- A manual retry keeps the button natively disabled for the whole
download; the quiet branch omits the `disabled:` dimming so background
and manual downloads render identically.
- The changelog tooltip stays available while downloading, just without
the update-tinted glass treatment.
- Tone is decided in `desktopUpdate.logic.ts` and covered by tests, so a
regression to the always-CTA behaviour would now fail the suite.

Tests:

- `vp test run apps/web/src/components/desktopUpdate.logic.test.ts
apps/web/src/state/desktopUpdate.test.ts
apps/web/src/components/desktopUpdate.toast.test.tsx
apps/desktop/src/updates/DesktopUpdates.test.ts`
- `vp run --filter @t3tools/web typecheck`
- Targeted lint for the changed TypeScript files

---
Written by an agent (T3 Code, claude-fable-5).
incognitojam added a commit that referenced this pull request Aug 15, 2026
Background update downloads landed in #110, but the sidebar control
still treated downloading as a call to action: it shared the
`isUpdateState` styling branch with the states that want a click, so an
automatic download lit the button and its changelog tooltip in update
blue while needing no input at all. The downloaded state then offered a
circular-arrow icon — the same metaphor this app uses for refresh and
retry everywhere else, including the check-for-updates state of this
very button.

This splits the tone decision into `resolveDesktopUpdateButtonTone`
(`"cta" | "quiet" | "idle"`), so call-to-action colour is reserved for
states that actually want a click: install, or retry a failed download.
The intended flow is now visually staged:

1. Check for updates in the background (existing pollers, unchanged)
2. Update available → download starts automatically (#110, unchanged)
3. **Downloading → muted progress ring around a download glyph, no CTA
colour**
4. **Downloaded → CTA colour with an upward arrow, matching the update
glyph in provider settings**

| | Downloading | Downloaded — ready to restart |
| --- | --- | --- |
| Before | ![Before: downloading rendered as a blue CTA with a spinning
refresh
icon](https://raw.githubusercontent.com/yngatech/t3code/assets/pr-update-pill-quiet-download/before-downloading.png)
| ![Before: downloaded rendered as a blue CTA with a circular rotate
arrow](https://raw.githubusercontent.com/yngatech/t3code/assets/pr-update-pill-quiet-download/before-downloaded.png)
|
| After | ![After: downloading rendered as a muted progress ring around
a download
glyph](https://raw.githubusercontent.com/yngatech/t3code/assets/pr-update-pill-quiet-download/after-downloading.png)
| ![After: downloaded rendered as a blue CTA with an upward circle
arrow](https://raw.githubusercontent.com/yngatech/t3code/assets/pr-update-pill-quiet-download/after-downloaded.png)
|

Full motion — indeterminate spin before the first progress event,
gliding through the 10% progress broadcasts, then flipping to the CTA on
completion:

https://github.com/user-attachments/assets/80d64f3c-06d3-4f9e-aace-bfa2e29f1be8

Implementation notes:

- The ring follows the `ContextWindowMeter` construct (track +
dash-offset arc, `-rotate-90 transform-gpu`,
`motion-reduce:transition-none`), with its stroke transitioned over
500ms so the 10%-step broadcasts from the main process glide instead of
jumping.
- `reduceDesktopUpdateStateOnDownloadStart` reports `downloadPercent: 0`
until the first progress event, which would draw a zero-length arc, so
`0` renders as an indeterminate spinning arc instead.
- A manual retry keeps the button natively disabled for the whole
download; the quiet branch omits the `disabled:` dimming so background
and manual downloads render identically.
- The changelog tooltip stays available while downloading, just without
the update-tinted glass treatment.
- Tone is decided in `desktopUpdate.logic.ts` and covered by tests, so a
regression to the always-CTA behaviour would now fail the suite.

Tests:

- `vp test run apps/web/src/components/desktopUpdate.logic.test.ts
apps/web/src/state/desktopUpdate.test.ts
apps/web/src/components/desktopUpdate.toast.test.tsx
apps/desktop/src/updates/DesktopUpdates.test.ts`
- `vp run --filter @t3tools/web typecheck`
- Targeted lint for the changed TypeScript files

---
Written by an agent (T3 Code, claude-fable-5).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant