diff --git a/client/app/(tabs)/settings.tsx b/client/app/(tabs)/settings.tsx
index fd5ba1f..1f49527 100644
--- a/client/app/(tabs)/settings.tsx
+++ b/client/app/(tabs)/settings.tsx
@@ -1,35 +1,39 @@
import { useGameRepairMutation, useGameResetMutation, useGameStartMutation, useGameStopMutation, useGameSwitchPlayerMutation } from '@/hooks/mutations/useGameMutation'
import { useAuth } from '@/hooks/useAuth'
-import { useGame } from '@/hooks/useGame'
+import { useGame, useUpdateGameState } from '@/hooks/useGame'
import { useRouter } from 'expo-router'
-import { FAB, List, Surface } from 'react-native-paper'
+import { useState } from 'react'
+import { Button, Dialog, FAB, List, Portal, Surface, Text } from 'react-native-paper'
export default function HistoryScreen() {
const router = useRouter()
const auth = useAuth()
const game = useGame()
+ const updateGameState = useUpdateGameState()
const gameStartMutation = useGameStartMutation({
auth,
- game,
+ updateGameState,
})
const gameStopMutation = useGameStopMutation({
auth,
- game,
+ updateGameState,
})
const gameSwitchMutation = useGameSwitchPlayerMutation({
auth,
- game,
+ updateGameState,
})
const gameRepairMutation = useGameRepairMutation({
auth,
- game,
+ updateGameState,
})
const gameResetMutation = useGameResetMutation({
auth,
- game,
+ updateGameState,
})
+ const [resetConfirmVisible, setResetConfirmVisible] = useState(false)
+
return (
@@ -74,8 +78,23 @@ export default function HistoryScreen() {
title="Réinitialiser les données de jeu"
description="Permet de détruire toutes les données. À manipuler avec précaution."
right={() => }
- onPress={() => gameResetMutation.mutate()} />
+ onPress={() => setResetConfirmVisible(true)} />
+
+
+
)
}
diff --git a/client/app/_layout.tsx b/client/app/_layout.tsx
index 87d2877..9e6eb09 100644
--- a/client/app/_layout.tsx
+++ b/client/app/_layout.tsx
@@ -14,6 +14,7 @@ import store from '@/utils/store'
import { useStartBackgroundFetchServiceEffect } from '@/utils/background'
import LoginProvider from '@/components/LoginProvider'
import GeolocationProvider from '@/components/GeolocationProvider'
+import GameProvider from '@/components/GameProvider'
const queryClient = new QueryClient({
defaultOptions: {
@@ -45,16 +46,18 @@ export default function RootLayout() {
onSuccess={() => queryClient.resumePausedMutations().then(() => queryClient.invalidateQueries())}>
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/client/components/GameProvider.tsx b/client/components/GameProvider.tsx
new file mode 100644
index 0000000..d64a85e
--- /dev/null
+++ b/client/components/GameProvider.tsx
@@ -0,0 +1,26 @@
+import { useAuth } from '@/hooks/useAuth'
+import { useUpdateGameState } from '@/hooks/useGame'
+import { useQuery } from '@tanstack/react-query'
+import { ReactNode, useEffect } from 'react'
+
+export default function GameProvider({ children }: { children: ReactNode }) {
+ const auth = useAuth()
+ const updateGameState = useUpdateGameState()
+ const gameQuery = useQuery({
+ queryKey: ['update-game'],
+ queryFn: () => fetch(`${process.env.EXPO_PUBLIC_TRAINTRAPE_MOI_SERVER}/game/`, {
+ headers: { "Authorization": `Bearer ${auth.token}` }}
+ ).then(resp => resp.json()),
+ enabled: auth.loggedIn,
+ refetchInterval: 5000,
+ })
+ const game = gameQuery.data
+ useEffect(() => {
+ if (game)
+ updateGameState(game)
+ }, [game])
+
+ return <>
+ {children}
+ >
+}
\ No newline at end of file
diff --git a/client/hooks/mutations/useGameMutation.ts b/client/hooks/mutations/useGameMutation.ts
index be8fb69..e423f1a 100644
--- a/client/hooks/mutations/useGameMutation.ts
+++ b/client/hooks/mutations/useGameMutation.ts
@@ -1,5 +1,5 @@
import { AuthState } from "@/utils/features/auth/authSlice"
-import { GameState } from "@/utils/features/game/gameSlice"
+import { GamePayload, GameState } from "@/utils/features/game/gameSlice"
import { useMutation } from "@tanstack/react-query"
type ErrorResponse = {
@@ -13,13 +13,13 @@ type ErrorFuncProps = { response?: ErrorResponse, error?: Error }
type onErrorFunc = (props: ErrorFuncProps) => void
type GameProps = {
- game: GameState
+ updateGameState: (payload: GamePayload) => { payload: GamePayload, type: "game/updateGameState" }
auth: AuthState
onPostSuccess?: onPostSuccessFunc
onError?: onErrorFunc
}
-export const useGameStartMutation = ({ game, auth, onPostSuccess, onError }: GameProps) => {
+export const useGameStartMutation = ({ auth, updateGameState, onPostSuccess, onError }: GameProps) => {
return useMutation({
mutationFn: async () => {
return fetch(`${process.env.EXPO_PUBLIC_TRAINTRAPE_MOI_SERVER}/game/start/`, {
@@ -36,6 +36,7 @@ export const useGameStartMutation = ({ game, auth, onPostSuccess, onError }: Gam
onError({ response: data })
return
}
+ updateGameState(data)
if (onPostSuccess)
onPostSuccess()
},
@@ -46,7 +47,7 @@ export const useGameStartMutation = ({ game, auth, onPostSuccess, onError }: Gam
})
}
-export const useGameStopMutation = ({ auth, game, onPostSuccess, onError }: GameProps) => {
+export const useGameStopMutation = ({ auth, updateGameState, onPostSuccess, onError }: GameProps) => {
return useMutation({
mutationFn: async () => {
return fetch(`${process.env.EXPO_PUBLIC_TRAINTRAPE_MOI_SERVER}/game/stop/`, {
@@ -63,6 +64,7 @@ export const useGameStopMutation = ({ auth, game, onPostSuccess, onError }: Game
onError({ response: data })
return
}
+ updateGameState(data)
if (onPostSuccess)
onPostSuccess()
},
@@ -73,7 +75,7 @@ export const useGameStopMutation = ({ auth, game, onPostSuccess, onError }: Game
})
}
-export const useGameSwitchPlayerMutation = ({ auth, game, onPostSuccess, onError }: GameProps) => {
+export const useGameSwitchPlayerMutation = ({ auth, updateGameState, onPostSuccess, onError }: GameProps) => {
return useMutation({
mutationFn: async () => {
return fetch(`${process.env.EXPO_PUBLIC_TRAINTRAPE_MOI_SERVER}/game/switch-running-player/`, {
@@ -90,6 +92,7 @@ export const useGameSwitchPlayerMutation = ({ auth, game, onPostSuccess, onError
onError({ response: data })
return
}
+ updateGameState(data)
if (onPostSuccess)
onPostSuccess()
},
@@ -100,7 +103,7 @@ export const useGameSwitchPlayerMutation = ({ auth, game, onPostSuccess, onError
})
}
-export const useGameRepairMutation = ({ auth, game, onPostSuccess, onError }: GameProps) => {
+export const useGameRepairMutation = ({ auth, onPostSuccess, onError }: GameProps) => {
return useMutation({
mutationFn: async () => {
return fetch(`${process.env.EXPO_PUBLIC_TRAINTRAPE_MOI_SERVER}/game/repair/`, {
@@ -127,7 +130,7 @@ export const useGameRepairMutation = ({ auth, game, onPostSuccess, onError }: Ga
})
}
-export const useGameResetMutation = ({ auth, game, onPostSuccess, onError }: GameProps) => {
+export const useGameResetMutation = ({ auth, updateGameState, onPostSuccess, onError }: GameProps) => {
return useMutation({
mutationFn: async () => {
return fetch(`${process.env.EXPO_PUBLIC_TRAINTRAPE_MOI_SERVER}/game/reset/`, {
@@ -144,6 +147,7 @@ export const useGameResetMutation = ({ auth, game, onPostSuccess, onError }: Gam
onError({ response: data })
return
}
+ updateGameState(data)
if (onPostSuccess)
onPostSuccess()
},
diff --git a/client/hooks/mutations/useGeolocationMutation.ts b/client/hooks/mutations/useGeolocationMutation.ts
index 33f92ce..b8aa25f 100644
--- a/client/hooks/mutations/useGeolocationMutation.ts
+++ b/client/hooks/mutations/useGeolocationMutation.ts
@@ -8,11 +8,6 @@ type ErrorResponse = {
statusCode: number
}
-type LoginForm = {
- name: string
- password: string
-}
-
type onPostSuccessFunc = (data: any, variables: LocationObject, context: unknown) => void
type ErrorFuncProps = { response?: ErrorResponse, error?: Error }
type onErrorFunc = (props: ErrorFuncProps) => void
diff --git a/client/hooks/useGame.ts b/client/hooks/useGame.ts
index b7443b9..8b2799f 100644
--- a/client/hooks/useGame.ts
+++ b/client/hooks/useGame.ts
@@ -1,5 +1,5 @@
import { useAppDispatch, useAppSelector } from "./useStore"
-import { setPlayerId, updateMoney } from "@/utils/features/game/gameSlice"
+import { GamePayload, setPlayerId, updateGameState, updateMoney } from "@/utils/features/game/gameSlice"
export const useGame = () => useAppSelector((state) => state.game)
export const useSetPlayerId = () => {
@@ -10,3 +10,7 @@ export const useUpdateMoney = () => {
const dispatch = useAppDispatch()
return (money: number) => dispatch(updateMoney(money))
}
+export const useUpdateGameState = () => {
+ const dispatch = useAppDispatch()
+ return (game: GamePayload) => dispatch(updateGameState(game))
+}
diff --git a/client/utils/features/challengeActions/challengeActionsSlice.ts b/client/utils/features/challengeActions/challengeActionsSlice.ts
index 9eed4f7..35fa4c8 100644
--- a/client/utils/features/challengeActions/challengeActionsSlice.ts
+++ b/client/utils/features/challengeActions/challengeActionsSlice.ts
@@ -7,10 +7,10 @@ export interface ChallengeAction {
description: string,
reward: number,
success: boolean,
- start: Date,
- end: Date | null,
- penaltyStart: Date | null,
- penaltyEnd: Date | null,
+ start: number, // date
+ end: number | null, // date
+ penaltyStart: number | null, // date
+ penaltyEnd: number | null, // date
}
export interface ActionsState {
diff --git a/client/utils/features/game/gameSlice.ts b/client/utils/features/game/gameSlice.ts
index 22ee376..f24684d 100644
--- a/client/utils/features/game/gameSlice.ts
+++ b/client/utils/features/game/gameSlice.ts
@@ -1,13 +1,28 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
+export interface RunPayload {
+ id: number
+ gameId: number
+ runnerId: number
+ start: string
+ end: string | null
+}
+
+export interface GamePayload {
+ id: number
+ started: boolean
+ currentRunId: number | null
+ currentRun: RunPayload | null
+}
+
export interface GameState {
playerId: number | null
gameStarted: boolean
money: number
currentRunner: boolean
- chaseFreeTime: Date | null
- penaltyStart: Date | null
- penaltyEnd: Date | null
+ chaseFreeTime: number | null // date
+ penaltyStart: number | null // date
+ penaltyEnd: number | null // date
}
const initialState: GameState = {
@@ -30,9 +45,18 @@ export const gameSlice = createSlice({
updateMoney: (state, action: PayloadAction) => {
state.money = action.payload
},
+ updateGameState: (state, action: PayloadAction) => {
+ const game: GamePayload = action.payload
+ state.gameStarted = game.started
+ state.currentRunner = state.playerId === game.currentRun?.runnerId
+ if (state.currentRunner)
+ state.chaseFreeTime = null
+ else if (game.currentRun)
+ state.chaseFreeTime = new Date(game.currentRun?.start).getTime() + 45 * 60 * 1000
+ }
},
})
-export const { setPlayerId, updateMoney } = gameSlice.actions
+export const { setPlayerId, updateMoney, updateGameState } = gameSlice.actions
export default gameSlice.reducer
diff --git a/client/utils/features/train/trainSlice.ts b/client/utils/features/train/trainSlice.ts
index 2ff066f..36dc477 100644
--- a/client/utils/features/train/trainSlice.ts
+++ b/client/utils/features/train/trainSlice.ts
@@ -83,8 +83,8 @@ export interface TrainTrip {
distance: number,
from: string,
to: string,
- departureTime: Date,
- arrivalTime: Date,
+ departureTime: number,
+ arrivalTime: number,
}
export interface TrainsState {