skyjo-fe/src/App.tsx
2023-09-18 14:01:33 +02:00

189 lines
6 KiB
TypeScript

import { useState, useEffect } from "react";
import { socket } from "./socket";
import { ConnectionState } from "./components/ConnectionState";
import { ConnectionManager } from "./components/ConnectionManager";
import { JoinSession } from "./components/JoinSession";
import { Events } from "./components/Events";
import { Game } from "./types/gameTypes";
import Action from "./components/Action";
export default function App() {
const [isConnected, setIsConnected] = useState(socket.connected);
const [messageEvents, setMessageEvents] = useState<string[]>([]);
const [session, setSession] = useState("");
const [clientsInRoom, setClientsInRoom] = useState(0);
const [gameData, setGameData] = useState<Game | null>(null);
const [messageDispaly, setMessageDisplay] = useState<string>("");
const showStartGameButton = session !== "" && clientsInRoom >= 2;
const remainingInCardStack = gameData?.cardStack?.cards?.length || 0;
const remainingInDiscardPile = gameData?.discardPile?.length || 0;
const topCardInDiscardPile =
gameData?.discardPile?.[remainingInDiscardPile - 1];
const playersData = extractMyData(gameData);
function startGame() {
socket.emit("new-game", { sessionId: session });
}
function clickCard(cardPosition: number) {
console.log("Clicked card", cardPosition);
socket.emit("click-card", cardPosition);
}
function drawFromCardStack() {
console.log("Draw card");
socket.emit("draw-from-card-stack", { sessionId: session });
}
function clickDiscardPile() {
console.log("Clicked discard pile");
socket.emit("click-discard-pile", { sessionId: session });
}
function extractMyData(gameData: Game | null) {
if (!gameData) return undefined;
return gameData.players.find((player) => player.socketId === socket.id);
}
function setTempMessage(message: string) {
setMessageDisplay(message);
setTimeout(() => {
setMessageDisplay("");
}, 3000);
}
useEffect(() => {
if (gameData?.phase === "game-over") {
setTempMessage("Game Over");
} else if (gameData?.phase === "game-started") {
setTempMessage("Game Started");
} else if (gameData?.phase === "waiting-for-players") {
setTempMessage("Waiting for players");
}
}, [gameData]);
useEffect(() => {
function onConnect() {
setIsConnected(true);
}
function onDisconnect() {
setIsConnected(false);
}
function onClientsInRoomUpdate(clients: number) {
setClientsInRoom(clients);
}
function onMessageEvent(value: string) {
setMessageEvents((previous) => [...previous, value]);
}
function onGameUpdate(gameData: Game) {
console.log("New game data", gameData);
setGameData(gameData);
}
socket.on("connect", onConnect);
socket.on("disconnect", onDisconnect);
socket.on("message", onMessageEvent);
socket.on("clients-in-session", onClientsInRoomUpdate);
socket.on("game-update", onGameUpdate);
return () => {
socket.off("connect", onConnect);
socket.off("disconnect", onDisconnect);
socket.off("message", onMessageEvent);
socket.off("clients-in-session", onClientsInRoomUpdate);
socket.off("game-update", onGameUpdate);
};
}, []);
return (
<div className="App">
<ConnectionState
isConnected={isConnected}
session={session}
clientsInRoom={clientsInRoom}
/>
<Events events={messageEvents} />
<ConnectionManager />
<JoinSession session={session} setSession={setSession} />
{showStartGameButton && <button onClick={startGame}>Start Game</button>}
{gameData &&
gameData.players.map((playerData, index) => (
<div key={index}>
<p>Player ID: {playerData.id}</p>
<p>Player Name: {playerData.name}</p>
<table>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
</tr>
</thead>
<tbody>
{Array(Math.ceil(playerData.cards.length / 4))
.fill(null)
.map((_, rowIndex) => (
<tr key={rowIndex}>
{Array(4)
.fill(null)
.map((_, colIndex) => {
const card =
playerData.cards[rowIndex * 4 + colIndex];
return (
<td key={colIndex}>
{card && (
<Action
data={playerData}
action={() =>
clickCard(rowIndex * 4 + colIndex)
}
>
{card.value}
</Action>
)}
</td>
);
})}
</tr>
))}
</tbody>
</table>
</div>
))}
<br />
{gameData?.cardStack && remainingInCardStack > 0 && (
<div>
<Action data={playersData} action={drawFromCardStack}>
Draw
</Action>
<span style={{ color: "grey", marginLeft: "5px" }}>
{remainingInCardStack} in Card Set
</span>
</div>
)}
{gameData?.discardPile && remainingInDiscardPile > 0 && (
<div>
<Action data={playersData} action={clickDiscardPile}>
{topCardInDiscardPile?.value}
</Action>
<span style={{ color: "grey", marginLeft: "5px" }}>
{remainingInDiscardPile} Discard Pile
</span>
</div>
)}
{playersData?.cardCache && (
<div>
<p>Card Cache: {playersData.cardCache.value}</p>
</div>
)}
{messageDispaly && messageDispaly !== "" && <p>{messageDispaly}</p>}
</div>
);
}