diff --git a/src/hooks/useLocationSharing.ts b/src/hooks/useLocationSharing.ts index 1202927..8af5f5a 100644 --- a/src/hooks/useLocationSharing.ts +++ b/src/hooks/useLocationSharing.ts @@ -38,8 +38,8 @@ export function useLocationSharing( onLocationUpdate, updateInterval = 5000, highAccuracy = true, - maxAge = 5000, // Allow cached position up to 5 seconds old - timeout = 30000, + maxAge = 30000, // Allow cached position up to 30 seconds old + timeout = 15000, // 15 second timeout before fallback } = options; const [isSharing, setIsSharing] = useState(false); @@ -49,6 +49,8 @@ export function useLocationSharing( const watchIdRef = useRef(null); const onLocationUpdateRef = useRef(onLocationUpdate); + const timeoutCountRef = useRef(0); + const usingLowAccuracyRef = useRef(false); // Keep callback ref updated useEffect(() => { @@ -73,6 +75,9 @@ export function useLocationSharing( }, []); const handlePosition = useCallback((position: GeolocationPosition) => { + // Reset timeout counter on successful position + timeoutCountRef.current = 0; + const location: ParticipantLocation = { latitude: position.coords.latitude, longitude: position.coords.longitude, @@ -90,12 +95,50 @@ export function useLocationSharing( onLocationUpdateRef.current?.(location); }, []); + // Restart watcher with low accuracy mode + const restartWithLowAccuracy = useCallback(() => { + if (watchIdRef.current !== null) { + navigator.geolocation.clearWatch(watchIdRef.current); + } + + console.log('Switching to low accuracy mode for faster location'); + usingLowAccuracyRef.current = true; + + const geoOptions: PositionOptions = { + enableHighAccuracy: false, + maximumAge: 60000, // Accept positions up to 1 minute old + timeout: 60000, // Longer timeout for low accuracy + }; + + watchIdRef.current = navigator.geolocation.watchPosition( + handlePosition, + (err) => { + setError(err); + console.warn('Geolocation warning (low accuracy):', err.message, '(code:', err.code, ')'); + }, + geoOptions + ); + }, [handlePosition]); + const handleError = useCallback((err: GeolocationPositionError) => { setError(err); + + // Count consecutive timeouts + if (err.code === 3) { // TIMEOUT + timeoutCountRef.current++; + console.warn('Geolocation timeout', timeoutCountRef.current, '/', 3); + + // After 2 timeouts, switch to low accuracy mode + if (timeoutCountRef.current >= 2 && !usingLowAccuracyRef.current && highAccuracy) { + restartWithLowAccuracy(); + return; + } + } + // Only log as warning, not error - timeouts are common indoors console.warn('Geolocation warning:', err.message, '(code:', err.code, ')'); // Don't stop sharing on errors - keep trying - }, []); + }, [highAccuracy, restartWithLowAccuracy]); const startSharing = useCallback(() => { if (!('geolocation' in navigator)) { @@ -107,6 +150,10 @@ export function useLocationSharing( return; // Already watching } + // Reset fallback flags + timeoutCountRef.current = 0; + usingLowAccuracyRef.current = false; + const geoOptions: PositionOptions = { enableHighAccuracy: highAccuracy, maximumAge: maxAge,