Deck chips open their deck

Deck-name chips in the Library, Card Search and the card preview modal are
now buttons (DeckChip) that open that deck in the Decks tab — on mobile,
straight to its building screen. App provides the open-deck callback via
context and hands the deck id to DeckView.

Closes #19
This commit is contained in:
2026-10-23 23:10:40 -05:00
parent 945e5ed766
commit b96931c7b8
6 changed files with 95 additions and 21 deletions

View File

@@ -16,6 +16,7 @@ import {
formatRelativeTime,
HoverPreviewProvider,
IconButton,
OpenDeckProvider,
Icons,
StatTile,
UndoBar,
@@ -241,6 +242,18 @@ export default function App() {
const [status, setStatus] = useState<Status | null>(null);
const [libStats, setLibStats] = useState<LibraryStats | null>(null);
const [tab, setTab] = usePersistedState<Tab>("active-tab", "add");
// A deck a chip elsewhere asked to open; DeckView picks it up and clears it.
const [openDeckId, setOpenDeckId] = useState<number | null>(null);
// Deck chips only carry the deck's name, which is unique per library.
const openDeck = useCallback(
async (name: string) => {
const deck = (await api.listDecks()).find((d) => d.name === name);
if (!deck) return;
setOpenDeckId(deck.id);
setTab("decks");
},
[setTab],
);
const [progress, setProgress] = useState<IngestProgress | null>(null);
const [busy, setBusy] = useState(false);
// Library sync state: signed in or not, and how the last sync went. Fetched
@@ -598,6 +611,7 @@ export default function App() {
if (status) setOpenLibrary(status.library.id);
return (
<OpenDeckProvider value={openDeck}>
<HoverPreviewProvider>
<div className="app">
<nav className="nav-rail">
@@ -763,7 +777,12 @@ export default function App() {
) : tab === "search" ? (
<CardSearch key={status?.library_label} onOfferUndo={offerUndo} />
) : tab === "decks" ? (
<DeckView key={status?.library_label} refreshSignal={deckRefreshSignal} />
<DeckView
key={status?.library_label}
refreshSignal={deckRefreshSignal}
openDeckId={openDeckId}
onOpenedDeck={() => setOpenDeckId(null)}
/>
) : tab === "game" ? (
// Like News, independent of the library: the game in progress
// is this device's scratch state, not synced data.
@@ -853,5 +872,6 @@ export default function App() {
onRunUndo={runUndo}
/>
</HoverPreviewProvider>
</OpenDeckProvider>
);
}