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";
import "./chess";
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,
} = useGameRoom(roomId!, userId, role, preferAs);
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}
👁 {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!"}
Reason: {gameOver.reason}
)}
{roomStatus === "finished" && (
)}
{roomStatus === "waiting" && (
Waiting for players ({players.length}/{plugin.maxPlayers})
{Array.from({ length: plugin.maxPlayers }).map((_, i) => {
const player = players[i];
return (
{player ? player.username[0]?.toUpperCase() : "?"}
{player ? player.username : Waiting...}
Player {i + 1}
);
})}
{role === "admin" && players.length < plugin.maxPlayers && (
)}
)}
{(roomStatus === "playing" || roomStatus === "finished") && gameState != null && (
)}
);
}