tack-up-now/app/routes/_index.tsx

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