From a67ca18ddaf0e0e6f6ed1425777068f70f2c9bce Mon Sep 17 00:00:00 2001 From: "Samir L. Boulema" Date: Fri, 8 May 2026 23:50:53 +0200 Subject: [PATCH] feat: Add support for double faced cards --- .github/workflows/workflow.yml | 2 +- manifest.json | 2 +- package.json | 2 +- src/renderer.ts | 94 +++++++++++++++++++++++----------- styles.css | 12 +++-- versions.json | 3 +- 6 files changed, 77 insertions(+), 38 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index b29be53..bd7966f 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -10,7 +10,7 @@ permissions: contents: read env: - version: '1.5.${{ github.run_number }}' + version: '1.6.${{ github.run_number }}' nodeVersion: '22' jobs: diff --git a/manifest.json b/manifest.json index 05ac306..484c38e 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "mtg-deck", "name": "MTG Deck", - "version": "1.5.52", + "version": "1.6.54", "minAppVersion": "0.15.0", "description": "Display your MTG decks and card lists in your notes.", "author": "Samir Boulema", diff --git a/package.json b/package.json index b47fcce..6789038 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mtg-deck", - "version": "1.5.52", + "version": "1.6.54", "description": "Display your MTG decks and card lists in your notes.", "main": "main.js", "scripts": { diff --git a/src/renderer.ts b/src/renderer.ts index a9a6631..6a5d3b7 100644 --- a/src/renderer.ts +++ b/src/renderer.ts @@ -286,11 +286,6 @@ export const renderDecklist = async ( // Make elements from parsedLines const sectionContainers: Element[] = []; - // Header section - const header = containerEl.createDiv({ cls: "header" }); - const imgElContainer = header.createDiv({ cls: "card-image-container" }); - const imgEl = imgElContainer.createEl("img", { cls: "card-image" }); - // Footer section const footer = containerEl.createDiv({ cls: "footer" }); @@ -309,6 +304,8 @@ export const renderDecklist = async ( .forEach((section: string) => { // Put the entire deck in containing div for styling const sectionContainer = containerEl.createDiv({ cls: "decklist__section-container" }); + const imgElContainer = sectionContainer.createDiv({ cls: "card-image-container" }); + const imgEl = imgElContainer.createEl("img", { cls: "card-image" }); // Create a heading const sectionHeadingEl = sectionContainer.createEl("h3", { cls: "decklist__section-heading" }); @@ -383,9 +380,11 @@ export const renderDecklist = async ( if (line.cardName) { const cardId = nameToId(line.cardName); const cardInfo = cardDataByCardId[cardId]; + const cardManaCost = cardInfo?.mana_cost + ?? cardInfo?.card_faces?.[0]?.mana_cost; - if (cardInfo?.mana_cost) { - cardInfo.mana_cost + if (cardManaCost) { + cardManaCost .replace(/\//g, "") .split("{") .slice(1) @@ -484,14 +483,14 @@ export const renderDecklist = async ( cls: "error", text: `${currencyMapping[ settings.decklist.preferredCurrency - ] + ] }${amountOwned.toFixed(2)}`, }); cardPriceEl!.createSpan({ text: ` / ${currencyMapping[ settings.decklist.preferredCurrency - ] + ] }${totalPrice.toFixed(2)}`, }); @@ -519,37 +518,70 @@ export const renderDecklist = async ( sectionTotalCounts[section] = sectionTotalCounts[section] + (line.cardCount || 0); - if (settings.decklist.showCardPreviews) { - // Event handlers for card artwork popover + // Show card preview on hover + if (settings.decklist.showCardPreviews && line.cardName) { + const cardId = nameToId(line.cardName); + const cardInfo = cardDataByCardId[cardId]; + const isDoubleFaced = (cardInfo?.card_faces?.length ?? 0) > 1 + && !cardInfo?.image_uris; + + let faceIndex = 0; + lineEl.addEventListener("mouseenter", () => { const cardId = nameToId(line.cardName); const cardInfo = cardDataByCardId[cardId]; - let imgUri: string | undefined; - if (cardInfo) { - // For single-faced cards... + if (!cardInfo) return; + + faceIndex = 0; + + const getImgUri = (index: number): string | undefined => { if (cardInfo.image_uris) { - imgUri = cardInfo.image_uris?.large; - // For double-faced cards... - } else if ( - cardInfo.card_faces && - cardInfo.card_faces.length > 1 - ) { - // Use the front-side of the card for preview - imgUri = - cardInfo.card_faces[0].image_uris?.large; + return cardInfo.image_uris.large; } - const offsetPaddingTop = 16; - imgElContainer.style.top = `${lineEl.offsetTop + offsetPaddingTop - }px`; - imgElContainer.style.left = `${cardCommentsEl.offsetLeft}px`; - } - if (typeof imgUri !== "undefined") { + return cardInfo.card_faces?.[index]?.image_uris?.large; + }; + + imgElContainer.style.display = "block"; + imgElContainer.style.top = `${lineEl.offsetTop}px`; + imgElContainer.style.right = "50px"; + imgElContainer.style.left = "auto"; + + const imgUri = getImgUri(faceIndex); + if (imgUri) { imgEl.src = imgUri; } + + if (isDoubleFaced) { + imgEl.style.cursor = "pointer"; + imgEl.onclick = () => { + faceIndex = faceIndex === 0 ? 1 : 0; + const uri = getImgUri(faceIndex); + if (uri) { + imgEl.src = uri; + } + }; + } else { + imgEl.style.cursor = "default"; + imgEl.onclick = null; + } }); - lineEl.addEventListener("mouseleave", () => { - imgEl.src = ""; + lineEl.addEventListener("mouseleave", (e) => { + // Only hide if we're not moving onto the image container + if (!imgElContainer.contains(e.relatedTarget as Node)) { + imgElContainer.style.display = "none"; + imgEl.src = ""; + imgEl.onclick = null; + } + }); + + imgElContainer.addEventListener("mouseleave", (e) => { + // Only hide if we're not moving back onto a table row + if (!sectionList.contains(e.relatedTarget as Node)) { + imgElContainer.style.display = "none"; + imgEl.src = ""; + imgEl.onclick = null; + } }); } } else if (line.lineType === "comment") { diff --git a/styles.css b/styles.css index c37aa3a..c29d9b9 100644 --- a/styles.css +++ b/styles.css @@ -4,6 +4,10 @@ padding: 8px; } +.decklist__section-container { + position: relative; +} + .decklist__section-container table { width: 100%; border: 1px solid var(--background-modifier-border); @@ -50,9 +54,11 @@ span.comment { } .card-image-container { - text-align: right; - position: absolute; - z-index: 1; + display: none; + position: absolute; + right: 0; + z-index: 1; + pointer-events: auto; } .count { diff --git a/versions.json b/versions.json index a7f26c9..bf8de42 100644 --- a/versions.json +++ b/versions.json @@ -4,5 +4,6 @@ "1.2.47": "0.15.0", "1.3.48": "0.15.0", "1.4.49": "0.15.0", - "1.5.52": "0.15.0" + "1.5.52": "0.15.0", + "1.6.54": "0.15.0" } \ No newline at end of file