diff --git a/package.json b/package.json index becc40e..7241b81 100644 --- a/package.json +++ b/package.json @@ -15,8 +15,10 @@ "dependencies": { "@szhsin/react-menu": "^3.0.2", "@types/": "szhsin/react-menu", + "@types/eventemitter2": "^4.1.0", "@types/styled-jsx": "^3.4.4", "@types/uuid": "^8.3.4", + "eventemitter2": "^6.4.7", "mancala.js": "^0.0.2-beta.3", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/src/MancalaApp.tsx b/src/MancalaApp.tsx index 2329499..ba62f58 100644 --- a/src/MancalaApp.tsx +++ b/src/MancalaApp.tsx @@ -29,35 +29,32 @@ const MancalaApp: FunctionComponent = () => { setConnetionState("connected"); }; const onConnectionLost = () => { - connectToServer("reconnecting"); + setConnetionState("reconnecting"); + connectToServer(); }; const onConnectionError = (event: Event) => { setConnetionState("error"); + connectToServer(); }; - const connectToServer = async (connectionState: ConnectionState) => { - setConnetionState(connectionState); + const onThemeChange = (theme: Theme) => { + setTheme(theme) + } + const connectToServer = async () => { const userKey = await context.userKeyStore.getUserKey(); setUserKey(userKey); - const rtmtws = context.rtmt as RTMTWS; - if (rtmtws) { - rtmtws.initWebSocket( - userKey, - onConnectionDone, - onConnectionLost, - onConnectionError - ); - } else { - console.error("context.rtmt is not RTMTWS"); - } + (context.rtmt as RTMTWS).initWebSocket(userKey); }; + React.useEffect(() => { - connectToServer("connecting"); - context.themeManager.onThemeChange = (theme: Theme) => { - setTheme(theme); - } + context.rtmt.on("open", onConnectionDone); + context.rtmt.on("close", onConnectionLost); + context.rtmt.on("error", onConnectionError); + context.themeManager.on("themechange", onThemeChange); + setConnetionState("connecting"); + connectToServer(); return () => { - // todo: dispose rtmt.dispose - //context.rtmt.dispose(); + context.rtmt.dispose(); + context.themeManager.off("themechange", onThemeChange); }; }, []); @@ -77,6 +74,7 @@ const MancalaApp: FunctionComponent = () => { context.themeManager.theme.textColor, context.themeManager.theme.textLightColor ); + if (!userKey) return <>; return ( <> diff --git a/src/components/InfoPanel.tsx b/src/components/InfoPanel.tsx index 850414b..5ccbafc 100644 --- a/src/components/InfoPanel.tsx +++ b/src/components/InfoPanel.tsx @@ -2,70 +2,83 @@ import * as React from "react"; import { FunctionComponent } from "react"; import { Context } from "../context/context"; import { Game } from "../models/Game"; +import { User } from "../models/User"; import { getColorByBrightness } from "../util/ColorUtil"; import CircularPanel from "./CircularPanel"; function getInfoPanelTextByGameState(params: { context: Context; game?: Game; - crashMessage?: string; - userKey?: string; - userKeyWhoLeave?: string; + currentUser: User; + whitePlayer: User; + blackPlayer: User; + leftPlayer?: User; + isSpectator?: boolean; }): string | undefined { const { context, game, - crashMessage, - userKey, - userKeyWhoLeave, + currentUser, + whitePlayer, + blackPlayer, + leftPlayer, + isSpectator } = params; - if (crashMessage) { - return context.texts.GameCrashed + " " + crashMessage; - } else if (userKeyWhoLeave) { - let message = context.texts.OpponentLeavesTheGame; - if (userKeyWhoLeave == userKey) { - message = context.texts.YouLeftTheGame; - } - return message; - } else if (game?.mancalaGame.state == "ended") { - const wonPlayer = game.mancalaGame.getWonPlayerId(); - let whoWon = - game.mancalaGame.getWonPlayerId() === userKey - ? context.texts.YouWon - : context.texts.YouLost; - if (!wonPlayer) { + + if (leftPlayer) { + return isSpectator ? `${leftPlayer.name} ${context.texts.UserLeftTheGame}` : + leftPlayer.id == currentUser.id ? context.texts.YouLeftTheGame : context.texts.OpponentLeftTheGame; + } + + const isGameEnded = game?.mancalaGame.state == "ended"; + if (isGameEnded) { + const wonPlayerID = game.mancalaGame.getWonPlayerId(); + const wonPlayer = wonPlayerID == whitePlayer.id ? whitePlayer : blackPlayer; + let whoWon; + if (wonPlayer) { + whoWon = isSpectator ? `${wonPlayer.name} ${context.texts.Won}` : + game.mancalaGame.getWonPlayerId() === currentUser.id + ? context.texts.YouWon + : context.texts.YouLost; + } else { whoWon = context.texts.GameDraw; } return context.texts.GameEnded + " " + whoWon; - } else { - if (game) { - return userKey ? game.mancalaGame.checkIsPlayerTurn(userKey) - ? context.texts.YourTurn - : context.texts.OpponentTurn : undefined; - } } + + if (game) { + const playingPlayer = game.mancalaGame.checkIsPlayerTurn(whitePlayer.id) ? whitePlayer : blackPlayer; + return isSpectator ? `${playingPlayer.name} ${context.texts.Playing}` : game.mancalaGame.checkIsPlayerTurn(currentUser.id) + ? context.texts.YourTurn + : context.texts.OpponentTurn; + } + return undefined; } const InfoPanel: FunctionComponent<{ context: Context; game?: Game; - crashMessage?: string; - userKey?: string; - userKeyWhoLeave?: string; + currentUser: User; + whitePlayer: User; + blackPlayer: User; + leftPlayer?: User; style?: React.CSSProperties; visible?: boolean; + isSpectator?: boolean; }> = ({ context, game, - crashMessage, - userKey, - userKeyWhoLeave, + currentUser, + whitePlayer, + blackPlayer, + leftPlayer, style, - visible + visible, + isSpectator }) => { if (visible === false) return <>; - const isUserTurn = userKey ? game?.mancalaGame.checkIsPlayerTurn(userKey) : false; + const isUserTurn = currentUser.id ? game?.mancalaGame.checkIsPlayerTurn(currentUser.id) : false; const containerColor = isUserTurn ? context.themeManager.theme.playerTurnColor : context.themeManager.theme.boardColor; @@ -77,9 +90,11 @@ const InfoPanel: FunctionComponent<{ const text = getInfoPanelTextByGameState({ context, game, - crashMessage, - userKey, - userKeyWhoLeave + currentUser, + whitePlayer, + blackPlayer, + leftPlayer, + isSpectator }); if (text) { return ( diff --git a/src/components/board/BoardView.tsx b/src/components/board/BoardView.tsx index 3da5925..29cf0dd 100644 --- a/src/components/board/BoardView.tsx +++ b/src/components/board/BoardView.tsx @@ -13,49 +13,39 @@ const BoardView: FunctionComponent<{ context: Context; boardId: string; boardViewModel: BoardViewModel; - userKey: string; + revert: boolean; onPitSelect: (index: number, pit: Pit) => void; -}> = ({ game, context, boardId, boardViewModel, userKey, onPitSelect: onPitSelect }) => { +}> = ({ game, context, boardId, boardViewModel, revert, onPitSelect: onPitSelect }) => { const mancalaGame = game?.mancalaGame; - const createPitView = (key: any, pitViewModel: PitViewModel, onClick: () => void) => { - return ; - }; - const player1Pits = mancalaGame?.board.player1Pits.map((pit, index) => { - const pitViewModel = boardViewModel.pits[pit.index]; - return createPitView(index, pitViewModel, () => { - if (mancalaGame?.turnPlayerId === mancalaGame?.player1Id && userKey === mancalaGame?.player1Id) - onPitSelect(mancalaGame?.board.player1Pits.indexOf(pit), pit); - }); - }); - const player2Pits = mancalaGame?.board.player2Pits.map((pit, index) => { - const pitViewModel = boardViewModel.pits[pit.index]; - return createPitView(index, pitViewModel, () => { - if (mancalaGame?.turnPlayerId === mancalaGame?.player2Id && userKey === mancalaGame?.player2Id) - onPitSelect(mancalaGame?.board.player2Pits.indexOf(pit), pit); - }); - }); const theme = context.themeManager.theme; - const player1BankViewModel = - boardViewModel.pits[mancalaGame?.board.player1BankIndex()]; - const player2BankViewModel = - boardViewModel.pits[mancalaGame?.board.player2BankIndex()]; - const isPlayer2 = userKey === mancalaGame?.player2Id; + + const createPitView = (key: any, pit: Pit, pitViewModel: PitViewModel) => { + return onPitSelect(pit.index, pit)} />; + }; + const createPitViewList = (pits: Pit[]) => pits.map((pit, index) => createPitView(index, pit, boardViewModel.pits[pit.index])); + + const player1Pits = createPitViewList(mancalaGame?.board.player1Pits); + const player2Pits = createPitViewList(mancalaGame?.board.player2Pits); + const player1BankIndex = mancalaGame?.board.player1BankIndex(); + const player2BankIndex = mancalaGame?.board.player2BankIndex(); + const player1BankViewModel = boardViewModel.pits[player1BankIndex]; + const player2BankViewModel = boardViewModel.pits[player2BankIndex]; return (
- {isPlayer2 ? player1Pits?.reverse() : player2Pits?.reverse()} - {isPlayer2 ? player2Pits : player1Pits} + {revert ? player1Pits?.reverse() : player2Pits?.reverse()} + {revert ? player2Pits : player1Pits}