aboutsummaryrefslogtreecommitdiffstats
path: root/tools/moderation-test.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-09-26 07:31:09 -0700
committerAdam Soltys <[email protected]>2026-09-26 07:31:09 -0700
commit9b49a11710dfb9ded1cf3297696c32ffc64bf7e8 (patch)
tree15ddfc197d366833ce232af8c4ab201a5e22dc7b /tools/moderation-test.js
parent1c388b3897ddd36c07f70b2b7f28467fd169e924 (diff)
downloadcoinosv3-9b49a11710dfb9ded1cf3297696c32ffc64bf7e8.tar.gz
coinosv3-9b49a11710dfb9ded1cf3297696c32ffc64bf7e8.zip
Feed: only the rows near the viewport are in the DOM, however far you scroll.
A long scroll left hundreds of rows mounted, and every repaint (a zap count, a profile landing, the thirty-second sync) rebuilt and diffed all of them — the slowdown deep in the feed. Rows beyond two and a half screens either side of the viewport are now replaced by a spacer at their measured height, so the page keeps its length (scrollbar, Back, arrival anchoring behave as before) while a repaint touches a few dozen rows. After svelte-virtual-list: measure after paint, estimate unmeasured rows at the running average, hold the reader's row still when a measurement corrects an estimate. Applies to the profile notes list too. Tests: feed-window-dom (120 posts, 27,800px page, 12–24 rows mounted, anchor held, spacers both sides); feed-live looks at the top after scrolling up; the moderation test's stub relay no longer lets real posts in. Co-Authored-By: Claude Fable 5.1 <[email protected]>
Diffstat (limited to 'tools/moderation-test.js')
-rw-r--r--tools/moderation-test.js6
1 files changed, 4 insertions, 2 deletions
diff --git a/tools/moderation-test.js b/tools/moderation-test.js
index 4ac7f69..78fd460 100644
--- a/tools/moderation-test.js
+++ b/tools/moderation-test.js
@@ -57,7 +57,7 @@ await page.evaluateOnNewDocument((fx) => {
if (kinds.includes(10000) && window.__mutes && (f.authors || []).includes(window.__mutes.pubkey)) answer(ws, m[1], [window.__mutes]);
else if (kinds.includes(1984) && (f.authors || []).includes(fx.author)) answer(ws, m[1], [fx.report]);
else if (kinds.includes(1) && f['#e'] && f['#e'].includes(fx.root)) answer(ws, m[1], fx.replies);
- else if (kinds.includes(1)) subs.push([ws, m[1], f]);
+ else if (kinds.includes(1)) { subs.push([ws, m[1], f]); answer(ws, m[1], []); return; } // no real posts: the feeds hold only what the test injects
}
if (m[0] === 'EVENT' && m[1]) {
window.__published.push(m[1]);
@@ -162,7 +162,9 @@ try {
const stuffed = post(TAGGER, 'airdrop ' + Array.from({ length: 14 }, (_, i) => '#tag' + i).join(' '), 5, [['t', 'bitcoin'], ...Array.from({ length: 14 }, (_, i) => ['t', 'tag' + i])]);
await page.evaluate((e) => window.__inject(e), stuffed);
await sleep(3500);
- check('a stranger\'s ordinary post lands', n > 0 && await waitText('a fine post from a stranger', 6000), n + ' sub(s)');
+ const landed = n > 0 && await waitText('a fine post from a stranger', 6000);
+ if (!landed && process.env.DEBUG) console.log('DEBUG feed:', await page.evaluate(() => ({ rows: document.querySelectorAll('.notes-feed > .row').length, booting: !!document.querySelector('.notes-feed[data-booting]'), spacers: document.querySelectorAll('.feed-spacer').length, text: (document.querySelector('.chat-page') || document.body).innerText.slice(0, 400).replace(/\n+/g, ' | ') })));
+ check('a stranger\'s ordinary post lands', landed, n + ' sub(s)');
check('six copies of the same pitch do not: the spammer is hidden', !(await has('buy the dip now')));
check('...nor does a post stuffed with hashtags', !(await has('airdrop')));