main_panel.svelte 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. <script lang="js">
  2. import CardThumb from './card_thumb.svelte';
  3. import { deck, setDeck, deckOps, format, setFormat } from '../deck';
  4. import { cardLimit } from '../card_db';
  5. import {
  6. parseYdk,
  7. genYdk,
  8. genYdke,
  9. downloadStringAsFile,
  10. } from '../utils';
  11. let fileInput;
  12. function openDeck() {
  13. fileInput.click();
  14. }
  15. function loadDeck(event) {
  16. const file = event.target.files[0];
  17. if (file) {
  18. const reader = new FileReader();
  19. reader.onload = (event) => {
  20. let content = event.target.result;
  21. setDeck(parseYdk(content));
  22. };
  23. reader.readAsText(file);
  24. }
  25. }
  26. function saveDeck() {
  27. let deckString = genYdk($deck);
  28. downloadStringAsFile(deckString)
  29. }
  30. function copyDeck() {
  31. let deckString = genYdk($deck);
  32. navigator.clipboard.writeText(deckString)
  33. .then(() => {
  34. alert('YDK卡组码已复制到剪贴板');
  35. })
  36. .catch(err => {
  37. alert("失败!");
  38. });
  39. }
  40. function shareDeck() {
  41. let url = window.location.href;
  42. url = url.split('#')[0]
  43. url = url + '#' + genYdke($deck);
  44. navigator.clipboard.writeText(url)
  45. .then(() => {
  46. alert('分享链接已复制到剪贴板');
  47. })
  48. .catch(err => {
  49. alert("失败!");
  50. });
  51. }
  52. function onDrop(to, event, targetIdx) {
  53. event.preventDefault();
  54. event.stopPropagation();
  55. const data = JSON.parse(event.dataTransfer.getData('text'));
  56. let from = data.area;
  57. if (from === 'search') {
  58. if (to === 'main') {
  59. deckOps.add2main(data.id, targetIdx);
  60. } else if (to === 'side') {
  61. deckOps.add2side(data.id, targetIdx);
  62. } else if (to === 'extra') {
  63. deckOps.add2extra(data.id, targetIdx);
  64. }
  65. } else {
  66. deckOps.move(from, to, data.idx, targetIdx);
  67. }
  68. }
  69. </script>
  70. <input bind:this={fileInput} style="display:none;" onchange={loadDeck} type="file" class="file-input" accept=".ydk" />
  71. <div class="middle-panel">
  72. <div class="control-bar">
  73. <button class="btn" onclick={openDeck}>打开</button>
  74. <button class="btn" onclick={saveDeck}>保存</button>
  75. <button class="btn" onclick={copyDeck}>复制到剪贴板</button>
  76. <button class="btn" onclick={shareDeck}>分享</button>
  77. <select bind:value={$format} class="select-format" id="format" onchange={()=>setFormat($format)}>
  78. <option value="none">无禁限</option>
  79. <option value="ocg">OCG</option>
  80. </select>
  81. </div>
  82. <div class="deck-section">
  83. <div class="deck-group">
  84. <h3>主卡组({$deck.main.length})</h3>
  85. <div role="region" ondragover={(e)=>e.preventDefault()} ondrop={(e)=>onDrop("main", e, -1)} class="card-grid main-deck">
  86. {#each $deck.main as card, i}
  87. <div class="card-grid-thumb" role="region" ondragover={(e)=>e.preventDefault()} ondrop={(e)=>onDrop("main", e, i)}>
  88. <CardThumb id={card} idx={i} area="main" limitNum={cardLimit(card, $format)} />
  89. </div>
  90. {/each}
  91. </div>
  92. </div>
  93. <div class="deck-group">
  94. <h3>额外卡组({$deck.extra.length})</h3>
  95. <div role="region" ondragover={(e)=>e.preventDefault()} ondrop={(e)=>onDrop("extra", e, -1)} class="card-grid extra-deck">
  96. {#each $deck.extra as card, i}
  97. <div class="card-grid-thumb" role="region" ondragover={(e)=>e.preventDefault()} ondrop={(e)=>onDrop("extra", e, i)}>
  98. <CardThumb id={card} idx={i} area="extra" limitNum={cardLimit(card, $format)} />
  99. </div>
  100. {/each}
  101. </div>
  102. </div>
  103. <div class="deck-group">
  104. <h3>副卡组({$deck.side.length})</h3>
  105. <div role="region" ondragover={(e)=>e.preventDefault()} ondrop={(e)=>onDrop("side", e, -1)} class="card-grid side-deck">
  106. {#each $deck.side as card, i}
  107. <div class="card-grid-thumb" role="region" ondragover={(e)=>e.preventDefault()} ondrop={(e)=>onDrop("side", e, i)}>
  108. <CardThumb id={card} idx={i} area="side" limitNum={cardLimit(card, $format)} />
  109. </div>
  110. {/each}
  111. </div>
  112. </div>
  113. </div>
  114. </div>
  115. <style>
  116. .middle-panel {
  117. width: 55%;
  118. padding: 20px;
  119. background-color: #fff;
  120. overflow-y: auto;
  121. }
  122. .control-bar {
  123. margin-bottom: 20px;
  124. }
  125. .btn {
  126. padding: 8px 20px;
  127. margin-right: 10px;
  128. background-color: #4CAF50;
  129. color: white;
  130. border: none;
  131. border-radius: 4px;
  132. cursor: pointer;
  133. }
  134. .select-format {
  135. padding: 8px 8px;
  136. margin-right: 10px;
  137. cursor: pointer;
  138. font-size: 1.1em;
  139. }
  140. .deck-group {
  141. margin-bottom: 30px;
  142. }
  143. .deck-group h3 {
  144. margin-bottom: 10px;
  145. color: #333;
  146. }
  147. .card-grid {
  148. display: grid;
  149. grid-template-columns: repeat(auto-fill, minmax(52px, 1fr));
  150. grid-auto-flow: dense;
  151. overflow-y: auto;
  152. padding: 10px;
  153. border: 1px solid #ddd;
  154. border-radius: 4px;
  155. min-height: 80px;
  156. }
  157. .card-grid-thumb {
  158. position: relative;
  159. aspect-ratio: 1/1.4;
  160. border-radius: 5px;
  161. }
  162. </style>