76 lines
2.4 KiB
TypeScript
76 lines
2.4 KiB
TypeScript
import { Component, createEffect, createSignal, Match, Show, Switch } from 'solid-js';
|
|
import createWebsocket from '@solid-primitives/websocket';
|
|
import { wsUrl } from './constants';
|
|
import Spinner from './components/Spinner';
|
|
import Welcome from './components/Welcome';
|
|
import { Board as BoardData, GameEvent, Move, ServerChessEvent, Side } from './events';
|
|
import Board from './components/Board';
|
|
import Popup from './components/Popup';
|
|
|
|
interface Props {
|
|
gameId: string;
|
|
}
|
|
|
|
const App: Component<Props> = (props) => {
|
|
const [board, setBoard] = createSignal<BoardData>(Array(64).fill(null));
|
|
const [possibleMoves, setPossibleMoves] = createSignal<Move[]>([]);
|
|
const [side, setSide] = createSignal<Side | null>(null);
|
|
const [currentEvent, setCurrentEvent] = createSignal<GameEvent | null>(null);
|
|
|
|
function handleEvent(e: MessageEvent<string>) {
|
|
const data = JSON.parse(e.data);
|
|
const event = ServerChessEvent.parse(data);
|
|
if (event.event === 'BoardUpdate') {
|
|
setBoard(event.data.board);
|
|
} else if (event.event === 'PossibleMoves') {
|
|
setPossibleMoves(event.data.moves);
|
|
} else if (event.event === 'StartGame') {
|
|
setSide(event.data.side);
|
|
} else if (event.event === 'GameEvent') {
|
|
setCurrentEvent(event.data);
|
|
} else if (event.event === 'ClearGameEvent') {
|
|
setCurrentEvent(null);
|
|
}
|
|
}
|
|
|
|
const [connect, disconnect, send, state, socket] = createWebsocket(wsUrl(props.gameId), handleEvent, console.error);
|
|
|
|
function joinGame() {
|
|
connect();
|
|
setSide(null);
|
|
setBoard(Array(64).fill(null));
|
|
setPossibleMoves([]);
|
|
setCurrentEvent(null);
|
|
}
|
|
|
|
function makeMove(move: Move) {
|
|
send(JSON.stringify({
|
|
event: 'MakeMove',
|
|
data: {
|
|
move,
|
|
},
|
|
}));
|
|
}
|
|
|
|
return <Switch fallback={<Spinner />}>
|
|
<Match when={state() === WebSocket.CLOSED}>
|
|
<Welcome gameId={props.gameId} joinGame={() => joinGame()} />
|
|
</Match>
|
|
<Match when={state() === WebSocket.CONNECTING}>
|
|
<Spinner />
|
|
</Match>
|
|
<Match when={state() === WebSocket.OPEN}>
|
|
<Show when={side() !== null} fallback={<>
|
|
<h1>Waiting for opponent...</h1>
|
|
<Spinner />
|
|
</>}>
|
|
<Board board={board} moves={possibleMoves} makeMove={makeMove} side={side()!} />
|
|
</Show>
|
|
<Show when={currentEvent() !== null}>
|
|
<Popup {...currentEvent()!} />
|
|
</Show>
|
|
</Match>
|
|
</Switch>
|
|
};
|
|
|
|
export default App;
|