feat(mobile): implement "Rejoin Game" functionality and fix storage bugs
This commit is contained in:
parent
8a485e2db3
commit
69664796ce
@ -4,4 +4,10 @@ export class LocalStorage implements Storage {
|
||||
getString(key: string): string | undefined {
|
||||
return localStorage.getItem(key) as string;
|
||||
}
|
||||
setString(key: string, value: string): void {
|
||||
localStorage.setItem(key, value);
|
||||
}
|
||||
deleteString(key: string): void {
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
}
|
||||
@ -55,6 +55,9 @@ export function GameScreen({ navigation, route }: GameScreenProps) {
|
||||
pitAnimator.setUpdatedGame(newGame);
|
||||
setHasOngoingAction(false);
|
||||
setGameUsersConnectionInfo(newGame.gameUsersConnectionInfo);
|
||||
if (newGame.mancalaGame.state === 'ended') {
|
||||
context.storage.deleteString('lastGameId');
|
||||
}
|
||||
}
|
||||
|
||||
const isUserOnline = (userId: string) => {
|
||||
@ -81,6 +84,7 @@ export function GameScreen({ navigation, route }: GameScreenProps) {
|
||||
const userKeyWhoLeave = message;
|
||||
setUserKeyWhoLeave(userKeyWhoLeave);
|
||||
setHasOngoingAction(false);
|
||||
context.storage.deleteString('lastGameId');
|
||||
};
|
||||
const onUserConnectionChange = (message: any) => {
|
||||
const gameUsersConnectionInfo = message as GameUsersConnectionInfo;
|
||||
@ -131,6 +135,7 @@ export function GameScreen({ navigation, route }: GameScreenProps) {
|
||||
text: t('Yes'),
|
||||
onPress: () => {
|
||||
context.rtmt.sendMessage(channel_leave_game, {});
|
||||
context.storage.deleteString('lastGameId');
|
||||
updateHeaderButton();
|
||||
},
|
||||
style: 'default',
|
||||
@ -144,6 +149,7 @@ export function GameScreen({ navigation, route }: GameScreenProps) {
|
||||
|
||||
const onNewGameClick = () => {
|
||||
if (Util.checkConnectionAndMaybeAlert(context, t("ConnectionLost"))) return;
|
||||
context.storage.deleteString('lastGameId');
|
||||
navigation.replace("Loby", { context })
|
||||
};
|
||||
|
||||
@ -193,12 +199,16 @@ export function GameScreen({ navigation, route }: GameScreenProps) {
|
||||
setLoadingStateGame(LoadingState.Loading())
|
||||
context.gameStore.get(gameId!!).then((game) => {
|
||||
if (game) {
|
||||
if (game.mancalaGame.state !== 'ended') {
|
||||
context.storage.setString('lastGameId', game.id);
|
||||
}
|
||||
pitAnimator = new PitAnimator(context.themeManager, updateBoardViewModel);
|
||||
setPitAnimator(pitAnimator);
|
||||
onGameUpdate(pitAnimator, game);
|
||||
unlistenMessages = listenMessages(game, pitAnimator);
|
||||
setLoadingStateGame(LoadingState.Loaded({ value: game }))
|
||||
} else {
|
||||
context.storage.deleteString('lastGameId');
|
||||
setLoadingStateGame(LoadingState.Error({ errorMessage: t('GameNotFound') }))
|
||||
}
|
||||
})
|
||||
@ -210,6 +220,7 @@ export function GameScreen({ navigation, route }: GameScreenProps) {
|
||||
|
||||
const updateHeaderButton = () => {
|
||||
const isGameEnded = game?.mancalaGame.state === "ended" || leftPlayer;
|
||||
const isError = gameLoadingState.isError();
|
||||
navigation.setOptions({
|
||||
headerRight: () => (
|
||||
<View style={{
|
||||
@ -219,13 +230,15 @@ export function GameScreen({ navigation, route }: GameScreenProps) {
|
||||
gap: 5
|
||||
}}>
|
||||
<Pressable onPress={() => {
|
||||
if (isGameEnded) {
|
||||
if (isError) {
|
||||
navigation.replace("Home", { context });
|
||||
} else if (isGameEnded) {
|
||||
onNewGameClick();
|
||||
} else {
|
||||
onLeaveGameClick();
|
||||
}
|
||||
}}>
|
||||
<CircularPanel color={context.themeManager.theme?.background} children={<Text style={{ color: context.themeManager.theme.textColor }}>{isGameEnded ? t('NewGame') : t('Leave')}</Text>} />
|
||||
<CircularPanel color={context.themeManager.theme?.background} children={<Text style={{ color: context.themeManager.theme.textColor }}>{isError ? t('Home') : (isGameEnded ? t('NewGame') : t('Leave'))}</Text>} />
|
||||
</Pressable>
|
||||
<Pressable onPress={() => {
|
||||
navigation.push("Help", { context })
|
||||
@ -240,7 +253,7 @@ export function GameScreen({ navigation, route }: GameScreenProps) {
|
||||
|
||||
React.useEffect(() => {
|
||||
updateHeaderButton();
|
||||
}, [navigation, game, userKeyWhoLeave]);
|
||||
}, [navigation, game, userKeyWhoLeave, gameLoadingState]);
|
||||
|
||||
const textColorOnAppBar = getColorByBrightness(
|
||||
context.themeManager.theme.appBarBgColor,
|
||||
|
||||
@ -11,6 +11,7 @@ export function HomeScreen({ navigation, route }: HomeScreenProps) {
|
||||
|
||||
const { context } = route.params;
|
||||
const { t } = useTranslation();
|
||||
const [lastGameId, setLastGameId] = React.useState<string | undefined>(undefined);
|
||||
|
||||
const textColorOnAppBar = getColorByBrightness(
|
||||
context.themeManager.theme.appBarBgColor,
|
||||
@ -32,6 +33,10 @@ export function HomeScreen({ navigation, route }: HomeScreenProps) {
|
||||
|
||||
React.useEffect(() => {
|
||||
updateHeaderButton();
|
||||
const savedGameId = context.storage.getString('lastGameId');
|
||||
if (savedGameId) {
|
||||
setLastGameId(savedGameId);
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
@ -39,6 +44,22 @@ export function HomeScreen({ navigation, route }: HomeScreenProps) {
|
||||
<Pressable onPress={() => navigation.replace('Loby', { context })}>
|
||||
<CircularPanel color={context.themeManager.theme?.boardColor} children={<Text style={{ color: context.themeManager.theme.textColor }}>{t('NewGame')}</Text>} />
|
||||
</Pressable>
|
||||
{lastGameId && (
|
||||
<>
|
||||
<View style={{ height: 20 }} />
|
||||
<Pressable onPress={async () => {
|
||||
try {
|
||||
const userKey = await context.userKeyStore.getUserKey();
|
||||
navigation.replace('Game', { context, gameId: lastGameId, userKey });
|
||||
} catch (error) {
|
||||
context.storage.deleteString('lastGameId');
|
||||
setLastGameId(undefined);
|
||||
}
|
||||
}}>
|
||||
<CircularPanel color={context.themeManager.theme?.boardColor} children={<Text style={{ color: context.themeManager.theme.textColor }}>{t('RejoinGame')}</Text>} />
|
||||
</Pressable>
|
||||
</>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ export default function LobyScreen({ navigation, route }: LobyScreenProps) {
|
||||
|
||||
const onGameStart = async (message: Object) => {
|
||||
const newGame: CommonMancalaGame = message as CommonMancalaGame;
|
||||
context.storage.setString('lastGameId', newGame.id);
|
||||
const userKey = await context.userKeyStore.getUserKey();
|
||||
navigation.replace("Game", { context, gameId: newGame.id, userKey })
|
||||
}
|
||||
|
||||
@ -8,4 +8,10 @@ export class LocalStorage implements Storage {
|
||||
getString(key: string): string | undefined {
|
||||
return storage.getString(key);
|
||||
}
|
||||
setString(key: string, value: string): void {
|
||||
storage.set(key, value);
|
||||
}
|
||||
deleteString(key: string): void {
|
||||
storage.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,7 +21,7 @@ export class GameStoreImpl implements GameStore {
|
||||
return game;
|
||||
} catch (error) {
|
||||
// todo check error
|
||||
Promise.resolve(undefined);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -36,5 +36,7 @@ export const en = {
|
||||
Cancel: "Cancel",
|
||||
Help: "Help",
|
||||
WebApp: "Goto WebApp",
|
||||
Privacy: "Open Privacy Policy"
|
||||
Privacy: "Open Privacy Policy",
|
||||
Home: "Home",
|
||||
RejoinGame: "Rejoin Game"
|
||||
}
|
||||
@ -36,5 +36,7 @@ export const tr = {
|
||||
Cancel: "İptal",
|
||||
Help: "Yardım",
|
||||
WebApp: "Web Uygulamasına Git",
|
||||
Privacy: "Gizlilik Politikasını Göster"
|
||||
Privacy: "Gizlilik Politikasını Göster",
|
||||
Home: "Ana Sayfa",
|
||||
RejoinGame: "Oyuna Geri Dön"
|
||||
};
|
||||
@ -1,4 +1,6 @@
|
||||
|
||||
export interface Storage {
|
||||
getString(key: string): string | undefined;
|
||||
setString(key: string, value: string): void;
|
||||
deleteString(key: string): void;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user