Commit 169a7810 authored by timel's avatar timel

feat: 组卡页ui

parent 848082e1
Pipeline #25890 failed with stages
in 1 minute and 11 seconds
......@@ -3,35 +3,30 @@
.detail {
z-index: 10;
position: absolute;
left: -100%;
top: 0;
width: 100%;
height: 100%;
padding: 0 0.625rem 1.25rem 0.625rem;
transition: 0.2s;
transition: 0.1s;
opacity: 0;
pointer-events: none;
}
.detail.open {
left: 0;
opacity: 1;
pointer-events: unset;
}
.container {
height: 100%;
background: linear-gradient(
to bottom right,
hsla(0, 0%, 100%, 0.2),
hsla(0, 0%, 100%, 0)
);
box-shadow:
-1px 0 0 2px rgba(255, 255, 255, 0.15),
0 0 30px 0 #ffffff54;
backdrop-filter: blur(1.25rem);
@include utils.noise-bg;
// @include utils.noise-bg;
padding: 1rem;
display: flex;
flex-direction: column;
position: relative;
border-radius: 0.5rem;
border: 1px solid rgba(255, 255, 255, 0.05);
background-color: hsla(0, 0%, 100%, 0.05);
backdrop-filter: blur(0.3rem);
}
.btn-close {
......@@ -41,24 +36,18 @@
}
.card {
--width: 10rem;
--width: 12rem;
width: var(--width);
height: calc(var(--width) / var(--card-ratio));
flex-shrink: 0;
border: 1px solid #ffffff52;
overflow: hidden;
box-shadow: 0 0 0.375rem 0.125rem #ffffff2b;
transition: 0.3s;
cursor: pointer;
&:hover {
--width: 13.75rem;
filter: contrast(1.1);
}
}
.title {
font-size: 1.25rem;
font-family: var(--nato-serif-font);
margin: 1.25rem 0 1rem;
display: flex;
justify-content: space-between;
......
......@@ -21,7 +21,8 @@ export const DeckSelect: React.FC<{
onDelete: (deckName: string) => Promise<any>;
onDownload: (deckName: string) => any;
onCopy: (deckName: string) => Promise<any>;
}> = ({ decks, selected, onSelect, onDelete, onDownload, onCopy }) => {
visible: boolean;
}> = ({ decks, selected, onSelect, onDelete, onDownload, onCopy, visible }) => {
const newDeck = useRef<IDeck[]>([]);
const { modal, message } = App.useApp();
......@@ -63,42 +64,36 @@ export const DeckSelect: React.FC<{
},
});
/** 从剪贴板导入。为什么错误处理这么丑陋... */
const importFromClipboard = () => {
// 检查浏览器是否支持 Clipboard API
if (navigator.clipboard) {
// 获取剪贴板内容
navigator.clipboard
.readText()
.then((text) => {
const deck = YGOProDeck.fromYdkString(text);
if (
!(deck.main.length + deck.extra.length + deck.side.length === 0)
) {
// YDK解析成功
const deckName = new Date().toLocaleString();
deckStore
.add({
deckName,
...deck,
})
.then((result) => {
if (result) {
message.success(`导入成功,卡组名为:${deckName}`);
onSelect(deckName);
} else {
message.error(`解析失败,请检查格式是否正确。`);
}
});
} else {
message.error(`解析失败,请检查格式是否正确。`);
}
})
.catch((err) => {
message.error("无法读取剪贴板内容:", err);
});
} else {
message.error("浏览器不支持 Clipboard API");
/** 从剪贴板导入。尝试让错误处理更加简洁. */
const importFromClipboard = async () => {
try {
// 检查浏览器是否支持 Clipboard API
if (!navigator.clipboard) {
throw new Error("浏览器不支持 Clipboard API");
}
// 使用 await 等待获取剪贴板内容
const text = await navigator.clipboard.readText();
const deck = YGOProDeck.fromYdkString(text);
// 检查是否成功解析 YDK
if (deck.main.length + deck.extra.length + deck.side.length === 0) {
throw new Error("解析失败,请检查格式是否正确。");
}
// YDK 解析成功
const deckName = new Date().toLocaleString();
const result = await deckStore.add({ deckName, ...deck });
// 检查添加结果
if (result) {
message.success(`导入成功,卡组名为:${deckName}`);
onSelect(deckName);
} else {
throw new Error("解析失败,请检查格式是否正确。");
}
} catch (err: any) {
message.error(`发生错误: ${err.message || err}`);
}
};
......@@ -121,7 +116,7 @@ export const DeckSelect: React.FC<{
].map((_, key) => ({ ..._, key }));
return (
<>
<div style={{ transition: "0.2s", opacity: visible ? 1 : 0 }}>
<div className={styles["deck-select"]}>
{decks.map(({ deckName }) => (
<div
......@@ -173,7 +168,7 @@ export const DeckSelect: React.FC<{
size="large"
/>
</Dropdown>
</>
</div>
);
};
......
......@@ -86,6 +86,7 @@ export const loader: LoaderFunction = async () => {
export const Component: React.FC = () => {
const snapDecks = useSnapshot(deckStore);
const { progress } = useSnapshot(initStore.sqlite);
const { open } = useSnapshot(selectedCard);
const [selectedDeck, setSelectedDeck] = useState<IDeck>(
deckStore.decks.at(0) ?? emptyDeck,
);
......@@ -141,6 +142,7 @@ export const Component: React.FC = () => {
if (deck) return await copyDeckToClipboard(deck);
else return false;
}}
visible={!open}
/>
</ScrollableArea>
<HigherCardDetail />
......
......@@ -11,7 +11,7 @@
pointer-events: none;
z-index: 100;
--bg-color: #323232;
width: 200px;
width: 160px;
}
.life-bar {
......@@ -24,16 +24,14 @@
padding: 1rem;
padding-bottom: 0.6rem;
border-radius: 8px;
// text-align: left;
display: flex;
flex-direction: column;
gap: 8px;
.name {
font-size: 0.8rem;
font-weight: bold;
}
.life {
font-size: 1.8rem;
font-size: 1.4rem;
}
}
.timer-container {
......
......@@ -31,7 +31,7 @@ export const theme: ThemeConfig = {
colorBgContainer: "hsla(0, 0%, 100%, 0.05)",
},
Dropdown: {
colorBgElevated: "#2e3c50",
// colorBgElevated: "#2e3c50",
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)",
},
......
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