Commit 3e96018c authored by Chunchi Che's avatar Chunchi Che

Merge branch 'optimize/wait_room' into 'main'

Optimize/wait room

See merge request mycard/Neos!102
parents 522ad723 60bab06a
Pipeline #20098 passed with stages
in 4 minutes and 43 seconds
import React from "react"; import React from "react";
import JoinRoom from "./JoinRoom"; import JoinRoom from "./JoinRoom";
import WaitRoom from "./WaitRoom"; import WaitRoomV2 from "./WaitRoom";
import { Routes, Route } from "react-router-dom"; import { Routes, Route } from "react-router-dom";
import Mora from "./Mora"; import Mora from "./Mora";
import NeosDuel from "./Duel/main"; import NeosDuel from "./Duel/main";
...@@ -10,7 +10,7 @@ export default function () { ...@@ -10,7 +10,7 @@ export default function () {
return ( return (
<Routes> <Routes>
<Route path="/" element={<JoinRoom />} /> <Route path="/" element={<JoinRoom />} />
<Route path="/:player/:passWd/:ip" element={<WaitRoom />} /> <Route path="/:player/:passWd/:ip" element={<WaitRoomV2 />} />
<Route path="/mora" element={<Mora />} /> <Route path="/mora" element={<Mora />} />
<Route path="/duel" element={<NeosDuel />} /> <Route path="/duel" element={<NeosDuel />} />
</Routes> </Routes>
......
/* import {
* 等待房间页面 Modal,
* Checkbox,
* */ Avatar,
import React, { useEffect, useState } from "react"; Space,
import { Link, useParams } from "react-router-dom"; Button,
import { fetchDeck } from "../api/deck"; Dropdown,
import { useAppSelector } from "../hook"; notification,
import { selectJoined } from "../reducers/joinSlice"; } from "antd";
import { selectChat } from "../reducers/chatSlice"; import { useNavigate } from "react-router-dom";
import React, { useState, useEffect } from "react";
import socketMiddleWare, { socketCmd } from "../middleware/socket";
import sqliteMiddleWare, { sqliteCmd } from "../middleware/sqlite";
import { store } from "../store";
import { import {
selectIsHost, selectIsHost,
selectPlayer0, selectPlayer0,
selectPlayer1, selectPlayer1,
selectObserverCount,
} from "../reducers/playerSlice"; } from "../reducers/playerSlice";
import { useAppSelector } from "../hook";
import { selectJoined } from "../reducers/joinSlice";
import { selectChat } from "../reducers/chatSlice";
import { fetchDeck } from "../api/deck";
import { import {
sendUpdateDeck, sendUpdateDeck,
sendHsReady, sendHsReady,
sendHsStart, sendHsStart,
} from "../api/ocgcore/ocgHelper"; } from "../api/ocgcore/ocgHelper";
import socketMiddleWare, { socketCmd } from "../middleware/socket"; import {
import sqliteMiddleWare, { sqliteCmd } from "../middleware/sqlite"; UserOutlined,
import { Button } from "antd"; CheckCircleFilled,
import { store } from "../store"; LoginOutlined,
LogoutOutlined,
SendOutlined,
DownOutlined,
TagOutlined,
} from "@ant-design/icons";
import { initMeExtraDeckMeta } from "../reducers/duel/extraDeckSlice"; import { initMeExtraDeckMeta } from "../reducers/duel/extraDeckSlice";
import "../styles/core.scss"; import type { MenuProps } from "antd";
import { Link, useParams } from "react-router-dom";
const READY_STATE = "ready"; const READY_STATE = "ready";
export default function WaitRoom() { const WaitRoom = () => {
const params = useParams<{ const params = useParams<{
player?: string; player?: string;
passWd?: string; passWd?: string;
...@@ -68,10 +81,18 @@ export default function WaitRoom() { ...@@ -68,10 +81,18 @@ export default function WaitRoom() {
const isHost = useAppSelector(selectIsHost); const isHost = useAppSelector(selectIsHost);
const player0 = useAppSelector(selectPlayer0); const player0 = useAppSelector(selectPlayer0);
const player1 = useAppSelector(selectPlayer1); const player1 = useAppSelector(selectPlayer1);
const observerCount = useAppSelector(selectObserverCount); const [api, contextHolder] = notification.useNotification();
const [deckTitle, setDeckTitle] = useState("请选择卡组");
// FIXME: 这些数据应该从`store`中获取
const decks: MenuProps["items"] = [
{
label: "hero",
key: "hero",
},
];
const handleChoseDeck = async () => { const handleChoseDeck = async (deckName: string) => {
const deck = await fetchDeck("hero"); const deck = await fetchDeck(deckName);
sendUpdateDeck(deck); sendUpdateDeck(deck);
dispatch(initMeExtraDeckMeta({ controler: 0, codes: deck.extra || [] })); dispatch(initMeExtraDeckMeta({ controler: 0, codes: deck.extra || [] }));
...@@ -87,51 +108,125 @@ export default function WaitRoom() { ...@@ -87,51 +108,125 @@ export default function WaitRoom() {
sendHsStart(); sendHsStart();
}; };
const navigate = useNavigate();
useEffect(() => {
if (joined) {
api.info({ message: "成功加入房间!", placement: "top" });
}
}, [joined]);
useEffect(() => {
if (chat != "") {
api.info({ message: "Chat", description: chat, placement: "bottom" });
}
}, [chat]);
return ( return (
<div className="wait_container"> <>
<div className="playerRegion"> <Modal
<h2>{joined ? "Room Joined!" : "Room Not Joined."}</h2> title="单局房间"
<p> open={true}
<Button disabled={!joined} onClick={handleChoseDeck}> footer={
choose hero.ydk <>
</Button> <Space direction="vertical" size={10}>
</p> <Space wrap size={10}>
<p> <Avatar size={25} icon={<CheckCircleFilled />} />
<Button disabled={!choseDeck} onClick={handleChoseReady}> <Button
ready disabled={!(choseDeck && joined)}
</Button> onClick={handleChoseReady}
</p> >
<p> 决斗准备
<Button onClick={handleChoseStart}> </Button>
<Link </Space>
to={ <Space wrap size={10}>
// 若当前玩家是房主并且对战双方都已准备完毕,跳转到猜拳页面; <Avatar size={25} icon={<LoginOutlined />} />
// 否则停留在当前页面。 <Button>到决斗者</Button>
!isHost || </Space>
player0.state !== READY_STATE || <Space wrap size={10}>
player1.state !== READY_STATE <Avatar size={25} icon={<LogoutOutlined />} />
? {} <Button>到旁观者</Button>
: { pathname: `/mora` } </Space>
} <Space wrap size={10}>
<Avatar size={25} icon={<SendOutlined />} />
<Button onClick={handleChoseStart}>
<Link
to={
// 若当前玩家是房主并且对战双方都已准备完毕,跳转到猜拳页面;
// 否则停留在当前页面。
!isHost ||
!joined ||
player0.state !== READY_STATE ||
player1.state !== READY_STATE
? {}
: { pathname: `/mora` }
}
>
开始游戏
</Link>
</Button>
</Space>
</Space>
</>
}
onCancel={() => {
// 断开websocket🔗,
socketMiddleWare({ cmd: socketCmd.DISCONNECT });
// 回到初始界面
navigate("/");
}}
>
<Space direction="vertical" size={16}>
<Space wrap size={16}>
<Avatar size={30} icon={<UserOutlined />} />
<Checkbox
defaultChecked={false}
checked={player0.state === READY_STATE}
disabled
>
{player0.name}
</Checkbox>
{player0.isHost === true ? (
<Avatar size={30} icon={<TagOutlined />} />
) : (
<></>
)}
</Space>
<Space wrap size={16}>
<Avatar size={30} icon={<UserOutlined />} />
<Checkbox
defaultChecked={false}
checked={player1.state === READY_STATE}
disabled
> >
start {player1.name}
</Link> </Checkbox>
</Button> {player1.isHost === true ? (
</p> <Avatar size={30} icon={<TagOutlined />} />
</div> ) : (
<div className="roomRegion"> <></>
<h2>Room Passwd: {passWd}</h2> )}
<p> </Space>
player0: {player0.isHost == true ? "[Host]" : ""} {player0.name}{" "} <Dropdown
{player0.state} menu={{
</p> items: decks,
<p> onClick: async ({ key }) => {
player1: {player1.isHost == true ? "[Host]" : ""} {player1.name}{" "} await handleChoseDeck(key);
{player1.state} setDeckTitle(key);
</p> },
<p>observer: {observerCount}</p> }}
<p>chat: {chat}</p> >
</div> <a onClick={(e) => e.preventDefault()}>
</div> <Space>
{deckTitle}
<DownOutlined />
</Space>
</a>
</Dropdown>
</Space>
</Modal>
{contextHolder}
</>
); );
} };
export default WaitRoom;
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