Files
SoulStream/handoff/rounds/ins-r46-js-head.txt
T
KeelrLeek 9f0601027c android: the handoff — the pending rounds, the pipeline, and what is unverified
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.
2026-09-14 07:57:41 -05:00

49 lines
2.3 KiB
Plaintext

/* THE QUEUE WINDOW. Every update carries a bounded slice of the queue —
the current item and QUEUE_WINDOW either side — because media3's
SimpleBasePlayer.getState() wants a playlist and an index into it, and
the migration to it should find this data already running rather than
written the same day. Nothing reads it yet: MediaService ignores both
fields and the card is exactly the card it was.
TEN either side, twenty-one entries at most. One would cover the card's
own prev and next and nothing else; a queue LIST — which is what Auto
asks for — wants a screenful plus a scroll in either direction, and a
car's list pages about five rows, so ten is two of those each way. It is
a CAP, not a length: a two-thousand-track queue crosses the bridge as
twenty-one entries exactly like a twenty-one-track one does. Measured at
two kilobytes of JSON for twenty-one short titles and six with long ones
and real Android cover paths — against the thirty to eighty kilobytes of
base64 cover that already ride this same call once per record, and an
update is a track change, a transport change or the thirty-second top-up,
never a position tick. */
const QUEUE_WINDOW = 10;
/** A queue entry as the window carries it: what a media3 MediaItem is built
* from, flat, with the cover NAMED rather than carried. The artist falls
* back to the record's the way the bar and the sheet's rows do. */
function windowItem(e) {
return {
id: e?.t?.id != null ? String(e.t.id) : null,
title: e?.t?.title || "",
artist: e?.t?.artist || e?.album?.artist || "",
album: e?.album?.title || "",
duration: e?.t?.duration_secs ?? null,
artKey: e?.album?.art_path || null,
};
}
/* What the card was last told about the queue around it. A PLAIN object,
not $state — nothing renders it, and push() must never make the bar's own
effects re-run — exactly as xfernote keeps its own mirror of the shade.
The walk reads it through __ss.card and holds it against what the plugin
logs on the far side of the bridge: a lock-screen card is not a thing a
page can be asked about, and this window is not even on the card. */
export const mediacard = {
updates: 0,
window: 0,
index: -1,
art: 0,
at: "",
};
let lastArtKey = null;