Commit 8d38baba authored by timel's avatar timel

Merge branch 'feat/0822' into 'main'

feat: forbidden and some fixes

See merge request mycard/Neos!284
parents 2f59f2df 31b1ad46
Pipeline #23247 passed with stages
in 10 minutes and 37 seconds
...@@ -129,6 +129,12 @@ ...@@ -129,6 +129,12 @@
.cardcover { .cardcover {
position: relative; position: relative;
} }
.cardlimit {
position: absolute;
top: 2px;
left: 2px;
width: 20px;
}
} }
.search-cards-container { .search-cards-container {
......
...@@ -26,7 +26,7 @@ import { LoaderFunction } from "react-router-dom"; ...@@ -26,7 +26,7 @@ import { LoaderFunction } from "react-router-dom";
import { proxy, useSnapshot } from "valtio"; import { proxy, useSnapshot } from "valtio";
import { subscribeKey } from "valtio/utils"; import { subscribeKey } from "valtio/utils";
import { type CardMeta, searchCards } from "@/api"; import { type CardMeta, searchCards, forbidden } from "@/api";
import { isToken } from "@/common"; import { isToken } from "@/common";
import { FtsConditions } from "@/middleware/sqlite/fts"; import { FtsConditions } from "@/middleware/sqlite/fts";
import { deckStore, type IDeck, initStore } from "@/stores"; import { deckStore, type IDeck, initStore } from "@/stores";
...@@ -50,6 +50,9 @@ import { ...@@ -50,6 +50,9 @@ import {
iDeckToEditingDeck, iDeckToEditingDeck,
type Type, type Type,
} from "./utils"; } from "./utils";
import { useConfig } from "@/config";
const { assetsPath } = useConfig();
export const loader: LoaderFunction = async () => { export const loader: LoaderFunction = async () => {
// 必须先加载卡组,不然页面会崩溃 // 必须先加载卡组,不然页面会崩溃
...@@ -440,7 +443,9 @@ const DeckZone: React.FC<{ ...@@ -440,7 +443,9 @@ const DeckZone: React.FC<{
onRightClick={() => editDeckStore.remove(type, card)} onRightClick={() => editDeckStore.remove(type, card)}
/> />
))} ))}
<div className={styles["editing-zone-name"]}>{type.toUpperCase()}</div> <div className={styles["editing-zone-name"]}>
{`${type.toUpperCase()}: ${cards.length}`}
</div>
</div> </div>
</div> </div>
); );
...@@ -505,6 +510,7 @@ const Card: React.FC<{ ...@@ -505,6 +510,7 @@ const Card: React.FC<{
}); });
drag(ref); drag(ref);
const [showText, setShowText] = useState(true); const [showText, setShowText] = useState(true);
const limitCnt = forbidden.get(value.id);
return ( return (
<div <div
className={styles.card} className={styles.card}
...@@ -525,6 +531,12 @@ const Card: React.FC<{ ...@@ -525,6 +531,12 @@ const Card: React.FC<{
code={value.id} code={value.id}
onLoad={() => setShowText(false)} onLoad={() => setShowText(false)}
/> />
{limitCnt !== undefined && (
<img
className={styles.cardlimit}
src={`${assetsPath}/Limit0${limitCnt}.png`}
/>
)}
</div> </div>
); );
}); });
......
import { proxy } from "valtio"; import { proxy } from "valtio";
import { type CardMeta } from "@/api"; import { type CardMeta, forbidden } from "@/api";
import { isExtraDeckCard, isToken } from "@/common"; import { isExtraDeckCard, isToken } from "@/common";
import { compareCards, type EditingDeck, type Type } from "./utils"; import { compareCards, type EditingDeck, type Type } from "./utils";
...@@ -40,6 +40,13 @@ export const editDeckStore = proxy({ ...@@ -40,6 +40,13 @@ export const editDeckStore = proxy({
editDeckStore.side = []; editDeckStore.side = [];
editDeckStore.edited = true; editDeckStore.edited = true;
}, },
getAll() {
return [
...editDeckStore.main,
...editDeckStore.extra,
...editDeckStore.side,
];
},
/** 一张卡能不能放入某个区 */ /** 一张卡能不能放入某个区 */
canAdd(card: CardMeta, type: Type): { result: boolean; reason: string } { canAdd(card: CardMeta, type: Type): { result: boolean; reason: string } {
const deckType = editDeckStore[type]; const deckType = editDeckStore[type];
...@@ -67,13 +74,14 @@ export const editDeckStore = proxy({ ...@@ -67,13 +74,14 @@ export const editDeckStore = proxy({
reason = "卡片种类不符合"; reason = "卡片种类不符合";
} }
const maxSameCard = 3; // TODO: 禁卡表 const maxSameCard = forbidden.get(card.id) ?? 3; // TODO: 禁卡表
const sameCardCount = deckType.filter((c) => c.id === card.id).length; const sameCardCount = editDeckStore
.getAll()
.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 };
}, },
}) satisfies EditingDeck; }) satisfies EditingDeck;
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
width: 450px; width: 450px;
font-size: 14px; font-size: 14px;
font-weight: 500; font-weight: 500;
line-height: 24px; line-height: 28px;
color: rgba(235, 245, 235, 0.5); color: rgba(235, 245, 235, 0.5);
} }
} }
......
...@@ -24,10 +24,10 @@ export const Component: React.FC = () => { ...@@ -24,10 +24,10 @@ export const Component: React.FC = () => {
src={`${NeosConfig.assetsPath}/neos-logo.svg`} src={`${NeosConfig.assetsPath}/neos-logo.svg`}
alt="YGO NEOS" alt="YGO NEOS"
/> />
<div className={styles.title}>游戏王网页对战模拟器</div> <div className={styles.title}>游戏王网页端对战平台</div>
<div className={styles.keywords}>开源、免费、轻量级</div> <div className={styles.keywords}>开源、免费、轻量级</div>
<div className={styles.details}> <div className={styles.details}>
这是有关Neos的详细介绍。观夫明堂之宏壮也,则突兀瞳曨,乍明乍蒙,若大古元气之结空。巃嵸颓沓,若嵬若嶪,似天阃地门之开阖。尔乃划岝峉以岳立,郁穹崇而鸿纷。冠百王而垂勋,烛万象而腾文 Neos是一个开源的游戏王网页端对战平台。在Neos中,你可以组建卡组,创建房间,邀请好友进行对战。目前,Neos已经实现了与来自YGOpro、YGOpro2、YGOmobile和KoishiPro等平台的玩家进行对战的功能,而今后更多客户端也将得到支持
</div> </div>
<LoginBtn logined={Boolean(user)} /> <LoginBtn logined={Boolean(user)} />
</div> </div>
......
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