import { json, type LoaderFunctionArgs, type MetaFunction, } from "@remix-run/node" import { useLoaderData } from "@remix-run/react" import React, { Suspense, useEffect, useState } from "react" import coerceSemver from "semver/functions/coerce" import versionAtLeast from "semver/functions/gte" import UAParser from "ua-parser-js" import { usePush } from "remix-pwa-monorepo/packages/push/client/hook" export const meta: MetaFunction = () => { return [ { title: "Tack Up Now!" }, { name: "description", content: "Get equinelive notifications" }, ] } export const loader = async ({ request }: LoaderFunctionArgs) => { const userAgent = request.headers.get("user-agent") const parsedUserAgent = new UAParser(userAgent ?? "") const os = parsedUserAgent.getOS() const isNonSafari = parsedUserAgent.getBrowser().name !== "Mobile Safari" const browser = parsedUserAgent.getBrowser().name const isSupported = os.name !== "iOS" || versionAtLeast(coerceSemver(os.version) ?? "0.0.0", "16.4.0") console.log("Wut", isNonSafari) return json({ isSupported, isNonSafari, browser }) } export default function Index() { const { isSupported, isNonSafari, browser } = useLoaderData() return (
{browser}
) } function LandingMessage({ isSupported, isNonSafari, }: { isSupported: boolean isNonSafari: boolean }) { const isClient = typeof window !== "undefined" const notificationsEnabled = isClient && "Notification" in window && window.Notification.permission === "granted" const isRunningPWA = isClient && (("standalone" in navigator && (navigator.standalone as boolean)) || matchMedia("(dislay-mode: standalone)").matches) const [rendered, setRendered] = useState(false) const [isInstalled, setIsInstalled] = useState(notificationsEnabled) useEffect(() => { setRendered(true) }, []) return !isClient || !rendered ? (
Loading
) : isInstalled ? (
Your Notifications
) : isNonSafari ? (
Safari
) : isRunningPWA && !notificationsEnabled ? ( setIsInstalled(true)} /> ) : isSupported ? (
Install Tack Up Now!
) : (
{"Sorry, your device doesn't support Tack Up Now! :("}
) } function EnableButton({ onSubscribe }: { onSubscribe: () => void }) { const { subscribeToPush, requestPermission, canSendPush } = usePush() function subscribe() { requestPermission() } useEffect(() => { if (!canSendPush) return subscribeToPush( urlB64ToUint8Array(applicationServerPublicKey) as any, (subscription) => { fetch("/api/subscribe", { method: "POST", body: JSON.stringify(subscription), }) onSubscribe() }, (error) => { const errorDiv = document.createElement("div") errorDiv.innerText = "Error thingy" + JSON.stringify(error) document.appendChild(errorDiv) } ) }, [canSendPush]) return } const applicationServerPublicKey = "BDTbzdtzJxwV0sscdsXla-GKvlcxqQr7edEfkX8-papwvvV1UVc3IMyRacl1BbgTi31nWPji2wKCZkjf1l5iX7Y" function urlB64ToUint8Array(base64String: string) { const padding = "=".repeat((4 - (base64String.length % 4)) % 4) const base64 = (base64String + padding).replace(/\-/g, "+").replace(/_/g, "/") const rawData = window.atob(base64) const outputArray = new Uint8Array(rawData.length) for (let i = 0; i < rawData.length; ++i) { outputArray[i] = rawData.charCodeAt(i) } return outputArray }