Printing tracking for owned copies and deck art, and an outdated-card-data notice
Owned copies can now be pinned to a printing + finish (nonfoil / foil / etched), activating the long-dormant library_card_copies table as groups of identical copies. library_cards.quantity_owned stays authoritative: groups are a subset of it, and the rest are "unspecified". Tracking more copies than are unspecified grows ownership to fit; lowering ownership trims the most recently added groups first. Migration 0006 adds the group quantity, a unique (card, printing, finish) index, and deck_cards.preferred_scryfall_id. A deck slot can show a chosen printing's art, both faces from that printing, falling back to the default when the id no longer resolves. It survives quantity/board changes and is kept by duplicate_deck. UI: the click preview's info tile gets a Printings section when opened from the Library or a deck (copy groups with steppers, "Add a printing…", and "Shown in this deck" with Change…/Default), backed by a printing picker grid. The picker takes Escape in the capture phase so it closes without closing the preview under it. Sync: CardEntry.printings (keyed "<scryfall_id>/<finish>") and DeckCardEntry.printing. Cards now merge field by field with groups per key, so a quantity edit and a printing added on another device both survive; merged groups are clamped deterministically. A document is written as version 2 only once it holds printing data, so older builds and servers refuse it instead of dropping the data and syncing the loss. Decklists: "(SET) NUM", optionally "*F*"/"*E*", round-trips through deck and library export/import. Library export writes a line per group plus one for unspecified copies. reference.db printings gain lang and released_at for picker labels and ordering. When the installed card data lacks any column this build's reference schema has (found by diffing against the schema applied in-memory, so no list to maintain), a notice under the top bar offers Update card data (and Import card data… on phones); "Not now" is remembered until something more goes missing.
This commit is contained in:
100
src/styles.css
100
src/styles.css
@@ -672,6 +672,27 @@ input[type="checkbox"] {
|
||||
border-bottom: 1px solid var(--border-soft);
|
||||
font-size: 13px;
|
||||
}
|
||||
/* Card data from an older version: same strip as the ingest bar, tinted as
|
||||
a warning. Wraps its buttons under the message on narrow screens. */
|
||||
.outdated-bar {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 8px 16px;
|
||||
padding: 8px 18px;
|
||||
background: rgba(224, 163, 74, 0.12);
|
||||
border-bottom: 1px solid rgba(224, 163, 74, 0.35);
|
||||
font-size: 13px;
|
||||
}
|
||||
.outdated-bar-message {
|
||||
flex: 1 1 260px;
|
||||
color: var(--text);
|
||||
}
|
||||
.outdated-bar-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
.ingest-bar-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -3299,3 +3320,82 @@ tbody tr:hover {
|
||||
font-size: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
Printings: the click preview's per-printing controls, and the picker
|
||||
============================================================ */
|
||||
.printing-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
min-width: 0;
|
||||
}
|
||||
.printing-row-thumb {
|
||||
width: 28px;
|
||||
height: 39px;
|
||||
flex-shrink: 0;
|
||||
object-fit: cover;
|
||||
border-radius: 3px;
|
||||
background: var(--bg-elev);
|
||||
}
|
||||
.printing-row-label {
|
||||
min-width: 0;
|
||||
font-size: 13px;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.printing-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
}
|
||||
.printing-actions button {
|
||||
padding: 2px 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
/* Above the click preview (450) it opens from. */
|
||||
.printing-picker-backdrop {
|
||||
z-index: 500;
|
||||
}
|
||||
.printing-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(min(130px, 40vw), 1fr));
|
||||
gap: var(--space-3);
|
||||
}
|
||||
.printing-option {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
min-width: 0;
|
||||
}
|
||||
.printing-option-art {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
border: 2px solid transparent;
|
||||
border-radius: var(--radius-card);
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
.printing-option-art:hover {
|
||||
border-color: var(--accent-hover);
|
||||
background: none;
|
||||
}
|
||||
.printing-option.selected .printing-option-art {
|
||||
border-color: var(--accent);
|
||||
}
|
||||
.printing-option-art img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
aspect-ratio: 488 / 680;
|
||||
object-fit: cover;
|
||||
border-radius: calc(var(--radius-card) - 2px);
|
||||
}
|
||||
.printing-option-label {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: var(--text-strong);
|
||||
}
|
||||
.printing-option-meta {
|
||||
font-size: 12px;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user