diff --git a/client/app/(tabs)/history.tsx b/client/app/(tabs)/history.tsx index e469bca..ac174f6 100644 --- a/client/app/(tabs)/history.tsx +++ b/client/app/(tabs)/history.tsx @@ -1,6 +1,9 @@ +import { useMoneyUpdates } from '@/hooks/useMoneyUpdates' import { Surface, Text } from 'react-native-paper' export default function HistoryScreen() { + const moneyUpdates = useMoneyUpdates() + return ( Ici on aura la gestion de l'historique des trains empruntés et des challenges effectués diff --git a/client/components/GameProvider.tsx b/client/components/GameProvider.tsx index 392458b..15de167 100644 --- a/client/components/GameProvider.tsx +++ b/client/components/GameProvider.tsx @@ -2,6 +2,7 @@ import { useAuth } from '@/hooks/useAuth' import { useChallengeActions, useDownloadChallengeActions } from '@/hooks/useChallengeActions' import { useDownloadChallenges } from '@/hooks/useChallenges' import { useGame, useUpdateActiveChallengeId, useUpdateGameState, useUpdateMoney, useUpdatePenalty } from '@/hooks/useGame' +import { useDownloadMoneyUpdates } from '@/hooks/useMoneyUpdates' import { useDownloadTrains } from '@/hooks/useTrain' import { isAuthValid } from '@/utils/features/auth/authSlice' import { ChallengeAction, ChallengeActionPayload } from '@/utils/features/challengeActions/challengeActionsSlice' @@ -20,6 +21,7 @@ export default function GameProvider({ children }: { children: ReactNode }) { const downloadTrains = useDownloadTrains() const downloadChallenges = useDownloadChallenges() const downloadChallengeActions = useDownloadChallengeActions() + const downloadMoneyUpdates = useDownloadMoneyUpdates() const gameQuery = useQuery({ queryKey: ['get-game', auth.token], @@ -63,11 +65,11 @@ export default function GameProvider({ children }: { children: ReactNode }) { }, [trainsQuery.status, trainsQuery.dataUpdatedAt]) const challengesQuery = useQuery({ - queryKey: ['get-challenges', game.playerId, auth.token], + queryKey: ['get-challenges', auth.token], queryFn: () => fetch(`${process.env.EXPO_PUBLIC_TRAINTRAPE_MOI_SERVER}/challenges/?size=10000`, { headers: { "Authorization": `Bearer ${auth.token}` }} ).then(resp => resp.json()), - enabled: isAuthValid(auth) && !!game.playerId, + enabled: isAuthValid(auth), refetchInterval: 5000, }) useEffect(() => { @@ -79,6 +81,19 @@ export default function GameProvider({ children }: { children: ReactNode }) { } }, [challengesQuery.status, challengesQuery.dataUpdatedAt]) + const moneyUpdatesQuery = useQuery({ + queryKey: ['get-money-updates', game.playerId, auth.token], + queryFn: () => fetch(`${process.env.EXPO_PUBLIC_TRAINTRAPE_MOI_SERVER}/money-updates/?playerId=${game.playerId}&size=10000`, { + headers: { "Authorization": `Bearer ${auth.token}` }} + ).then(resp => resp.json()), + enabled: isAuthValid(auth) && !!game.playerId, + refetchInterval: 5000, + }) + useEffect(() => { + if (moneyUpdatesQuery.isSuccess && moneyUpdatesQuery.data) + downloadMoneyUpdates(moneyUpdatesQuery.data) + }, [moneyUpdatesQuery.status, moneyUpdatesQuery.dataUpdatedAt]) + useEffect(() => { const now = new Date().getTime() const activeChallenge: ChallengeAction | undefined = challengeActions.challengeActions diff --git a/client/components/GeolocationProvider.tsx b/client/components/GeolocationProvider.tsx index 5b072fd..fe19558 100644 --- a/client/components/GeolocationProvider.tsx +++ b/client/components/GeolocationProvider.tsx @@ -5,6 +5,7 @@ import { useGeolocationMutation } from '@/hooks/mutations/useGeolocationMutation import { useStartGeolocationServiceEffect } from '@/utils/geolocation' import { Platform } from 'react-native' import { useQuery } from '@tanstack/react-query' +import { isAuthValid } from '@/utils/features/auth/authSlice' export default function GeolocationProvider({ children }: { children: ReactNode }) { useStartGeolocationServiceEffect() @@ -36,8 +37,9 @@ export default function GeolocationProvider({ children }: { children: ReactNode headers: { "Authorization": `Bearer ${auth.token}`, "Content-Type": "application/json", - }} - ).then(resp => resp.json()), + }, + }).then(resp => resp.json()), + enabled: isAuthValid(auth), refetchInterval: 5000, }) useEffect(() => { diff --git a/client/hooks/mutations/useGeolocationMutation.ts b/client/hooks/mutations/useGeolocationMutation.ts index b8aa25f..4d5cf53 100644 --- a/client/hooks/mutations/useGeolocationMutation.ts +++ b/client/hooks/mutations/useGeolocationMutation.ts @@ -40,6 +40,11 @@ export const useGeolocationMutation = ({ auth, onPostSuccess, onError }: PostPro }, networkMode: 'offlineFirst', onSuccess: async (data, location: LocationObject, context: unknown) => { + if (data.statusCode) { + if (onError) + onError({ response: data }) + return + } if (onPostSuccess) onPostSuccess(data, location, context) }, diff --git a/client/hooks/useMoneyUpdates.ts b/client/hooks/useMoneyUpdates.ts new file mode 100644 index 0000000..61750e0 --- /dev/null +++ b/client/hooks/useMoneyUpdates.ts @@ -0,0 +1,8 @@ +import { useAppDispatch, useAppSelector } from "./useStore" +import { downloadMoneyUpdates, MoneyUpdatesPayload } from "@/utils/features/moneyUpdates/moneyUpdatesSlice" + +export const useMoneyUpdates = () => useAppSelector((state) => state.moneyUpdates.moneyUpdates) +export const useDownloadMoneyUpdates = () => { + const dispath = useAppDispatch() + return (moneyUpdatesData: MoneyUpdatesPayload) => dispath(downloadMoneyUpdates(moneyUpdatesData)) +} diff --git a/client/utils/features/moneyUpdates/moneyUpdatesSlice.ts b/client/utils/features/moneyUpdates/moneyUpdatesSlice.ts new file mode 100644 index 0000000..8fe3497 --- /dev/null +++ b/client/utils/features/moneyUpdates/moneyUpdatesSlice.ts @@ -0,0 +1,43 @@ +import { createSlice, PayloadAction } from '@reduxjs/toolkit' +import { PaginationMeta } from '../common' + +export interface MoneyUpdate { + id: number + playerId: number + reason: 'START' | 'NEW_RUN' | 'BUY_TRAIN' | 'WIN_CHALLENGE' + timestamp: number + runId: number | null + actionId: number | null + tripId: number | null +} + +export interface MoneyUpdatesState { + moneyUpdates: MoneyUpdate[] +} + +const initialState: MoneyUpdatesState = { + moneyUpdates: [] +} + +export interface MoneyUpdatesPayload { + data: MoneyUpdate[] + meta: PaginationMeta +} + +export const moneyUpdatesSlice = createSlice({ + name: 'moneyUpdates', + initialState: initialState, + reducers: { + downloadMoneyUpdates(state, action: PayloadAction) { + state.moneyUpdates = state.moneyUpdates.filter(moneyUpdate => action.payload.data.filter(dlMU => dlMU.id === moneyUpdate.id) === null) + for (const dlMU of action.payload.data) { + state.moneyUpdates.push(dlMU) + } + state.moneyUpdates.sort((mu1, mu2) => mu2.id - mu1.id) + }, + }, +}) + +export const { downloadMoneyUpdates } = moneyUpdatesSlice.actions + +export default moneyUpdatesSlice.reducer diff --git a/client/utils/store.ts b/client/utils/store.ts index 5ba312a..2c176e6 100644 --- a/client/utils/store.ts +++ b/client/utils/store.ts @@ -4,6 +4,7 @@ import challengesReducer from './features/challenges/challengesSlice' import challengeActionsReducer from './features/challengeActions/challengeActionsSlice' import gameReducer from './features/game/gameSlice' import locationReducer from './features/location/locationSlice' +import moneyUpdatesReducer from './features/moneyUpdates/moneyUpdatesSlice' import trainReducer from './features/train/trainSlice' const store = configureStore({ @@ -13,6 +14,7 @@ const store = configureStore({ challengeActions: challengeActionsReducer, game: gameReducer, location: locationReducer, + moneyUpdates: moneyUpdatesReducer, train: trainReducer, }, })