tack-up-now/app/useInstallState.ts

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,
})