diff options
| author | Mistivia <i@mistivia.com> | 2025-02-08 13:55:37 +0800 |
|---|---|---|
| committer | Mistivia <i@mistivia.com> | 2025-02-08 13:55:37 +0800 |
| commit | ea9350a570fcb8011bb2678ad8b60486772e411d (patch) | |
| tree | 81a0655e79cdaaf2dac8806f73bb6d0312ed26c3 | |
| parent | 86b9e2de76283ac6ee1e7761dcf6ce0730f26e7a (diff) | |
impl ydke share
| -rw-r--r-- | src/components/MainPanel.svelte | 21 | ||||
| -rw-r--r-- | src/components/RightPanel.svelte | 19 | ||||
| -rw-r--r-- | src/control/deck.js | 27 | ||||
| -rw-r--r-- | src/control/search.js | 7 | ||||
| -rw-r--r-- | src/utils.js | 46 |
5 files changed, 111 insertions, 9 deletions
diff --git a/src/components/MainPanel.svelte b/src/components/MainPanel.svelte index b5f5f2e..5cef824 100644 --- a/src/components/MainPanel.svelte +++ b/src/components/MainPanel.svelte @@ -1,7 +1,12 @@ <script lang="js"> import CardThumb from './CardThumb.svelte'; import { deck, setDeck } from '../control/deck'; - import { parseYdk, genYdk, downloadStringAsFile} from '../utils' + import { + parseYdk, + genYdk, + genYdke, + downloadStringAsFile, + } from '../utils'; let fileInput; @@ -26,6 +31,19 @@ downloadStringAsFile('mydeck.ydk', deckString) } + function shareDeck() { + let url = window.location.href; + url = url.split('#')[0] + url = url + '#' + genYdke($deck); + navigator.clipboard.writeText(url) + .then(() => { + alert('分享链接已复制到剪贴板') + }) + .catch(err => { + alert("失败!"); + }); + } + </script> <input bind:this={fileInput} style="display:none;" onchange={loadDeck} type="file" class="file-input" accept=".ydk" /> @@ -34,6 +52,7 @@ <div class="control-bar"> <button class="btn" onclick={openDeck}>打开</button> <button class="btn" onclick={saveDeck}>保存</button> + <button class="btn" onclick={shareDeck}>分享</button> </div> <div class="deck-section"> <div class="deck-group"> diff --git a/src/components/RightPanel.svelte b/src/components/RightPanel.svelte index 5ede942..062e33c 100644 --- a/src/components/RightPanel.svelte +++ b/src/components/RightPanel.svelte @@ -1,9 +1,14 @@ -<script lang="ts"> +<script lang="js"> + import CardThumb from './CardThumb.svelte'; + import { resultCards } from '../control/search' -import CardThumb from './CardThumb.svelte'; + function onPrevPage() { -let cardList = $state([]); + } + function onNextPage() { + + } </script> <div class="right-panel"> @@ -11,9 +16,9 @@ let cardList = $state([]); <input type="text" placeholder="搜索卡牌..."> </div> <div class="card-list"> - {#if cardList.length > 0} + {#if $resultCards.length > 0} <div class="card-item"> - {#each cardList as card} + {#each $resultCards as card} <div class="card-thumbnail"> <CardThumb id= {card.id} /> </div> @@ -23,8 +28,8 @@ let cardList = $state([]); {/if} </div> <div class="pagination"> - <button class="page-btn">上一页</button> - <button class="page-btn">下一页</button> + <button class="page-btn" onclick={onPrevPage}>上一页</button> + <button class="page-btn" onclick={onNextPage}>下一页</button> </div> </div> diff --git a/src/control/deck.js b/src/control/deck.js index 328e106..98c48fb 100644 --- a/src/control/deck.js +++ b/src/control/deck.js @@ -1,11 +1,36 @@ import { writable } from "svelte/store"; +import { parseYdke } from '../utils'; let deck = writable({main: [], extra: [], side: []}); -let setDeck = (d) => { +function setDeck(d) { + d.main.sort(); + d.extra.sort(); + d.side.sort(); deck.set(d); + localStorage.setItem('cachedDeck', JSON.stringify(d)); }; +function initDeck() { + let url = window.location.href.split('#'); + if (url.length === 2) { + let deck = parseYdke(url[1]); + if (deck.main.length > 0 || deck.extra.length > 0 || deck.extra.length > 0) { + setDeck(deck); + window.location.replace("/"); + return; + } + } + let cachedDeck = localStorage.getItem('cachedDeck'); + if (cachedDeck !== null) { + cachedDeck = JSON.parse(cachedDeck); + setDeck(cachedDeck) + return; + } +} + +initDeck(); + export { deck, setDeck, diff --git a/src/control/search.js b/src/control/search.js new file mode 100644 index 0000000..93a9fc9 --- /dev/null +++ b/src/control/search.js @@ -0,0 +1,7 @@ +import { writable } from 'svelte/store'; + +let resultCards = writable([]); + +export { + resultCards, +}; diff --git a/src/utils.js b/src/utils.js index 3176400..ba5d905 100644 --- a/src/utils.js +++ b/src/utils.js @@ -55,10 +55,56 @@ function downloadStringAsFile(filename, text) { URL.revokeObjectURL(link.href); } +function ydkeEncode(d) { + let deck = []; + for (let card of d) { + let num = parseInt(card); + if (isNaN(num)) continue; + deck.push(num); + } + const buffer = new ArrayBuffer(deck.length * 4); + const view = new DataView(buffer); + for (let i = 0; i < deck.length; i++) { + // Little-endian + view.setUint32(i * 4, deck[i], true); + } + return btoa(String.fromCharCode(...new Uint8Array(buffer))); +} + +function ydkeDecode(encodedDeck) { + const binaryString = atob(encodedDeck); + const buffer = new ArrayBuffer(binaryString.length); + const view = new DataView(buffer); + for (let i = 0; i < binaryString.length; i++) { + view.setUint8(i, binaryString.charCodeAt(i)); + } + const deck = []; + for (let i = 0; i < buffer.byteLength; i += 4) { + deck.push(String(view.getUint32(i, true))); // Little-endian + } + return deck; +} + +function parseYdke(ydkeString) { + const [mainEncoded, extraEncoded, sideEncoded] = ydkeString.split('!'); + const main = ydkeDecode(mainEncoded); + const extra = ydkeDecode(extraEncoded); + const side = ydkeDecode(sideEncoded); + return { main, extra, side }; +} + +function genYdke(deck) { + const mainEncoded = ydkeEncode(deck.main); + const extraEncoded = ydkeEncode(deck.extra); + const sideEncoded = ydkeEncode(deck.side); + return `${mainEncoded}!${extraEncoded}!${sideEncoded}`; +} export { parseYdk, genYdk, + parseYdke, + genYdke, downloadStringAsFile, }; |
