Owned-quantity stepper in the card preview modal

The preview's Owned row gets the same −/+ stepper as the library list,
refetching copy groups (which shrink with the total) and refreshing the
caller. Card Search now passes a preview context too, so its previews get
the stepper and printing controls.

Closes #3
This commit is contained in:
2026-10-23 22:35:03 -05:00
parent 089b96e501
commit 89ef5d0848
2 changed files with 25 additions and 10 deletions

View File

@@ -1018,6 +1018,14 @@ function PrintingsSection({
setCopies(await api.listLibraryCopies(card.oracle_id));
});
// Copy groups that no longer fit are trimmed when the total drops, so
// refetch them along with it.
const adjustOwned = (delta: number) =>
run(async () => {
setOwned(await api.addOwned(card.oracle_id, delta));
setCopies(await api.listLibraryCopies(card.oracle_id));
});
const showPrinting = (scryfallId: string | null) =>
run(async () => {
const entry = await api.setDeckCardPrinting(ctx.deckId!, card.oracle_id, scryfallId);
@@ -1057,14 +1065,17 @@ function PrintingsSection({
)}
<div className="preview-info-section">
<span className="preview-info-label">Owned</span>
<span>
{owned} cop{owned === 1 ? "y" : "ies"}
{tracked > 0 && (
<span className="muted">
{" "}
· {tracked} by printing · {Math.max(0, owned - tracked)} unspecified
</span>
)}
<span className="row" style={{ gap: 8 }}>
<QtyStepper value={owned} onDecrement={() => adjustOwned(-1)} onIncrement={() => adjustOwned(1)} />
<span>
cop{owned === 1 ? "y" : "ies"}
{tracked > 0 && (
<span className="muted">
{" "}
· {tracked} by printing · {Math.max(0, owned - tracked)} unspecified
</span>
)}
</span>
</span>
{copies.map((c) => (
<div key={`${c.scryfall_id}/${c.finish}`} className="printing-row">

View File

@@ -1,5 +1,5 @@
import { useEffect, useRef, useState } from "react";
import { api, Deck, LibraryCard, LibraryFacets, LibraryFilter } from "../api";
import { api, Deck, LibraryCard, LibraryFacets, LibraryFilter, PreviewContext } from "../api";
import {
CardThumb,
CardTile,
@@ -231,6 +231,9 @@ export function CardSearch({
}
}
// Lets the click preview adjust ownership and printings, refetching after.
const preview: PreviewContext = { onChanged: () => setRefreshKey((k) => k + 1) };
async function adjust(oracleId: string, delta: number) {
const qty = await api.addOwned(oracleId, delta);
setRows((rs) => rs.map((c) => (c.oracle_id === oracleId ? { ...c, quantity_owned: qty } : c)));
@@ -298,7 +301,7 @@ export function CardSearch({
/>
</td>
<td className="cell-thumb">
<CardThumb card={c} />
<CardThumb card={c} preview={preview} />
</td>
<td>
<ColorPips mask={c.color_identity} />
@@ -343,6 +346,7 @@ export function CardSearch({
<CardTile
key={c.oracle_id}
card={c}
preview={preview}
selected={selected.has(c.oracle_id)}
rotated={horizontalView}
cornerLeft={