🐐
This commit is contained in:
@@ -243,6 +243,7 @@ WIKIDATA_INSTANCE_TYPE_MAP = {
|
|||||||
"Q24034552": CardType.science_thing, # mathematical concept
|
"Q24034552": CardType.science_thing, # mathematical concept
|
||||||
"Q12089225": CardType.science_thing, # mineral species
|
"Q12089225": CardType.science_thing, # mineral species
|
||||||
"Q55640599": CardType.science_thing, # group of chemical entities
|
"Q55640599": CardType.science_thing, # group of chemical entities
|
||||||
|
"Q17339814": CardType.science_thing, # group or class of chemical substances
|
||||||
"Q119459661": CardType.science_thing, # scientific activity
|
"Q119459661": CardType.science_thing, # scientific activity
|
||||||
"Q113145171": CardType.science_thing, # type of chemical entity
|
"Q113145171": CardType.science_thing, # type of chemical entity
|
||||||
|
|
||||||
|
|||||||
@@ -163,6 +163,14 @@ def get_cards(user: UserModel = Depends(get_current_user), db: Session = Depends
|
|||||||
for card in cards
|
for card in cards
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@app.get("/cards/in-decks")
|
||||||
|
def get_cards_in_decks(user: UserModel = Depends(get_current_user), db: Session = Depends(get_db)):
|
||||||
|
deck_ids = [d.id for d in db.query(DeckModel).filter(DeckModel.user_id == user.id, DeckModel.deleted == False).all()]
|
||||||
|
if not deck_ids:
|
||||||
|
return []
|
||||||
|
card_ids = db.query(DeckCardModel.card_id).filter(DeckCardModel.deck_id.in_(deck_ids)).distinct().all()
|
||||||
|
return [str(row.card_id) for row in card_ids]
|
||||||
|
|
||||||
@app.post("/open_pack")
|
@app.post("/open_pack")
|
||||||
@limiter.limit("10/minute")
|
@limiter.limit("10/minute")
|
||||||
async def open_pack(request: Request, user: UserModel = Depends(get_current_user), db: Session = Depends(get_db)):
|
async def open_pack(request: Request, user: UserModel = Depends(get_current_user), db: Session = Depends(get_db)):
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
let {
|
let {
|
||||||
allCards = [],
|
allCards = [],
|
||||||
selectedIds = $bindable(new Set()),
|
selectedIds = $bindable(new Set()),
|
||||||
|
inDeckIds = new Set(),
|
||||||
onclose = null,
|
onclose = null,
|
||||||
costLimit = null, // if set, prevents selecting cards that would exceed it
|
costLimit = null, // if set, prevents selecting cards that would exceed it
|
||||||
showFooter = true, // set false to hide the Done button (e.g. inline deck builder)
|
showFooter = true, // set false to hide the Done button (e.g. inline deck builder)
|
||||||
@@ -185,6 +186,9 @@
|
|||||||
{#if selectedIds.has(card.id)}
|
{#if selectedIds.has(card.id)}
|
||||||
<div class="selected-badge">✓</div>
|
<div class="selected-badge">✓</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if inDeckIds.has(card.id)}
|
||||||
|
<div class="in-deck-badge" title="In a deck">⊞</div>
|
||||||
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
@@ -410,6 +414,21 @@
|
|||||||
z-index: 10;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.in-deck-badge {
|
||||||
|
position: absolute;
|
||||||
|
top: 6px;
|
||||||
|
right: 6px;
|
||||||
|
background: rgba(13, 8, 2, 0.75);
|
||||||
|
color: #7ecfcf;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1;
|
||||||
|
padding: 3px 5px;
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 1px solid rgba(126, 207, 207, 0.5);
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
.status {
|
.status {
|
||||||
font-family: 'Crimson Text', serif;
|
font-family: 'Crimson Text', serif;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
|||||||
@@ -11,20 +11,23 @@
|
|||||||
let selectorOpen = $state(false);
|
let selectorOpen = $state(false);
|
||||||
let shattering = $state(false);
|
let shattering = $state(false);
|
||||||
let result = $state(null); // { gained, shards }
|
let result = $state(null); // { gained, shards }
|
||||||
|
let inDeckIds = $state(new Set());
|
||||||
|
|
||||||
const selectedCards = $derived(allCards.filter(c => selectedIds.has(c.id)));
|
const selectedCards = $derived(allCards.filter(c => selectedIds.has(c.id)));
|
||||||
const totalYield = $derived(selectedCards.reduce((sum, c) => sum + c.cost, 0));
|
const totalYield = $derived(selectedCards.reduce((sum, c) => sum + c.cost, 0));
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
if (!localStorage.getItem('token')) { goto('/auth'); return; }
|
if (!localStorage.getItem('token')) { goto('/auth'); return; }
|
||||||
const [cardsRes, profileRes] = await Promise.all([
|
const [cardsRes, profileRes, inDecksRes] = await Promise.all([
|
||||||
apiFetch(`${API_URL}/cards`),
|
apiFetch(`${API_URL}/cards`),
|
||||||
apiFetch(`${API_URL}/profile`),
|
apiFetch(`${API_URL}/profile`),
|
||||||
|
apiFetch(`${API_URL}/cards/in-decks`),
|
||||||
]);
|
]);
|
||||||
if (cardsRes.status === 401) { goto('/auth'); return; }
|
if (cardsRes.status === 401) { goto('/auth'); return; }
|
||||||
allCards = await cardsRes.json();
|
allCards = await cardsRes.json();
|
||||||
const profile = await profileRes.json();
|
const profile = await profileRes.json();
|
||||||
shards = profile.shards;
|
shards = profile.shards;
|
||||||
|
if (inDecksRes.ok) inDeckIds = new Set(await inDecksRes.json());
|
||||||
});
|
});
|
||||||
|
|
||||||
async function shatter() {
|
async function shatter() {
|
||||||
@@ -95,6 +98,7 @@
|
|||||||
<CardSelector
|
<CardSelector
|
||||||
allCards={allCards}
|
allCards={allCards}
|
||||||
bind:selectedIds={selectedIds}
|
bind:selectedIds={selectedIds}
|
||||||
|
{inDeckIds}
|
||||||
onclose={() => { selectorOpen = false; }}
|
onclose={() => { selectorOpen = false; }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user