Skip to content

fix(tray): emit config-changed on auth_lost so Paired-as UI updates#137

Merged
ntatschner merged 1 commit into
nextfrom
fix/sync-paused-emit-config-changed
May 30, 2026
Merged

fix(tray): emit config-changed on auth_lost so Paired-as UI updates#137
ntatschner merged 1 commit into
nextfrom
fix/sync-paused-emit-config-changed

Conversation

@ntatschner
Copy link
Copy Markdown
Collaborator

Summary

Follow-up to PR #132. Surfaced today on the live tray-v1.8.12 build: when the tray actually hits a real device-revoke 401, clear_persisted_device_token blanks access_token + claimed_handle on disk, but no config-changed is emitted. React state stays at the old paired values, so the SettingsPane's "Paired as TheCodeSaiyan" card stays mounted even though the health pill correctly flips to PAUSED. User has to click Unpair manually before they can enter a fresh pairing code.

Fix: after emitting sync-paused in spawn_lane's auth_lost branch, also config::load() the cleared config and emit config-changed. App.tsx's existing listener propagates the empty remote_sync block down to SettingsPane → isPaired flips false → pair-code input replaces the "Paired as" card. No manual Unpair click needed.

Test plan

  • cargo test -p starstats-client --bin starstats-client → 210 passed.
  • cargo fmt -p starstats-client --check clean.
  • cargo clippy -p starstats-client --bin starstats-client --tests -- -D warnings clean.
  • Manual on the released alpha: pair a device, then revoke it server-side. Expect: health pill flips to PAUSED and "Paired as" card transitions to the "enter code" input automatically, without an Unpair click.

Compatibility

No API contract change. The emit re-publishes whatever is currently on disk; React's existing config-changed listener handles it identically to any other config update.

Related

After a real device-revoke 401, `clear_persisted_device_token` (in
the drain_lane / fetch_me_check paths) blanks `access_token` and
`claimed_handle` on disk. The sync worker then sees `auth_lost=true`
on its next iteration, exits, and emits `sync-paused` — which the
Settings pane uses to flip the health pill to PAUSED.

What was missing: a `config-changed` emit. The React-side config
state stays at whatever `setConfig(...)` last received, so even
though disk says "unpaired", the SettingsPane reads `isPaired =
!!access_token && !!claimed_handle` from React state and keeps the
"Paired as TheCodeSaiyan" card mounted. The user had to click
Unpair manually to force a refresh before they could enter a fresh
pairing code.

Now: after emitting `sync-paused`, also `config::load()` the
freshly-cleared config and emit `config-changed`. App.tsx's
existing listener (`setConfig(e.payload)`) propagates the empty
remote_sync block down to SettingsPane, which naturally transitions
from the "Paired as" card to the "enter pairing code" input.

Surfaced 2026-05-29 on the live `tray-v1.8.12` build (PR #132
shipped today). User test confirmed PAUSED state fires correctly
but the pair UI didn't transition without manual Unpair.

`clear_persisted_device_token` itself doesn't emit because it's
called from drain_lane / fetch_me_check contexts without
`AppHandle` in scope. Plumbing the handle through would touch every
caller; the simpler move is to make the spawn_lane auth_lost branch
(which already has the handle) responsible for the user-visible
emit. No tests added — the existing fixture surface doesn't reach
the spawn_lane loop, and the emit itself is unit-untestable without
mocking Tauri's event bus. The change is exercised end-to-end on
the next user-facing repro.
@ntatschner ntatschner merged commit 3efae51 into next May 30, 2026
11 checks passed
@ntatschner ntatschner deleted the fix/sync-paused-emit-config-changed branch May 30, 2026 03:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant