aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-10-14 22:21:25 -0700
committerAdam Soltys <[email protected]>2026-10-14 22:21:25 -0700
commitebc59e50cf86e8edfab21a5be9063e5d5eeab07b (patch)
treeefc4dc4b463fd93dab42c68e10232d3b8a162c60 /tools
parent0355c21254d6d452fd4afbec28db3e124bc1d61a (diff)
downloadcoinosv3-ebc59e50cf86e8edfab21a5be9063e5d5eeab07b.tar.gz
coinosv3-ebc59e50cf86e8edfab21a5be9063e5d5eeab07b.zip
Media pager: a spin of the wheel flies past the posts and lands snapped on one. A notch was a step, and a breath between steps meant a flick of the wheel moved two or three pictures at most (Adam). Now each notch adds a post to go — the third and later notches of a quick run (within 400 ms) add two, so a flick is a few posts and a spin a dozen — and the pager glides through them with the pictures passing (pagerFly: a longer glide, 100 ms + 110 per screen, eased out), landing snapped on the last. The posts passed are not arrived at: the slide observer stands down while flying (no clip starts, nothing marked seen, no counts asked), and the landing arrives (pager.arrive, the observer's old body). A notch back against a flight catches it on the post it is passing and steps back from there; a touch or a key catches it too (pagerGlide now takes a duration and an onDone that pagerHold fires on interruption, with the snap restored). A notch from rest is the single quick step it was; sideways notches and trackpad runs step as before. tools/pager-wheel-test.js: a spin of five flies eight posts on and lands snapped (gliding mid-way), the spin back, a notch against the flight. feed-video-pager-test's two failures are on HEAD before this.
Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01J1Kon8bxJoHRpJdSzshCkp
Diffstat (limited to 'tools')
-rw-r--r--tools/pager-wheel-test.js31
1 files changed, 25 insertions, 6 deletions
diff --git a/tools/pager-wheel-test.js b/tools/pager-wheel-test.js
index b73171b..1828f77 100644
--- a/tools/pager-wheel-test.js
+++ b/tools/pager-wheel-test.js
@@ -13,7 +13,7 @@ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
let ok = true;
const check = (n, c, d = '') => { console.log(` ${c ? '✓' : '✗'} ${n}${d ? ' — ' + d : ''}`); if (!c) ok = false; };
const png = (size) => Bun.spawnSync(['ffmpeg', '-loglevel', 'error', '-f', 'lavfi', '-i', 'testsrc=size=' + size, '-frames:v', '1', '-f', 'image2', '-c:v', 'png', 'pipe:1']).stdout;
-const PICS = { a1: png('400x300'), a2: png('300x400'), b: png('320x320'), d: png('360x240') };
+const PICS = { a1: png('400x300'), a2: png('300x400'), b: png('320x320'), d: png('360x240'), e: png('240x180') };
const SK = generateSecretKey(), AUTHOR = getPublicKey(SK);
const now = Math.floor(Date.now() / 1000);
@@ -22,7 +22,7 @@ const html = await buildHtml({ minify: true, pwa: false });
const server = Bun.serve({ port: 0, fetch: (req) => {
const path = new URL(req.url).pathname;
if (path.startsWith('/punks')) return new Response(Bun.file('dist' + path));
- const m = /^\/(a1|a2|b|d)\.png$/.exec(path);
+ const m = /^\/(a1|a2|b|d|e)\d*\.png$/.exec(path);
if (m) return new Response(PICS[m[1]], { headers: { 'content-type': 'image/png' } });
return new Response(html, { headers: { 'content-type': 'text/html' } });
} });
@@ -32,7 +32,7 @@ const seeded = [
post('one picture ' + U('b'), 200),
post('only words here, nothing to look at', 300),
post('a last picture ' + U('d'), 400),
- ...Array.from({ length: 12 }, (_, i) => post('filler ' + i + ' ' + 'lorem ipsum dolor sit amet. '.repeat(5), 500 + i * 60)),
+ ...Array.from({ length: 12 }, (_, i) => post('more ' + i + ' ' + U('e' + i), 500 + i * 60)), // a dozen more, one picture each, for a flight
];
const browser = await puppeteer.launch({ executablePath: '/usr/bin/google-chrome', headless: 'new', args: ['--no-sandbox', '--blink-settings=primaryHoverType=2,availableHoverTypes=2,primaryPointerType=4,availablePointerTypes=4'] /* a pointer that hovers: headless has none */ });
@@ -113,10 +113,29 @@ try {
check('shift+wheel at the first: stays', (await curPic()) === 'a1.png', await curPic());
await wheel(100, { mods: 8 }); await resting('a2.png');
await sleep(300);
+ console.log('\n[a spin flies, and lands snapped]');
+ // posts with pictures, in order: a (two), b, d, e0 … e11 — a spin of five
+ // notches is 1 + 1 + 2 + 2 + 2 = 8 posts on from a: e5
for (let i = 0; i < 5; i++) { await wheel(100); await sleep(10); }
- await sleep(700);
- check('a spin of five notches in a blink is a step or two, not five', ['b.png', 'd.png'].includes(await curPic()), await curPic());
- await wheel(-100); await resting('b.png'); await wheel(-100); await resting('a2.png'); await wheel(100); await resting('b.png');
+ await sleep(250);
+ const mid = await pos();
+ check('mid-flight: between posts, gliding', /glide:true/.test(mid) && (await curPic()) === 'between', mid);
+ check('a spin of five notches flies eight posts on and lands snapped', await resting('e5.png'), await curPic() + ' ' + await pos());
+ check('the landing is arrived at: the sideways arrows know the post', await page.evaluate(() => !document.querySelector('.media-pager').classList.contains('has-right')));
+ for (let i = 0; i < 5; i++) { await wheel(-100); await sleep(10); }
+ check('a spin back flies back the same way', await resting('a2.png'), await curPic() + ' ' + await pos());
+ // a notch against a flight catches it on the post it is passing
+ for (let i = 0; i < 5; i++) { await wheel(100); await sleep(10); }
+ await sleep(200);
+ await wheel(-100);
+ await sleep(900);
+ const caught = await curPic();
+ check('a notch back mid-flight catches it, snapped on a post short of the target', caught !== 'between' && !['e5.png', 'a1.png', 'a2.png'].includes(caught), caught + ' ' + await pos());
+ await sleep(300);
+ await wheel(-100); await resting(caught === 'b.png' ? 'a2.png' : caught === 'd.png' ? 'b.png' : caught === 'e0.png' ? 'd.png' : 'e' + (Number(caught[1]) - 1) + '.png');
+ // back to b for what follows
+ while ((await curPic()) !== 'b.png') { await wheel((await curPic()) === 'a2.png' || (await curPic()) === 'a1.png' ? 100 : -100); await sleep(500); }
+ await sleep(300);
console.log('\n[a trackpad\'s run is one step]');
await sleep(300);