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