OwnGPT.v2 / client /src /hooks /useInstallPrompt.js
parthib07's picture
Upload 199 files
212c959 verified
import { useEffect, useMemo, useState } from 'react'
function isStandaloneDisplay() {
if (typeof window === 'undefined') return false
return (
window.matchMedia?.('(display-mode: standalone)').matches ||
window.navigator.standalone === true
)
}
function detectPlatform() {
if (typeof navigator === 'undefined') return 'desktop'
const userAgent = navigator.userAgent || ''
const isIOS =
/iPad|iPhone|iPod/.test(userAgent) ||
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)
if (isIOS) return 'ios'
if (/Android/i.test(userAgent)) return 'android'
return 'desktop'
}
function getManualInstallInstructions(platform) {
if (platform === 'ios') {
return 'Open this app in Safari, tap Share, then choose Add to Home Screen.'
}
if (platform === 'android') {
return 'Open the browser menu and choose Install app or Add to Home screen.'
}
return 'Open the browser menu and choose Install OwnGPT, Install app, or Create shortcut.'
}
export function useInstallPrompt() {
const [deferredPrompt, setDeferredPrompt] = useState(null)
const [isInstalled, setIsInstalled] = useState(() => isStandaloneDisplay())
const [platform, setPlatform] = useState(() => detectPlatform())
useEffect(() => {
if (typeof window === 'undefined') return undefined
const handleBeforeInstallPrompt = (event) => {
event.preventDefault()
setDeferredPrompt(event)
}
const handleInstalled = () => {
setDeferredPrompt(null)
setIsInstalled(true)
}
const handleModeChange = () => {
setIsInstalled(isStandaloneDisplay())
}
const mediaQuery = window.matchMedia?.('(display-mode: standalone)')
window.addEventListener('beforeinstallprompt', handleBeforeInstallPrompt)
window.addEventListener('appinstalled', handleInstalled)
mediaQuery?.addEventListener?.('change', handleModeChange)
setPlatform(detectPlatform())
setIsInstalled(isStandaloneDisplay())
return () => {
window.removeEventListener('beforeinstallprompt', handleBeforeInstallPrompt)
window.removeEventListener('appinstalled', handleInstalled)
mediaQuery?.removeEventListener?.('change', handleModeChange)
}
}, [])
const manualInstructions = useMemo(() => getManualInstallInstructions(platform), [platform])
const installState = isInstalled ? 'installed' : deferredPrompt ? 'ready' : 'manual'
const install = async () => {
if (isInstalled) {
return { status: 'installed', platform, instructions: manualInstructions }
}
if (!deferredPrompt) {
return { status: 'manual', platform, instructions: manualInstructions }
}
deferredPrompt.prompt()
const choice = await deferredPrompt.userChoice.catch(() => null)
setDeferredPrompt(null)
return {
status: choice?.outcome === 'accepted' ? 'accepted' : 'dismissed',
platform,
instructions: manualInstructions,
}
}
return {
install,
installState,
canPromptInstall: Boolean(deferredPrompt),
isInstalled,
platform,
manualInstructions,
}
}