Commit 12f150aa authored by Chunchi Che's avatar Chunchi Che

Merge branch 'feat/deck/choose' into 'main'

add upload ydk function

See merge request mycard/Neos!103
parents 3e96018c 67423dc3
Pipeline #20103 passed with stages
in 4 minutes and 51 seconds
......@@ -30,3 +30,58 @@ function _objToMap(object: any): Map<string, IDeck> {
return map;
}
export function parseYdk(text: string): IDeck | undefined {
const lineIter = text.split("\n");
const deck: { main: number[]; extra: number[]; side: number[] } = {
main: [],
extra: [],
side: [],
};
let flag = -1;
for (const line of lineIter) {
switch (line) {
case "#main\r": {
flag = 1;
break;
}
case "#extra\r": {
flag = 2;
break;
}
case "!side\r": {
flag = 3;
break;
}
default: {
let code = Number(line);
if (!isNaN(code)) {
if (code > 100) {
switch (flag) {
case 1: {
deck.main.push(code);
break;
}
case 2: {
deck.extra.push(code);
break;
}
case 3: {
deck.side.push(code);
break;
}
default: {
break;
}
}
}
}
break;
}
}
}
return deck.main.length == 0 ? undefined : deck;
}
......@@ -6,6 +6,8 @@ import {
Button,
Dropdown,
notification,
Upload,
message,
} from "antd";
import { useNavigate } from "react-router-dom";
import React, { useState, useEffect } from "react";
......@@ -20,7 +22,7 @@ import {
import { useAppSelector } from "../hook";
import { selectJoined } from "../reducers/joinSlice";
import { selectChat } from "../reducers/chatSlice";
import { fetchDeck } from "../api/deck";
import { fetchDeck, IDeck, parseYdk } from "../api/deck";
import {
sendUpdateDeck,
sendHsReady,
......@@ -34,9 +36,10 @@ import {
SendOutlined,
DownOutlined,
TagOutlined,
UploadOutlined,
} from "@ant-design/icons";
import { initMeExtraDeckMeta } from "../reducers/duel/extraDeckSlice";
import type { MenuProps } from "antd";
import type { MenuProps, UploadProps } from "antd";
import { Link, useParams } from "react-router-dom";
const READY_STATE = "ready";
......@@ -84,22 +87,52 @@ const WaitRoom = () => {
const [api, contextHolder] = notification.useNotification();
const [deckTitle, setDeckTitle] = useState("请选择卡组");
// FIXME: 这些数据应该从`store`中获取
// TODO: 云卡组
const decks: MenuProps["items"] = [
{
label: "hero",
key: "hero",
},
];
const [uploadState, setUploadState] = useState("");
const uploadProps: UploadProps = {
name: "file",
onChange(info) {
if (uploadState != "ERROR") {
info.file.status = "done";
}
},
beforeUpload(file, _) {
const reader = new FileReader();
reader.readAsText(file);
reader.onload = (e) => {
const text = e.target?.result as string;
const deck = parseYdk(text);
if (deck) {
// YDK解析成功
message.success(`${file.name}解析成功`);
const handleChoseDeck = async (deckName: string) => {
const deck = await fetchDeck(deckName);
onDeckReady(deck);
} else {
message.error(`${file.name}解析失败`);
setUploadState("ERROR");
}
};
},
};
const onDeckReady = (deck: IDeck) => {
sendUpdateDeck(deck);
dispatch(initMeExtraDeckMeta({ controler: 0, codes: deck.extra || [] }));
setChoseDeck(true);
};
const handleChoseDeck = async (deckName: string) => {
const deck = await fetchDeck(deckName);
onDeckReady(deck);
};
const handleChoseReady = () => {
sendHsReady();
};
......@@ -206,22 +239,31 @@ const WaitRoom = () => {
<></>
)}
</Space>
<Dropdown
menu={{
items: decks,
onClick: async ({ key }) => {
await handleChoseDeck(key);
setDeckTitle(key);
},
}}
>
<a onClick={(e) => e.preventDefault()}>
<Space>
{deckTitle}
<DownOutlined />
</Space>
</a>
</Dropdown>
<Space wrap size={16}>
<Dropdown
menu={{
items: decks,
onClick: async ({ key }) => {
await handleChoseDeck(key);
setDeckTitle(key);
},
}}
>
<a onClick={(e) => e.preventDefault()}>
<Space>
{deckTitle}
<DownOutlined />
</Space>
</a>
</Dropdown>
</Space>
<Space>
<Upload {...uploadProps}>
<Button icon={<UploadOutlined />}>
没有卡组?点击上传YDK文件
</Button>
</Upload>
</Space>
</Space>
</Modal>
{contextHolder}
......
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