'use client'; import { useEffect, useCallback, useRef } from 'react'; // Background Sync API types (not in default TypeScript libs) interface SyncManager { register(tag: string): Promise; } interface ServiceWorkerRegistrationWithSync extends ServiceWorkerRegistration { sync: SyncManager; } interface UseServiceWorkerMessagesOptions { onLocationRequest?: () => void; onLocationSync?: () => void; } /** * Hook to handle messages from the service worker * Used for background location sync and silent push notifications */ export function useServiceWorkerMessages(options: UseServiceWorkerMessagesOptions = {}) { const optionsRef = useRef(options); optionsRef.current = options; useEffect(() => { if (!('serviceWorker' in navigator)) { return; } const handleMessage = (event: MessageEvent) => { console.log('[App] Service worker message:', event.data); switch (event.data?.type) { case 'REQUEST_LOCATION_UPDATE': // Service worker is requesting a location update (from silent push) optionsRef.current.onLocationRequest?.(); break; case 'REQUEST_LOCATION_SYNC': // Service worker wants to sync location (device came back online) optionsRef.current.onLocationSync?.(); break; } }; navigator.serviceWorker.addEventListener('message', handleMessage); return () => { navigator.serviceWorker.removeEventListener('message', handleMessage); }; }, []); // Register for background sync const registerBackgroundSync = useCallback(async () => { if (!('serviceWorker' in navigator) || !('SyncManager' in window)) { console.log('[App] Background sync not supported'); return false; } try { const registration = await navigator.serviceWorker.ready as ServiceWorkerRegistrationWithSync; await registration.sync.register('rmaps-location-sync'); console.log('[App] Background sync registered'); return true; } catch (error) { console.error('[App] Background sync registration failed:', error); return false; } }, []); return { registerBackgroundSync, }; }