add to homescreen feature
This commit is contained in:
61
src/hooks/usePWAInstall.ts
Normal file
61
src/hooks/usePWAInstall.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
|
||||
interface BeforeInstallPromptEvent extends Event {
|
||||
prompt: () => Promise<void>
|
||||
userChoice: Promise<{ outcome: 'accepted' | 'dismissed' }>
|
||||
}
|
||||
|
||||
interface PWAInstall {
|
||||
canInstall: boolean // Android/Chrome: native prompt available
|
||||
isIOS: boolean // iOS Safari: must show manual instructions
|
||||
isInstalled: boolean // Already running as installed PWA
|
||||
triggerInstall: () => Promise<void>
|
||||
}
|
||||
|
||||
export function usePWAInstall(): PWAInstall {
|
||||
const [deferredPrompt, setDeferredPrompt] = useState<BeforeInstallPromptEvent | null>(null)
|
||||
const [isInstalled, setIsInstalled] = useState(false)
|
||||
|
||||
const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !(window as unknown as { MSStream?: unknown }).MSStream
|
||||
|
||||
useEffect(() => {
|
||||
// Detect if already installed (standalone mode)
|
||||
const mq = window.matchMedia('(display-mode: standalone)')
|
||||
const iosStandalone = (navigator as unknown as { standalone?: boolean }).standalone === true
|
||||
if (mq.matches || iosStandalone) {
|
||||
setIsInstalled(true)
|
||||
return
|
||||
}
|
||||
|
||||
const handler = (e: Event) => {
|
||||
e.preventDefault()
|
||||
setDeferredPrompt(e as BeforeInstallPromptEvent)
|
||||
}
|
||||
|
||||
window.addEventListener('beforeinstallprompt', handler)
|
||||
|
||||
window.addEventListener('appinstalled', () => {
|
||||
setIsInstalled(true)
|
||||
setDeferredPrompt(null)
|
||||
})
|
||||
|
||||
return () => window.removeEventListener('beforeinstallprompt', handler)
|
||||
}, [])
|
||||
|
||||
const triggerInstall = async () => {
|
||||
if (!deferredPrompt) return
|
||||
await deferredPrompt.prompt()
|
||||
const { outcome } = await deferredPrompt.userChoice
|
||||
if (outcome === 'accepted') {
|
||||
setIsInstalled(true)
|
||||
setDeferredPrompt(null)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
canInstall: !!deferredPrompt,
|
||||
isIOS,
|
||||
isInstalled,
|
||||
triggerInstall,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user