Clean up instructions
Test / test (push) Failing after 43s
Details
Test / test (push) Failing after 43s
Details
This commit is contained in:
parent
a62fd5ffdb
commit
987b419018
|
|
@ -3,6 +3,7 @@
|
||||||
"tabWidth": 2,
|
"tabWidth": 2,
|
||||||
"semi": false,
|
"semi": false,
|
||||||
"singleQuote": false,
|
"singleQuote": false,
|
||||||
|
"maxLineLength": 120,
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{
|
||||||
"files": [
|
"files": [
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
import React from "react"
|
||||||
|
import { useEffect } from "react"
|
||||||
|
import { usePush } from "remix-pwa-monorepo/packages/push/client/hook"
|
||||||
|
|
||||||
|
export default function EnableNotifications({
|
||||||
|
onSubscribe,
|
||||||
|
}: {
|
||||||
|
onSubscribe: () => void
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>Allow Notifications</h1>
|
||||||
|
<div>
|
||||||
|
Tack Up Now requires your permission to send notifications in order to
|
||||||
|
function properly
|
||||||
|
</div>
|
||||||
|
<EnableButton onSubscribe={onSubscribe} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}, [canSendPush])
|
||||||
|
|
||||||
|
return <button onClick={subscribe}>Enable Notifications</button>
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
import React from "react"
|
||||||
|
|
||||||
|
import shareIcon from "../../public/images/safari-share-icon.png"
|
||||||
|
|
||||||
|
export default function InstallPWA() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>Install Tack Up Now!</h1>
|
||||||
|
<div>
|
||||||
|
Install Tack Up Now on your device to get notified when it's time to
|
||||||
|
tack up
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<ul>
|
||||||
|
<span>Tap </span>
|
||||||
|
<img style={{ width: "2rem" }} src={shareIcon} />
|
||||||
|
<span> and choose </span>
|
||||||
|
<span className="bold">Add to Home Screen</span>
|
||||||
|
</ul>
|
||||||
|
<ul>
|
||||||
|
<span>On the next screen, tap </span>
|
||||||
|
<span className="bold">Add</span>
|
||||||
|
</ul>
|
||||||
|
<ul>
|
||||||
|
<span>Then open </span>
|
||||||
|
<span className="bold">Tack Up Now</span>
|
||||||
|
<span> from your home screen</span>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
import React from "react"
|
||||||
|
import useInstallState from "../useInstallState"
|
||||||
|
import EnableNotifications from "./EnableNotifications"
|
||||||
|
import OpenSafari from "./OpenSafari"
|
||||||
|
import InstallPWA from "./InstallPWA"
|
||||||
|
import Unsupported from "./Unsupported"
|
||||||
|
|
||||||
|
interface InstallPromptsProps {
|
||||||
|
isMobileSafari: boolean
|
||||||
|
isSupported: boolean
|
||||||
|
notificationsEnabled: boolean
|
||||||
|
onInstallComplete: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function InstallPrompts({
|
||||||
|
isSupported,
|
||||||
|
isMobileSafari,
|
||||||
|
onInstallComplete,
|
||||||
|
}: InstallPromptsProps) {
|
||||||
|
const { step } = useInstallState({ isSupported, isMobileSafari })
|
||||||
|
|
||||||
|
const steps = {
|
||||||
|
"open safari": <OpenSafari />,
|
||||||
|
install: <InstallPWA />,
|
||||||
|
"enable notifications": (
|
||||||
|
<EnableNotifications onSubscribe={onInstallComplete} />
|
||||||
|
),
|
||||||
|
unsupported: <Unsupported />,
|
||||||
|
}
|
||||||
|
|
||||||
|
return steps[step as keyof typeof steps] ?? null
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
import React from "react"
|
||||||
|
|
||||||
|
export default function OpenSafari() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div>This device requires Tack Up Now to be installed using Safari</div>
|
||||||
|
<br />
|
||||||
|
<div>Open tackupnow.com in Safari to continue!</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
import React, { useState } from "react"
|
||||||
|
|
||||||
|
export default function Unsupported() {
|
||||||
|
const [showWhy, setShowWhy] = useState(false)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>{"Sorry :("}</h1>
|
||||||
|
<br />
|
||||||
|
<div>Your device doesn't support Tack Up Now!</div>
|
||||||
|
|
||||||
|
{showWhy ? (
|
||||||
|
<div>
|
||||||
|
iOS 16.3 and under does not support notification delivery through web
|
||||||
|
apps, so Tack Up Now can't send notifications to your device.
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<button onClick={() => setShowWhy(true)}>Why not?</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -7,6 +7,10 @@ import {
|
||||||
} from "@remix-run/react"
|
} from "@remix-run/react"
|
||||||
import React from "react"
|
import React from "react"
|
||||||
import { ManifestLink } from "@remix-pwa/sw"
|
import { ManifestLink } from "@remix-pwa/sw"
|
||||||
|
import { LinksFunction } from "@remix-run/node"
|
||||||
|
import styles from "./styles/styles.css?url"
|
||||||
|
|
||||||
|
export const links: LinksFunction = () => [{ rel: "stylesheet", href: styles }]
|
||||||
|
|
||||||
export function Layout({ children }: { children: React.ReactNode }) {
|
export function Layout({ children }: { children: React.ReactNode }) {
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,8 @@ import React, { Suspense, useEffect, useState } from "react"
|
||||||
import coerceSemver from "semver/functions/coerce"
|
import coerceSemver from "semver/functions/coerce"
|
||||||
import versionAtLeast from "semver/functions/gte"
|
import versionAtLeast from "semver/functions/gte"
|
||||||
import UAParser from "ua-parser-js"
|
import UAParser from "ua-parser-js"
|
||||||
import { usePush } from "remix-pwa-monorepo/packages/push/client/hook"
|
import InstallPrompts from "../install/InstallPrompts"
|
||||||
|
import useInstallState from "../useInstallState"
|
||||||
|
|
||||||
export const meta: MetaFunction = () => {
|
export const meta: MetaFunction = () => {
|
||||||
return [
|
return [
|
||||||
|
|
@ -21,25 +22,24 @@ export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||||
const userAgent = request.headers.get("user-agent")
|
const userAgent = request.headers.get("user-agent")
|
||||||
const parsedUserAgent = new UAParser(userAgent ?? "")
|
const parsedUserAgent = new UAParser(userAgent ?? "")
|
||||||
const os = parsedUserAgent.getOS()
|
const os = parsedUserAgent.getOS()
|
||||||
const isNonSafari = parsedUserAgent.getBrowser().name !== "Mobile Safari"
|
const isMobileSafari = parsedUserAgent.getBrowser().name !== "Mobile Safari"
|
||||||
const browser = parsedUserAgent.getBrowser().name
|
|
||||||
const isSupported =
|
const isSupported =
|
||||||
os.name !== "iOS" ||
|
os.name !== "iOS" ||
|
||||||
versionAtLeast(coerceSemver(os.version) ?? "0.0.0", "16.4.0")
|
versionAtLeast(coerceSemver(os.version) ?? "0.0.0", "16.4.0")
|
||||||
|
|
||||||
console.log("Wut", isNonSafari)
|
return json({ isSupported, isMobileSafari })
|
||||||
|
|
||||||
return json({ isSupported, isNonSafari, browser })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Index() {
|
export default function Index() {
|
||||||
const { isSupported, isNonSafari, browser } = useLoaderData<typeof loader>()
|
const { isSupported, isMobileSafari } = useLoaderData<typeof loader>()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ fontFamily: "system-ui, sans-serif", lineHeight: "1.8" }}>
|
<div style={{ fontFamily: "system-ui, sans-serif", lineHeight: "1.8" }}>
|
||||||
<Suspense>
|
<Suspense>
|
||||||
<LandingMessage isSupported={isSupported} isNonSafari={isNonSafari} />
|
<LandingMessage
|
||||||
{browser}
|
isSupported={isSupported}
|
||||||
|
isMobileSafari={isMobileSafari}
|
||||||
|
/>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
@ -47,86 +47,30 @@ export default function Index() {
|
||||||
|
|
||||||
function LandingMessage({
|
function LandingMessage({
|
||||||
isSupported,
|
isSupported,
|
||||||
isNonSafari,
|
isMobileSafari,
|
||||||
}: {
|
}: {
|
||||||
isSupported: boolean
|
isSupported: boolean
|
||||||
isNonSafari: boolean
|
isMobileSafari: boolean
|
||||||
}) {
|
}) {
|
||||||
const isClient = typeof window !== "undefined"
|
const { installed } = useInstallState({ isSupported, isMobileSafari })
|
||||||
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 [rendered, setRendered] = useState(false)
|
||||||
const [isInstalled, setIsInstalled] = useState(notificationsEnabled)
|
const [isInstalled, setIsInstalled] = useState(installed)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setRendered(true)
|
setRendered(true)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return !isClient || !rendered ? (
|
return !rendered ? (
|
||||||
<div>Loading</div>
|
<div>Loading</div>
|
||||||
) : isInstalled ? (
|
) : isInstalled ? (
|
||||||
<div>Your Notifications</div>
|
<div>Your Notifications</div>
|
||||||
) : isNonSafari ? (
|
|
||||||
<div>Safari</div>
|
|
||||||
) : isRunningPWA && !notificationsEnabled ? (
|
|
||||||
<EnableButton onSubscribe={() => setIsInstalled(true)} />
|
|
||||||
) : isSupported ? (
|
|
||||||
<div>Install Tack Up Now!</div>
|
|
||||||
) : (
|
) : (
|
||||||
<div>{"Sorry, your device doesn't support Tack Up Now! :("}</div>
|
<InstallPrompts
|
||||||
|
isMobileSafari={isMobileSafari}
|
||||||
|
isSupported={isSupported}
|
||||||
|
notificationsEnabled={false}
|
||||||
|
onInstallComplete={() => setIsInstalled(true)}
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
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 <button onClick={subscribe}>Enable notifications</button>
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
.bold {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
import { usePush } from "remix-pwa-monorepo/packages/push/client/hook"
|
||||||
|
|
||||||
|
type IOSInstallStep =
|
||||||
|
| "loading"
|
||||||
|
| "install"
|
||||||
|
| "open safari"
|
||||||
|
| "enable notifications"
|
||||||
|
| "unsupported"
|
||||||
|
|
||||||
|
export default function useInstallState({
|
||||||
|
isSupported,
|
||||||
|
isMobileSafari,
|
||||||
|
}: {
|
||||||
|
isSupported: boolean
|
||||||
|
isMobileSafari: 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 isRunningPWA =
|
||||||
|
("standalone" in navigator && (navigator.standalone as boolean)) ||
|
||||||
|
matchMedia("(dislay-mode: standalone)").matches
|
||||||
|
|
||||||
|
return {
|
||||||
|
step: !isMobileSafari
|
||||||
|
? "open safari"
|
||||||
|
: !isRunningPWA && isMobileSafari
|
||||||
|
? "install"
|
||||||
|
: !notificationsEnabled
|
||||||
|
? "enable notifications"
|
||||||
|
: (null as IOSInstallStep | null),
|
||||||
|
installed: notificationsEnabled,
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 2.6 KiB |
Loading…
Reference in New Issue