From 8db69685c4cab82e15007effde3f16aa42cefd9e Mon Sep 17 00:00:00 2001 From: Eric Wagoner Date: Wed, 5 Aug 2026 21:37:35 -0400 Subject: [PATCH] Version cards get the wrong-game escape hatch; scroll stops yanking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Eric stared at game 589's complete printing list hunting for boxes BGG files as SEPARATE games — the escape (wrong match, on the Titles edit panel) was two pages from where the dead end happens. Version cards now carry "wrong game — re-match", posting the existing reopen-match endpoint: the card moves to the Matches section where re-search and manual id live. And highlight() scrolled the active card into view on EVERY render — for a mouse user the cursor idles on card one, so every button click yanked the page to the top. Scrolling now happens only on keyboard moves. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_016jXZFSTZQKzAC8fqpWSz9g --- data/matches.csv | 2 +- src/bggpipe/templates/pages/review.html | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/data/matches.csv b/data/matches.csv index ce08012..d65e011 100644 --- a/data/matches.csv +++ b/data/matches.csv @@ -134,4 +134,4 @@ BOTANY: PERILOUS PERFUMES,417064,Botany: Perilous Perfumes,2024,boardgameexpansi Civilization: West Extension Map,2058,Civilization: West Extension Map,1986,boardgameexpansion,auto,,,version_unknown,"[{""bgg_id"": 2058, ""name"": ""Civilization: West Extension Map"", ""year"": 1986, ""type"": ""boardgameexpansion"", ""exact"": true, ""fuzzy"": 100.0, ""owned"": null, ""rank"": null}]",[],,, Artistry: Delightful Doorways Mini Expansion,452833,Artistry: Delightful Doorways Mini Expansion,2025,boardgameexpansion,auto,,,version_unknown,"[{""bgg_id"": 452833, ""name"": ""Artistry: Delightful Doorways Mini Expansion"", ""year"": 2025, ""type"": ""boardgameexpansion"", ""exact"": true, ""fuzzy"": 100.0, ""owned"": null, ""rank"": null}]",[],,, castle panic wizard's tower,104590,Castle Panic: The Wizard's Tower,2011,boardgameexpansion,auto,,,version_unknown,"[{""bgg_id"": 104590, ""name"": ""Castle Panic: The Wizard's Tower"", ""year"": 2011, ""type"": ""boardgameexpansion"", ""exact"": true, ""fuzzy"": 100.0, ""owned"": null, ""rank"": null}]",[],,, -WIZ-WAR,589,Wiz-War,1983,boardgame,auto,,,version_unknown,"[{""bgg_id"": 589, ""name"": ""Wiz-War"", ""year"": 1983, ""type"": ""boardgame"", ""exact"": true, ""fuzzy"": 100.0, ""owned"": null, ""rank"": null}]",[],IMG_4504.jpeg,, +WIZ-WAR,589,Wiz-War,1983,boardgame,auto,,,version_ambiguous,"[{""bgg_id"": 589, ""name"": ""Wiz-War"", ""year"": 1983, ""type"": ""boardgame"", ""exact"": true, ""fuzzy"": 100.0, ""owned"": null, ""rank"": null}]","[{""version_id"": 188937, ""name"": ""First edition"", ""year"": 1985, ""publishers"": [""Jolly Games""], ""languages"": [""English""], ""score"": 1}, {""version_id"": 360421, ""name"": ""Second edition"", ""year"": 1985, ""publishers"": [""Jolly Games""], ""languages"": [""English""], ""score"": 1}, {""version_id"": 360420, ""name"": ""Third edition"", ""year"": 1986, ""publishers"": [""Jolly Games""], ""languages"": [""English""], ""score"": 1}, {""version_id"": 29214, ""name"": ""Fourth edition"", ""year"": 1987, ""publishers"": [""Jolly Games""], ""languages"": [""English""], ""score"": 1}, {""version_id"": 26114, ""name"": ""Fifth edition"", ""year"": 1991, ""publishers"": [""Chessex""], ""languages"": [""English""], ""score"": 1}, {""version_id"": 27352, ""name"": ""Chessex sixth edition"", ""year"": 1993, ""publishers"": [""Chessex""], ""languages"": [""English""], ""score"": 1}, {""version_id"": 28612, ""name"": ""Chessex classic edition 1997"", ""year"": 1997, ""publishers"": [""Chessex""], ""languages"": [""English""], ""score"": 1}]",IMG_4504.jpeg,, diff --git a/src/bggpipe/templates/pages/review.html b/src/bggpipe/templates/pages/review.html index 7cabb3b..c26f114 100644 --- a/src/bggpipe/templates/pages/review.html +++ b/src/bggpipe/templates/pages/review.html @@ -106,6 +106,9 @@ function versionCard(row, idx) { + `; @@ -193,6 +196,12 @@ function render() { decide(b.closest(".card"), "reject")); m.querySelectorAll(".golocal").forEach(b => b.onclick = () => decide(b.closest(".card"), "local")); + m.querySelectorAll(".wronggame").forEach(b => b.onclick = () => + post("/api/reopen-match", { + title_raw: b.closest(".card").dataset.title, + source_photos: b.closest(".card").dataset.photos, + row_ix: rowIx(b.closest(".card")), + })); m.querySelectorAll(".allversions").forEach(b => b.onclick = () => post("/api/open-versions", { title_raw: b.closest(".card").dataset.title, @@ -216,10 +225,12 @@ function render() { const actionables = () => [...document.querySelectorAll(".actionable")]; -function highlight() { +function highlight(scroll = false) { actionables().forEach((el, i) => el.classList.toggle("active", i === ACTIVE)); + // scroll only for KEYBOARD moves: a mouse user's cursor idles on card + // one, and scrolling to it on every re-render yanks them to the top const el = actionables()[ACTIVE]; - if (el) el.scrollIntoView({block: "nearest", behavior: "auto"}); + if (el && scroll) el.scrollIntoView({block: "nearest", behavior: "auto"}); } const rowIx = card => Number(card.dataset.rowix); // every card template sets it @@ -247,8 +258,8 @@ document.addEventListener("keydown", e => { if (!cards.length) return; const card = cards[ACTIVE]; const kind = card?.dataset.kind; - if (e.key === "j" || e.key === "ArrowDown") { ACTIVE = Math.min(ACTIVE + 1, cards.length - 1); highlight(); } - else if (e.key === "k" || e.key === "ArrowUp") { ACTIVE = Math.max(ACTIVE - 1, 0); highlight(); } + if (e.key === "j" || e.key === "ArrowDown") { ACTIVE = Math.min(ACTIVE + 1, cards.length - 1); highlight(true); } + else if (e.key === "k" || e.key === "ArrowUp") { ACTIVE = Math.max(ACTIVE - 1, 0); highlight(true); } else if (/^[1-9]$/.test(e.key) && kind === "match") { const li = card.querySelectorAll("[data-pick]")[Number(e.key) - 1]; if (li) decide(card, "pick", Number(li.dataset.pick));