Commit cf314eab authored by Chunchi Che's avatar Chunchi Che

finish side migration 90%

parent 0f2427e4
Pipeline #23298 passed with stages
in 13 minutes and 29 seconds
...@@ -2,7 +2,6 @@ import React, { useEffect } from "react"; ...@@ -2,7 +2,6 @@ import React, { useEffect } from "react";
import { resetUniverse } from "@/stores"; import { resetUniverse } from "@/stores";
import { ChangeSideModal, TpModal } from "../Side";
import { import {
Alert, Alert,
AnnounceModal, AnnounceModal,
...@@ -23,6 +22,7 @@ import { LifeBar, Mat, Menu, Underlying } from "./PlayMat"; ...@@ -23,6 +22,7 @@ import { LifeBar, Mat, Menu, Underlying } from "./PlayMat";
export const Component: React.FC = () => { export const Component: React.FC = () => {
useEffect(() => { useEffect(() => {
return () => { return () => {
// FIXME
// Duel组件卸载的时候初始化一些store // Duel组件卸载的时候初始化一些store
resetUniverse(); resetUniverse();
}; };
...@@ -47,8 +47,6 @@ export const Component: React.FC = () => { ...@@ -47,8 +47,6 @@ export const Component: React.FC = () => {
<AnnounceModal /> <AnnounceModal />
<SimpleSelectCardsModal /> <SimpleSelectCardsModal />
<EndModal /> <EndModal />
<ChangeSideModal />
<TpModal />
</> </>
); );
}; };
......
...@@ -30,7 +30,7 @@ const router = createBrowserRouter([ ...@@ -30,7 +30,7 @@ const router = createBrowserRouter([
}, },
{ {
path: "/side", path: "/side",
lazy: () => import("./NewSide"), lazy: () => import("./Side"),
}, },
], ],
}, },
......
import { CheckOutlined, UndoOutlined } from "@ant-design/icons";
import { App, Button, Space } from "antd";
import React, { useState } from "react";
import { DndProvider } from "react-dnd";
import { HTML5Backend } from "react-dnd-html5-backend";
import { CardMeta, fetchCard } from "@/api";
import { isExtraDeckCard } from "@/common";
import { deckStore, IDeck } from "@/stores";
import { CardDetail } from "../BuildDeck/CardDetail";
import { Background, DeckZone, ScrollableArea, Type } from "../Shared";
import { Chat } from "../WaitRoom/Chat";
import styles from "./index.module.scss";
export const Component: React.FC = () => {
const { message } = App.useApp();
const { decks } = deckStore;
const initialDeck = JSON.parse(JSON.stringify(decks[0]));
const [deck, setDeck] = useState<IDeck>(initialDeck);
const [selectedCard, setSelectedCard] = useState(0);
const canAdd = (card: CardMeta, type: Type, _source: Type | "search") => {
const cardType = card.data.type ?? 0;
if (
(type === "extra" && !isExtraDeckCard(cardType)) ||
(type === "main" && isExtraDeckCard(cardType))
) {
return { result: false, reason: "卡片种类不符合" };
} else {
return { result: true, reason: "" };
}
};
const onChange = (
card: CardMeta,
source: Type | "search",
destination: Type,
) => {
setDeck((prev) => {
const deck = { ...prev };
if (source !== "search") {
const removeIndex = deck[source].findIndex((id) => id === card.id);
if (removeIndex !== -1) {
deck[source].splice(removeIndex, 1);
}
}
deck[destination].push(card.id);
return deck;
});
};
const onReset = () => {
setDeck(JSON.parse(JSON.stringify(decks[0])));
message.info("重置成功");
};
return (
<DndProvider backend={HTML5Backend}>
<Background />
<div className={styles.container}>
<div className={styles.sider}>
<Chat />
</div>
<div className={styles.content}>
<div className={styles["deck-container"]}>
<Space className={styles.title}>
<div>请拖动更换副卡组</div>
<Space style={{ marginRight: 6 }}>
<Button
type="text"
size="small"
icon={<UndoOutlined />}
onClick={onReset}
>
重置
</Button>
<Button type="primary" size="small" icon={<CheckOutlined />}>
确定
</Button>
</Space>
</Space>
<ScrollableArea className={styles["deck-zone"]}>
{(["main", "extra", "side"] as const).map((type) => (
<DeckZone
key={type}
type={type}
cards={[...deck[type]].map((id) => fetchCard(id))}
canAdd={canAdd}
onChange={onChange}
onElementClick={(card) => setSelectedCard(card.id)}
/>
))}
</ScrollableArea>
</div>
</div>
<div className={styles["detail-container"]}>
<CardDetail code={selectedCard} open={true} onClose={() => {}} />
</div>
</div>
</DndProvider>
);
};
import { App, Button, Modal } from "antd";
import React, { useEffect } from "react";
import { DndProvider } from "react-dnd";
import { HTML5Backend } from "react-dnd-html5-backend";
import { useSnapshot } from "valtio";
import { CardMeta, sendUpdateDeck } from "@/api";
import { roomStore, SideStage, sideStore } from "@/stores";
import { DeckEditor } from "../../BuildDeck";
import { editDeckStore } from "../../BuildDeck/store";
import { iDeckToEditingDeck } from "../../BuildDeck/utils";
import { Background } from "../../Shared";
export const ChangeSideModal: React.FC = () => {
const { message } = App.useApp();
const { deckName, main, extra, side } = useSnapshot(editDeckStore);
const { stage } = useSnapshot(sideStore);
const { errorMsg } = useSnapshot(roomStore);
const cardMeta2Id = (meta: CardMeta) => meta.id;
const handleSummit = () => {
const newDeck = {
deckName: deckName,
main: main.map(cardMeta2Id),
extra: extra.map(cardMeta2Id),
side: side.map(cardMeta2Id),
};
sendUpdateDeck(newDeck);
editDeckStore.edited = false;
};
useEffect(() => {
if (stage === SideStage.SIDE_CHANGED) {
message.info("副卡组更换成功,请耐心等待其他玩家更换卡组");
}
}, [stage]);
useEffect(() => {
if (errorMsg !== undefined && errorMsg !== "") {
message.error(errorMsg);
roomStore.errorMsg = undefined;
}
}, [errorMsg]);
return (
<Modal
title="请选择更换副卡组"
open={
stage === SideStage.SIDE_CHANGING || stage === SideStage.SIDE_CHANGED
}
width={700}
closable={false}
footer={
<Button
disabled={stage > SideStage.SIDE_CHANGING}
onClick={handleSummit}
>
副卡组更换完毕
</Button>
}
>
<DndProvider backend={HTML5Backend}>
<Background />
<DeckEditor
deck={sideStore.deck}
onClear={() => message.error("对局中清空卡组不怕找不回来吗?!")}
onSave={() => message.error("点击右下角按钮确认副卡组更换完毕")}
onReset={async () => {
editDeckStore.set(await iDeckToEditingDeck(sideStore.deck));
}}
/>
</DndProvider>
</Modal>
);
};
export * from "./ChangeSideModal"; import { CheckOutlined, UndoOutlined } from "@ant-design/icons";
export * from "./TpModal"; import { App, Button, Space } from "antd";
import React, { useEffect, useState } from "react";
import { DndProvider } from "react-dnd";
import { HTML5Backend } from "react-dnd-html5-backend";
import { useNavigate } from "react-router-dom";
import { useSnapshot } from "valtio";
import { CardMeta, fetchCard, sendUpdateDeck } from "@/api";
import { isExtraDeckCard } from "@/common";
import { IDeck, roomStore, SideStage, sideStore } from "@/stores";
import { CardDetail } from "../BuildDeck/CardDetail";
import { Background, DeckZone, ScrollableArea, Type } from "../Shared";
import { Chat } from "../WaitRoom/Chat";
import styles from "./index.module.scss";
import { TpModal } from "./TpModal";
export const Component: React.FC = () => {
const { message } = App.useApp();
const { deck: sideDeck } = sideStore;
const { stage } = useSnapshot(sideStore);
const { errorMsg } = useSnapshot(roomStore);
const initialDeck = JSON.parse(JSON.stringify(sideDeck));
const [deck, setDeck] = useState<IDeck>(initialDeck);
const [selectedCard, setSelectedCard] = useState(0);
const navigate = useNavigate();
const canAdd = (card: CardMeta, type: Type, _source: Type | "search") => {
const cardType = card.data.type ?? 0;
if (
(type === "extra" && !isExtraDeckCard(cardType)) ||
(type === "main" && isExtraDeckCard(cardType))
) {
return { result: false, reason: "卡片种类不符合" };
} else {
return { result: true, reason: "" };
}
};
const onChange = (
card: CardMeta,
source: Type | "search",
destination: Type,
) => {
setDeck((prev) => {
const deck = { ...prev };
if (source !== "search") {
const removeIndex = deck[source].findIndex((id) => id === card.id);
if (removeIndex !== -1) {
deck[source].splice(removeIndex, 1);
}
}
deck[destination].push(card.id);
return deck;
});
};
const onReset = () => {
setDeck(JSON.parse(JSON.stringify(sideDeck)));
message.info("重置成功");
};
const onSummit = () => sendUpdateDeck(deck);
useEffect(() => {
if (stage === SideStage.SIDE_CHANGED) {
message.info("副卡组更换成功,请耐心等待其他玩家更换卡组");
}
if (stage === SideStage.DUEL_START) {
// 决斗开始,跳转
navigate("/duel");
}
}, [stage]);
useEffect(() => {
if (errorMsg !== undefined && errorMsg !== "") {
message.error(errorMsg);
roomStore.errorMsg = undefined;
}
}, [errorMsg]);
return (
<DndProvider backend={HTML5Backend}>
<Background />
<div className={styles.container}>
<div className={styles.sider}>
<Chat />
</div>
<div className={styles.content}>
<div className={styles["deck-container"]}>
<Space className={styles.title}>
<div>请拖动更换副卡组</div>
<Space style={{ marginRight: 6 }}>
<Button
type="text"
size="small"
icon={<UndoOutlined />}
onClick={onReset}
>
重置
</Button>
<Button
type="primary"
size="small"
icon={<CheckOutlined />}
disabled={stage > SideStage.SIDE_CHANGING}
onClick={onSummit}
>
确定
</Button>
</Space>
</Space>
<ScrollableArea className={styles["deck-zone"]}>
{(["main", "extra", "side"] as const).map((type) => (
<DeckZone
key={type}
type={type}
cards={[...deck[type]].map((id) => fetchCard(id))}
canAdd={canAdd}
onChange={onChange}
onElementClick={(card) => setSelectedCard(card.id)}
/>
))}
</ScrollableArea>
</div>
</div>
<div className={styles["detail-container"]}>
<CardDetail code={selectedCard} open={true} onClose={() => {}} />
</div>
</div>
<TpModal />
</DndProvider>
);
};
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