64 lines
1.4 KiB
TypeScript
64 lines
1.4 KiB
TypeScript
import { usePush } from "./usePush"
|
|
|
|
type IOSInstallStep =
|
|
| "loading"
|
|
| "install"
|
|
| "open safari"
|
|
| "enable notifications"
|
|
| "unsupported"
|
|
| "permission denied"
|
|
|
|
export default function useInstallState({
|
|
isSupported,
|
|
isMobileSafari,
|
|
isIOS,
|
|
}: {
|
|
isSupported: boolean
|
|
isMobileSafari: boolean
|
|
isIOS: boolean
|
|
}) {
|
|
const isClient = typeof window !== "undefined"
|
|
|
|
if (!isClient)
|
|
return {
|
|
step: isSupported ? "loading" : ("unsupported" as IOSInstallStep),
|
|
installed: false,
|
|
}
|
|
|
|
const { canSendPush } = usePush()
|
|
|
|
const notificationsEnabled =
|
|
("Notification" in window &&
|
|
window.Notification.permission === "granted") ||
|
|
canSendPush
|
|
|
|
const permissionDenied =
|
|
"Notification" in window && window.Notification.permission === "denied"
|
|
|
|
const isRunningPWA =
|
|
("standalone" in navigator && (navigator.standalone as boolean)) ||
|
|
matchMedia("(dislay-mode: standalone)").matches
|
|
|
|
const iOSStates = [
|
|
state(!isMobileSafari, "open safari"),
|
|
state(!isRunningPWA, "install"),
|
|
]
|
|
|
|
const states = [
|
|
state(!isSupported, "unsupported"),
|
|
...(isIOS ? iOSStates : []),
|
|
state(permissionDenied, "permission denied"),
|
|
state(!notificationsEnabled, "enable notifications"),
|
|
]
|
|
|
|
return {
|
|
step: states.find(({ active }) => active)?.result ?? null,
|
|
installed: notificationsEnabled,
|
|
}
|
|
}
|
|
|
|
const state = (active: boolean, result: IOSInstallStep) => ({
|
|
active,
|
|
result,
|
|
})
|