import { useState } from "react"; import { useParams, useNavigate, useLocation } from "react-router-dom"; import { useGameRoom } from "../lib/useGameRoom"; import { gameUIRegistry } from "./registry"; import { Loader2 } from "lucide-react"; function CopyInviteLink({ url }: { url: string }) { const [copied, setCopied] = useState(false); function copy() { navigator.clipboard.writeText(url).then(() => { setCopied(true); setTimeout(() => setCopied(false), 2000); }); } return (
Share this link to invite:
{url}
); } export function GameRoom({ userId, role }: { userId: string; role?: string }) { const { gameSlug, roomId } = useParams<{ gameSlug: string; roomId: string }>(); const navigate = useNavigate(); const location = useLocation(); const preferAs = (location.state as { preferAs?: "player" | "spectator" } | null)?.preferAs ?? "player"; const { gameState, players, spectators, roomStatus, isSpectator, gameOver, error, sendAction, leaveRoom, sessionReplaced, rejoin, fillRoom, startGame, roomOptions, } = useGameRoom(roomId!, userId, role, preferAs); const betAmount = roomOptions.betAmount ?? 0; const plugin = gameSlug ? gameUIRegistry.get(gameSlug) : undefined; if (!plugin) { return (
Unknown Game

The game type "{gameSlug}" doesn't exist.

); } if (roomStatus === "not_found") { return (
Room Not Found

This room no longer exists or has expired.

); } if (roomStatus === "connecting") { return (

{preferAs === "spectator" ? "Joining as spectator..." : "Joining room..."}

); } const GameComponent = plugin.component; return (
{plugin.icon}

{plugin.name}

{roomStatus === "waiting" ? "Waiting" : roomStatus === "playing" ? "Playing" : "Finished"} {isSpectator && Spectating} {betAmount > 0 && ( {betAmount} AU{players.length > 1 ? `/player` : ""} )} 👁 {spectators.length}
{sessionReplaced && (

You opened this game in another tab. Actions from this tab are disabled.

)} {error && (
{error}
)} {gameOver && (
{gameOver.winner ? `Winner: ${players.find(p => p.discordId === gameOver.winner)?.username ?? gameOver.winner}` : "Draw!"}
{gameOver.reason}
{gameOver.payout && (
{gameOver.payout.refunded ? `Wager refunded: ${gameOver.payout.amount} AU` : `Payout: ${gameOver.payout.amount} AU`}
)}
)} {roomStatus === "finished" && (
)} {roomStatus === "waiting" && (
Waiting for players ({players.length}/{plugin.maxPlayers})
{Array.from({ length: Math.max(players.length + 1, plugin.minPlayers ?? 1, Math.min(plugin.maxPlayers, 4)) }).map((_, i) => { if (i >= plugin.maxPlayers) return null; const player = players[i]; return (
{player ? player.username[0]?.toUpperCase() : "?"}
{player ? player.username : Waiting...}
Player {i + 1}
); })}
{plugin.manualStart && players.length >= (plugin.minPlayers ?? 1) && players[0]?.discordId === userId && ( )} {role === "admin" && players.length < plugin.maxPlayers && ( )}
)} {(roomStatus === "playing" || roomStatus === "finished") && gameState != null && ( )}
); }