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