Initial commit: MTG personal library catalog (Tauri v2 + React/TS)
Full working app with:
- Rust core (mtgc-core): Scryfall ingester, nucleo fuzzy search, SQLite two-DB
architecture (reference.db + library.db via ATTACH), criteria filters, deck ops
- Tauri v2 shell exposing the core as typed IPC commands
- React/TS frontend: card entry, library browser, deck editor
- Features: fuzzy card search, color/CMC/type/commander-identity filters,
tile/list view toggle, hover card previews, deck format + commander support,
per-card location field, grouping by type/subtype/CMC/color, localStorage
persistence for active tab/deck/grouping, Discord-inspired dark UI (#C8553D accent)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 19:37:56 -05:00
|
|
|
// Typed wrappers over the Tauri command bridge into mtgc-core.
|
|
|
|
|
import { invoke } from "@tauri-apps/api/core";
|
|
|
|
|
|
|
|
|
|
// --- Types (mirror the serde-serialized core structs) ---------------------
|
|
|
|
|
|
|
|
|
|
export interface CardRef {
|
|
|
|
|
oracle_id: string;
|
|
|
|
|
name: string;
|
|
|
|
|
mana_value: number;
|
|
|
|
|
colors: number; // WUBRG bitmask
|
|
|
|
|
color_identity: number; // WUBRG bitmask
|
|
|
|
|
type_line: string;
|
2026-07-22 20:55:17 -05:00
|
|
|
// Printed/displayed sideways (Battles, Planes, Phenomena). The stored
|
|
|
|
|
// image itself is portrait-shaped with the content rotated, so viewers
|
|
|
|
|
// must rotate it 90° to display right-side up.
|
|
|
|
|
horizontal: boolean;
|
Initial commit: MTG personal library catalog (Tauri v2 + React/TS)
Full working app with:
- Rust core (mtgc-core): Scryfall ingester, nucleo fuzzy search, SQLite two-DB
architecture (reference.db + library.db via ATTACH), criteria filters, deck ops
- Tauri v2 shell exposing the core as typed IPC commands
- React/TS frontend: card entry, library browser, deck editor
- Features: fuzzy card search, color/CMC/type/commander-identity filters,
tile/list view toggle, hover card previews, deck format + commander support,
per-card location field, grouping by type/subtype/CMC/color, localStorage
persistence for active tab/deck/grouping, Discord-inspired dark UI (#C8553D accent)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 19:37:56 -05:00
|
|
|
image_uri: string; // Scryfall "normal" image URL, or "" if unavailable
|
Card preview modal, library quantity steppers, and UI polish
- Fix keyboard-nav selection highlight (search results, deck list): the
Discord-styling rewrite dropped the --panel-2 CSS variable it relied
on, so ↑/↓ moved selection but rendered no visible highlight.
- Add click-to-preview: clicking a card thumbnail/tile now opens a
larger centered modal (list and tile views), with a flip button for
double-faced cards' back face. Hover preview is unchanged and clears
when a click-preview opens.
- Add a QtyStepper component (rounded [− N +] pill, with an `overlay`
variant for tile corners) and use it consistently for owned-copy
counts on Add Cards, and the Library list and tile views.
- Add matching +/- steppers to the Library views; decrementing to 0
dims the row for a 5s grace period (still fully interactive) before
it drops out, so an accidental removal can be undone with +.
- Topbar: fill remaining width with the library path (no more premature
truncation), add icons to Open/New Library and Download/Update card
data, and drop the trailing "…" from the library buttons.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-07 20:55:18 -05:00
|
|
|
back_image_uri: string; // back face for transform/MDFC/reversible cards, else ""
|
2026-07-08 23:54:47 -05:00
|
|
|
produced_mana: number; // WUBRG bitmask of mana this card can tap for
|
|
|
|
|
produces_colorless: boolean; // can produce {C}
|
2026-07-14 21:32:25 -05:00
|
|
|
price_usd: number; // USD market price, or 0 if unknown
|
2026-07-20 00:21:22 -05:00
|
|
|
legalities: number; // 2 bits/format bitmask, see LEGALITY_FORMATS
|
Initial commit: MTG personal library catalog (Tauri v2 + React/TS)
Full working app with:
- Rust core (mtgc-core): Scryfall ingester, nucleo fuzzy search, SQLite two-DB
architecture (reference.db + library.db via ATTACH), criteria filters, deck ops
- Tauri v2 shell exposing the core as typed IPC commands
- React/TS frontend: card entry, library browser, deck editor
- Features: fuzzy card search, color/CMC/type/commander-identity filters,
tile/list view toggle, hover card previews, deck format + commander support,
per-card location field, grouping by type/subtype/CMC/color, localStorage
persistence for active tab/deck/grouping, Discord-inspired dark UI (#C8553D accent)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 19:37:56 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface LibraryCard extends CardRef {
|
|
|
|
|
quantity_owned: number;
|
|
|
|
|
decks: string[];
|
|
|
|
|
quantity_assigned: number;
|
|
|
|
|
location: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface DeckEntry extends CardRef {
|
|
|
|
|
quantity: number;
|
|
|
|
|
is_commander: boolean;
|
2026-07-14 21:32:25 -05:00
|
|
|
/** On the maybeboard: tracked against the deck but excluded from deck
|
|
|
|
|
* analysis stats and library assignment totals. */
|
|
|
|
|
is_maybeboard: boolean;
|
Initial commit: MTG personal library catalog (Tauri v2 + React/TS)
Full working app with:
- Rust core (mtgc-core): Scryfall ingester, nucleo fuzzy search, SQLite two-DB
architecture (reference.db + library.db via ATTACH), criteria filters, deck ops
- Tauri v2 shell exposing the core as typed IPC commands
- React/TS frontend: card entry, library browser, deck editor
- Features: fuzzy card search, color/CMC/type/commander-identity filters,
tile/list view toggle, hover card previews, deck format + commander support,
per-card location field, grouping by type/subtype/CMC/color, localStorage
persistence for active tab/deck/grouping, Discord-inspired dark UI (#C8553D accent)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 19:37:56 -05:00
|
|
|
quantity_owned: number;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-22 23:11:26 -05:00
|
|
|
/**
|
|
|
|
|
* A `CardRef` plus whatever ownership context the caller happens to have
|
|
|
|
|
* (present on `LibraryCard`/`DeckEntry`, absent on a bare `CardRef`). The
|
|
|
|
|
* click-to-preview modal's info tile renders these fields when present and
|
|
|
|
|
* omits them otherwise — callers don't need to do anything special, since
|
|
|
|
|
* `LibraryCard`/`DeckEntry`/`CardRef` are all structurally assignable here.
|
|
|
|
|
*/
|
|
|
|
|
export type PreviewCard = CardRef & {
|
|
|
|
|
quantity_owned?: number;
|
|
|
|
|
decks?: string[];
|
|
|
|
|
};
|
|
|
|
|
|
Initial commit: MTG personal library catalog (Tauri v2 + React/TS)
Full working app with:
- Rust core (mtgc-core): Scryfall ingester, nucleo fuzzy search, SQLite two-DB
architecture (reference.db + library.db via ATTACH), criteria filters, deck ops
- Tauri v2 shell exposing the core as typed IPC commands
- React/TS frontend: card entry, library browser, deck editor
- Features: fuzzy card search, color/CMC/type/commander-identity filters,
tile/list view toggle, hover card previews, deck format + commander support,
per-card location field, grouping by type/subtype/CMC/color, localStorage
persistence for active tab/deck/grouping, Discord-inspired dark UI (#C8553D accent)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 19:37:56 -05:00
|
|
|
export interface Deck {
|
|
|
|
|
id: number;
|
|
|
|
|
name: string;
|
|
|
|
|
format: string;
|
|
|
|
|
commander_oracle_id: string | null;
|
|
|
|
|
notes: string;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-20 00:21:22 -05:00
|
|
|
export interface DeckImportResult {
|
|
|
|
|
deck: Deck;
|
|
|
|
|
unresolved: string[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface LibraryImportResult {
|
|
|
|
|
added: [string, number][];
|
|
|
|
|
unresolved: string[];
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-21 21:04:36 -05:00
|
|
|
export interface SynergyReason {
|
|
|
|
|
category: string; // "Tribal" | "Mechanic" | "Archetype" | "Mana base"
|
|
|
|
|
detail: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface CardSuggestion {
|
|
|
|
|
card: CardRef;
|
|
|
|
|
quantity_owned: number;
|
|
|
|
|
score: number;
|
|
|
|
|
reasons: SynergyReason[];
|
|
|
|
|
edhrec_rank: number | null;
|
|
|
|
|
}
|
|
|
|
|
|
Initial commit: MTG personal library catalog (Tauri v2 + React/TS)
Full working app with:
- Rust core (mtgc-core): Scryfall ingester, nucleo fuzzy search, SQLite two-DB
architecture (reference.db + library.db via ATTACH), criteria filters, deck ops
- Tauri v2 shell exposing the core as typed IPC commands
- React/TS frontend: card entry, library browser, deck editor
- Features: fuzzy card search, color/CMC/type/commander-identity filters,
tile/list view toggle, hover card previews, deck format + commander support,
per-card location field, grouping by type/subtype/CMC/color, localStorage
persistence for active tab/deck/grouping, Discord-inspired dark UI (#C8553D accent)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 19:37:56 -05:00
|
|
|
export interface LibraryFilter {
|
|
|
|
|
text?: string | null;
|
|
|
|
|
colors_exact?: number | null;
|
|
|
|
|
colors_include?: number | null;
|
|
|
|
|
commander_identity?: number | null;
|
|
|
|
|
cmc_min?: number | null;
|
|
|
|
|
cmc_max?: number | null;
|
|
|
|
|
types?: string[];
|
|
|
|
|
subtypes?: string[];
|
|
|
|
|
keywords?: string[];
|
|
|
|
|
in_deck?: number | null;
|
2026-07-07 21:35:09 -05:00
|
|
|
location?: string | null;
|
2026-07-08 23:54:47 -05:00
|
|
|
oracle_text?: string | null;
|
Initial commit: MTG personal library catalog (Tauri v2 + React/TS)
Full working app with:
- Rust core (mtgc-core): Scryfall ingester, nucleo fuzzy search, SQLite two-DB
architecture (reference.db + library.db via ATTACH), criteria filters, deck ops
- Tauri v2 shell exposing the core as typed IPC commands
- React/TS frontend: card entry, library browser, deck editor
- Features: fuzzy card search, color/CMC/type/commander-identity filters,
tile/list view toggle, hover card previews, deck format + commander support,
per-card location field, grouping by type/subtype/CMC/color, localStorage
persistence for active tab/deck/grouping, Discord-inspired dark UI (#C8553D accent)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 19:37:56 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface Status {
|
|
|
|
|
library_path: string;
|
|
|
|
|
reference_path: string;
|
|
|
|
|
reference_ready: boolean;
|
|
|
|
|
card_count: number;
|
2026-07-07 21:35:09 -05:00
|
|
|
reference_updated_at: number | null; // unix seconds
|
Initial commit: MTG personal library catalog (Tauri v2 + React/TS)
Full working app with:
- Rust core (mtgc-core): Scryfall ingester, nucleo fuzzy search, SQLite two-DB
architecture (reference.db + library.db via ATTACH), criteria filters, deck ops
- Tauri v2 shell exposing the core as typed IPC commands
- React/TS frontend: card entry, library browser, deck editor
- Features: fuzzy card search, color/CMC/type/commander-identity filters,
tile/list view toggle, hover card previews, deck format + commander support,
per-card location field, grouping by type/subtype/CMC/color, localStorage
persistence for active tab/deck/grouping, Discord-inspired dark UI (#C8553D accent)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 19:37:56 -05:00
|
|
|
}
|
|
|
|
|
|
Deck actions UI, consistent icon buttons, native select fix, sidebar stats
- DeckView: rename/duplicate/delete deck via row-hover icon actions, with
a ConfirmDialog for delete and PromptDialog (with friendly name-
collision errors) for rename/duplicate.
- Add a shared IconButton (plus overlay/danger variants) and replace
every ad hoc close/remove button in the app with it: deck actions,
remove-card-from-deck (list and tile), clear-commander, the card-
preview close, and the ingest-progress dismiss.
- Fix native <select> (Group by, Format, In deck): only color/border were
overridden, leaving native OS chrome (height, arrow, popup) in place.
Drop appearance and draw a custom chevron so they match text inputs.
- Click-to-preview: show both faces of a double-faced card side by side
on wide viewports instead of requiring Flip, and size the preview
images larger overall.
- Sidebar footer: replace the plain "N cards" line with a "Your library"
panel (unique/copies/decks tiles + a WUBRG color-distribution bar),
polling get_library_stats while card data is loaded.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-07 21:21:47 -05:00
|
|
|
export interface LibraryStats {
|
|
|
|
|
unique_cards: number;
|
|
|
|
|
total_copies: number;
|
|
|
|
|
deck_count: number;
|
|
|
|
|
color_counts: [number, number, number, number, number]; // W, U, B, R, G
|
|
|
|
|
colorless_count: number;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-08 23:54:47 -05:00
|
|
|
export interface LibraryFacets {
|
|
|
|
|
types: string[];
|
|
|
|
|
subtypes: string[];
|
|
|
|
|
keywords: string[];
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-07 20:22:31 -05:00
|
|
|
export interface IngestStageInfo {
|
|
|
|
|
id: string;
|
|
|
|
|
label: string;
|
|
|
|
|
weight: number; // fraction of total work, 0..1, sums to 1 across all stages
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface IngestProgress {
|
|
|
|
|
stage: "index" | "oracle" | "printings" | "optimize" | string;
|
|
|
|
|
message: string;
|
|
|
|
|
overall_percent: number; // 0..100 cumulative across all stages
|
|
|
|
|
stages: IngestStageInfo[];
|
|
|
|
|
}
|
|
|
|
|
|
Initial commit: MTG personal library catalog (Tauri v2 + React/TS)
Full working app with:
- Rust core (mtgc-core): Scryfall ingester, nucleo fuzzy search, SQLite two-DB
architecture (reference.db + library.db via ATTACH), criteria filters, deck ops
- Tauri v2 shell exposing the core as typed IPC commands
- React/TS frontend: card entry, library browser, deck editor
- Features: fuzzy card search, color/CMC/type/commander-identity filters,
tile/list view toggle, hover card previews, deck format + commander support,
per-card location field, grouping by type/subtype/CMC/color, localStorage
persistence for active tab/deck/grouping, Discord-inspired dark UI (#C8553D accent)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 19:37:56 -05:00
|
|
|
// --- WUBRG bitmask helpers ------------------------------------------------
|
|
|
|
|
|
|
|
|
|
export const COLORS: { bit: number; code: string; label: string }[] = [
|
|
|
|
|
{ bit: 1, code: "W", label: "White" },
|
|
|
|
|
{ bit: 2, code: "U", label: "Blue" },
|
|
|
|
|
{ bit: 4, code: "B", label: "Black" },
|
|
|
|
|
{ bit: 8, code: "R", label: "Red" },
|
|
|
|
|
{ bit: 16, code: "G", label: "Green" },
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
export function maskToLetters(mask: number): string {
|
|
|
|
|
return COLORS.filter((c) => mask & c.bit)
|
|
|
|
|
.map((c) => c.code)
|
|
|
|
|
.join("");
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-20 00:21:22 -05:00
|
|
|
// --- Legality bitmask helpers ----------------------------------------------
|
|
|
|
|
// Mirrors mtgc-core's model::LEGALITY_FORMATS / Legalities exactly: 2 bits per
|
|
|
|
|
// format, in this fixed order. Do not reorder.
|
|
|
|
|
|
|
|
|
|
export const LEGALITY_FORMATS: { key: string; label: string }[] = [
|
|
|
|
|
{ key: "standard", label: "Standard" },
|
|
|
|
|
{ key: "pioneer", label: "Pioneer" },
|
|
|
|
|
{ key: "modern", label: "Modern" },
|
|
|
|
|
{ key: "legacy", label: "Legacy" },
|
|
|
|
|
{ key: "vintage", label: "Vintage" },
|
|
|
|
|
{ key: "pauper", label: "Pauper" },
|
|
|
|
|
{ key: "commander", label: "Commander" },
|
|
|
|
|
{ key: "brawl", label: "Brawl" },
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
export type LegalStatus = "not_legal" | "legal" | "banned" | "restricted";
|
|
|
|
|
|
|
|
|
|
const LEGAL_STATUS_CODES: readonly LegalStatus[] = ["not_legal", "legal", "banned", "restricted"];
|
|
|
|
|
|
|
|
|
|
export function legalStatusFor(legalities: number, formatLabel: string): LegalStatus {
|
|
|
|
|
const i = LEGALITY_FORMATS.findIndex((f) => f.label === formatLabel);
|
|
|
|
|
if (i < 0) return "not_legal";
|
|
|
|
|
const code = (legalities >> (i * 2)) & 0b11;
|
|
|
|
|
return LEGAL_STATUS_CODES[code];
|
|
|
|
|
}
|
|
|
|
|
|
Initial commit: MTG personal library catalog (Tauri v2 + React/TS)
Full working app with:
- Rust core (mtgc-core): Scryfall ingester, nucleo fuzzy search, SQLite two-DB
architecture (reference.db + library.db via ATTACH), criteria filters, deck ops
- Tauri v2 shell exposing the core as typed IPC commands
- React/TS frontend: card entry, library browser, deck editor
- Features: fuzzy card search, color/CMC/type/commander-identity filters,
tile/list view toggle, hover card previews, deck format + commander support,
per-card location field, grouping by type/subtype/CMC/color, localStorage
persistence for active tab/deck/grouping, Discord-inspired dark UI (#C8553D accent)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 19:37:56 -05:00
|
|
|
// --- Commands -------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
export const api = {
|
|
|
|
|
getStatus: () => invoke<Status>("get_status"),
|
|
|
|
|
setLibraryPath: (path: string) => invoke<Status>("set_library_path", { path }),
|
|
|
|
|
updateCardData: () => invoke<Status>("update_card_data"),
|
2026-07-07 20:22:31 -05:00
|
|
|
cancelUpdateCardData: () => invoke<void>("cancel_update_card_data"),
|
Initial commit: MTG personal library catalog (Tauri v2 + React/TS)
Full working app with:
- Rust core (mtgc-core): Scryfall ingester, nucleo fuzzy search, SQLite two-DB
architecture (reference.db + library.db via ATTACH), criteria filters, deck ops
- Tauri v2 shell exposing the core as typed IPC commands
- React/TS frontend: card entry, library browser, deck editor
- Features: fuzzy card search, color/CMC/type/commander-identity filters,
tile/list view toggle, hover card previews, deck format + commander support,
per-card location field, grouping by type/subtype/CMC/color, localStorage
persistence for active tab/deck/grouping, Discord-inspired dark UI (#C8553D accent)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 19:37:56 -05:00
|
|
|
|
|
|
|
|
searchCards: (query: string, limit = 20) =>
|
|
|
|
|
invoke<CardRef[]>("search_cards", { query, limit }),
|
|
|
|
|
|
|
|
|
|
addOwned: (oracleId: string, delta: number) =>
|
|
|
|
|
invoke<number>("add_owned", { oracleId, delta }),
|
|
|
|
|
setOwned: (oracleId: string, quantity: number) =>
|
|
|
|
|
invoke<number>("set_owned", { oracleId, quantity }),
|
|
|
|
|
setLocation: (oracleId: string, location: string) =>
|
|
|
|
|
invoke<void>("set_location", { oracleId, location }),
|
|
|
|
|
|
|
|
|
|
searchLibrary: (filter: LibraryFilter) =>
|
|
|
|
|
invoke<LibraryCard[]>("search_library", { filter }),
|
2026-07-22 20:55:17 -05:00
|
|
|
searchReference: (filter: LibraryFilter, limit: number) =>
|
|
|
|
|
invoke<LibraryCard[]>("search_reference", { filter, limit }),
|
Deck actions UI, consistent icon buttons, native select fix, sidebar stats
- DeckView: rename/duplicate/delete deck via row-hover icon actions, with
a ConfirmDialog for delete and PromptDialog (with friendly name-
collision errors) for rename/duplicate.
- Add a shared IconButton (plus overlay/danger variants) and replace
every ad hoc close/remove button in the app with it: deck actions,
remove-card-from-deck (list and tile), clear-commander, the card-
preview close, and the ingest-progress dismiss.
- Fix native <select> (Group by, Format, In deck): only color/border were
overridden, leaving native OS chrome (height, arrow, popup) in place.
Drop appearance and draw a custom chevron so they match text inputs.
- Click-to-preview: show both faces of a double-faced card side by side
on wide viewports instead of requiring Flip, and size the preview
images larger overall.
- Sidebar footer: replace the plain "N cards" line with a "Your library"
panel (unique/copies/decks tiles + a WUBRG color-distribution bar),
polling get_library_stats while card data is loaded.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-07 21:21:47 -05:00
|
|
|
getLibraryStats: () => invoke<LibraryStats>("get_library_stats"),
|
2026-07-08 23:54:47 -05:00
|
|
|
getLibraryFacets: () => invoke<LibraryFacets>("get_library_facets"),
|
2026-07-22 20:55:17 -05:00
|
|
|
getReferenceFacets: () => invoke<LibraryFacets>("get_reference_facets"),
|
Initial commit: MTG personal library catalog (Tauri v2 + React/TS)
Full working app with:
- Rust core (mtgc-core): Scryfall ingester, nucleo fuzzy search, SQLite two-DB
architecture (reference.db + library.db via ATTACH), criteria filters, deck ops
- Tauri v2 shell exposing the core as typed IPC commands
- React/TS frontend: card entry, library browser, deck editor
- Features: fuzzy card search, color/CMC/type/commander-identity filters,
tile/list view toggle, hover card previews, deck format + commander support,
per-card location field, grouping by type/subtype/CMC/color, localStorage
persistence for active tab/deck/grouping, Discord-inspired dark UI (#C8553D accent)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 19:37:56 -05:00
|
|
|
|
|
|
|
|
listDecks: () => invoke<Deck[]>("list_decks"),
|
|
|
|
|
createDeck: (name: string, commanderOracleId: string | null) =>
|
|
|
|
|
invoke<Deck>("create_deck", { name, commanderOracleId }),
|
|
|
|
|
deleteDeck: (deckId: number) => invoke<void>("delete_deck", { deckId }),
|
Deck actions UI, consistent icon buttons, native select fix, sidebar stats
- DeckView: rename/duplicate/delete deck via row-hover icon actions, with
a ConfirmDialog for delete and PromptDialog (with friendly name-
collision errors) for rename/duplicate.
- Add a shared IconButton (plus overlay/danger variants) and replace
every ad hoc close/remove button in the app with it: deck actions,
remove-card-from-deck (list and tile), clear-commander, the card-
preview close, and the ingest-progress dismiss.
- Fix native <select> (Group by, Format, In deck): only color/border were
overridden, leaving native OS chrome (height, arrow, popup) in place.
Drop appearance and draw a custom chevron so they match text inputs.
- Click-to-preview: show both faces of a double-faced card side by side
on wide viewports instead of requiring Flip, and size the preview
images larger overall.
- Sidebar footer: replace the plain "N cards" line with a "Your library"
panel (unique/copies/decks tiles + a WUBRG color-distribution bar),
polling get_library_stats while card data is loaded.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-07 21:21:47 -05:00
|
|
|
renameDeck: (deckId: number, name: string) => invoke<void>("rename_deck", { deckId, name }),
|
|
|
|
|
duplicateDeck: (deckId: number, newName: string) =>
|
|
|
|
|
invoke<Deck>("duplicate_deck", { deckId, newName }),
|
Initial commit: MTG personal library catalog (Tauri v2 + React/TS)
Full working app with:
- Rust core (mtgc-core): Scryfall ingester, nucleo fuzzy search, SQLite two-DB
architecture (reference.db + library.db via ATTACH), criteria filters, deck ops
- Tauri v2 shell exposing the core as typed IPC commands
- React/TS frontend: card entry, library browser, deck editor
- Features: fuzzy card search, color/CMC/type/commander-identity filters,
tile/list view toggle, hover card previews, deck format + commander support,
per-card location field, grouping by type/subtype/CMC/color, localStorage
persistence for active tab/deck/grouping, Discord-inspired dark UI (#C8553D accent)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 19:37:56 -05:00
|
|
|
setDeckFormat: (deckId: number, format: string) =>
|
|
|
|
|
invoke<void>("set_deck_format", { deckId, format }),
|
|
|
|
|
setDeckCommander: (deckId: number, oracleId: string | null) =>
|
|
|
|
|
invoke<void>("set_deck_commander", { deckId, oracleId }),
|
|
|
|
|
setDeckCard: (
|
|
|
|
|
deckId: number,
|
|
|
|
|
oracleId: string,
|
|
|
|
|
quantity: number,
|
|
|
|
|
isCommander = false,
|
2026-07-14 21:32:25 -05:00
|
|
|
isMaybeboard = false,
|
|
|
|
|
) => invoke<void>("set_deck_card", { deckId, oracleId, quantity, isCommander, isMaybeboard }),
|
Initial commit: MTG personal library catalog (Tauri v2 + React/TS)
Full working app with:
- Rust core (mtgc-core): Scryfall ingester, nucleo fuzzy search, SQLite two-DB
architecture (reference.db + library.db via ATTACH), criteria filters, deck ops
- Tauri v2 shell exposing the core as typed IPC commands
- React/TS frontend: card entry, library browser, deck editor
- Features: fuzzy card search, color/CMC/type/commander-identity filters,
tile/list view toggle, hover card previews, deck format + commander support,
per-card location field, grouping by type/subtype/CMC/color, localStorage
persistence for active tab/deck/grouping, Discord-inspired dark UI (#C8553D accent)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 19:37:56 -05:00
|
|
|
deckContents: (deckId: number) => invoke<DeckEntry[]>("deck_contents", { deckId }),
|
2026-07-21 21:04:36 -05:00
|
|
|
suggestCards: (deckId: number, offset = 0, unusual = false) =>
|
|
|
|
|
invoke<CardSuggestion[]>("suggest_cards", { deckId, offset, unusual }),
|
Initial commit: MTG personal library catalog (Tauri v2 + React/TS)
Full working app with:
- Rust core (mtgc-core): Scryfall ingester, nucleo fuzzy search, SQLite two-DB
architecture (reference.db + library.db via ATTACH), criteria filters, deck ops
- Tauri v2 shell exposing the core as typed IPC commands
- React/TS frontend: card entry, library browser, deck editor
- Features: fuzzy card search, color/CMC/type/commander-identity filters,
tile/list view toggle, hover card previews, deck format + commander support,
per-card location field, grouping by type/subtype/CMC/color, localStorage
persistence for active tab/deck/grouping, Discord-inspired dark UI (#C8553D accent)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 19:37:56 -05:00
|
|
|
cardDecks: (oracleId: string) => invoke<Deck[]>("card_decks", { oracleId }),
|
2026-07-20 00:21:22 -05:00
|
|
|
|
|
|
|
|
exportDeck: (deckId: number, path: string) => invoke<void>("export_deck", { deckId, path }),
|
|
|
|
|
importDeck: (path: string, name: string) =>
|
|
|
|
|
invoke<DeckImportResult>("import_deck", { path, name }),
|
|
|
|
|
exportLibraryCards: (oracleIds: string[], path: string) =>
|
|
|
|
|
invoke<void>("export_library_cards", { oracleIds, path }),
|
|
|
|
|
importLibraryCards: (path: string) =>
|
|
|
|
|
invoke<LibraryImportResult>("import_library_cards", { path }),
|
Initial commit: MTG personal library catalog (Tauri v2 + React/TS)
Full working app with:
- Rust core (mtgc-core): Scryfall ingester, nucleo fuzzy search, SQLite two-DB
architecture (reference.db + library.db via ATTACH), criteria filters, deck ops
- Tauri v2 shell exposing the core as typed IPC commands
- React/TS frontend: card entry, library browser, deck editor
- Features: fuzzy card search, color/CMC/type/commander-identity filters,
tile/list view toggle, hover card previews, deck format + commander support,
per-card location field, grouping by type/subtype/CMC/color, localStorage
persistence for active tab/deck/grouping, Discord-inspired dark UI (#C8553D accent)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 19:37:56 -05:00
|
|
|
};
|