Skip to content

fix: stop syncing banner flashing purple over the nav bar - #278

Merged
brianorwhatever merged 1 commit into
mainfrom
fix/purple-sync-banner-flash
Oct 7, 2026
Merged

brianorwhatever merged 1 commit into
mainfrom
fix/purple-sync-banner-flash

Conversation

@brianorwhatever

Copy link
Copy Markdown
Contributor

Problem

A purple bar flashed over the nav bar from time to time. It was the OfflineIndicator "Syncing…" banner. It shows as violet because src/index.css remaps the amber-* colors to violet.

offlineObserver starts a background sync every 5s. SyncManager.sync announced 'syncing' at the start of every run, even when it had nothing to send. That made the banner appear for a moment on each run.

Fix

  • src/lib/sync.ts: announce 'syncing' only once an operation is actually about to be sent. Edits in conflict, out of retries, or still in backoff no longer trigger it.
  • OfflineIndicator.tsx: also require pendingCount > 0 before showing the syncing banner.

Tests

  • Added 4 cases to scripts/sync-auth.test.mjs. They cover idle polling, already-acknowledged work, and ineligible work (conflict, retries used up, backoff).
  • node --test scripts/sync-auth.test.mjs: 13/13 pass. The 4 new cases fail when run against the old sync.ts.
  • tsc -b passes.
  • Not checked by eye in the running app.

🤖 Generated with Claude Code

The offline observer triggers a sync every 5s. SyncManager announced
'syncing' at the start of every run, even with nothing eligible to send,
so OfflineIndicator briefly rendered its banner (violet via the amber
remap) over the nav bar.

Only announce 'syncing' once an operation is actually being sent, and
require pending changes before showing the banner.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@railway-app

railway-app Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

🚅 Deployed to the boop-pr-278 environment in Friends

Service Status Web Updated
boop ✅ Success (View Logs) Web Oct 7, 2026 at 4:37 am UTC

@railway-app
railway-app Bot temporarily deployed to Friends / boop-pr-278 October 7, 2026 04:34 Destroyed

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

I reviewed the fix that stops the "Syncing…" banner flashing every time the 5s offlineObserver background poll runs.

  • syncing is announced only when there is real work — SyncManager.sync now calls notify({ status: 'syncing' }) once, and only after an operation has passed every eligibility filter (acked, conflict, retries used up, backoff, predecessor-blocked, and a null result from prepareOperationForSync). The call sits right before executeMutation. Idle polls now emit only synced. Polls that find only ineligible work emit only error.
  • OfflineIndicator also checks pendingCount > 0 — this is an extra guard on the syncing banner. Its only effect is to hide the banner when nothing is pending.
  • Regression tests — the new cases compare the exact status sequences with deepEqual, so they fail on the old code, which always emitted syncing first. The ineligible-work cases also check that mutation is never called. node --test scripts/sync-auth.test.mjs passes locally (13/13).

I also checked the other places that read the sync status. useOffline passes the status through for each account. SyncStatus.tsx uses syncing only to disable "Sync now". Neither depends on the old behaviour of announcing syncing at the start of every run.

Pullfrog  | View workflow run | Using claude-opus-5-5 | 𝕏

@brianorwhatever
brianorwhatever merged commit 3225203 into main Oct 7, 2026
10 checks passed

This branch was successfully deployed

No deployments
Friends / boop-pr-278 — 5949e590 Deployed Oct 7, 2026 by railway-app[bot]
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