115 lines
3.1 KiB
TypeScript
115 lines
3.1 KiB
TypeScript
import useWebSocket from "react-use-websocket";
|
|
import React from "react";
|
|
import {useNavigate, useParams} from "react-router";
|
|
import {GHButton} from "../components/Button";
|
|
import useTitle from "../../utils/hooks/TitleHook";
|
|
import Game from "../components/Game";
|
|
|
|
interface GameState {
|
|
PlayerName: string;
|
|
Hand: string[];
|
|
CurrentCard: string;
|
|
CurrentPlayer: string;
|
|
Players: string[];
|
|
}
|
|
|
|
interface ChatMessage {
|
|
PlayerName: string;
|
|
Message: string;
|
|
}
|
|
|
|
interface SocketMessage {
|
|
Type: string;
|
|
Payload: any;
|
|
}
|
|
|
|
const Room = () => {
|
|
|
|
useTitle('Mau!');
|
|
|
|
const navigateTo = useNavigate();
|
|
|
|
const {roomId} = useParams();
|
|
|
|
const WS_URL = `${process.env.REACT_APP_WEBSOCKET_URL}/room/${roomId}`;
|
|
|
|
const [gameState, setGameState] = React.useState<GameState>({
|
|
PlayerName: '',
|
|
Hand: [],
|
|
CurrentCard: '',
|
|
CurrentPlayer: '',
|
|
Players: []
|
|
});
|
|
const [chatMessages, setChatMessages] = React.useState<ChatMessage[]>([]);
|
|
const [chatInput, setChatInput] = React.useState<string>('');
|
|
|
|
const websocket = useWebSocket(WS_URL, {
|
|
onOpen: () => {
|
|
console.log('WebSocket connection established.');
|
|
},
|
|
onMessage: (event) => {
|
|
const data = JSON.parse(event.data);
|
|
const payload = JSON.parse(data.Payload);
|
|
if (data.Type === 'GAME') setGameState(payload);
|
|
if (data.Type === 'CHAT') setChatMessages(prev => [...prev, payload]);
|
|
}
|
|
});
|
|
|
|
const handleLeaveRoom = () => {
|
|
const socket = websocket.getWebSocket();
|
|
if (socket) socket.close();
|
|
navigateTo('/');
|
|
}
|
|
|
|
const handleSend = (message: SocketMessage) => {
|
|
websocket.sendMessage(JSON.stringify(message));
|
|
}
|
|
|
|
const handleCardSend = (card: string) => {
|
|
handleSend({
|
|
Type: "GAME",
|
|
Payload: JSON.stringify({
|
|
Action: "PLAYCARD",
|
|
Data: JSON.stringify({
|
|
CardType: card.split(' ')[0],
|
|
CardValue: card.split(' ')[1]
|
|
})
|
|
})
|
|
})
|
|
}
|
|
|
|
const handleDraw = () => {
|
|
handleSend({
|
|
Type: "GAME",
|
|
Payload: JSON.stringify({
|
|
Action: "DRAW",
|
|
Data: ""
|
|
})
|
|
});
|
|
}
|
|
|
|
const handleChat = (message: string) => {
|
|
handleSend({
|
|
Type: "CHAT",
|
|
Payload: message
|
|
});
|
|
}
|
|
|
|
return (
|
|
<div>
|
|
<h1>Room {roomId}</h1>
|
|
<GHButton onClick={handleLeaveRoom}>Leave Room</GHButton>
|
|
<Game gameState={gameState} handleCardSend={handleCardSend} handleDraw={handleDraw}/>
|
|
<input type="text" placeholder={"Chat"} value={chatInput} onChange={(e) => setChatInput(e.target.value)} />
|
|
<button onClick={() => handleChat(chatInput)}>Send</button>
|
|
<ul>
|
|
{chatMessages.map((message, index) => (
|
|
<li key={index}>{message.PlayerName}: {message.Message}</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default Room;
|