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.
This commit is contained in:
1 parent
867fd42972
commit
9f0601027c
400 files changed
+26401
-3
No files matched your search
@@ -0,0 +1,97 @@
|
||||
// Round fourteen: the server's room list filtered by name and extended on
|
||||
// demand (it was capped at 80 with no way to the rest).
|
||||
const fs = require('fs');
|
||||
const 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/screens/Community.svelte');
|
||||
rep(` const otherRooms = $derived(slsk.rooms.filter((r) => !slsk.joined[r.name]).slice(0, 80));`,
|
||||
` /* the server's rooms: filtered by name, the biggest first, 80 at a
|
||||
time with a way to the rest */
|
||||
let roomQ = $state("");
|
||||
let roomCap = $state(80);
|
||||
const roomsMatching = $derived.by(() => {
|
||||
const k = roomQ.trim().toLowerCase();
|
||||
const list = slsk.rooms.filter((r) => !slsk.joined[r.name]);
|
||||
return k ? list.filter((r) => r.name.toLowerCase().includes(k)) : list;
|
||||
});
|
||||
const otherRooms = $derived(roomsMatching.slice(0, roomCap));
|
||||
$effect(() => { void roomQ; roomCap = 80; });`);
|
||||
rep(` <div class="sec" style="padding-top:{joinedNames.length ? 18 : 8}px"><h2>Rooms <em>· {slsk.rooms.length} on the server</em></h2></div>
|
||||
{#if !slsk.rooms.length}
|
||||
<div class="sec-note">Asking the server for its rooms…</div>
|
||||
{/if}`,
|
||||
` <div class="sec" style="padding-top:{joinedNames.length ? 18 : 8}px"><h2>Rooms <em>· {slsk.rooms.length} on the server</em></h2></div>
|
||||
{#if !slsk.rooms.length}
|
||||
<div class="sec-note">Asking the server for its rooms…</div>
|
||||
{:else if slsk.rooms.length > 8}
|
||||
<div class="sfield roomfilter">
|
||||
<Icon name="search" size={18} />
|
||||
<input value={roomQ} oninput={(e) => (roomQ = e.currentTarget.value)} type="search" placeholder="Find a room" autocomplete="off" autocapitalize="off" spellcheck="false" aria-label="Find a room" />
|
||||
{#if roomQ}<button class="iconbtn sm" onclick={() => (roomQ = "")} aria-label="Clear"><Icon name="x" size={18} /></button>{/if}
|
||||
</div>
|
||||
{#if roomQ}<div class="sec-note">{roomsMatching.length} of {slsk.rooms.length} rooms</div>{/if}
|
||||
{/if}`);
|
||||
{
|
||||
// the "+ N more" after the room rows: the {/each} that closes otherRooms
|
||||
const a = ` {#each otherRooms as r (r.name)}
|
||||
<button class="row" onclick={() => open(r.name)}>
|
||||
<span class="art hash"><Icon name="hash" size={20} /></span>
|
||||
<span class="b"><span class="t">{r.name}</span><span class="m">{r.users} in the room</span></span>
|
||||
<span class="r"><Icon name="plus" size={18} /></span>
|
||||
</button>
|
||||
{/each}`;
|
||||
once(a);
|
||||
s = s.replace(a, () => a + `
|
||||
{#if roomsMatching.length > roomCap}
|
||||
<div style="padding: 4px var(--pad) 8px"><button class="btn btn-ghost wide" onclick={() => (roomCap += 200)}>+ {roomsMatching.length - roomCap} more rooms</button></div>
|
||||
{/if}`);
|
||||
}
|
||||
save();
|
||||
|
||||
load('src/lib/mockLibrary.js');
|
||||
rep(`const ROOMS = [["Lounge", 412], ["Electronic", 98], ["Vinyl Rips", 37], ["Jazz", 61], ["Lossless Only", 23]];`,
|
||||
`const ROOMS = [["Lounge", 412], ["Electronic", 98], ["Vinyl Rips", 37], ["Jazz", 61], ["Lossless Only", 23], ...Array.from({ length: 90 }, (_, i) => ["Room " + (i + 1), 90 - i])];`);
|
||||
save();
|
||||
|
||||
load('tests/mobile/smoke.mjs');
|
||||
rep(` qfirst: (document.querySelector('.q-face .row .t') || {}).textContent || '',`,
|
||||
` qfirst: (document.querySelector('.q-face .row .t') || {}).textContent || '',
|
||||
rooms: document.querySelectorAll('.screen button.row .art.hash').length,`);
|
||||
rep(` /* the fake network: a room with a few lines in it */
|
||||
{ do: \`__click('.screen button.row', 'Lounge')\`, name: "room", wait: 2400 },`,
|
||||
` /* the room list: filtered by name, the rest on demand */
|
||||
{ do: \`(function () { var i = document.querySelector('.roomfilter input'); i.value = 'vin'; i.dispatchEvent(new Event('input', { bubbles: true })); })()\`, name: "rooms-filtered", wait: 500 },
|
||||
{ do: \`(function () { var i = document.querySelector('.roomfilter input'); i.value = ''; i.dispatchEvent(new Event('input', { bubbles: true })); })()\`, wait: 400 },
|
||||
{ do: \`__click('.screen .btn', 'more rooms')\`, name: "rooms-more", wait: 500 },
|
||||
/* the fake network: a room with a few lines in it */
|
||||
{ do: \`__click('.screen button.row', 'Lounge')\`, name: "room", wait: 2400 },`);
|
||||
rep(` room: (i) => i.screen.includes("tr-push") && i.msgs >= 2,`,
|
||||
` room: (i) => i.screen.includes("tr-push") && i.msgs >= 2,
|
||||
"rooms-filtered": (i) => i.rooms === 1,
|
||||
"rooms-more": (i) => i.rooms >= 95,`);
|
||||
save();
|
||||
|
||||
load('src/mobile/shell.css');
|
||||
s = s.replace(/\s*$/, String.fromCharCode(10)) + `
|
||||
/* Community: the room filter sits with the section, not the page's own field */
|
||||
.sfield.roomfilter { margin-top: 2px; }
|
||||
`;
|
||||
save();
|
||||
|
||||
load('ANDROID.md');
|
||||
rep(`## A peer, and their shares`, `The server's room list on Community is filtered by name and shows 80 at a
|
||||
time with a way to the rest (Soulseek lists hundreds).
|
||||
|
||||
## A peer, and their shares`);
|
||||
save();
|
||||
console.log('round fourteen wired');
|
||||
Reference in new issue
Block a user