Boutons de démarrage du jeu fonctionnels
This commit is contained in:
parent
c28097d443
commit
61b0cd51ae
@ -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 (
|
||||
<Surface
|
||||
style={{ flex: 1 }}>
|
||||
@ -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={() => <FAB icon="reload-alert" size="small" variant={'tertiary'} />}
|
||||
onPress={() => gameResetMutation.mutate()} />
|
||||
onPress={() => setResetConfirmVisible(true)} />
|
||||
</List.Section>
|
||||
<Portal>
|
||||
<Dialog key="confirmReset" visible={resetConfirmVisible} onDismiss={() => setResetConfirmVisible(false)}>
|
||||
<Dialog.Title>Confirmer</Dialog.Title>
|
||||
<Dialog.Content>
|
||||
<Text variant="bodyMedium">
|
||||
Cette action va réinitialiser TOUTES les données de jeu : l'historique des positions, les défis réalisés et les trains empruntés.
|
||||
Êtes-vous réellement sûr⋅e de vouloir tout supprimer ?
|
||||
</Text>
|
||||
</Dialog.Content>
|
||||
<Dialog.Actions>
|
||||
<Button onPress={() => setResetConfirmVisible(false)}>Annuler</Button>
|
||||
<Button onPress={() => { setResetConfirmVisible(false); gameResetMutation.mutate() }}>Confirmer</Button>
|
||||
</Dialog.Actions>
|
||||
</Dialog>
|
||||
</Portal>
|
||||
</Surface>
|
||||
)
|
||||
}
|
||||
|
@ -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,6 +46,7 @@ export default function RootLayout() {
|
||||
onSuccess={() => queryClient.resumePausedMutations().then(() => queryClient.invalidateQueries())}>
|
||||
<LoginProvider loginRedirect={'/login'}>
|
||||
<GeolocationProvider>
|
||||
<GameProvider>
|
||||
<PaperProvider theme={colorScheme === 'dark' ? MD3DarkTheme : MD3LightTheme}>
|
||||
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
|
||||
<Stack>
|
||||
@ -55,6 +57,7 @@ export default function RootLayout() {
|
||||
<StatusBar style="auto" />
|
||||
</ThemeProvider>
|
||||
</PaperProvider>
|
||||
</GameProvider>
|
||||
</GeolocationProvider>
|
||||
</LoginProvider>
|
||||
</PersistQueryClientProvider>
|
||||
|
26
client/components/GameProvider.tsx
Normal file
26
client/components/GameProvider.tsx
Normal file
@ -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}
|
||||
</>
|
||||
}
|
@ -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()
|
||||
},
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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<number>) => {
|
||||
state.money = action.payload
|
||||
},
|
||||
updateGameState: (state, action: PayloadAction<GamePayload>) => {
|
||||
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
|
||||
|
@ -83,8 +83,8 @@ export interface TrainTrip {
|
||||
distance: number,
|
||||
from: string,
|
||||
to: string,
|
||||
departureTime: Date,
|
||||
arrivalTime: Date,
|
||||
departureTime: number,
|
||||
arrivalTime: number,
|
||||
}
|
||||
|
||||
export interface TrainsState {
|
||||
|
Loading…
Reference in New Issue
Block a user