'use client'; import { useEffect, useRef } from 'react'; import { getSettings, saveDriverLocation, isAuthenticated } from '@/lib/pocketbase'; export default function LocationTracker() { const watchRef = useRef(null); const intervalRef = useRef | null>(null); const wakeLockRef = useRef(null); useEffect(() => { if (!('geolocation' in navigator)) return; const settings = getSettings(); const intervalMs = Math.max(30000, settings.locationInterval * 1000); const sendLocation = (position: GeolocationPosition) => { if (!isAuthenticated()) return; if (position.coords.accuracy > settings.minimumAccuracy) return; const auth = JSON.parse(localStorage.getItem('pocketbase_auth') || '{}'); const user = auth?.model; if (!user) return; saveDriverLocation({ driver: user.id, latitude: position.coords.latitude, longitude: position.coords.longitude, accuracy: position.coords.accuracy || undefined, altitude: position.coords.altitude || undefined, speed: position.coords.speed || undefined, heading: position.coords.heading || undefined, timestamp: new Date().toISOString(), }); }; // 1. watchPosition keeps GPS active (helps Android stay alive longer) watchRef.current = navigator.geolocation.watchPosition( sendLocation, () => {}, { enableHighAccuracy: settings.enableHighAccuracy, maximumAge: 5000, // fresh GPS every 5s timeout: 30000, } ); // 2. Interval fallback (for when watchPosition is throttled) intervalRef.current = setInterval(() => { navigator.geolocation.getCurrentPosition( sendLocation, () => {}, { enableHighAccuracy: settings.enableHighAccuracy, maximumAge: intervalMs, timeout: 30000 } ); }, intervalMs); // 3. Screen Wake Lock — keeps phone awake while app is open if ('wakeLock' in navigator) { navigator.wakeLock.request('screen') .then((lock) => { wakeLockRef.current = lock; }) .catch(() => {}); // Re-acquire if page regains focus const onFocus = () => { if (!wakeLockRef.current) { navigator.wakeLock.request('screen') .then((lock) => { wakeLockRef.current = lock; }) .catch(() => {}); } }; document.addEventListener('visibilitychange', () => { if (document.visibilityState === 'visible') onFocus(); }); } return () => { if (watchRef.current !== null) { navigator.geolocation.clearWatch(watchRef.current); watchRef.current = null; } if (intervalRef.current !== null) { clearInterval(intervalRef.current); intervalRef.current = null; } if (wakeLockRef.current) { wakeLockRef.current.release(); wakeLockRef.current = null; } }; }, []); return null; }