mancala/src/Home.tsx

166 lines
5.1 KiB
TypeScript
Raw Normal View History

2021-06-27 19:28:55 +03:00
import * as React from 'react';
2021-06-29 03:29:46 +03:00
import { FunctionComponent, useState } from 'react';
import BoardView from './components/BoardView';
import { context } from './context'
import { Board, GameMove, Hole, Store } from './mancala';
import { Game } from './mancala';
import { decodeText, encodeText } from './rtmt/byte_util';
import { Bytes } from './rtmt/rtmt';
2021-06-27 19:28:55 +03:00
import { RTMTWS } from './rtmt/rtmt_websocket';
2021-06-29 03:29:46 +03:00
import { channel_game_move, channel_leave_game, channel_on_game_update } from './channel_names';
2021-07-02 23:13:38 +03:00
import Button from './components/Button';
2021-06-27 19:28:55 +03:00
2021-06-29 03:29:46 +03:00
const testBoard = (): Board => {
const board = new Board(
[new Hole(0), new Hole(4), new Hole(4), new Hole(3), new Hole(2), new Hole(1)],
[new Hole(4), new Hole(4), new Hole(4), new Hole(4), new Hole(4), new Hole(10)],
new Store(0), new Store(0))
return board
}
2021-06-30 19:41:53 +03:00
const testGame = new Game("0", "1", testBoard(), "player2", "playing")
2021-06-29 03:29:46 +03:00
2021-07-02 23:13:38 +03:00
type ConnectionState = "connecting" | "error" | "connected" | "reconnecting"
2021-06-29 03:29:46 +03:00
const Home: FunctionComponent<{ initial?: number }> = ({ initial = 0 }) => {
const [userKey, setUserKey] = useState(undefined);
const [game, setGame] = useState<Game>(undefined)
2021-07-02 23:13:38 +03:00
const [connectionState, setConnetionState] = useState<ConnectionState>("connecting")
2021-06-30 19:41:53 +03:00
2021-07-02 23:13:38 +03:00
const onConnectionDone = () => {
setConnetionState("connected")
}
const onConnectionLost = () => {
connectToServer("reconnecting")
}
2021-06-30 19:41:53 +03:00
2021-07-02 23:13:38 +03:00
const onConnectionError = (event: Event) => {
setConnetionState("error")
}
const connectToServer = (connectionState: ConnectionState) => {
setConnetionState(connectionState)
2021-06-29 03:29:46 +03:00
context.userKeyStore.getUserKey((userKey: string) => {
setUserKey(userKey)
const rtmtws = context.rtmt as RTMTWS
if (rtmtws) {
2021-07-02 23:13:38 +03:00
rtmtws.initWebSocket(userKey, onConnectionDone, onConnectionLost, onConnectionError)
2021-06-29 03:29:46 +03:00
} else {
console.log("context.rtmt is not RTMTWS");
}
})
2021-07-02 23:13:38 +03:00
}
2021-06-29 03:29:46 +03:00
2021-07-02 23:13:38 +03:00
const listenMessages = () => {
2021-06-29 03:29:46 +03:00
context.rtmt.listenMessage(channel_on_game_update, (message: Bytes) => {
const newGame: Game = JSON.parse(decodeText(message))
console.log("on game update");
console.log(newGame);
2021-06-30 19:41:53 +03:00
setGame(new Game(newGame.player1, newGame.player2, newGame.board, newGame.turn, newGame.state))
2021-06-29 03:29:46 +03:00
})
2021-06-27 19:28:55 +03:00
2021-06-29 03:29:46 +03:00
context.rtmt.listenMessage(channel_on_game_update, (message: Bytes) => {
const newGame: Game = JSON.parse(decodeText(message))
console.log("on game update");
console.log(newGame);
2021-06-30 19:41:53 +03:00
setGame(new Game(newGame.player1, newGame.player2, newGame.board, newGame.turn, newGame.state))
2021-06-29 03:29:46 +03:00
})
2021-06-27 19:28:55 +03:00
2021-06-29 03:29:46 +03:00
context.rtmt.listenMessage("on_game_start", (message) => {
const newGame: Game = JSON.parse(decodeText(message))
console.log("on_game_start");
console.log(newGame);
2021-06-30 19:41:53 +03:00
setGame(new Game(newGame.player1, newGame.player2, newGame.board, newGame.turn, newGame.state))
2021-06-27 19:28:55 +03:00
})
}
2021-07-02 23:13:38 +03:00
React.useEffect(() => {
listenMessages()
connectToServer("connecting")
}, [])
const newGameClick = () => {
context.rtmt.sendMessage("new_game", new Uint8Array())
}
2021-06-29 03:29:46 +03:00
const leaveGame = () => {
context.rtmt.sendMessage(channel_leave_game, new Uint8Array())
}
const onHoleSelect = (index: number, hole: Hole) => {
const gameMove: GameMove = { index: index }
context.rtmt.sendMessage(channel_game_move, encodeText(JSON.stringify(gameMove)))
}
2021-07-02 23:13:38 +03:00
const showConnectionState = connectionState != "connected"
const connectionStateText = () => {
let map: { [key: string]: string } = {
"connecting": context.texts.Connecting,
"connected": context.texts.Connected,
"error": context.texts.CannotConnect,
"reconnecting": context.texts.ConnectingAgain
};
return map[connectionState]
}
2021-06-29 03:29:46 +03:00
return <div style={{
display: "flex",
flexDirection: "column",
2021-06-30 16:11:22 +03:00
alignItems: "center",
background: "#EEEEEE",
flex: "1",
2021-06-29 03:29:46 +03:00
}}>
2021-07-02 23:13:38 +03:00
{
showConnectionState && <div style={{
position: "absolute",
bottom: "0px",
left: "0px",
padding: "15px 15px 5px 5px",
borderTopRightRadius: "1vw",
minWidth: "10vw",
minHeight: "1vw",
background: "grey"
}}>
{connectionStateText()}
</div>}
2021-06-30 16:11:22 +03:00
<div style={{
padding: "0px 50px",
2021-06-30 19:41:53 +03:00
background: "rgb(228, 228, 228)",
2021-06-30 16:11:22 +03:00
display: 'flex',
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
alignSelf: "stretch"
}}>
2021-07-02 23:13:38 +03:00
<h1
style={{
margin: "10px 0px",
}}
>{context.texts.Mancala}</h1>
2021-06-30 19:41:53 +03:00
{
game && (
<div>
2021-07-02 23:13:38 +03:00
{game.state == "ended" && <button onClick={newGameClick}>{context.texts.NewGame}</button>}
<Button color="white" text={context.texts.Leave} onClick={leaveGame} />
2021-06-30 19:41:53 +03:00
</div>)
}
2021-07-02 23:13:38 +03:00
{!game && <Button color="white" text={context.texts.NewGame} onClick={newGameClick} />}
2021-06-30 16:11:22 +03:00
</div>
{game && (
<>
2021-07-02 23:13:38 +03:00
{game.state == "ended" ? <h4>{context.texts.GameEnded}</h4> :
<h4>{game.checkGameTurn(userKey) ? context.texts.YourTurn : context.texts.OpponentTurn}</h4>
2021-06-30 19:41:53 +03:00
}
2021-06-30 16:11:22 +03:00
<BoardView userKey={userKey} game={game} onHoleSelect={onHoleSelect} />
</>
)}
2021-06-29 03:29:46 +03:00
</div>
2021-06-27 19:28:55 +03:00
}
export default Home