not reseting state on browser disconnect or reconnect
This commit is contained in:
@@ -7,7 +7,7 @@ export const ClusterStatus = () => {
|
||||
const [channelStatus, setChannelStatus] = useState<string>("waiting");
|
||||
const [channel, setChannel] = useState<Channel | undefined>();
|
||||
const [clusterStatus, setClusterStatus] = useState<
|
||||
{ otherNodes: string[]; connectedNode: string } | undefined
|
||||
{ otherNodes: string[]; connectedNode: string, gameNode: string } | undefined
|
||||
>();
|
||||
|
||||
useEffect(() => {
|
||||
@@ -36,11 +36,12 @@ export const ClusterStatus = () => {
|
||||
|
||||
newChannel.on(
|
||||
"node_list",
|
||||
(payload: { other_nodes: string[]; connected_node: string }) => {
|
||||
(payload: { other_nodes: string[]; connected_node: string; game_node: string }) => {
|
||||
console.log("Received node list:", payload.other_nodes);
|
||||
setClusterStatus({
|
||||
otherNodes: payload.other_nodes,
|
||||
connectedNode: payload.connected_node,
|
||||
gameNode: payload.game_node,
|
||||
});
|
||||
},
|
||||
);
|
||||
@@ -58,40 +59,61 @@ export const ClusterStatus = () => {
|
||||
: [];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div>ClusterStatus</div>
|
||||
<div>Channel: {channelStatus}</div>
|
||||
<div className="bg-navy-800 border border-navy-600 rounded-lg p-4 min-w-64">
|
||||
|
||||
<div className=" text-navy-300 mb-3">
|
||||
Channel:{" "}
|
||||
<span
|
||||
className={
|
||||
channelStatus === "connected" ? "text-navy-200" : "text-navy-500"
|
||||
}
|
||||
>
|
||||
{channelStatus}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-navy-300 mb-2">
|
||||
Game Node:{" "}
|
||||
<span className="text-navy-200">
|
||||
{clusterStatus ? clusterStatus.gameNode : "unknown"}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
{allNodes.length === 0 ? (
|
||||
<span className="text-navy-300">No nodes available</span>
|
||||
<span className="text-navy-500 text-sm italic">
|
||||
No nodes available
|
||||
</span>
|
||||
) : (
|
||||
<>
|
||||
{allNodes.map((node) => {
|
||||
const isConnected = node === clusterStatus?.connectedNode;
|
||||
return (
|
||||
<div
|
||||
key={node}
|
||||
className={
|
||||
isConnected
|
||||
? "text-navy-100 font-semibold"
|
||||
: "text-navy-400"
|
||||
}
|
||||
>
|
||||
allNodes.map((node) => {
|
||||
const isConnected = node === clusterStatus?.connectedNode;
|
||||
return (
|
||||
<div
|
||||
key={node}
|
||||
className={`flex items-center justify-between gap-2 rounded px-2 py-1 text-sm ${
|
||||
isConnected ? "bg-navy-700 text-navy-100" : "text-navy-400"
|
||||
}`}
|
||||
>
|
||||
<span className="truncate">
|
||||
{node}
|
||||
{isConnected && (
|
||||
<span className="ml-2 text-xs text-navy-300">(you)</span>
|
||||
<span className="ml-2 text-xs text-navy-400">(you)</span>
|
||||
)}
|
||||
<button
|
||||
onClick={() => {
|
||||
channel?.push("kill_node", { node });
|
||||
}}
|
||||
>
|
||||
kill
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
</span>
|
||||
<button
|
||||
onClick={() => channel?.push("kill_node", { node })}
|
||||
className={`
|
||||
text-xs px-2 py-1 rounded border-2
|
||||
bg-accent-900 border-accent-400 text-accent-200
|
||||
hover:bg-accent-900 hover:border-accent-500 hover:text-accent-100
|
||||
transition-all duration-200
|
||||
`}
|
||||
>
|
||||
kill
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,6 @@ import { useWebSocketContext } from "./useWebSocketContext";
|
||||
interface GameChannelContextValue {
|
||||
channel: Channel | null;
|
||||
channelStatus: string;
|
||||
isJoined: boolean;
|
||||
isOverridden: boolean;
|
||||
joinGame: (name: string) => void;
|
||||
}
|
||||
@@ -23,7 +22,6 @@ export function GameChannelProvider({
|
||||
}) {
|
||||
const { socket, isConnected } = useWebSocketContext();
|
||||
const [channelStatus, setChannelStatus] = useState<string>("waiting");
|
||||
const [isJoined, setIsJoined] = useState(false);
|
||||
const [isOverridden, setIsOverridden] = useState(false);
|
||||
const [channel, setChannel] = useState<Channel | null>(null);
|
||||
|
||||
@@ -63,7 +61,6 @@ export function GameChannelProvider({
|
||||
console.log(`Leaving channel: ${channelName}`);
|
||||
newChannel.leave();
|
||||
setChannel(null);
|
||||
setIsJoined(false);
|
||||
setChannelStatus("waiting");
|
||||
};
|
||||
}, [socket, isConnected, channelName]);
|
||||
@@ -76,12 +73,10 @@ export function GameChannelProvider({
|
||||
.receive("ok", () => {
|
||||
console.log(`✓ Joined game as: ${name}`);
|
||||
setChannelStatus("joined");
|
||||
setIsJoined(true);
|
||||
})
|
||||
.receive("error", (resp: unknown) => {
|
||||
console.log(`✗ Failed to join game:`, resp);
|
||||
setChannelStatus("join failed");
|
||||
setIsJoined(false);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -90,7 +85,6 @@ export function GameChannelProvider({
|
||||
value={{
|
||||
channel,
|
||||
channelStatus,
|
||||
isJoined,
|
||||
isOverridden,
|
||||
joinGame,
|
||||
}}
|
||||
|
||||
@@ -16,15 +16,9 @@ const GameStateSchema = z.object({
|
||||
type Player = z.infer<typeof PlayerSchema>;
|
||||
|
||||
export const BoardDisplay = ({ playerName }: { playerName: string }) => {
|
||||
const { channel, isJoined, joinGame } = useGameChannelContext();
|
||||
const { channel, joinGame } = useGameChannelContext();
|
||||
const [players, setPlayers] = useState<Record<string, Player>>({});
|
||||
|
||||
useEffect(() => {
|
||||
if (channel && !isJoined) {
|
||||
joinGame(playerName);
|
||||
}
|
||||
}, [channel, isJoined, playerName, joinGame]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!channel) return;
|
||||
|
||||
@@ -43,8 +37,22 @@ export const BoardDisplay = ({ playerName }: { playerName: string }) => {
|
||||
};
|
||||
}, [channel]);
|
||||
|
||||
const playerNames = Object.keys(players);
|
||||
const isJoined = playerNames.includes(playerName);
|
||||
|
||||
return (
|
||||
<div className="relative w-200 h-150 bg-navy-800 my-12.5 mx-auto border-2 border-navy-700 overflow-hidden">
|
||||
{!isJoined && (
|
||||
<div className="absolute inset-0 flex items-center justify-center bg-navy-900/70 z-10">
|
||||
<button
|
||||
onClick={() => joinGame(playerName)}
|
||||
disabled={!channel}
|
||||
className="px-8 py-3 bg-accent-600 hover:bg-accent-500 disabled:bg-navy-600 disabled:cursor-not-allowed text-navy-100 font-semibold rounded-lg transition-colors"
|
||||
>
|
||||
Join Game
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
{Object.entries(players).map(([name, player]) => (
|
||||
<BoardPlayer
|
||||
key={name}
|
||||
|
||||
Reference in New Issue
Block a user