Skip to content

feature: flash the browser tab for match found, calls, chat and notifications - #625

Merged
lukepolo merged 5 commits into
mainfrom
feature/tab-flash
Sep 29, 2026
Merged

lukepolo merged 5 commits into
mainfrom
feature/tab-flash

Conversation

@lukepolo

@lukepolo lukepolo commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Flashes the browser tab's title and icon while it is hidden for a match found, an organizer call, new chat or a new personal alert, and stops as soon as the tab is looked at.

  • useTabFlash: per-kind counts driven by page visibility and deduped by id; the title alternates (N) <text> (localized, steady under reduced motion) and adopts unhead's title; the favicon gets a red count dot, stays title-only when a branded icon can't be drawn, and retries a failed draw after a minute
  • Sources: the matchmaking confirmation and the bell (plugin), lobby:chat and direct:incoming, and the camera page's talkback; skips your own messages, in-game relayed lines (source: "game"), match rooms, the chat pop-out, and store alerts in layout-less pop-outs
  • Bell: new NotificationStore.unreadPersonalAlertCount counts unread personal rows once (no invite double count, no staff rows), baselined on hide or on the subscription's first delivery
  • Settings → Notifications → Browser tab: per-device toggles in localStorage, all on by default
  • Never touches the app badge

Merge/deploy: standalone; best after #607 and #623 (no conflicts with either).

Tests: the bell double count, a stale icon landing after the flash stopped, 5stack's icon on a brand, the failed-icon retry, flashes for in-game lines, first-load bell alerts, store alerts in pop-outs, and a talkback that connects after the page is gone all fail without the fix. Not covered: a DM visible in the chat pop-out still counts in the hidden main tab (needs a BroadcastChannel). Based on DEAFCS ecb4414

…ications

While the 5stack tab is hidden, a match found, an organizer calling on the
camera page, a new chat message or a new bell notification flashes the
title as "(N) <text>" and swaps the favicon for the branded icon with a red
count dot. Looking at the tab again stops it and restores both.

- useTabFlash: per-kind counts, keyed dedupe, unhead-safe title handling
- tab-flash plugin: match confirmation + bell (only what arrives after the
  tab was hidden), skipped in the chat pop-out
- chat hooks in useChatTabSetup / useIncomingDirectMessages, call hook in
  useCameraTalkback
- useBranding: faviconOverride + brandedFaviconHref so a flash and a
  branding change can't clobber each other
- per-device toggles under Settings > Notifications > Browser tab
Chat signals dedupe on the message id, as #607's unread counting does,
and the organizer-call signal moves from join() to poll(), so both open
PRs merge without conflicts.
- Bell flashes count unread personal rows (invites, news and league
  scheduling each insert one), so one invite no longer reads as two and
  staff-only infrastructure rows don't flash.
- The bell baseline waits for the notifications subscription's first
  delivery instead of a 10s settle window.
- Layout-less windows the app opens (camera, replay, stream deck, match
  and file pop-outs) keep their own organizer-call signal but leave the
  store-driven alerts to the main window.
- A branded icon that can't be drawn stays title-only instead of showing
  5stack's icon; a failed draw is retried after a minute.
- A talkback join that lands after the camera page is gone no longer
  signals.
In-game say_team lines are about to be relayed into match_team rooms, so a
chat signal now skips any message with source "game", in any room. Match
rooms stay left out entirely for APIs whose messages carry no source.
@lukepolo
lukepolo merged commit e6bc6df into main Sep 29, 2026
2 checks passed
@lukepolo
lukepolo deleted the feature/tab-flash branch September 29, 2026 01:01
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