chs/src-web/App.tsx
2022-11-02 14:25:59 +00:00

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;