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 JoinRoom from "./JoinRoom";
import WaitRoom from "./WaitRoom";
import WaitRoomV2 from "./WaitRoom";
import { Routes, Route } from "react-router-dom";
import Mora from "./Mora";
import NeosDuel from "./Duel/main";
......@@ -10,7 +10,7 @@ export default function () {
return (
<Routes>
<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="/duel" element={<NeosDuel />} />
</Routes>
......
/*
* 等待房间页面
*
* */
import React, { useEffect, useState } from "react";
import { Link, useParams } from "react-router-dom";
import { fetchDeck } from "../api/deck";
import { useAppSelector } from "../hook";
import { selectJoined } from "../reducers/joinSlice";
import { selectChat } from "../reducers/chatSlice";
import {
Modal,
Checkbox,
Avatar,
Space,
Button,
Dropdown,
notification,
} from "antd";
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 {
selectIsHost,
selectPlayer0,
selectPlayer1,
selectObserverCount,
} from "../reducers/playerSlice";
import { useAppSelector } from "../hook";
import { selectJoined } from "../reducers/joinSlice";
import { selectChat } from "../reducers/chatSlice";
import { fetchDeck } from "../api/deck";
import {
sendUpdateDeck,
sendHsReady,
sendHsStart,
} from "../api/ocgcore/ocgHelper";
import socketMiddleWare, { socketCmd } from "../middleware/socket";
import sqliteMiddleWare, { sqliteCmd } from "../middleware/sqlite";
import { Button } from "antd";
import { store } from "../store";
import {
UserOutlined,
CheckCircleFilled,
LoginOutlined,
LogoutOutlined,
SendOutlined,
DownOutlined,
TagOutlined,
} from "@ant-design/icons";
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";
export default function WaitRoom() {
const WaitRoom = () => {
const params = useParams<{
player?: string;
passWd?: string;
......@@ -68,10 +81,18 @@ export default function WaitRoom() {
const isHost = useAppSelector(selectIsHost);
const player0 = useAppSelector(selectPlayer0);
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 deck = await fetchDeck("hero");
const handleChoseDeck = async (deckName: string) => {
const deck = await fetchDeck(deckName);
sendUpdateDeck(deck);
dispatch(initMeExtraDeckMeta({ controler: 0, codes: deck.extra || [] }));
......@@ -87,51 +108,125 @@ export default function WaitRoom() {
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 (
<div className="wait_container">
<div className="playerRegion">
<h2>{joined ? "Room Joined!" : "Room Not Joined."}</h2>
<p>
<Button disabled={!joined} onClick={handleChoseDeck}>
choose hero.ydk
</Button>
</p>
<p>
<Button disabled={!choseDeck} onClick={handleChoseReady}>
ready
<>
<Modal
title="单局房间"
open={true}
footer={
<>
<Space direction="vertical" size={10}>
<Space wrap size={10}>
<Avatar size={25} icon={<CheckCircleFilled />} />
<Button
disabled={!(choseDeck && joined)}
onClick={handleChoseReady}
>
决斗准备
</Button>
</p>
<p>
</Space>
<Space wrap size={10}>
<Avatar size={25} icon={<LoginOutlined />} />
<Button>到决斗者</Button>
</Space>
<Space wrap size={10}>
<Avatar size={25} icon={<LogoutOutlined />} />
<Button>到旁观者</Button>
</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` }
}
>
start
开始游戏
</Link>
</Button>
</p>
</div>
<div className="roomRegion">
<h2>Room Passwd: {passWd}</h2>
<p>
player0: {player0.isHost == true ? "[Host]" : ""} {player0.name}{" "}
{player0.state}
</p>
<p>
player1: {player1.isHost == true ? "[Host]" : ""} {player1.name}{" "}
{player1.state}
</p>
<p>observer: {observerCount}</p>
<p>chat: {chat}</p>
</div>
</div>
</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
>
{player1.name}
</Checkbox>
{player1.isHost === true ? (
<Avatar size={30} icon={<TagOutlined />} />
) : (
<></>
)}
</Space>
<Dropdown
menu={{
items: decks,
onClick: async ({ key }) => {
await handleChoseDeck(key);
setDeckTitle(key);
},
}}
>
<a onClick={(e) => e.preventDefault()}>
<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