Commit ebe9d703 authored by Chunchi Che's avatar Chunchi Che

use waitroom v2

parent 3090b5bb
Pipeline #20095 failed with stages
in 3 minutes and 41 seconds
import React from "react"; import React from "react";
import JoinRoom from "./JoinRoom"; import JoinRoom from "./JoinRoom";
import WaitRoom from "./WaitRoom";
import WaitRoomV2 from "./WaitRoomV2"; import WaitRoomV2 from "./WaitRoomV2";
import { Routes, Route } from "react-router-dom"; import { Routes, Route } from "react-router-dom";
import Mora from "./Mora"; import Mora from "./Mora";
...@@ -11,10 +10,9 @@ export default function () { ...@@ -11,10 +10,9 @@ 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 />} />
<Route path="/waitroomv2" element={<WaitRoomV2 />} />
</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,8 +81,6 @@ export default function WaitRoom() { ...@@ -68,8 +81,6 @@ 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 handleChoseDeck = async () => { const handleChoseDeck = async () => {
const deck = await fetchDeck("hero"); const deck = await fetchDeck("hero");
...@@ -87,51 +98,132 @@ export default function WaitRoom() { ...@@ -87,51 +98,132 @@ export default function WaitRoom() {
sendHsStart(); sendHsStart();
}; };
const navigate = useNavigate();
const items: MenuProps["items"] = [
{
label: "卡组1",
key: "1",
},
{
label: "卡组2",
key: "2",
},
{
label: "卡组3",
key: "3",
},
];
const [api, contextHolder] = notification.useNotification();
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)}
onClick={handleChoseReady}
>
决斗准备
</Button> </Button>
</p> </Space>
<p> <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}> <Button onClick={handleChoseStart}>
<Link <Link
to={ to={
// 若当前玩家是房主并且对战双方都已准备完毕,跳转到猜拳页面; // 若当前玩家是房主并且对战双方都已准备完毕,跳转到猜拳页面;
// 否则停留在当前页面。 // 否则停留在当前页面。
!isHost || !isHost ||
!joined ||
player0.state !== READY_STATE || player0.state !== READY_STATE ||
player1.state !== READY_STATE player1.state !== READY_STATE
? {} ? {}
: { pathname: `/mora` } : { pathname: `/mora` }
} }
> >
start 开始游戏
</Link> </Link>
</Button> </Button>
</p> </Space>
</div> </Space>
<div className="roomRegion"> </>
<h2>Room Passwd: {passWd}</h2> }
<p> onCancel={() => {
player0: {player0.isHost == true ? "[Host]" : ""} {player0.name}{" "} // 断开websocket🔗,
{player0.state} socketMiddleWare({ cmd: socketCmd.DISCONNECT });
</p> // 回到初始界面
<p> navigate("/");
player1: {player1.isHost == true ? "[Host]" : ""} {player1.name}{" "} }}
{player1.state} >
</p> <Space direction="vertical" size={16}>
<p>observer: {observerCount}</p> <Space wrap size={16}>
<p>chat: {chat}</p> <Avatar size={30} icon={<UserOutlined />} />
</div> <Checkbox
</div> 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, onClick: ({ key }) => {} }}>
<a onClick={(e) => e.preventDefault()}>
<Space>
卡组选择
<DownOutlined />
</Space>
</a>
</Dropdown>
</Space>
</Modal>
{contextHolder}
</>
); );
} };
export default WaitRoom;
import { Modal, Checkbox, Avatar, Space, Button, Dropdown, Tag } from "antd";
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 {
UserOutlined,
CheckCircleFilled,
LoginOutlined,
LogoutOutlined,
SendOutlined,
DownOutlined,
TagOutlined,
} from "@ant-design/icons";
import { initMeExtraDeckMeta } from "../reducers/duel/extraDeckSlice";
import type { MenuProps } from "antd";
import { Link, useParams } from "react-router-dom";
const READY_STATE = "ready";
const WaitRoom = () => {
const params = useParams<{
player?: string;
passWd?: string;
ip?: string;
}>();
const [choseDeck, setChoseDeck] = useState<boolean>(false);
const { player, passWd, ip } = params;
const dispatch = store.dispatch;
const isHost = useAppSelector(selectIsHost);
const player0 = useAppSelector(selectPlayer0);
const player1 = useAppSelector(selectPlayer1);
const handleChoseDeck = async () => {
const deck = await fetchDeck("hero");
sendUpdateDeck(deck);
dispatch(initMeExtraDeckMeta({ controler: 0, codes: deck.extra || [] }));
setChoseDeck(true);
};
const handleChoseReady = () => {
sendHsReady();
};
const handleChoseStart = () => {
sendHsStart();
};
const items: MenuProps["items"] = [
{
label: "卡组1",
key: "1",
},
{
label: "卡组2",
key: "2",
},
{
label: "卡组3",
key: "3",
},
];
useEffect(() => {
if (ip && player && player.length != 0 && passWd && passWd.length != 0) {
const init = async () => {
// 页面第一次渲染时,通过socket中间件向ygopro服务端请求建立长连接
socketMiddleWare({
cmd: socketCmd.CONNECT,
initInfo: {
ip,
player,
passWd,
},
});
// 初始化sqlite
await sqliteMiddleWare({
cmd: sqliteCmd.INIT,
initInfo: { dbUrl: "/ygopro-database/locales/zh-CN/cards.cdb" },
});
};
init();
}
}, []);
return (
<Modal
title="单局房间"
open={true}
footer={
<>
<Space direction="vertical" size={10}>
<Space wrap size={10}>
<Avatar size={25} icon={<CheckCircleFilled />} />
<Button disabled={!choseDeck} onClick={handleChoseReady}>
决斗准备
</Button>
</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 ||
player0.state !== READY_STATE ||
player1.state !== READY_STATE
? {}
: { pathname: `/mora` }
}
>
开始游戏
</Link>
</Button>
</Space>
</Space>
</>
}
>
<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, onClick: ({ key }) => {} }}>
<a onClick={(e) => e.preventDefault()}>
<Space>
卡组选择
<DownOutlined />
</Space>
</a>
</Dropdown>
</Space>
</Modal>
);
};
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