Merge pull request #30 from jhalitaksoy/feature/game-model

Feature/game model
This commit is contained in:
Halit Aksoy 2022-08-01 22:35:24 +03:00 committed by GitHub
commit 2ea22f5303
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 100 additions and 62 deletions

View File

@ -1,5 +1,4 @@
import { import {
MancalaGame,
GameStep, GameStep,
HistoryItem, HistoryItem,
GAME_STEP_GAME_MOVE, GAME_STEP_GAME_MOVE,
@ -7,11 +6,13 @@ import {
GAME_STEP_BOARD_CLEARED, GAME_STEP_BOARD_CLEARED,
GAME_STEP_LAST_STONE_IN_BANK, GAME_STEP_LAST_STONE_IN_BANK,
GAME_STEP_DOUBLE_STONE_IN_PIT, GAME_STEP_DOUBLE_STONE_IN_PIT,
MancalaGame,
} from "mancala.js"; } from "mancala.js";
import { v4 } from "uuid"; import { v4 } from "uuid";
import { Context } from "../context/context"; import { Context } from "../context/context";
import BoardViewModelFactory from "../factory/BoardViewModelFactory"; import BoardViewModelFactory from "../factory/BoardViewModelFactory";
import { PitViewModelFactory } from "../factory/PitViewModelFactory"; import { PitViewModelFactory } from "../factory/PitViewModelFactory";
import { Game } from "../models/Game";
import { getColorByBrightness } from "../util/ColorUtil"; import { getColorByBrightness } from "../util/ColorUtil";
import BoardViewModel from "../viewmodel/BoardViewModel"; import BoardViewModel from "../viewmodel/BoardViewModel";
@ -19,8 +20,8 @@ const animationUpdateInterval = 300;
export default class PitAnimator { export default class PitAnimator {
context: Context; context: Context;
game: MancalaGame | undefined; game: Game | undefined;
oldGame: MancalaGame | undefined; oldGame: Game | undefined;
currentIntervalID: number; currentIntervalID: number;
onBoardViewModelUpdate: (boardViewModel: BoardViewModel) => void; onBoardViewModelUpdate: (boardViewModel: BoardViewModel) => void;
boardViewModel: BoardViewModel | undefined; boardViewModel: BoardViewModel | undefined;
@ -36,13 +37,17 @@ export default class PitAnimator {
this.onBoardViewModelUpdate = onBoardViewModelUpdate; this.onBoardViewModelUpdate = onBoardViewModelUpdate;
} }
public setNewGame(game: MancalaGame) { get mancalaGame(): MancalaGame | undefined {
return this.game?.mancalaGame;
}
public setNewGame(game: Game) {
this.reset(); this.reset();
this.game = game; this.game = game;
this.onBoardViewModelUpdate?.(this.getBoardViewModelFromGame(this.game)); this.onBoardViewModelUpdate?.(this.getBoardViewModelFromGame(this.game));
} }
public setUpdatedGame(game: MancalaGame) { public setUpdatedGame(game: Game) {
this.resetAnimationState(); this.resetAnimationState();
if (!this.game) { if (!this.game) {
this.setNewGame(game); this.setNewGame(game);
@ -55,8 +60,8 @@ export default class PitAnimator {
onGameMoveAnimationStart() { onGameMoveAnimationStart() {
this.stopCurrentAnimation(); this.stopCurrentAnimation();
if (this.game && this.oldGame && this.game.history.length > 0) { if (this.game && this.oldGame && this.mancalaGame && this.mancalaGame?.history.length > 0) {
const lastHistoryItem = this.game.history[this.game.history.length - 1]; const lastHistoryItem = this.mancalaGame.history[this.mancalaGame.history.length - 1];
if (lastHistoryItem.gameSteps.length > 0) { if (lastHistoryItem.gameSteps.length > 0) {
this.animationIndex = 0; this.animationIndex = 0;
this.currentHistoryItem = lastHistoryItem; this.currentHistoryItem = lastHistoryItem;
@ -68,13 +73,13 @@ export default class PitAnimator {
} }
onAnimate() { onAnimate() {
if (!this.currentHistoryItem || !this.game || !this.oldBoardViewModel) return; if (!this.currentHistoryItem || !this.game || !this.oldBoardViewModel || !this.mancalaGame) return;
if (this.animationIndex === this.currentHistoryItem.gameSteps.length) { if (this.animationIndex === this.currentHistoryItem.gameSteps.length) {
this.clearCurrentInterval(); this.clearCurrentInterval();
this.onBoardViewModelUpdate?.(this.getBoardViewModelFromGame(this.game)); this.onBoardViewModelUpdate?.(this.getBoardViewModelFromGame(this.game));
} else { } else {
const gameStep = this.currentHistoryItem.gameSteps[this.animationIndex]; const gameStep = this.currentHistoryItem.gameSteps[this.animationIndex];
const index = this.game.board.getPitIndexCircularly(gameStep.index); const index = this.mancalaGame.board.getPitIndexCircularly(gameStep.index);
this.animatePit(index, this.oldBoardViewModel, gameStep); this.animatePit(index, this.oldBoardViewModel, gameStep);
this.onBoardViewModelUpdate?.(this.oldBoardViewModel); this.onBoardViewModelUpdate?.(this.oldBoardViewModel);
} }
@ -92,7 +97,7 @@ export default class PitAnimator {
boardViewModel: BoardViewModel, boardViewModel: BoardViewModel,
gameStep: GameStep gameStep: GameStep
) { ) {
if (!this.currentHistoryItem || !this.game) return; if (!this.currentHistoryItem || !this.game || !this.mancalaGame) return;
const pitViewModel = boardViewModel.pits[index]; const pitViewModel = boardViewModel.pits[index];
if (this.animationIndex === 0) { if (this.animationIndex === 0) {
//This is one stone move case, TODO: beautify it later //This is one stone move case, TODO: beautify it later
@ -112,7 +117,7 @@ export default class PitAnimator {
} else if (gameStep.type === GAME_STEP_LAST_STONE_IN_EMPTY_PIT) { } else if (gameStep.type === GAME_STEP_LAST_STONE_IN_EMPTY_PIT) {
pitViewModel.pitColor = theme.pitGetRivalStonePitAnimateColor; pitViewModel.pitColor = theme.pitGetRivalStonePitAnimateColor;
pitViewModel.stoneCount = 0; pitViewModel.stoneCount = 0;
const oppositeIndex = this.game.board.getPitIndexCircularly( const oppositeIndex = this.mancalaGame.board.getPitIndexCircularly(
gameStep.data.oppositeIndex gameStep.data.oppositeIndex
); );
const oppositePitViewModel = boardViewModel.pits[oppositeIndex]; const oppositePitViewModel = boardViewModel.pits[oppositeIndex];
@ -122,13 +127,13 @@ export default class PitAnimator {
pitViewModel.pitColor = theme.pitLastStoneInBankPitAnimateColor; pitViewModel.pitColor = theme.pitLastStoneInBankPitAnimateColor;
} else if (gameStep.type === GAME_STEP_BOARD_CLEARED) { } else if (gameStep.type === GAME_STEP_BOARD_CLEARED) {
for (const index of gameStep.data.pitIndexesThatHasStone) { for (const index of gameStep.data.pitIndexesThatHasStone) {
const oppositeIndex = this.game.board.getPitIndexCircularly(index); const oppositeIndex = this.mancalaGame.board.getPitIndexCircularly(index);
const oppositePitViewModel = boardViewModel.pits[oppositeIndex]; const oppositePitViewModel = boardViewModel.pits[oppositeIndex];
oppositePitViewModel.pitColor = theme.pitGetRivalStonePitAnimateColor; oppositePitViewModel.pitColor = theme.pitGetRivalStonePitAnimateColor;
oppositePitViewModel.stoneCount = 0; oppositePitViewModel.stoneCount = 0;
} }
} else if (gameStep.type === GAME_STEP_DOUBLE_STONE_IN_PIT) { } else if (gameStep.type === GAME_STEP_DOUBLE_STONE_IN_PIT) {
const _index = this.game.board.getPitIndexCircularly(index); const _index = this.mancalaGame.board.getPitIndexCircularly(index);
const pitViewModel = boardViewModel.pits[_index]; const pitViewModel = boardViewModel.pits[_index];
pitViewModel.pitColor = theme.pitGetRivalStonePitAnimateColor; pitViewModel.pitColor = theme.pitGetRivalStonePitAnimateColor;
pitViewModel.stoneCount = 0; pitViewModel.stoneCount = 0;
@ -164,13 +169,13 @@ export default class PitAnimator {
} }
} }
public getBoardViewModelFromGame(game: MancalaGame): BoardViewModel { public getBoardViewModelFromGame(game: Game): BoardViewModel {
const pitViewModels = this.createPitViewModelsFromGame(game); const pitViewModels = this.createPitViewModelsFromGame(game);
return BoardViewModelFactory.create(v4(), pitViewModels); return BoardViewModelFactory.create(v4(), pitViewModels);
} }
private createPitViewModelsFromGame(game: MancalaGame) { private createPitViewModelsFromGame(game: Game) {
return game.board.pits.map((pit) => { return game.mancalaGame.board.pits.map((pit) => {
const theme = this.context.themeManager.theme; const theme = this.context.themeManager.theme;
const stoneCount = pit.stoneCount; const stoneCount = pit.stoneCount;
const stoneColor = theme.stoneColor; const stoneColor = theme.stoneColor;

View File

@ -1,13 +1,13 @@
import { MancalaGame } from "mancala.js";
import * as React from "react"; import * as React from "react";
import { FunctionComponent } from "react"; import { FunctionComponent } from "react";
import { Context } from "../context/context"; import { Context } from "../context/context";
import { Game } from "../models/Game";
import { getColorByBrightness } from "../util/ColorUtil"; import { getColorByBrightness } from "../util/ColorUtil";
import CircularPanel from "./CircularPanel"; import CircularPanel from "./CircularPanel";
function getInfoPanelTextByGameState(params: { function getInfoPanelTextByGameState(params: {
context: Context; context: Context;
game?: MancalaGame; game?: Game;
crashMessage?: string; crashMessage?: string;
userKey?: string; userKey?: string;
userKeyWhoLeave?: string; userKeyWhoLeave?: string;
@ -27,10 +27,10 @@ function getInfoPanelTextByGameState(params: {
message = context.texts.YouLeftTheGame; message = context.texts.YouLeftTheGame;
} }
return message; return message;
} else if (game?.state == "ended") { } else if (game?.mancalaGame.state == "ended") {
const wonPlayer = game.getWonPlayerId(); const wonPlayer = game.mancalaGame.getWonPlayerId();
let whoWon = let whoWon =
game.getWonPlayerId() === userKey game.mancalaGame.getWonPlayerId() === userKey
? context.texts.YouWon ? context.texts.YouWon
: context.texts.YouLost; : context.texts.YouLost;
if (!wonPlayer) { if (!wonPlayer) {
@ -39,7 +39,7 @@ function getInfoPanelTextByGameState(params: {
return context.texts.GameEnded + " " + whoWon; return context.texts.GameEnded + " " + whoWon;
} else { } else {
if (game) { if (game) {
return userKey ? game.checkIsPlayerTurn(userKey) return userKey ? game.mancalaGame.checkIsPlayerTurn(userKey)
? context.texts.YourTurn ? context.texts.YourTurn
: context.texts.OpponentTurn : undefined; : context.texts.OpponentTurn : undefined;
} }
@ -49,7 +49,7 @@ function getInfoPanelTextByGameState(params: {
const InfoPanel: FunctionComponent<{ const InfoPanel: FunctionComponent<{
context: Context; context: Context;
game?: MancalaGame; game?: Game;
crashMessage?: string; crashMessage?: string;
userKey?: string; userKey?: string;
userKeyWhoLeave?: string; userKeyWhoLeave?: string;
@ -65,7 +65,7 @@ const InfoPanel: FunctionComponent<{
visible visible
}) => { }) => {
if (visible === false) return <></>; if (visible === false) return <></>;
const isUserTurn = userKey ? game?.checkIsPlayerTurn(userKey) : false; const isUserTurn = userKey ? game?.mancalaGame.checkIsPlayerTurn(userKey) : false;
const containerColor = isUserTurn const containerColor = isUserTurn
? context.themeManager.theme.playerTurnColor ? context.themeManager.theme.playerTurnColor
: context.themeManager.theme.boardColor; : context.themeManager.theme.boardColor;

View File

@ -1,43 +1,45 @@
import * as React from "react"; import * as React from "react";
import { MancalaGame, Pit } from "mancala.js";
import { FunctionComponent } from "react"; import { FunctionComponent } from "react";
import { Context } from "../../context/context"; import { Context } from "../../context/context";
import BoardViewModel from "../../viewmodel/BoardViewModel"; import BoardViewModel from "../../viewmodel/BoardViewModel";
import PitViewModel from "../../viewmodel/PitViewModel"; import PitViewModel from "../../viewmodel/PitViewModel";
import PitView from "./PitView"; import PitView from "./PitView";
import StoreView from "./StoreView"; import StoreView from "./StoreView";
import { Game } from "../../models/Game";
import { Pit } from "mancala.js";
const BoardView: FunctionComponent<{ const BoardView: FunctionComponent<{
game: MancalaGame; game: Game;
context: Context; context: Context;
boardId: string; boardId: string;
boardViewModel: BoardViewModel; boardViewModel: BoardViewModel;
userKey: string; userKey: string;
onPitSelect: (index: number, pit: Pit) => void; onPitSelect: (index: number, pit: Pit) => void;
}> = ({ game, context, boardId, boardViewModel, userKey, onPitSelect: onPitSelect }) => { }> = ({ game, context, boardId, boardViewModel, userKey, onPitSelect: onPitSelect }) => {
const mancalaGame = game?.mancalaGame;
const createPitView = (key: any, pitViewModel: PitViewModel, onClick: () => void) => { const createPitView = (key: any, pitViewModel: PitViewModel, onClick: () => void) => {
return <PitView key={key} pitViewModel={pitViewModel} onClick={onClick} />; return <PitView key={key} pitViewModel={pitViewModel} onClick={onClick} />;
}; };
const player1Pits = game?.board.player1Pits.map((pit, index) => { const player1Pits = mancalaGame?.board.player1Pits.map((pit, index) => {
const pitViewModel = boardViewModel.pits[pit.index]; const pitViewModel = boardViewModel.pits[pit.index];
return createPitView(index, pitViewModel, () => { return createPitView(index, pitViewModel, () => {
if (game.turnPlayerId === game.player1Id && userKey === game.player1Id) if (mancalaGame?.turnPlayerId === mancalaGame?.player1Id && userKey === mancalaGame?.player1Id)
onPitSelect(game.board.player1Pits.indexOf(pit), pit); onPitSelect(mancalaGame?.board.player1Pits.indexOf(pit), pit);
}); });
}); });
const player2Pits = game?.board.player2Pits.map((pit, index) => { const player2Pits = mancalaGame?.board.player2Pits.map((pit, index) => {
const pitViewModel = boardViewModel.pits[pit.index]; const pitViewModel = boardViewModel.pits[pit.index];
return createPitView(index, pitViewModel, () => { return createPitView(index, pitViewModel, () => {
if (game.turnPlayerId === game.player2Id && userKey === game.player2Id) if (mancalaGame?.turnPlayerId === mancalaGame?.player2Id && userKey === mancalaGame?.player2Id)
onPitSelect(game.board.player2Pits.indexOf(pit), pit); onPitSelect(mancalaGame?.board.player2Pits.indexOf(pit), pit);
}); });
}); });
const theme = context.themeManager.theme; const theme = context.themeManager.theme;
const player1BankViewModel = const player1BankViewModel =
boardViewModel.pits[game.board.player1BankIndex()]; boardViewModel.pits[mancalaGame?.board.player1BankIndex()];
const player2BankViewModel = const player2BankViewModel =
boardViewModel.pits[game.board.player2BankIndex()]; boardViewModel.pits[mancalaGame?.board.player2BankIndex()];
const isPlayer2 = userKey === game?.player2Id; const isPlayer2 = userKey === mancalaGame?.player2Id;
return ( return (
<div className="board" style={{ background: theme.boardColor }}> <div className="board" style={{ background: theme.boardColor }}>
<StoreView <StoreView

13
src/models/Game.ts Normal file
View File

@ -0,0 +1,13 @@
import { MancalaGame } from "mancala.js";
import { UserConnectionInfo } from "./UserConnectionInfo";
export interface Game {
id: string;
mancalaGame: MancalaGame;
gameUsersConnectionInfo: GameUsersConnectionInfo;
}
export interface GameUsersConnectionInfo {
user1ConnectionInfo: UserConnectionInfo;
user2ConnectionInfo: UserConnectionInfo;
}

View File

@ -1,4 +1,4 @@
import { CommonMancalaGame, MancalaGame, Pit } from 'mancala.js'; import { MancalaGame, Pit } from 'mancala.js';
import * as React from 'react'; import * as React from 'react';
import { FunctionComponent, useState } from 'react'; import { FunctionComponent, useState } from 'react';
import { useNavigate, useParams } from 'react-router'; import { useNavigate, useParams } from 'react-router';
@ -23,11 +23,11 @@ import useWindowDimensions from '../hooks/useWindowDimensions';
import { ConnectionState } from '../models/ConnectionState'; import { ConnectionState } from '../models/ConnectionState';
import { GameMove } from '../models/GameMove'; import { GameMove } from '../models/GameMove';
import { LoadingState } from '../models/LoadingState'; import { LoadingState } from '../models/LoadingState';
import { UserConnectionInfo } from '../models/UserConnectionInfo';
import { Theme } from '../theme/Theme'; import { Theme } from '../theme/Theme';
import { getColorByBrightness } from '../util/ColorUtil'; import { getColorByBrightness } from '../util/ColorUtil';
import BoardViewModel from '../viewmodel/BoardViewModel'; import BoardViewModel from '../viewmodel/BoardViewModel';
import Center from '../components/Center'; import Center from '../components/Center';
import { Game, GameUsersConnectionInfo } from '../models/Game';
const GamePage: FunctionComponent<{ const GamePage: FunctionComponent<{
context: Context, context: Context,
@ -37,7 +37,7 @@ const GamePage: FunctionComponent<{
}> = ({ context, userKey, theme, connectionState }) => { }> = ({ context, userKey, theme, connectionState }) => {
let params = useParams<{ gameId: string }>(); let params = useParams<{ gameId: string }>();
const [game, setGame] = useState<MancalaGame | undefined>(undefined); const [game, setGame] = useState<Game | undefined>(undefined);
const [crashMessage, setCrashMessage] = useState<string | undefined>(undefined); const [crashMessage, setCrashMessage] = useState<string | undefined>(undefined);
@ -53,20 +53,36 @@ const GamePage: FunctionComponent<{
// We have to block future actions if there is an ongoing action. // We have to block future actions if there is an ongoing action.
const [hasOngoingAction, setHasOngoingAction] = useState<boolean>(false); const [hasOngoingAction, setHasOngoingAction] = useState<boolean>(false);
const [isOpponentOnline, setIsOpponentOnline] = useState<boolean>(false); const [gameUsersConnectionInfo, setGameUsersConnectionInfo] = useState<GameUsersConnectionInfo | undefined>();
const { height, width } = useWindowDimensions(); const { height, width } = useWindowDimensions();
const navigate = useNavigate(); const navigate = useNavigate();
const [gameLoadingState, setLoadingStateGame] = useState<LoadingState<MancalaGame>>(LoadingState.Unset()); const [gameLoadingState, setLoadingStateGame] = useState<LoadingState<Game>>(LoadingState.Unset());
const onGameUpdate = (pitAnimator: PitAnimator, message: Object) => { const mancalaGame: MancalaGame | undefined = game?.mancalaGame;
const newGame: CommonMancalaGame = message as CommonMancalaGame;
const mancalaGame = MancalaGame.createFromMancalaGame(newGame); const onGameUpdate = (pitAnimator: PitAnimator, newGame: Game) => {
setGame(mancalaGame); setGame(newGame);
pitAnimator.setUpdatedGame(mancalaGame); pitAnimator.setUpdatedGame(newGame);
setHasOngoingAction(false); setHasOngoingAction(false);
setGameUsersConnectionInfo(newGame.gameUsersConnectionInfo);
}
const isUserOnline = (userId: string) => {
if (!gameUsersConnectionInfo) return false;
const user1ConnectionInfo = gameUsersConnectionInfo.user1ConnectionInfo;
const user2ConnectionInfo = gameUsersConnectionInfo.user2ConnectionInfo;
if (user1ConnectionInfo.userId === userId) return user1ConnectionInfo.isOnline;
if (user2ConnectionInfo.userId === userId) return user2ConnectionInfo.isOnline;
return false;
}
const onGameUpdateEvent = (pitAnimator: PitAnimator, message: Object) => {
const newGame: Game = message as Game;
newGame.mancalaGame = MancalaGame.createFromMancalaGame(newGame.mancalaGame);
onGameUpdate(pitAnimator, newGame);
} }
const onGameCrashed = (message: any) => { const onGameCrashed = (message: any) => {
const newCrashMessage = message as string; const newCrashMessage = message as string;
@ -80,13 +96,12 @@ const GamePage: FunctionComponent<{
setHasOngoingAction(false); setHasOngoingAction(false);
}; };
const onUserConnectionChange = (message: any) => { const onUserConnectionChange = (message: any) => {
const userConnectionInfo = message as UserConnectionInfo; const gameUsersConnectionInfo = message as GameUsersConnectionInfo;
//todo: change this when implementing watch the game feature setGameUsersConnectionInfo(gameUsersConnectionInfo);
setIsOpponentOnline(userConnectionInfo.isOnline);
}; };
const listenMessages = (pitAnimator: PitAnimator) : () => void => { const listenMessages = (pitAnimator: PitAnimator): () => void => {
const _onGameUpdate = (message: object) => onGameUpdate(pitAnimator, message); const _onGameUpdate = (message: object) => onGameUpdateEvent(pitAnimator, message);
context.rtmt.listenMessage(channel_on_game_update, _onGameUpdate); context.rtmt.listenMessage(channel_on_game_update, _onGameUpdate);
context.rtmt.listenMessage(channel_on_game_crashed, onGameCrashed); context.rtmt.listenMessage(channel_on_game_crashed, onGameCrashed);
context.rtmt.listenMessage(channel_on_game_user_leave, onGameUserLeave); context.rtmt.listenMessage(channel_on_game_user_leave, onGameUserLeave);
@ -106,12 +121,13 @@ const GamePage: FunctionComponent<{
}; };
const getBoardIndex = (index: number) => { const getBoardIndex = (index: number) => {
if (!game) return -1; if (!game || !mancalaGame) return -1;
if (userKey === game.player2Id) return index + game.board.pits.length / 2; const pitsLenght = mancalaGame.board.pits.length;
if (userKey === mancalaGame.player2Id) return index + pitsLenght / 2;
return index; return index;
}; };
const getOpponentId = () => game?.player1Id === userKey ? game?.player2Id : game?.player1Id; const getOpponentId = () => mancalaGame?.player1Id === userKey ? mancalaGame?.player2Id : mancalaGame?.player1Id;
const checkHasAnOngoingAction = () => hasOngoingAction; const checkHasAnOngoingAction = () => hasOngoingAction;
@ -143,15 +159,13 @@ const GamePage: FunctionComponent<{
React.useEffect(() => { React.useEffect(() => {
let pitAnimator: PitAnimator | undefined; let pitAnimator: PitAnimator | undefined;
let unlistenMessages: ()=>void; let unlistenMessages: () => void;
setLoadingStateGame(LoadingState.Loading()) setLoadingStateGame(LoadingState.Loading())
context.gameStore.get(params.gameId!!).then((game) => { context.gameStore.get(params.gameId!!).then((game) => {
if (game) { if (game) {
setGame(game);
setHasOngoingAction(false);
pitAnimator = new PitAnimator(context, updateBoardViewModel); pitAnimator = new PitAnimator(context, updateBoardViewModel);
pitAnimator.setNewGame(game);
setPitAnimator(pitAnimator); setPitAnimator(pitAnimator);
onGameUpdate(pitAnimator, game);
unlistenMessages = listenMessages(pitAnimator); unlistenMessages = listenMessages(pitAnimator);
setLoadingStateGame(LoadingState.Loaded({ value: game })) setLoadingStateGame(LoadingState.Loaded({ value: game }))
} else { } else {
@ -169,9 +183,10 @@ const GamePage: FunctionComponent<{
context.themeManager.theme.textColor, context.themeManager.theme.textColor,
context.themeManager.theme.textLightColor context.themeManager.theme.textLightColor
); );
const renderNewGameBtn = userKeyWhoLeave || !game || (game && game.state == "ended"); const renderNewGameBtn = userKeyWhoLeave || !game || (game && game.mancalaGame.state == "ended");
const showBoardView = game && boardViewModel && userKey && true; const showBoardView = game && boardViewModel && userKey && true;
const opponentUser = { id: getOpponentId() || "0", name: "Anonymous", isOnline: isOpponentOnline, isAnonymous: true }; const opponentId = getOpponentId();
const opponentUser = { id: getOpponentId() || "0", name: "Anonymous", isOnline: opponentId ? isUserOnline(opponentId) : false, isAnonymous: true };
const user = { id: userKey || "1", name: "Anonymous", isOnline: connectionState === "connected", isAnonymous: true }; const user = { id: userKey || "1", name: "Anonymous", isOnline: connectionState === "connected", isAnonymous: true };
const isMobile = width < 600; const isMobile = width < 600;

View File

@ -1,8 +1,9 @@
import { CommonMancalaGame, MancalaGame } from "mancala.js"; import { CommonMancalaGame, MancalaGame } from "mancala.js";
import { Game } from "../models/Game";
import { HttpService } from "../service/HttpService"; import { HttpService } from "../service/HttpService";
export interface GameStore { export interface GameStore {
get(id: string): Promise<MancalaGame | undefined>; get(id: string): Promise<Game | undefined>;
} }
export class GameStoreImpl implements GameStore { export class GameStoreImpl implements GameStore {
@ -11,11 +12,13 @@ export class GameStoreImpl implements GameStore {
this.httpService = props.httpService; this.httpService = props.httpService;
} }
async get(id: string): Promise<MancalaGame | undefined> { async get(id: string): Promise<Game | undefined> {
try { try {
const response = await this.httpService.get(`/game/${id}`); const response = await this.httpService.get(`/game/${id}`);
const json = await response.json(); const json = await response.json();
return MancalaGame.createFromMancalaGame(json as CommonMancalaGame); const game: Game = json as Game;
game.mancalaGame = MancalaGame.createFromMancalaGame(game.mancalaGame);
return game;
} catch (error) { } catch (error) {
// todo check error // todo check error
Promise.resolve(undefined); Promise.resolve(undefined);