From 2a67ec0a42b26ada69e4a04295ab0168c011c44c Mon Sep 17 00:00:00 2001 From: Ken-ichi Date: Tue, 23 Jul 2024 20:04:50 -0400 Subject: [PATCH] Bugfix: stop watching location when screen blurs (#1841) This wasn't quite working as intended. Also sets isFetchingLocation correctly when it starts to fetch location. --- src/sharedHooks/useWatchPosition.ts | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/sharedHooks/useWatchPosition.ts b/src/sharedHooks/useWatchPosition.ts index 61a1030cc..5969cd9e1 100644 --- a/src/sharedHooks/useWatchPosition.ts +++ b/src/sharedHooks/useWatchPosition.ts @@ -7,8 +7,6 @@ import { useCallback, useEffect, useState } from "react"; export const TARGET_POSITIONAL_ACCURACY = 10; -export const TIMEOUT = 2000; - interface UserLocation { latitude: number, longitude: number, @@ -18,15 +16,14 @@ interface UserLocation { const geolocationOptions = { distanceFilter: 0, enableHighAccuracy: true, - maximumAge: 0, - timeout: TIMEOUT + maximumAge: 0 }; const useWatchPosition = ( options: { shouldFetchLocation: boolean } ) => { const navigation = useNavigation( ); - const [currentPosition, setCurrentPosition] = useState( null ); + const [currentPosition, setCurrentPosition] = useState( null ); const [subscriptionId, setSubscriptionId] = useState( null ); const [userLocation, setUserLocation] = useState( null ); const { shouldFetchLocation } = options; @@ -36,12 +33,13 @@ const useWatchPosition = ( options: { ); const watchPosition = ( ) => { + setIsFetchingLocation( true ); const success = ( position: GeolocationResponse ) => { setCurrentPosition( position ); }; const failure = ( error: GeolocationError ) => { - console.warn( error, ": useWatchPosition error" ); + console.warn( "useWatchPosition error: ", error ); setIsFetchingLocation( false ); }; @@ -53,11 +51,11 @@ const useWatchPosition = ( options: { ); setSubscriptionId( watchID ); } catch ( error ) { - failure( error ); + failure( error as GeolocationError ); } }; - const stopWatch = useCallback( id => { + const stopWatch = useCallback( ( id: number ) => { Geolocation.clearWatch( id ); setSubscriptionId( null ); setCurrentPosition( null ); @@ -72,7 +70,10 @@ const useWatchPosition = ( options: { positional_accuracy: currentPosition?.coords?.accuracy }; setUserLocation( newLocation ); - if ( currentPosition?.coords?.accuracy < TARGET_POSITIONAL_ACCURACY ) { + if ( + subscriptionId !== null + && currentPosition?.coords?.accuracy < TARGET_POSITIONAL_ACCURACY + ) { stopWatch( subscriptionId ); } }, [currentPosition, stopWatch, subscriptionId] ); @@ -84,14 +85,15 @@ const useWatchPosition = ( options: { }, [shouldFetchLocation] ); useEffect( ( ) => { + // When we leave the screen this hook was used on... const unsubscribe = navigation.addListener( "blur", ( ) => { - setSubscriptionId( null ); - setCurrentPosition( null ); - setIsFetchingLocation( false ); + // ...stop watching for location updates if we were... + if ( subscriptionId !== null ) stopWatch( subscriptionId ); + // ...and wipe the current location so we don't pick up a stale one later setUserLocation( null ); } ); return unsubscribe; - }, [navigation] ); + }, [navigation, stopWatch, subscriptionId] ); return { isFetchingLocation,