Stockage de la géolocalisation en arrière-plan et utilisation sur la carte
This commit is contained in:
24
client/utils/features/location/locationSlice.ts
Normal file
24
client/utils/features/location/locationSlice.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
|
||||
import { LocationObject } from 'expo-location'
|
||||
|
||||
interface LocationState {
|
||||
location: LocationObject | null
|
||||
}
|
||||
|
||||
const initialState: LocationState = {
|
||||
location: null
|
||||
}
|
||||
|
||||
export const locationSlice = createSlice({
|
||||
name: 'location',
|
||||
initialState: initialState,
|
||||
reducers: {
|
||||
setLocation: (state, action: PayloadAction<LocationObject>) => {
|
||||
state.location = action.payload
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export const { setLocation } = locationSlice.actions
|
||||
|
||||
export default locationSlice.reducer
|
60
client/utils/geolocation.ts
Normal file
60
client/utils/geolocation.ts
Normal file
@ -0,0 +1,60 @@
|
||||
import * as Location from 'expo-location'
|
||||
import * as TaskManager from 'expo-task-manager'
|
||||
import { Platform } from 'react-native'
|
||||
import { setLocation } from './features/location/locationSlice'
|
||||
import store from './store'
|
||||
import { useEffect } from 'react'
|
||||
|
||||
const LOCATION_TASK = "fetch-geolocation"
|
||||
|
||||
TaskManager.defineTask(LOCATION_TASK, async ({ data, error }: any) => {
|
||||
if (error) {
|
||||
console.error(error)
|
||||
return
|
||||
}
|
||||
const { locations } = data
|
||||
store.dispatch(setLocation(locations.at(-1)))
|
||||
for (let location of locations) {
|
||||
// TODO Envoyer les positions au serveur
|
||||
}
|
||||
})
|
||||
|
||||
export async function startGeolocationService(): Promise<void | (() => void)> {
|
||||
if (Platform.OS !== "web" && await Location.hasStartedLocationUpdatesAsync(LOCATION_TASK))
|
||||
return async () => await Location.stopLocationUpdatesAsync(LOCATION_TASK)
|
||||
|
||||
await Location.enableNetworkProviderAsync().catch(error => alert(error))
|
||||
|
||||
const { status: foregroundStatus } = await Location.requestForegroundPermissionsAsync()
|
||||
if (foregroundStatus !== 'granted')
|
||||
alert("Vous devez activer votre géolocalisation pour utiliser l'application.")
|
||||
|
||||
const { status: backgroundStatus } = await Location.requestBackgroundPermissionsAsync()
|
||||
if (backgroundStatus !== 'granted')
|
||||
alert("Vous devez activer votre géolocalisation en arrière-plan pour utiliser l'application.")
|
||||
|
||||
if (Platform.OS !== "web") {
|
||||
await Location.startLocationUpdatesAsync(LOCATION_TASK, {
|
||||
accuracy: Location.Accuracy.BestForNavigation,
|
||||
activityType: Location.ActivityType.OtherNavigation,
|
||||
deferredUpdatesInterval: 100,
|
||||
foregroundService: {
|
||||
killServiceOnDestroy: false,
|
||||
notificationBody: "Géolocalisation activée pour « Traintrape-moi »",
|
||||
notificationTitle: "Traintrape-moi",
|
||||
notificationColor: "#FFFF00",
|
||||
}
|
||||
})
|
||||
return async () => await Location.stopLocationUpdatesAsync(LOCATION_TASK)
|
||||
}
|
||||
else {
|
||||
const locationSubscription = await Location.watchPositionAsync({accuracy: Location.Accuracy.BestForNavigation}, location_nouveau => store.dispatch(setLocation(location_nouveau)))
|
||||
return locationSubscription.remove
|
||||
}
|
||||
}
|
||||
|
||||
export const useStartGeolocationServiceEffect = () => useEffect(() => {
|
||||
let cleanup: void | (() => void) = () => {}
|
||||
startGeolocationService().then(result => cleanup = result)
|
||||
return cleanup
|
||||
}, [])
|
13
client/utils/store.ts
Normal file
13
client/utils/store.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { configureStore } from '@reduxjs/toolkit'
|
||||
import locationReducer from './features/location/locationSlice'
|
||||
|
||||
const store = configureStore({
|
||||
reducer: {
|
||||
location: locationReducer,
|
||||
},
|
||||
})
|
||||
|
||||
export default store
|
||||
|
||||
export type RootState = ReturnType<typeof store.getState>
|
||||
export type AppDispatch = typeof store.dispatch
|
Reference in New Issue
Block a user