Files
SoulStream/handoff/rounds/patch-round17.cjs
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

63 lines
3.2 KiB
JavaScript

// Round seventeen: the nav's badges — the desktop's title-bar download ring
// as a count on You while transfers are in flight, and the unread chats
// on Community.
const fs = require('fs');
const root = process.env.SS_ROOT || 'F:/Coding/SoulStream/';
let p, s;
const load = (file) => { p = file; s = fs.readFileSync(root + p, 'utf8'); };
const save = () => fs.writeFileSync(root + p, s);
const once = (a) => {
const i = s.indexOf(a);
if (i < 0) throw new Error('missing in ' + p + ': ' + a.slice(0, 90));
if (s.indexOf(a, i + 1) >= 0) throw new Error('ambiguous in ' + p + ': ' + a.slice(0, 90));
return i;
};
const rep = (a, b) => { once(a); s = s.replace(a, () => b); };
load('src/mobile/Mobile.svelte');
rep(` import { transfers, bindTransfers } from "./transfers.svelte.js";`,
` import { transfers, bindTransfers, active as activeTransfers } from "./transfers.svelte.js";`);
rep(` import { slsk, bindSlsk, connectStored } from "./slsk.svelte.js";`,
` import { slsk, bindSlsk, connectStored, unreadTotal } from "./slsk.svelte.js";`);
rep(` <span class="gl"><Icon name={icon} size={22} /></span>
<span class="lb">{label}</span>
</button>
{/each}
</nav>`,
` <span class="gl">
<Icon name={icon} size={22} />
{#if id === "you" && activeTransfers().length}<span class="nb">{activeTransfers().length}</span>{/if}
{#if id === "community" && unreadTotal()}<span class="nb">{unreadTotal()}</span>{/if}
</span>
<span class="lb">{label}</span>
</button>
{/each}
</nav>`);
save();
load('src/mobile/shell.css');
s = s.replace(/\s*$/, String.fromCharCode(10)) + `
/* the nav's badges: transfers in flight on You, unread chats on Community */
.nav button .gl .nb { position: absolute; top: -3px; right: -12px; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 999px; background: var(--accent); color: #04121a; font-size: 10px; font-weight: 800; line-height: 16px; text-align: center; box-shadow: 0 0 0 2px var(--nav-bg, #101014); }
`;
save();
load('tests/mobile/smoke.mjs');
rep(` countline: (document.querySelector('.countline .t-sub') || {}).textContent || '',`,
` countline: (document.querySelector('.countline .t-sub') || {}).textContent || '',
navBadges: [].map.call(document.querySelectorAll('.nav .nb'), function (b) { return b.textContent.trim(); }).join('|'),`);
// A record saving: You's badge counts the flight. The assertion belongs
// HERE and not on the Transfers screen two steps later — by the time the
// walk has settled and tapped its way to You, the mock's burst has already
// finished and the badge is correctly gone.
rep(` "cat-album-save": (i) => /^Saving \\d+ from /.test(i.save),`,
` "cat-album-save": (i) => /^Saving \\d+ from /.test(i.save) && /^\\d+$/.test(i.navBadges),`);
save();
load('ANDROID.md');
rep(`The Library's count line carries the collection's hours`, `The nav wears two badges the desktop's chrome has: transfers in flight on
You (the title bar's download ring) and unread chats on Community.
The Library's count line carries the collection's hours`);
save();
console.log('round seventeen wired');