mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-25 04:37:13 -05:00
52 lines
1.9 KiB
TypeScript
52 lines
1.9 KiB
TypeScript
import { Config } from "~/config";
|
|
import { logger } from "~/utils/logger";
|
|
import { NOTIFICATIONS_SUBSCRIBE_ROUTE } from "~/utils/urls";
|
|
|
|
/** Whether this browser supports push notifications. Only call after hydration. */
|
|
export function isPushSupported() {
|
|
return (
|
|
"serviceWorker" in navigator &&
|
|
"PushManager" in window &&
|
|
"Notification" in window
|
|
);
|
|
}
|
|
|
|
/** Subscribes this browser to push (reusing a live subscription) and syncs it to the server. Throws if either fails, meaning the server may not know where to deliver. */
|
|
export async function subscribeToPush() {
|
|
const registration = await navigator.serviceWorker.register("/sw-2.js");
|
|
const subscription =
|
|
(await registration.pushManager.getSubscription()) ??
|
|
(await registration.pushManager.subscribe({
|
|
userVisibleOnly: true,
|
|
applicationServerKey: Config.vapid.publicKey,
|
|
}));
|
|
|
|
const response = await fetch(NOTIFICATIONS_SUBSCRIBE_ROUTE, {
|
|
method: "post",
|
|
body: JSON.stringify(subscription),
|
|
headers: { "content-type": "application/json" },
|
|
});
|
|
if (!response.ok) {
|
|
throw new Error(
|
|
`Syncing push subscription to server failed: ${response.status}`,
|
|
);
|
|
}
|
|
}
|
|
|
|
/** This browser's live push subscription, or null (never subscribed, expired, revoked). Only call after hydration. */
|
|
export async function findPushSubscription() {
|
|
const registration = await navigator.serviceWorker.getRegistration();
|
|
return (await registration?.pushManager.getSubscription()) ?? null;
|
|
}
|
|
|
|
/** Self-heals push for an opted-in browser: resubscribes and re-syncs when the subscription expired, was revoked, or the server lost its copy (e.g. 410 Gone). Safe on every load; failures are swallowed. */
|
|
export async function resyncPushSubscription() {
|
|
if (!isPushSupported() || Notification.permission !== "granted") return;
|
|
|
|
try {
|
|
await subscribeToPush();
|
|
} catch (err) {
|
|
logger.error("Failed to resync push subscription", err);
|
|
}
|
|
}
|