forked from abdlelahalwali8-a11y/dr-appointments-hub
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathusePWA.ts
More file actions
1 lines (1 loc) · 6.32 KB
/
Copy pathusePWA.ts
File metadata and controls
1 lines (1 loc) · 6.32 KB
1
import { useEffect, useState, useCallback } from 'react';\n\nexport interface PWAState {\n isInstallable: boolean;\n isInstalled: boolean;\n deferredPrompt: any;\n isOnline: boolean;\n isSupported: boolean;\n}\n\nexport const usePWA = () => {\n const [pwaState, setPWAState] = useState<PWAState>({\n isInstallable: false,\n isInstalled: false,\n deferredPrompt: null,\n isOnline: typeof navigator !== 'undefined' ? navigator.onLine : true,\n isSupported: typeof window !== 'undefined' && 'serviceWorker' in navigator,\n });\n\n // Register service worker\n useEffect(() => {\n if (!pwaState.isSupported) return;\n\n const registerServiceWorker = async () => {\n try {\n const registration = await navigator.serviceWorker.register('/service-worker.js', {\n scope: '/',\n });\n console.log('Service Worker registered:', registration);\n } catch (error) {\n console.error('Service Worker registration failed:', error);\n }\n };\n\n registerServiceWorker();\n }, [pwaState.isSupported]);\n\n // Handle beforeinstallprompt event\n useEffect(() => {\n const handleBeforeInstallPrompt = (e: Event) => {\n e.preventDefault();\n setPWAState((prev) => ({\n ...prev,\n isInstallable: true,\n deferredPrompt: e,\n }));\n };\n\n const handleAppInstalled = () => {\n setPWAState((prev) => ({\n ...prev,\n isInstalled: true,\n isInstallable: false,\n deferredPrompt: null,\n }));\n };\n\n window.addEventListener('beforeinstallprompt', handleBeforeInstallPrompt);\n window.addEventListener('appinstalled', handleAppInstalled);\n\n // Check if app is already installed\n if (window.matchMedia('(display-mode: standalone)').matches) {\n setPWAState((prev) => ({\n ...prev,\n isInstalled: true,\n }));\n }\n\n return () => {\n window.removeEventListener('beforeinstallprompt', handleBeforeInstallPrompt);\n window.removeEventListener('appinstalled', handleAppInstalled);\n };\n }, []);\n\n // Handle online/offline events\n useEffect(() => {\n const handleOnline = () => {\n setPWAState((prev) => ({ ...prev, isOnline: true }));\n };\n\n const handleOffline = () => {\n setPWAState((prev) => ({ ...prev, isOnline: false }));\n };\n\n window.addEventListener('online', handleOnline);\n window.addEventListener('offline', handleOffline);\n\n return () => {\n window.removeEventListener('online', handleOnline);\n window.removeEventListener('offline', handleOffline);\n };\n }, []);\n\n // Install PWA\n const installPWA = useCallback(async () => {\n if (!pwaState.deferredPrompt) return false;\n\n try {\n pwaState.deferredPrompt.prompt();\n const { outcome } = await pwaState.deferredPrompt.userChoice;\n \n if (outcome === 'accepted') {\n setPWAState((prev) => ({\n ...prev,\n isInstallable: false,\n deferredPrompt: null,\n }));\n return true;\n }\n return false;\n } catch (error) {\n console.error('Error installing PWA:', error);\n return false;\n }\n }, [pwaState.deferredPrompt]);\n\n // Request notification permission\n const requestNotificationPermission = useCallback(async () => {\n if (!('Notification' in window)) {\n console.log('Notifications not supported');\n return false;\n }\n\n if (Notification.permission === 'granted') {\n return true;\n }\n\n if (Notification.permission !== 'denied') {\n const permission = await Notification.requestPermission();\n return permission === 'granted';\n }\n\n return false;\n }, []);\n\n // Send notification\n const sendNotification = useCallback(\n async (title: string, options?: NotificationOptions) => {\n if (!pwaState.isSupported) return false;\n\n try {\n const registration = await navigator.serviceWorker.ready;\n await registration.showNotification(title, {\n icon: '/icons/icon-192x192.png',\n badge: '/icons/icon-192x192.png',\n ...options,\n });\n return true;\n } catch (error) {\n console.error('Error sending notification:', error);\n return false;\n }\n },\n [pwaState.isSupported]\n );\n\n // Subscribe to push notifications\n const subscribeToPushNotifications = useCallback(async (vapidPublicKey: string) => {\n if (!pwaState.isSupported) return null;\n\n try {\n const registration = await navigator.serviceWorker.ready;\n const subscription = await registration.pushManager.subscribe({\n userVisibleOnly: true,\n applicationServerKey: vapidPublicKey,\n });\n return subscription;\n } catch (error) {\n console.error('Error subscribing to push notifications:', error);\n return null;\n }\n }, [pwaState.isSupported]);\n\n // Unsubscribe from push notifications\n const unsubscribeFromPushNotifications = useCallback(async () => {\n if (!pwaState.isSupported) return false;\n\n try {\n const registration = await navigator.serviceWorker.ready;\n const subscription = await registration.pushManager.getSubscription();\n if (subscription) {\n await subscription.unsubscribe();\n return true;\n }\n return false;\n } catch (error) {\n console.error('Error unsubscribing from push notifications:', error);\n return false;\n }\n }, [pwaState.isSupported]);\n\n // Request periodic background sync\n const requestPeriodicSync = useCallback(\n async (tag: string, minInterval: number = 24 * 60 * 60 * 1000) => {\n if (!pwaState.isSupported) return false;\n\n try {\n const registration = await navigator.serviceWorker.ready;\n if ('periodicSync' in registration) {\n await registration.periodicSync.register(tag, {\n minInterval,\n });\n return true;\n }\n return false;\n } catch (error) {\n console.error('Error requesting periodic sync:', error);\n return false;\n }\n },\n [pwaState.isSupported]\n );\n\n return {\n ...pwaState,\n installPWA,\n requestNotificationPermission,\n sendNotification,\n subscribeToPushNotifications,\n unsubscribeFromPushNotifications,\n requestPeriodicSync,\n };\n};\n\nexport default usePWA;\n