114 lines
2.9 KiB
TypeScript
114 lines
2.9 KiB
TypeScript
import {
|
|
json,
|
|
type LoaderFunctionArgs,
|
|
type MetaFunction,
|
|
} from "@remix-run/node"
|
|
import { useLoaderData } from "@remix-run/react"
|
|
import React, { useEffect, useRef, useState } from "react"
|
|
import coerceSemver from "semver/functions/coerce"
|
|
import versionAtLeast from "semver/functions/gte"
|
|
import UAParser from "ua-parser-js"
|
|
import ClientOnly from "../ClientOnly"
|
|
import InstallPrompts from "../install/InstallPrompts"
|
|
import useInstallState from "../useInstallState"
|
|
|
|
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 isMobileSafari = parsedUserAgent.getBrowser().name === "Mobile Safari"
|
|
const isSupported =
|
|
os.name !== "iOS" ||
|
|
versionAtLeast(coerceSemver(os.version) ?? "0.0.0", "16.4.0")
|
|
|
|
const isIOS = os.name === "iOS"
|
|
|
|
const cookies = parseCookies(request.headers.get("Cookie"))
|
|
const userIdCookie = cookies?.find(({ key }) => key === "userId")
|
|
|
|
const newUserId =
|
|
userIdCookie === undefined ? Math.floor(Math.random()) * 5 : null
|
|
|
|
return json(
|
|
{
|
|
isSupported,
|
|
isMobileSafari,
|
|
isIOS,
|
|
},
|
|
{
|
|
headers:
|
|
newUserId !== null && isSupported && isIOS && isMobileSafari
|
|
? {
|
|
"Set-Cookie": `userId=${newUserId}`,
|
|
}
|
|
: {},
|
|
}
|
|
)
|
|
}
|
|
|
|
export default function Index() {
|
|
const { isSupported, isMobileSafari, isIOS } = useLoaderData<typeof loader>()
|
|
|
|
return (
|
|
<div style={{ fontFamily: "system-ui, sans-serif", lineHeight: "1.8" }}>
|
|
<TackUpNow
|
|
isSupported={isSupported}
|
|
isMobileSafari={isMobileSafari}
|
|
isIOS={isIOS}
|
|
/>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
function parseCookies(cookieString: string | null | undefined) {
|
|
if (cookieString === null || cookieString === undefined) return
|
|
|
|
const allCookieStrings = cookieString.split(";")
|
|
const cookies = allCookieStrings.map((string) => {
|
|
const [key, value] = string.trim().split("=")
|
|
|
|
return { key, value }
|
|
})
|
|
|
|
return cookies
|
|
}
|
|
|
|
function TackUpNow({
|
|
isSupported,
|
|
isMobileSafari,
|
|
isIOS,
|
|
}: {
|
|
isSupported: boolean
|
|
isMobileSafari: boolean
|
|
isIOS: boolean
|
|
}) {
|
|
const { installed } = useInstallState({ isSupported, isMobileSafari, isIOS })
|
|
|
|
const [isInstalled, setIsInstalled] = useState(installed)
|
|
|
|
return (
|
|
<ClientOnly fallback={<div>Loading</div>}>
|
|
{() =>
|
|
isInstalled ? (
|
|
<div>Your Notifications</div>
|
|
) : (
|
|
<InstallPrompts
|
|
isMobileSafari={isMobileSafari}
|
|
isSupported={isSupported}
|
|
isIOS={isIOS}
|
|
notificationsEnabled={false}
|
|
onInstallComplete={() => setIsInstalled(true)}
|
|
/>
|
|
)
|
|
}
|
|
</ClientOnly>
|
|
)
|
|
}
|