Commit f24a07ec authored by timel's avatar timel

feat: copy deck to clipboard

parent 4cc684e9
Pipeline #23091 passed with stages
in 14 minutes and 17 seconds
import {
CopyOutlined,
DeleteOutlined,
DownloadOutlined,
FileAddOutlined,
InboxOutlined,
PlusOutlined,
CopyOutlined,
} from "@ant-design/icons";
import { App, Button, Dropdown, MenuProps, Upload, UploadProps } from "antd";
import React, { useRef, useState } from "react";
......@@ -20,7 +20,8 @@ export const DeckSelect: React.FC<{
onSelect: (deckName: string) => any;
onDelete: (deckName: string) => Promise<any>;
onDownload: (deckName: string) => any;
}> = ({ decks, selected, onSelect, onDelete, onDownload }) => {
onCopy: (deckName: string) => Promise<any>;
}> = ({ decks, selected, onSelect, onDelete, onDownload, onCopy }) => {
const newDeck = useRef<IDeck[]>([]);
const { modal, message } = App.useApp();
......@@ -130,6 +131,17 @@ export const DeckSelect: React.FC<{
{selected === deckName && <div className={styles.selected} />}
<span>{deckName}</span>
<div className={styles.btns}>
<Button
icon={<CopyOutlined />}
type="text"
size="small"
onClick={cancelBubble(async () => {
const result = await onCopy(deckName);
result
? message.success("复制成功")
: message.error("复制失败");
})}
/>
<Button
icon={<DeleteOutlined />}
type="text"
......@@ -139,6 +151,7 @@ export const DeckSelect: React.FC<{
onSelect(decks[0].deckName);
})}
/>
<Button
icon={<DownloadOutlined />}
type="text"
......
......@@ -44,6 +44,7 @@ import { Filter } from "./Filter";
import styles from "./index.module.scss";
import { editDeckStore } from "./store";
import {
copyDeckToClipboard,
downloadDeckAsYDK,
editingDeckToIDeck,
iDeckToEditingDeck,
......@@ -106,6 +107,11 @@ export const Component: React.FC = () => {
const deck = deckStore.get(name);
if (deck) downloadDeckAsYDK(deck);
}}
onCopy={async (name) => {
const deck = deckStore.get(name);
if (deck) return await copyDeckToClipboard(deck);
else return false;
}}
/>
</ScrollableArea>
<HigherCardDetail />
......
......@@ -36,8 +36,8 @@ export const compareCards = (a: CardMeta, b: CardMeta): number => {
return a.id - b.id;
};
/** 下载卡组YDK文件 **/
export function downloadDeckAsYDK(deck: IDeck) {
/** 生成ydk格式的卡组文本 */
function genYdkText(deck: IDeck): string {
const lines: string[] = [];
lines.push("#created by neos");
lines.push("#main");
......@@ -46,7 +46,12 @@ export function downloadDeckAsYDK(deck: IDeck) {
lines.push(...deck.extra.map((cardId) => cardId.toString()));
lines.push("!side");
lines.push(...deck.side.map((cardId) => cardId.toString()));
const text = lines.join("\n");
return lines.join("\n");
}
/** 下载卡组YDK文件 **/
export function downloadDeckAsYDK(deck: IDeck) {
const text = genYdkText(deck);
const blob = new Blob([text], { type: "text/plain" });
const url = URL.createObjectURL(blob);
......@@ -58,3 +63,14 @@ export function downloadDeckAsYDK(deck: IDeck) {
URL.revokeObjectURL(url);
}
/** 将卡组复制到剪贴板 */
export async function copyDeckToClipboard(deck: IDeck): Promise<boolean> {
const text = genYdkText(deck);
try {
await navigator.clipboard.writeText(text);
return true;
} catch (e) {
return false;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment