Commit 60b5b6ba authored by Chunchi Che's avatar Chunchi Che

impl WatchModal

parent 714bed00
Pipeline #23634 passed with stages
in 13 minutes and 17 seconds
...@@ -16,11 +16,12 @@ ...@@ -16,11 +16,12 @@
"loginUrl":"https://accounts.moecube.com/signin", "loginUrl":"https://accounts.moecube.com/signin",
"logoutUrl":"https://accounts.moecube.com/signout", "logoutUrl":"https://accounts.moecube.com/signout",
"profileUrl":"https://accounts.moecube.com/profiles", "profileUrl":"https://accounts.moecube.com/profiles",
"athleticWatchUrl":"wss://tiramisu.moecube.com:8923",
"entertainWatchUrl":"wss://tiramisu.moecube.com:7923",
"streamInterval":20, "streamInterval":20,
"startDelay":1000, "startDelay":1000,
"ui":{ "ui":{
"hint":{ "hint":{
"waitingDuration":1.5,
"maxCount":1 "maxCount":1
} }
}, },
......
...@@ -16,11 +16,12 @@ ...@@ -16,11 +16,12 @@
"loginUrl":"https://accounts.moecube.com/signin", "loginUrl":"https://accounts.moecube.com/signin",
"logoutUrl":"https://accounts.moecube.com/signout", "logoutUrl":"https://accounts.moecube.com/signout",
"profileUrl":"https://accounts.moecube.com/profiles", "profileUrl":"https://accounts.moecube.com/profiles",
"athleticWatchUrl":"wss://tiramisu.moecube.com:8923",
"entertainWatchUrl":"wss://tiramisu.moecube.com:7923",
"streamInterval":20, "streamInterval":20,
"startDelay":1000, "startDelay":1000,
"ui":{ "ui":{
"hint":{ "hint":{
"waitingDuration":1.5,
"maxCount":1 "maxCount":1
} }
}, },
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
"react-dnd-html5-backend": "^16.0.1", "react-dnd-html5-backend": "^16.0.1",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-router-dom": "^6.15.0", "react-router-dom": "^6.15.0",
"react-use-websocket": "^4.5.0",
"sql.js": "^1.8.0", "sql.js": "^1.8.0",
"u-reset.css": "^2.0.1", "u-reset.css": "^2.0.1",
"uuid": "^9.0.0", "uuid": "^9.0.0",
...@@ -5934,6 +5935,15 @@ ...@@ -5934,6 +5935,15 @@
"react-dom": ">=16.8" "react-dom": ">=16.8"
} }
}, },
"node_modules/react-use-websocket": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/react-use-websocket/-/react-use-websocket-4.5.0.tgz",
"integrity": "sha512-oxYVLWM3Lv0InCfjW7hG/Hk0hkE0P1SiLd5/I3d5x0W4riAnDUkD4VEu7qNVAqxNjBF3nU7k0jLMOetLXpwfsA==",
"peerDependencies": {
"react": ">= 18.0.0",
"react-dom": ">= 18.0.0"
}
},
"node_modules/reactcss": { "node_modules/reactcss": {
"version": "1.2.3", "version": "1.2.3",
"resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz", "resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz",
...@@ -11106,6 +11116,12 @@ ...@@ -11106,6 +11116,12 @@
"react-router": "6.15.0" "react-router": "6.15.0"
} }
}, },
"react-use-websocket": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/react-use-websocket/-/react-use-websocket-4.5.0.tgz",
"integrity": "sha512-oxYVLWM3Lv0InCfjW7hG/Hk0hkE0P1SiLd5/I3d5x0W4riAnDUkD4VEu7qNVAqxNjBF3nU7k0jLMOetLXpwfsA==",
"requires": {}
},
"reactcss": { "reactcss": {
"version": "1.2.3", "version": "1.2.3",
"resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz", "resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz",
......
import { Modal } from "antd"; import { App, List, Modal } from "antd";
import React from "react"; import React, { useState } from "react";
import useWebSocket, { ReadyState } from "react-use-websocket";
import { proxy, useSnapshot } from "valtio"; import { proxy, useSnapshot } from "valtio";
import { useConfig } from "@/config";
const { athleticWatchUrl } = useConfig();
interface Info {
event: "init" | "create" | "update" | "delete";
data: Room | Room[] | string;
}
interface Room {
id?: string;
title?: string;
users?: { username: string; position: number }[];
options: Options;
}
interface Options {
mode: number;
rule: number;
start_lp: number;
start_lp_tag: number;
start_hand: number;
draw_count: number;
duel_rule: number;
no_check_deck: boolean;
no_shuffle_deck: boolean;
lflist?: number;
time_limit?: number;
auto_death: boolean;
}
const localStore = proxy({ const localStore = proxy({
open: false, open: false,
}); });
export const WatchModal: React.FC = () => { export const WatchModal: React.FC = () => {
const { open } = useSnapshot(localStore); const { open } = useSnapshot(localStore);
const [rooms, setRooms] = useState<Room[]>([]);
const { message } = App.useApp();
const url = new URL(athleticWatchUrl);
url.searchParams.set("filter", "started");
const { readyState } = useWebSocket(url.toString(), {
onMessage: (event) => {
const info: Info = JSON.parse(event.data);
switch (info.event) {
case "init": {
//@ts-ignore
const rooms: Room[] = info.data;
setRooms(rooms);
break;
}
case "create": {
//@ts-ignore
const room: Room = info.data;
setRooms((prev) => prev.concat(room));
break;
}
case "update": {
//@ts-ignore
const room: Room = info.data;
setRooms((prev) => {
const target = prev.find((item) => item.id === room.id);
if (target) {
Object.assign(target, info.data);
}
return prev;
});
break;
}
case "delete": {
//@ts-ignore
const id: string = info.data;
setRooms((prev) => {
prev.splice(
prev.findIndex((room) => room.id === id),
1,
);
return prev;
});
break;
}
}
},
onError: (_e) => message.error("Websocket Error!"),
});
return ( return (
<Modal <Modal
title="观看回放" title="观看回放"
...@@ -15,7 +98,28 @@ export const WatchModal: React.FC = () => { ...@@ -15,7 +98,28 @@ export const WatchModal: React.FC = () => {
centered centered
footer={<></>} footer={<></>}
onCancel={() => (localStore.open = false)} onCancel={() => (localStore.open = false)}
></Modal> >
<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}>
<List.Item.Meta
title={`${room.users?.at(0)?.username}与${room.users?.at(1)
?.username}的决斗`}
/>
</List.Item>
)}
/>
</Modal>
); );
}; };
......
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