Attention cues review fixes (#238)

- NEW lane: Gate A notice pinned below the rows (it scrolled off with >3
  entries, same rule as the rail, #46); rows at text-xs for the wall.
- Mobile chip moved off MapView's centred "Live" chip, which it covered.
- Keyword cues re-resolve to the incident once correlation links the call,
  so the lane row is clickable and the pin pulses.
- Enabling notifications sends one confirmation notification; a browser
  that grants permission but throws on construct (mobile Chrome) now shows
  "unsupported" instead of a switched-on control that never delivers.
- useActiveIncidentsState: includeMetadataChanges so `loaded` flips on a
  metadata-only server sync (quiet org / offline start) instead of waiting
  for the first incident change and swallowing it into the baseline.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Logan Cusano
2026-10-05 03:52:02 -04:00
co-authored by Claude Opus 5.5
parent eb0faf2aea
commit 292c4fffd9
4 changed files with 53 additions and 17 deletions
@@ -173,6 +173,20 @@ export function AttentionControls({ prefs, onChange, armed }: Props) {
if (p === "default") {
try { p = (await Notification.requestPermission()) as NotifyState; } catch { p = notifyState(); }
}
if (p === "granted") {
// Confirm with one notification (as the tone confirms with a beep). It
// doubles as the support check: mobile Chrome grants permission but
// throws on `new Notification()` without a service worker, which would
// otherwise leave a switched-on control that never delivers anything.
try {
new Notification("DRB · Notifications on", {
body: `Cues will appear here while the live wall tab is hidden.\n${MACHINE_OUTPUT_NOTICE_TEXT}`,
tag: "drb-attn:on",
});
} catch {
p = "unsupported";
}
}
setPerm(p);
if (p === "granted") onChange({ ...prefs, notify: true });
};
@@ -215,7 +229,7 @@ export function AttentionControls({ prefs, onChange, armed }: Props) {
<span>
<span className="text-ink font-medium">Browser notifications while this tab is hidden</span>
{perm === "denied" && <span className="block text-ink-muted">Blocked in this browser&apos;s site settings — allow notifications there first.</span>}
{perm === "unsupported" && <span className="block text-ink-muted">This browser doesn&apos;t support page notifications.</span>}
{perm === "unsupported" && <span className="block text-ink-muted">This browser doesn&apos;t show notifications from a web page (mobile browsers often only allow them from installed apps).</span>}
</span>
</label>
<div>