diff options
| author | Adam Soltys <[email protected]> | 2026-10-09 08:21:44 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-10-09 08:21:44 -0700 |
| commit | 9918e6ce7d1ea812921ee816913ed45e8e368906 (patch) | |
| tree | 6c7963ebe877dc0da9961df1257a21d89c0e9b59 /tools/feed-new-posts-test.js | |
| parent | 4b0d0b3adb6941b88ba43eb0359cb221ae848235 (diff) | |
| download | coinosv3-9918e6ce7d1ea812921ee816913ed45e8e368906.tar.gz coinosv3-9918e6ce7d1ea812921ee816913ed45e8e368906.zip | |
Feed: the "new posts" pill only ever takes you up. It counts the new posts you haven't scrolled up to yet (going up to one, or past it, takes it and everything below it off), and the tap glides to the nearest of them above the post at the top of your screen — reading one newer than the oldest, you were sent back down to the oldest. A new post peeking in at the top edge still counts as above you. The count updates as you scroll up, and the notice clears when none are left (this replaces the at-the-top check)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01MgAFLnkF7KrdhuyCLMNgtL
Diffstat (limited to 'tools/feed-new-posts-test.js')
| -rw-r--r-- | tools/feed-new-posts-test.js | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/tools/feed-new-posts-test.js b/tools/feed-new-posts-test.js index aa3e667..35b8e84 100644 --- a/tools/feed-new-posts-test.js +++ b/tools/feed-new-posts-test.js @@ -27,7 +27,7 @@ await test.feed(); const bundle = await Bun.build({ entrypoints: ['nav-test-entry'], target: 'browser', plugins: [{ name: 'nav-test', setup(build) { build.onResolve({filter:/^nav-test-entry$/},()=>({path:'entry',namespace:'nav-test'})); build.onLoad({filter:/.*/,namespace:'nav-test'},()=>({contents:entry,loader:'js',resolveDir:process.cwd()})); - build.onLoad({filter:/src\/features\/messages\.js$/},async({path})=>({loader:'js',contents:(await Bun.file(path).text()).replace("id: 'messages',", "id: 'messages', testSeed: async (notes) => { const c = feedNow(); await c.boot; Object.assign(c, { notes, status: 'ready', booting: false, end: true, shown: 20, unseen: 0, fresh: null, deferred: [] }); }, testUnseen: () => { feed.unseen = 2; }, testArrive: (notes) => admitFeed(notes, feed), testChats: (n, m) => { stCache = null; if (m != null) st().communities = Array.from({ length: m }, (_, i) => ({ ...COMMUNITY, community_id: (i + 1).toString(16).padStart(64, 'd'), name: 'Room ' + i })); threads.clear(); for (let i = 0; i < n; i++) { const peer = (i + 1).toString(16).padStart(64, 'c'); threads.set(peer, new Map([['r' + i, { rumor: { id: 'r' + i, kind: 14, pubkey: peer, tags: [], content: 'hi ' + i, created_at: 1700000000 - i }, mine: false }]])); } },")})); + build.onLoad({filter:/src\/features\/messages\.js$/},async({path})=>({loader:'js',contents:(await Bun.file(path).text()).replace("id: 'messages',", "id: 'messages', testSeed: async (notes) => { const c = feedNow(); await c.boot; Object.assign(c, { notes, status: 'ready', booting: false, end: true, shown: 20, unseen: 0, fresh: null, ahead: null, deferred: [] }); }, testUnseen: () => { feed.unseen = 2; }, testArrive: (notes) => admitFeed(notes, feed), testChats: (n, m) => { stCache = null; if (m != null) st().communities = Array.from({ length: m }, (_, i) => ({ ...COMMUNITY, community_id: (i + 1).toString(16).padStart(64, 'd'), name: 'Room ' + i })); threads.clear(); for (let i = 0; i < n; i++) { const peer = (i + 1).toString(16).padStart(64, 'c'); threads.set(peer, new Map([['r' + i, { rumor: { id: 'r' + i, kind: 14, pubkey: peer, tags: [], content: 'hi ' + i, created_at: 1700000000 - i }, mine: false }]])); } },")})); build.onLoad({filter:/src\/nostr\.js$/},async({path})=>({loader:'js',contents:(await Bun.file(path).text()) .replace('export async function queryOn(relays, filter, maxWait = 1500) {','export async function queryOn(relays, filter, maxWait = 1500) { return [];') .replace(/export function subscribeOn\(([^)]*)\) \{/,'export function subscribeOn($1) { return () => {};')})); @@ -99,6 +99,21 @@ try { assert(!(await page.$('.notes-feed > .row.note-fresh[data-key="'+F(0)+'"]')),'a post barely on screen starts fading too'); await page.evaluate(()=>window.scrollTo(0,0)); await sleep(300); assert.deepEqual(await fresh(),[],'back at the top, the rest fade once seen'); + // Only ever up: reading a new post that's newer than the oldest one, the + // pill counts just the ones above you and the tap goes up to the nearest. + await test_reset(); + await page.evaluate((id)=>{const r=document.querySelector('.notes-feed > [data-key="'+id+'"]');window.scrollTo(0,scrollY+r.getBoundingClientRect().top-100);},reading); + await sleep(300); + await page.evaluate(()=>test.arrive(3)); await sleep(300); + await page.evaluate((id)=>{const r=document.querySelector('.notes-feed > [data-key="'+id+'"]');window.scrollTo(0,scrollY+r.getBoundingClientRect().top-100);},F(1)); + await sleep(400); + assert.equal(await page.$eval('.feed-new-pill .n',e=>e.textContent),'1','scrolled up past two new posts: one left above'); + const yUp=await page.evaluate(()=>scrollY); + await page.tap('.feed-new-pill'); await sleep(400); + assert(await page.evaluate(()=>scrollY)<yUp,'the tap went up, not down to the oldest new post'); + const newest=await top(F(0)); + assert(newest>=0&&newest<=20,'...landing on the new post above: '+newest); + await page.evaluate(()=>window.scrollTo(0,0)); await sleep(300); // swipe the pill away: it goes, the page doesn't move, and it's back once more arrive await page.evaluate((id)=>{const r=document.querySelector('.notes-feed > [data-key="'+id+'"]');window.scrollTo(0,scrollY+r.getBoundingClientRect().top-100);},reading); await sleep(300); @@ -124,5 +139,5 @@ try { assert.equal(await page.evaluate(()=>scrollY),y1,'and is not a tap'); assert.equal(await page.$eval('.feed-new-pill',e=>e.style.transform),'','sprung back into place'); assert.deepEqual(errors,[]); - console.log('✓ New posts: pill lands on the oldest new post; a tint starts its 3s fade the moment any of the post is on screen; the reading row stays put; swiping the pill dismisses it until more arrive'); + console.log('✓ New posts: pill lands on the oldest new post (never below where you are); a tint starts its 3s fade the moment any of the post is on screen; the reading row stays put; swiping the pill dismisses it until more arrive'); } finally { await page.close(); await browser.close(); server.stop(true); } |
