Version cards get the wrong-game escape hatch; scroll stops yanking
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 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016jXZFSTZQKzAC8fqpWSz9g
This commit is contained in:
co-authored by
Claude Fable 5
parent
3e61a03686
commit
8db69685c4
@@ -106,6 +106,9 @@ function versionCard(row, idx) {
|
||||
<button class="allversions"
|
||||
title="the cues shortlisted these — fetch every published printing instead">
|
||||
list every printing</button>
|
||||
<button class="wronggame"
|
||||
title="none of these printings is your box: BGG may file it as a SEPARATE game — re-match it">
|
||||
wrong game — re-match</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>`;
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user