Everything written this session that has not been through the device: rounds 43 to 48 (each patch adversarially verified, 43's transient-notice expectation fixed), a partial round 49, the pipeline scripts, the Android Auto design and the icon comparison mock. Also the two harness changes that were never A/B'd — adaptive waits, which may only shorten a declared wait and never lengthen it, and a ship that runs the mock walk and the deploy at the same time. The A/B and its 255-step baseline are in handoff/tools; main stays at what the phone has actually walked.
25 lines
1.3 KiB
Plaintext
25 lines
1.3 KiB
Plaintext
|
|
/* ── what the machine says ───────────────────────────────────────── */
|
|
/* A tab's own name: the section, and when the dot is up, what the
|
|
number counts. "You, 3 transfers" — not a stray 3 read out before
|
|
the word it belongs to. */
|
|
function tabCount(id) {
|
|
if (id === "you") return activeTransfers().length;
|
|
if (id === "community") return unreadTotal();
|
|
return 0;
|
|
}
|
|
function tabName(id, label) {
|
|
const n = tabCount(id);
|
|
if (!n) return label;
|
|
return label + ", " + n + (id === "you" ? " transfer" + (n === 1 ? "" : "s") : " unread");
|
|
}
|
|
|
|
/* The one live region. It is mounted for the life of the app on
|
|
purpose: a region that appears with its words already inside it is
|
|
announced reliably by neither TalkBack nor VoiceOver, so an
|
|
announcement here is a TEXT CHANGE in a node that was always there.
|
|
The desktop does the same (FollowToast's always-mounted .layer,
|
|
PreviewOverlay's .sr-announce). Never drawn — shell.css clips it to
|
|
a pixel. */
|
|
const announce = $derived([player.error || lib.error, notice.text, notice.action?.label].filter(Boolean).join(". "));
|