dosemate / frontend /src /push.js
DoseMate
Deploy DoseMate to Hugging Face Spaces
a0c836f
Raw History Blame Contribute Delete
2.12 kB
// Web Push registration + subscription helpers.
import { getVapidKey, subscribePush } from "./api"
export function pushSupported() {
return "serviceWorker" in navigator && "PushManager" in window
}
export async function registerSW() {
if (!("serviceWorker" in navigator)) return null
return navigator.serviceWorker.register("/sw.js")
}
function urlBase64ToUint8Array(base64String) {
const padding = "=".repeat((4 - (base64String.length % 4)) % 4)
const base64 = (base64String + padding).replace(/-/g, "+").replace(/_/g, "/")
const raw = window.atob(base64)
const arr = new Uint8Array(raw.length)
for (let i = 0; i < raw.length; i++) arr[i] = raw.charCodeAt(i)
return arr
}
// Triggered from a user gesture (the Profile "Enable reminders" button).
export async function enableReminders() {
if (!pushSupported()) {
throw new Error("Push notifications are not supported in this browser.")
}
// If already blocked, requestPermission() returns "denied" without a prompt.
if (Notification.permission === "denied") {
throw new Error("Notifications are blocked for this site. Click the lock/info icon at the left of the address bar β†’ Site settings β†’ set Notifications to Allow β†’ reload and try again.")
}
const permission = await Notification.requestPermission()
if (permission !== "granted") {
throw new Error("Please choose 'Allow' on the notification prompt to enable reminders.")
}
const registration = await registerSW()
await navigator.serviceWorker.ready
const publicKey = await getVapidKey()
if (!publicKey) {
throw new Error("Server is missing VAPID keys. Set VAPID_PUBLIC_KEY / VAPID_PRIVATE_KEY in .env.")
}
const existing = await registration.pushManager.getSubscription()
const subscription =
existing ||
(await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(publicKey),
}))
const json = subscription.toJSON()
await subscribePush({
endpoint: json.endpoint,
keys: { p256dh: json.keys.p256dh, auth: json.keys.auth },
})
return true
}