diff --git a/mobile/src/App.tsx b/mobile/src/App.tsx
index 3e72a67..45e7d19 100644
--- a/mobile/src/App.tsx
+++ b/mobile/src/App.tsx
@@ -75,9 +75,12 @@ function App() {
return (
-
-
-
+
+
+
);
diff --git a/mobile/src/components/board/BoardView.tsx b/mobile/src/components/board/BoardView.tsx
index 5ae7a6e..735d413 100644
--- a/mobile/src/components/board/BoardView.tsx
+++ b/mobile/src/components/board/BoardView.tsx
@@ -7,7 +7,9 @@ import PitView from "./PitView";
import StoreView from "./StoreView";
import { Game } from "../../models/Game";
import { Pit } from "mancala.js";
-import { View } from "react-native";
+import { View, Dimensions } from "react-native";
+import StoneView from "./StoneView";
+import Util from "../../util/Util";
const BoardView: FunctionComponent<{
game: Game;
@@ -17,11 +19,30 @@ const BoardView: FunctionComponent<{
revert: boolean;
onPitSelect: (index: number, pit: Pit) => void;
}> = ({ game, context, boardId, boardViewModel, revert, onPitSelect: onPitSelect }) => {
+ const windowWidth = Dimensions.get('window').width;
+ const windowHeight = Dimensions.get('window').height;
+
+ const boardMargin = 0;
+ const boardPadding = 10;
+ const gap = 5;
+ const totalGap = gap * 7;
+
+ const pitWidth = (windowWidth - boardMargin * 2 - boardPadding * 2 - totalGap) / 8;
+
const mancalaGame = game?.mancalaGame;
const theme = context.themeManager.theme;
const createPitView = (key: any, pit: Pit, pitViewModel: PitViewModel) => {
- return onPitSelect(pit.index, pit)} />;
+ const stones = [...Util.range(pitViewModel.stoneCount)].map((i, index) => (
+
+ ));
+ return onPitSelect(pit.index, pit)}
+ style={{width: pitWidth, height: pitWidth}} >
+ {stones}
+ ;
};
const createPitViewList = (pits: Pit[]) => pits.map((pit, index) => createPitView(index, pit, boardViewModel.pits[pit.index]));
@@ -31,29 +52,59 @@ const BoardView: FunctionComponent<{
const player2BankIndex = mancalaGame?.board.player2BankIndex();
const player1BankViewModel = boardViewModel.pits[player1BankIndex];
const player2BankViewModel = boardViewModel.pits[player2BankIndex];
+
+ const primaryStoreViewModel = revert ? player1BankViewModel : player2BankViewModel;
+ const secondaryStoreViewModel = revert ? player2BankViewModel : player1BankViewModel;
+ const stonesPrimaryStore = [...Util.range(primaryStoreViewModel.stoneCount)].map((i, index) => (
+
+ ));
+ const stonesSecondaryStore = [...Util.range(secondaryStoreViewModel.stoneCount)].map((i, index) => (
+
+ ));
+
return (
+ pitViewModel={primaryStoreViewModel}
+ style={{width: pitWidth, height: pitWidth * 2 + gap}}
+ fontSize={pitWidth / 5}
+ >
+ {stonesPrimaryStore}
+
+
+
+ {revert ? player1Pits?.reverse() : player2Pits?.reverse()}
+
+
+ {revert ? player2Pits : player1Pits}
+
+
- {revert ? player1Pits?.reverse() : player2Pits?.reverse()}
- {revert ? player2Pits : player1Pits}
+ pitViewModel={secondaryStoreViewModel}
+ style={{width: pitWidth, height: pitWidth * 2 + gap}}
+ fontSize={pitWidth / 5}
+ >
+ {stonesSecondaryStore}
+
);
};
diff --git a/mobile/src/components/board/PitView.tsx b/mobile/src/components/board/PitView.tsx
index 2a89d3c..a5a075d 100644
--- a/mobile/src/components/board/PitView.tsx
+++ b/mobile/src/components/board/PitView.tsx
@@ -3,33 +3,35 @@ import { FunctionComponent } from "react";
import Util from "../../util/Util";
import PitViewModel from "../../viewmodel/PitViewModel";
import StoneView from "./StoneView";
-import { Pressable, View } from "react-native";
+import { Pressable, View, ViewStyle } from "react-native";
const PitView: FunctionComponent<{
pitViewModel: PitViewModel;
onClick: () => void;
-}> = ({ pitViewModel, onClick }) => {
- const stones = [...Util.range(pitViewModel.stoneCount)].map((i, index) => (
-
- ));
-
+ style: ViewStyle,
+ children: React.ReactNode
+}> = ({ pitViewModel, onClick, style, children }) => {
return (
-
-
+
- {stones}
-
-
+ {children}
+
+
+
);
};
diff --git a/mobile/src/components/board/StoneView.tsx b/mobile/src/components/board/StoneView.tsx
index 84a809e..e52f5a4 100644
--- a/mobile/src/components/board/StoneView.tsx
+++ b/mobile/src/components/board/StoneView.tsx
@@ -1,16 +1,16 @@
import * as React from "react";
import { FunctionComponent } from "react";
-import { View } from "react-native";
+import { View, ViewStyle } from "react-native";
-const StoneView: FunctionComponent<{ color: string }> = ({ color }) => {
+const StoneView: FunctionComponent<{ color: string, style?: ViewStyle }> = ({ color, style }) => {
return (
-
+ }, style]}>
);
};
diff --git a/mobile/src/components/board/StoreView.tsx b/mobile/src/components/board/StoreView.tsx
index b0a5162..b51a2f7 100644
--- a/mobile/src/components/board/StoreView.tsx
+++ b/mobile/src/components/board/StoreView.tsx
@@ -5,17 +5,16 @@ import { getColorByBrightness } from "../../util/ColorUtil";
import Util from "../../util/Util";
import PitViewModel from "../../viewmodel/PitViewModel";
import StoneView from "./StoneView";
-import { Text, View } from "react-native";
+import { Text, View, ViewStyle } from "react-native";
const StoreView: FunctionComponent<{
context: Context;
pitViewModel: PitViewModel;
- gridColumn: string;
- gridRow: string;
-}> = ({ context, pitViewModel, gridColumn, gridRow }) => {
- const stones = [...Util.range(pitViewModel.stoneCount)].map((i, index) => (
-
- ));
+ style: ViewStyle,
+ children: React.ReactNode
+ fontSize: number
+}> = ({ context, pitViewModel, style, children, fontSize }) => {
+
const textColor = getColorByBrightness(
pitViewModel.pitColor,
context.themeManager.theme.textColor,
@@ -23,11 +22,8 @@ const StoreView: FunctionComponent<{
);
return (
- {stones}
+ flexDirection: "row"
+ }]}>
+ {children}
- {stones.length}
+ {pitViewModel.stoneCount}
);
diff --git a/mobile/src/screens/GameScreen.tsx b/mobile/src/screens/GameScreen.tsx
index d47805e..df9f69e 100644
--- a/mobile/src/screens/GameScreen.tsx
+++ b/mobile/src/screens/GameScreen.tsx
@@ -1,5 +1,5 @@
import * as React from 'react';
-import { View, Button, Text, useWindowDimensions } from 'react-native';
+import { View, Button, Text, useWindowDimensions, Alert } from 'react-native';
import { useTranslation } from 'react-i18next';
import { GameScreenProps } from '../types';
import { useState } from 'react';
@@ -76,7 +76,7 @@ export function GameScreen({ navigation, route }: GameScreenProps) {
}
const onGameCrashed = (message: any) => {
const newCrashMessage = message as string;
- Snackbar.show({text: t("InternalErrorOccurred")});
+ Snackbar.show({ text: t("InternalErrorOccurred") });
console.error("on_game_crash");
console.error(newCrashMessage);
}
@@ -125,24 +125,29 @@ export function GameScreen({ navigation, route }: GameScreenProps) {
const onLeaveGameClick = () => {
if (Util.checkConnectionAndMaybeAlert(context, t("ConnectionLost"))) return;
-
- // TODO
- //swal({
- // title: context.texts.AreYouSureToLeaveGame,
- // icon: "warning",
- // buttons: [context.texts.Yes, context.texts.Cancel],
- // dangerMode: true,
- //})
- // .then((cancel) => {
- // if (!cancel) {
- // context.rtmt.sendMessage(channel_leave_game, {});
- // }
- // });
+ Alert.alert(t('AreYouSureToLeaveGame'), "", [
+ {
+ text: t('Cancel'),
+ style: 'cancel',
+ },
+ {
+ text: t('Yes'),
+ onPress: () => {
+ context.rtmt.sendMessage(channel_leave_game, {});
+ updateHeaderButton();
+ },
+ style: 'default',
+ },
+ ],
+ {
+ cancelable: true,
+ onDismiss: () => { }
+ });
};
const onNewGameClick = () => {
if (Util.checkConnectionAndMaybeAlert(context, t("ConnectionLost"))) return;
- navigation.navigate("Loby", { context })
+ navigation.replace("Loby", { context })
};
const onPitSelect = (index: number, pit: Pit) => {
@@ -150,31 +155,31 @@ export function GameScreen({ navigation, route }: GameScreenProps) {
return;
}
if (userKeyWhoLeave) {
- Snackbar.show({text: t("GameEnded")});
+ Snackbar.show({ text: t("GameEnded") });
return;
}
if (game.mancalaGame.state === "ended") {
- Snackbar.show({text: t("GameEnded")});
+ Snackbar.show({ text: t("GameEnded") });
return;
}
if (Util.checkConnectionAndMaybeAlert(context, t("ConnectionLost"))) return;
if (game.mancalaGame.getPlayerIdByIndex(index) !== userKey) {
- Snackbar.show({text: t("UCanOnlyPlayYourOwnPits")});
+ Snackbar.show({ text: t("UCanOnlyPlayYourOwnPits") });
return;
}
const pitIndexForUser = index % (game.mancalaGame.board.totalPitCount() / 2);
if (!game.mancalaGame.canPlayerMove(userKey, pitIndexForUser)) {
- Snackbar.show({text: t("OpponentTurn")});
+ Snackbar.show({ text: t("OpponentTurn") });
return;
}
if (checkHasAnOngoingAction()) {
- Snackbar.show({text: t("UMustWaitUntilCurrentMoveComplete")});
+ Snackbar.show({ text: t("UMustWaitUntilCurrentMoveComplete") });
return;
}
if (!boardViewModel) return;
//TODO: this check should be in mancala.js
if (pit.stoneCount === 0) {
- Snackbar.show({text: t("UCanNotPlayEmptyPit")});
+ Snackbar.show({ text: t("UCanNotPlayEmptyPit") });
return;
}
setHasOngoingAction(true);
@@ -206,6 +211,25 @@ export function GameScreen({ navigation, route }: GameScreenProps) {
};
}, []);
+ const updateHeaderButton = () => {
+ console.info(game?.mancalaGame.state)
+ navigation.setOptions({
+ headerRight: () => (
+