Commit 6d3d6113 authored by Chunchi Che's avatar Chunchi Che

update styles

parent 8cd7aa95
Pipeline #23645 passed with stages
in 14 minutes and 57 seconds
.container {
display: flex;
flex-direction: column;
font: var(--theme-font);
font-size: 1rem;
.search {
margin-bottom: 1rem;
.input {
border: 1px solid #afbdd2;
background: transparent;
}
}
.item {
display: flex;
padding: 1rem 0;
.avatar {
flex: 1;
margin-left: 1rem;
}
.title {
flex: 2;
}
.mode {
flex: 1;
display: flex;
justify-content: center;
color: #5f6b7c;
}
}
.item:hover {
border: 2px solid #1059c6;
border-radius: 0.5rem;
cursor: pointer;
}
.item-selected {
border: 2px solid #1059c6;
border-radius: 0.5rem;
box-shadow: 0 0 0 2px #0087e6 inset;
}
.divider {
margin: 0;
}
}
import { App, Avatar, List } from "antd";
import { SearchOutlined } from "@ant-design/icons";
import { App, Avatar, Button, Divider, Empty, Input } from "antd";
import classNames from "classnames";
import React, { useState } from "react";
import useWebSocket, { ReadyState } from "react-use-websocket";
import { proxy, useSnapshot } from "valtio";
import { useConfig } from "@/config";
import { ScrollableArea } from "../Shared";
import styles from "./WatchContent.module.scss";
const { athleticWatchUrl, avatarApi } = useConfig();
interface Info {
......@@ -33,11 +39,14 @@ interface Options {
auto_death: boolean;
}
export const WatchContent: React.FC<{
setWatchID: React.Dispatch<React.SetStateAction<string | undefined>>;
}> = ({ setWatchID }) => {
export const watchStore = proxy<{ watchID: string | undefined }>({
watchID: undefined,
});
export const WatchContent: React.FC = () => {
const [rooms, setRooms] = useState<Room[]>([]);
const { message } = App.useApp();
const { watchID } = useSnapshot(watchStore);
// 暂时只支持竞技匹配的观战,TODO:后面需要加上娱乐匹配的支持
const url = new URL(athleticWatchUrl);
url.searchParams.set("filter", "started");
......@@ -90,33 +99,52 @@ export const WatchContent: React.FC<{
});
return (
<List
itemLayout="vertical"
loading={readyState === ReadyState.CONNECTING}
size="small"
pagination={{
position: "bottom",
align: "center",
pageSize: 5,
simple: true,
}}
dataSource={rooms}
renderItem={(room) => (
<List.Item key={room.id} onClick={() => setWatchID(room.id)}>
<List.Item.Meta
avatar={
<div className={styles.container}>
<div className={styles.search}>
<Input
className={styles.input}
placeholder="搜索房间"
bordered={false}
suffix={<Button type="text" icon={<SearchOutlined />} />}
/>
</div>
<ScrollableArea maxHeight="50vh">
{readyState === ReadyState.CONNECTING || rooms.length === 0 ? (
<Empty />
) : (
rooms.map((room) => (
<div key={room.id}>
<div
className={classNames(styles.item, {
[styles["item-selected"]]: watchID && watchID === room.id,
})}
onClick={() => (watchStore.watchID = room.id)}
>
<div className={styles.avatar}>
<Avatar
src={avatarApi.replace(
"{username}",
room.users?.at(0)?.username ?? "?",
)}
/>
}
title={`${room.users?.at(0)?.username} 与 ${room.users?.at(1)
?.username} 的决斗`}
/>
</List.Item>
<Avatar
src={avatarApi.replace(
"{username}",
room.users?.at(1)?.username ?? "?",
)}
/>
</div>
<div className={styles.title}>
{`${room.users?.at(0)?.username} 与 ${room.users?.at(1)
?.username} 的决斗`}
</div>
<div className={styles.mode}>竞技匹配</div>
</div>
<Divider className={styles.divider} />
</div>
))
)}
</ScrollableArea>
</div>
);
};
......@@ -18,7 +18,7 @@ import styles from "./index.module.scss";
import { MatchModal, matchStore } from "./MatchModal";
import { ReplayModal, replayOpen } from "./ReplayModal";
import { connectSrvpro, getEncryptedPasswd } from "./util";
import { WatchContent } from "./WatchContent";
import { WatchContent, watchStore } from "./WatchContent";
const { servers: serverList } = useConfig();
......@@ -38,9 +38,11 @@ export const Component: React.FC = () => {
const [singleLoading, setSingleLoading] = useState(false); // 单人模式的loading状态
const [matchLoading, setMatchLoading] = useState(false); // 匹配模式的loading状态
const [watchLoading, setWatchLoading] = useState(false); // 观战模式的loading状态
const [watchID, setWatchID] = useState<string | undefined>(undefined);
const navigate = useNavigate();
// FIXME: 这里有bug,第一次选择房间的时候获取不到watchID
const { watchID } = useSnapshot(watchStore);
// 竞技匹配
const onCompetitiveMatch = () => message.error("暂未开放,敬请期待");
......@@ -71,6 +73,7 @@ export const Component: React.FC = () => {
} else {
modal.info({
icon: null,
width: "40vw",
okText: "进入观战",
onOk: async () => {
if (watchID) {
......@@ -98,7 +101,7 @@ export const Component: React.FC = () => {
},
centered: true,
maskClosable: true,
content: <WatchContent setWatchID={setWatchID} />,
content: <WatchContent />,
});
}
};
......
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