Commit 5fd899f7 authored by timel's avatar timel

feat: use useApp to load message

parent e2e6ef39
Pipeline #23020 failed with stages
in 12 minutes and 13 seconds
......@@ -20,21 +20,25 @@ import "@/styles/core.scss";
import "@/styles/inject.scss";
import { ProConfigProvider } from "@ant-design/pro-provider";
import { ConfigProvider, theme } from "antd";
import { ConfigProvider, App } from "antd";
import zhCN from "antd/locale/zh_CN";
import React from "react";
import ReactDOM from "react-dom/client";
import { NeosRouter } from "./ui/NeosRouter";
import { theme } from "@/ui/theme";
const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);
root.render(
<ConfigProvider theme={{ algorithm: theme.darkAlgorithm }} locale={zhCN}>
<ProConfigProvider dark>
<NeosRouter />
</ProConfigProvider>
<ConfigProvider theme={theme} locale={zhCN}>
<App>
<ProConfigProvider dark>
<NeosRouter />
</ProConfigProvider>
</App>
</ConfigProvider>
);
......@@ -18,10 +18,9 @@ body {
--theme-font: "Electrolize", sans-serif;
--header-height: 56px;
#root {
height: 100%;
margin: 0 auto;
width: 100%;
display: flex;
flex-direction: column;
}
}
......
......@@ -16,3 +16,9 @@
--os-handle-bg-hover: rgba(255, 255, 255, 0.44);
--os-handle-bg-active: rgba(255, 255, 255, 0.66);
}
.ant-app {
display: flex;
height: 100%;
flex-direction: column;
}
......@@ -14,6 +14,8 @@ import {
Input,
Space,
type ThemeConfig,
message,
App,
} from "antd";
import { memo, useEffect, useRef, useState } from "react";
import { DndProvider, useDrag, useDrop } from "react-dnd";
......@@ -69,6 +71,25 @@ export const Component: React.FC = () => {
const { sqlite } = useSnapshot(initStore);
const [selectedDeck, setSelectedDeck] = useState<IDeck>(deckStore.decks[0]);
const { message, notification, modal } = App.useApp();
const handleDeckEditorReset = async () => {
editDeckStore.set(await iDeckToEditingDeck(selectedDeck));
message.info("重置成功");
};
const handleDeckEditorSave = async () => {
const tmpIDeck = editingDeckToIDeck(editDeckStore);
const result = await deckStore.update(selectedDeck.deckName, tmpIDeck);
if (result) {
setSelectedDeck(tmpIDeck);
message.info("保存成功");
} else {
editDeckStore.set(await iDeckToEditingDeck(selectedDeck));
message.error("保存失败");
}
};
return (
<DndProvider backend={HTML5Backend}>
<ConfigProvider theme={theme}>
......@@ -93,19 +114,14 @@ export const Component: React.FC = () => {
<div className={styles.deck}>
<DeckEditor
deck={selectedDeck}
onReset={async () => {
editDeckStore.set(await iDeckToEditingDeck(selectedDeck));
}}
onSave={async () => {
const tmpIDeck = editingDeckToIDeck(editDeckStore);
await deckStore.update(selectedDeck.deckName, tmpIDeck);
setSelectedDeck(tmpIDeck);
}}
onClear={editDeckStore.clear}
onReset={handleDeckEditorReset}
onSave={handleDeckEditorSave}
/>
</div>
<div className={styles.select}>
{sqlite.progress === 1 ? (
<CardSelect />
<Search />
) : (
<div className={styles.container}>
<Loading />
......@@ -123,9 +139,10 @@ Component.displayName = "Build";
/** 正在编辑的卡组 */
const DeckEditor: React.FC<{
deck: IDeck;
onClear: () => void;
onReset: () => void;
onSave: () => void;
}> = ({ deck, onReset, onSave }) => {
}> = ({ deck, onClear, onReset, onSave }) => {
const snapEditDeck = useSnapshot(editDeckStore);
useEffect(() => {
iDeckToEditingDeck(deck).then(editDeckStore.set);
......@@ -151,7 +168,7 @@ const DeckEditor: React.FC<{
type="text"
size="small"
icon={<DeleteOutlined />}
onClick={editDeckStore.clear}
onClick={onClear}
>
清空
</Button>
......@@ -183,12 +200,13 @@ const DeckEditor: React.FC<{
};
/** 卡片库,选择卡片加入正在编辑的卡组 */
const CardSelect: React.FC = () => {
const Search: React.FC = () => {
const { message, notification, modal } = App.useApp();
const [searchWord, setSearchWord] = useState("");
const [searchResult, setSearchResult] = useState<CardMeta[]>([]);
const handleSearch = async () => {
const result = (await searchCards(searchWord)).filter((card) =>
isToken(card.data.type ?? 0)
const result = (await searchCards(searchWord)).filter(
(card) => !isToken(card.data.type ?? 0)
); // 衍生物不显示
setSearchResult(result);
};
......@@ -211,7 +229,20 @@ const CardSelect: React.FC = () => {
/>
</div>
<div className={styles["select-btns"]}>
<Button block type="text" icon={<FilterOutlined />}>
<Button
block
type="text"
icon={<FilterOutlined />}
onClick={() => {
modal.confirm({
centered: true,
title: null,
icon: null,
content: "TODO",
footer: null,
});
}}
>
筛选
{/* TODO: 下面这个Badge应根据有无筛选规则而显示 */}
{false && <Badge dot offset={[5, -5]} />}
......@@ -247,6 +278,7 @@ const CardSelect: React.FC = () => {
const DeckZone: React.FC<{
type: Type;
}> = ({ type }) => {
const { message } = App.useApp();
const cards = useSnapshot(editDeckStore)[type];
const [_, dropRef] = useDrop({
accept: ["Card"], // 指明该区域允许接收的拖放物。可以是单个,也可以是数组
......@@ -254,11 +286,14 @@ const DeckZone: React.FC<{
// 当拖拽物在这个拖放区域放下时触发,这个item就是拖拽物的item(拖拽物携带的数据)
drop: ({ value, source }: { value: CardMeta; source: Type | "search" }) => {
if (type === source) return;
if (canAdd(value, type, editDeckStore)) {
const { result, reason } = canAdd(value, type, editDeckStore);
if (result) {
editDeckStore.add(type, value);
if (source !== "search") {
editDeckStore.remove(source, value);
}
} else {
message.error(reason);
}
},
});
......
......@@ -46,7 +46,7 @@ export const canAdd = (
const countLimit = type === "main" ? 60 : 15;
if (initialCards.length >= countLimit) {
result = false;
reason = `超过${countLimit}张的上限`;
reason = `超过 ${countLimit} 张的上限`;
}
// 接着需要检查卡的种类
if (
......@@ -61,7 +61,7 @@ export const canAdd = (
const sameCardCount = initialCards.filter((c) => c.id === card.id).length;
if (sameCardCount >= maxSameCard) {
result = false;
reason = `超过同名卡${maxSameCard}张的上限`;
reason = `超过同名卡 ${maxSameCard} 张的上限`;
}
return { result, reason };
};
......
......@@ -27,7 +27,7 @@ export const Component: React.FC = () => {
const navigate = useNavigate();
useEffect(() => {
// 人机对战跳转
// 人机对战跳转;
if (joined) {
navigate(`/waitroom`);
}
......
import { type ThemeConfig, theme as antdTheme } from "antd";
export const theme: ThemeConfig = {
algorithm: antdTheme.darkAlgorithm,
components: {
Message: {
colorBgElevated: "#3f4d60",
boxShadow:
"0 6px 16px 0 rgb(51 51 51 / 80%), 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 9px 28px 8px rgba(0, 0, 0, 0.05)",
},
Modal: {
colorBgElevated: "#1f242c",
},
},
};
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