Commit d8217948 authored by timel's avatar timel

feat: card name behind cover, as placeholder

parent e4e6b9f5
Pipeline #22979 canceled with stages
in 28 seconds
......@@ -91,6 +91,28 @@
width: 100%;
background-color: rgba(255, 255, 255, 0.1);
aspect-ratio: var(--card-ratio);
position: relative;
background-size: contain;
.cardname {
font-size: 0.9rem;
position: absolute;
padding: 5px;
top: 0;
bottom: 0;
max-height: 100%;
margin: auto;
left: 0;
height: fit-content;
width: 100%;
text-align: center;
line-height: 1.75em;
overflow: hidden; //超出的文本隐藏
text-overflow: ellipsis; //溢出用省略号显示
}
.cardcover {
position: relative;
// z-index: 1;
}
}
.search-cards-container {
......
......@@ -15,7 +15,7 @@ import {
Space,
type ThemeConfig,
} from "antd";
import { useEffect, useState } from "react";
import { memo, useEffect, useState } from "react";
import { useSnapshot } from "valtio";
import { subscribeKey } from "valtio/utils";
......@@ -26,7 +26,14 @@ import { CardDetail } from "./CardDetail";
import { DeckSelect } from "./DeckSelect";
import styles from "./index.module.scss";
import { LoaderFunction } from "react-router-dom";
import { searchCards, type CardMeta } from "@/api";
import { searchCards, type CardMeta, fetchCard } from "@/api";
import { v4 as v4uuid } from "uuid";
import classNames from "classnames";
import {
iDeckToEditingDeck,
type EditingDeck,
editingDeckToIDeck,
} from "./utils";
const theme: ThemeConfig = {
components: {
......@@ -95,9 +102,14 @@ const DeckEditor: React.FC<{
deck: IDeck;
onSave: (deck: IDeck) => void;
}> = ({ deck, onSave }) => {
const [editingDeck, setEditingDeck] = useState<IDeck>(deck);
const [editingDeck, setEditingDeck] = useState<EditingDeck>({
deckName: deck.deckName,
main: [],
extra: [],
side: [],
});
useEffect(() => {
setEditingDeck(deck);
iDeckToEditingDeck(deck).then(setEditingDeck);
}, [deck]);
return (
<div className={styles.container}>
......@@ -123,7 +135,7 @@ const DeckEditor: React.FC<{
type="text"
size="small"
icon={<CheckOutlined />}
onClick={() => onSave(editingDeck)}
onClick={() => onSave(editingDeckToIDeck(editingDeck))}
>
保存
</Button>
......@@ -133,10 +145,8 @@ const DeckEditor: React.FC<{
{(["main", "extra", "side"] as const).map((type) => (
<div key={type} className={styles[type]}>
<div className={styles["card-continer"]}>
{editingDeck[type].map((code, i) => (
<div className={styles.card} key={i}>
<YgoCard code={code} />
</div>
{editingDeck[type].map((item) => (
<Card value={item} key={v4uuid()} />
))}
</div>
</div>
......@@ -192,14 +202,27 @@ const CardSelect: React.FC = () => {
</Button>
</div>
<ScrollableArea className={styles["search-cards-container"]}>
<div className={styles["search-cards"]}>
{searchResult.map(({ id }, i) => (
<div className={styles.card} key={i}>
<YgoCard code={id} />
</div>
))}
</div>
<SearchResults results={searchResult} />
</ScrollableArea>
</div>
);
};
/** 搜索区的搜索结果,使用memo避免重复渲染 */
const SearchResults: React.FC<{
results: CardMeta[];
}> = memo(({ results }) => (
<div className={styles["search-cards"]}>
{results.map((item) => (
<Card value={item} key={v4uuid()} />
))}
</div>
));
/** 本组件内使用的单张卡片,增加了文字在图片下方 */
const Card: React.FC<{ value: CardMeta }> = memo(({ value }) => (
<div className={styles.card}>
<div className={styles.cardname}>{value.text.name}</div>
<YgoCard className={styles.cardcover} code={value.id} />
</div>
));
import { type CardMeta, fetchCard } from "@/api";
import { type IDeck } from "@/stores";
/** 用在卡组编辑 */
export interface EditingDeck {
deckName: string;
main: CardMeta[];
extra: CardMeta[];
side: CardMeta[];
}
export const iDeckToEditingDeck = async (
ideck: IDeck
): Promise<EditingDeck> => ({
deckName: ideck.deckName,
main: await Promise.all(ideck.main.map(fetchCard)),
extra: await Promise.all(ideck.extra.map(fetchCard)),
side: await Promise.all(ideck.side.map(fetchCard)),
});
export const editingDeckToIDeck = (deck: EditingDeck): IDeck => ({
deckName: deck.deckName,
main: deck.main.map((card) => card.id),
extra: deck.extra.map((card) => card.id),
side: deck.side.map((card) => card.id),
});
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