From 199883e8c617c66d2a7a175f373d2f18001e22e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kr=C3=BCger?= Date: Mon, 18 May 2026 17:29:00 +0200 Subject: [PATCH] Lightbox always scopes to full issue, not visible cards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously the lightbox list was built from whichever cards happened to be in the DOM (e.g. only tagged posts on a /tags/ page). Now all three open paths — card click, VTA navigation, and direct URL load — scope the list to all posts sharing the same issue as the opened post. Co-Authored-By: Claude Sonnet 4.6 --- assets/js/app.js | 15 +++++++++------ static/js/app.js | 15 +++++++++------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/assets/js/app.js b/assets/js/app.js index cefc81d..90b3f78 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -358,8 +358,9 @@ if (!card) return; e.preventDefault(); const slug = card.dataset.slug; - const visibleSlugs = Array.from(document.querySelectorAll('.card[data-slug]')).map(c => c.dataset.slug); - const scopedList = POSTS.filter(p => visibleSlugs.includes(p.slug)); + const clicked = POSTS.find(p => p.slug === slug); + const issueId = clicked ? clicked.issue : null; + const scopedList = issueId ? POSTS.filter(p => p.issue === issueId) : POSTS; // Update URL without page reload history.pushState({ slug }, '', card.href); lbOpen(slug, scopedList.length ? scopedList : POSTS); @@ -426,8 +427,9 @@ const script = doc.querySelector('script[data-open-slug]'); const openSlug = window.__ROUX_OPEN_SLUG = doc.querySelector('[data-open-slug]')?.dataset.openSlug || null; if (openSlug) { - const visibleSlugs = Array.from(document.querySelectorAll('.card[data-slug]')).map(c => c.dataset.slug); - const scoped = POSTS.filter(p => visibleSlugs.includes(p.slug)); + const opened = POSTS.find(p => p.slug === openSlug); + const issueId = opened ? opened.issue : null; + const scoped = issueId ? POSTS.filter(p => p.issue === issueId) : POSTS; lbOpen(openSlug, scoped.length ? scoped : POSTS); } }); @@ -450,8 +452,9 @@ // ── On single-post pages: auto-open lightbox if (window.__ROUX_OPEN_SLUG && POSTS.length) { - const visibleSlugs = Array.from(document.querySelectorAll('.card[data-slug]')).map(c => c.dataset.slug); - const scoped = POSTS.filter(p => visibleSlugs.includes(p.slug)); + const opened = POSTS.find(p => p.slug === window.__ROUX_OPEN_SLUG); + const issueId = opened ? opened.issue : null; + const scoped = issueId ? POSTS.filter(p => p.issue === issueId) : POSTS; lbOpen(window.__ROUX_OPEN_SLUG, scoped.length ? scoped : POSTS); } diff --git a/static/js/app.js b/static/js/app.js index cefc81d..90b3f78 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -358,8 +358,9 @@ if (!card) return; e.preventDefault(); const slug = card.dataset.slug; - const visibleSlugs = Array.from(document.querySelectorAll('.card[data-slug]')).map(c => c.dataset.slug); - const scopedList = POSTS.filter(p => visibleSlugs.includes(p.slug)); + const clicked = POSTS.find(p => p.slug === slug); + const issueId = clicked ? clicked.issue : null; + const scopedList = issueId ? POSTS.filter(p => p.issue === issueId) : POSTS; // Update URL without page reload history.pushState({ slug }, '', card.href); lbOpen(slug, scopedList.length ? scopedList : POSTS); @@ -426,8 +427,9 @@ const script = doc.querySelector('script[data-open-slug]'); const openSlug = window.__ROUX_OPEN_SLUG = doc.querySelector('[data-open-slug]')?.dataset.openSlug || null; if (openSlug) { - const visibleSlugs = Array.from(document.querySelectorAll('.card[data-slug]')).map(c => c.dataset.slug); - const scoped = POSTS.filter(p => visibleSlugs.includes(p.slug)); + const opened = POSTS.find(p => p.slug === openSlug); + const issueId = opened ? opened.issue : null; + const scoped = issueId ? POSTS.filter(p => p.issue === issueId) : POSTS; lbOpen(openSlug, scoped.length ? scoped : POSTS); } }); @@ -450,8 +452,9 @@ // ── On single-post pages: auto-open lightbox if (window.__ROUX_OPEN_SLUG && POSTS.length) { - const visibleSlugs = Array.from(document.querySelectorAll('.card[data-slug]')).map(c => c.dataset.slug); - const scoped = POSTS.filter(p => visibleSlugs.includes(p.slug)); + const opened = POSTS.find(p => p.slug === window.__ROUX_OPEN_SLUG); + const issueId = opened ? opened.issue : null; + const scoped = issueId ? POSTS.filter(p => p.issue === issueId) : POSTS; lbOpen(window.__ROUX_OPEN_SLUG, scoped.length ? scoped : POSTS); }