import { useQuery } from '@tanstack/react-query' import React, { ReactNode, useEffect } from 'react' import { Platform } from 'react-native' import { Constants } from '@/constants/Constants' import { useAuth } from '@/hooks/useAuth' import { useSetLocationAccuracy } from '@/hooks/useGame' import { useGeolocationMutation } from '@/hooks/mutations/useGeolocationMutation' import { useQueuedLocations, useSetLastPlayerLocation, useSetLastPlayerLocations, useUnqueueLocation } from '@/hooks/useLocation' import { isAuthValid } from '@/utils/features/auth/authSlice' import { PlayerLocation } from '@/utils/features/location/locationSlice' import { useStartGeolocationServiceEffect } from '@/utils/geolocation' import * as SecureStore from '@/utils/SecureStore' import { socket } from '@/utils/socket' import { Accuracy } from 'expo-location' export default function GeolocationProvider({ children }: { children: ReactNode }) { useStartGeolocationServiceEffect() const auth = useAuth() const setLocationAccuracy = useSetLocationAccuracy() const geolocationsQueue = useQueuedLocations() const unqueueLocation = useUnqueueLocation() const setLastPlayerLocations = useSetLastPlayerLocations() const setLastPlayerLocation = useSetLastPlayerLocation() const geolocationMutation = useGeolocationMutation({ auth, onPostSuccess: (data, variables) => unqueueLocation(variables), onError: ({ response, error }) => console.error(response, error), }) useEffect(() => { SecureStore.getItemAsync('locationAccuracy').then(locationAccuracyString => { if (!locationAccuracyString) setLocationAccuracy(Accuracy.Balanced) else if (locationAccuracyString === 'null') setLocationAccuracy(null) else setLocationAccuracy(+locationAccuracyString) }) }, []) if (Platform.OS !== "web") { useEffect(() => { if (geolocationsQueue.length === 0 || geolocationMutation.isPending || !isAuthValid(auth)) return const locToSend = geolocationsQueue[0] geolocationMutation.mutate(locToSend) }, [auth, geolocationMutation.status, geolocationsQueue]) } const lastLocationsQuery = useQuery({ queryKey: ['get-last-locations', auth.token], queryFn: () => fetch(`${process.env.EXPO_PUBLIC_TRAINTRAPE_MOI_SERVER}/geolocations/last-locations/`, { method: "GET", headers: { "Authorization": `Bearer ${auth.token}`, "Content-Type": "application/json", }, }).then(resp => resp.json()), initialData: [], enabled: isAuthValid(auth), refetchInterval: Constants.QUERY_REFETCH_INTERVAL * 1000, }) useEffect(() => { if (lastLocationsQuery.isSuccess && lastLocationsQuery.data) setLastPlayerLocations(lastLocationsQuery.data) }, [lastLocationsQuery.status, lastLocationsQuery.dataUpdatedAt]) useEffect(() => { const locationListener = async (data: PlayerLocation) => { if (data.playerId) setLastPlayerLocation(data) } socket.on('last-location', locationListener) return () => { socket.off('last-location', locationListener) } }, []) return <> {children} }