fix(feed): render the grid after the disclaimer is dismissed (logged-out)

KNOWN_BUGS #1: logged out, the video grid stayed empty after dismissing the
disclaimer until a manual page refresh.

Reproduced deterministically with scripts/perf/disclaimer-grid.mjs (fresh
context, real relays) once it actually waits for and dismisses the
disclaimer: post-dismiss card timeline was 0,0,0,… and only a reload
yielded 132 cards.

Root cause: bootstrapInterface (js/index.js) opens the disclaimer — which
makes the background inert via staticModalAccessibility — and THEN awaits
handleHashChange(), which loads the feed view and renders into that
inert/hidden background, so the initial grid mount/render is dropped.
Dismissing the disclaimer never re-triggered a render.

Fix: disclaimer.js hide() now dispatches a `bitvid:disclaimer-dismissed`
event; index.js listens once and calls application.loadVideos(true) so the
feed re-renders into the now-interactive background. Only fires when a shown
disclaimer is dismissed, so returning visitors (who never see it) get no
redundant reload.

Harness after fix: post-dismiss timeline 132,132,… immediately. Full build
+ unit suite green.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
thePR0M3TH3ANandClaude Opus 4.8 committed 2026-06-16 15:40:06 -04:00
1 parent bf30233649
commit 4f7ef08935
4 files changed
+70 -17

No files matched your search

+23 -7
View File
@@ -19,23 +19,39 @@ page.on("pageerror", (e) => logs.push(`[pageerror] ${String(e).split("\n")[0]}`)
await page.goto(APP, { waitUntil: "domcontentloaded", timeout: 30000 });
// Wait for disclaimer modal to appear.
await page.waitForTimeout(3000);
// Wait for the disclaimer accept button to actually exist (loadDisclaimer is async).
await page.waitForSelector("#acceptDisclaimer", { timeout: 15000 }).catch(() => {});
await page.waitForTimeout(1500);
const hadDisclaimer = await page.evaluate(() => {
const m = document.getElementById("disclaimerModal");
return !!m && getComputedStyle(m).display !== "none" && m.offsetParent !== null;
if (!m) return false;
const cs = getComputedStyle(m);
// Detect via several common "shown" mechanisms, not just display.
return (
m.offsetParent !== null ||
cs.display !== "none" ||
m.classList.contains("is-open") ||
m.getAttribute("aria-hidden") === "false" ||
!m.hasAttribute("hidden")
);
});
const beforeDismiss = await cardCount(page);
// Dismiss the disclaimer (click its primary/accept button).
// Dismiss the disclaimer via its real accept button.
let clicked = false;
try {
const btn = page.locator('#disclaimerModal button, [data-testid="disclaimer-accept"]').first();
const btn = page.locator("#acceptDisclaimer").first();
if (await btn.count()) { await btn.click({ timeout: 4000 }); clicked = true; }
} catch (_) {}
await page.waitForTimeout(6000);
const afterDismiss = await cardCount(page);
// Poll the grid for up to ~15s AFTER dismiss — captures "never renders".
const timeline = [];
for (let i = 0; i < 15; i++) {
await page.waitForTimeout(1000);
timeline.push(await cardCount(page));
}
const afterDismiss = timeline[timeline.length - 1];
console.log("post-dismiss card timeline (1s steps):", timeline.join(","));
// Now reload and re-check (the "refresh fixes it" path).
await page.reload({ waitUntil: "domcontentloaded" });