2025-06-30 18:58:24 +02:00
|
|
|
/*
|
|
|
|
SPDX-FileCopyrightText: © 2025 Hornwitser <code@hornwitser.no>
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
*/
|
2025-03-07 16:08:45 +01:00
|
|
|
function notificationSupported() {
|
|
|
|
return (
|
|
|
|
import.meta.client
|
|
|
|
&& "serviceWorker" in navigator
|
|
|
|
&& "PushManager" in window
|
|
|
|
&& "showNotification" in ServiceWorkerRegistration.prototype
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
export const usePushNotification = () => {
|
|
|
|
const subscription = ref<PushSubscription | null>(null);
|
|
|
|
const supported = ref<boolean | undefined>(undefined);
|
|
|
|
const runtimeConfig = useRuntimeConfig();
|
|
|
|
|
|
|
|
function checkSupport() {
|
|
|
|
return supported.value = notificationSupported();
|
|
|
|
}
|
|
|
|
|
|
|
|
async function postSubscription(subscription: PushSubscriptionJSON) {
|
|
|
|
const result = await $fetch("/api/subscribe", {
|
|
|
|
method: "POST",
|
|
|
|
body: { subscription },
|
|
|
|
});
|
|
|
|
console.log("/api/subscribe returned", result);
|
|
|
|
}
|
|
|
|
|
|
|
|
async function postUnsubscription() {
|
|
|
|
const result = await $fetch("/api/unsubscribe", {
|
|
|
|
method: "POST",
|
|
|
|
});
|
|
|
|
console.log("/api/unsubscribe returned", result);
|
|
|
|
}
|
|
|
|
|
|
|
|
async function subscribe() {
|
|
|
|
if (!checkSupport())
|
|
|
|
return;
|
|
|
|
|
|
|
|
let registration;
|
|
|
|
try {
|
|
|
|
registration = await navigator.serviceWorker.register("/sw.js");
|
|
|
|
} catch (err) {
|
|
|
|
console.error("Failed to register service worker:", err);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check if we already have a subscription.
|
|
|
|
if (!subscription.value) {
|
|
|
|
subscription.value = await registration.pushManager.getSubscription();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create a new push subscription if none exists.
|
|
|
|
if (!subscription.value) {
|
|
|
|
try {
|
|
|
|
subscription.value = await registration.pushManager.subscribe({
|
|
|
|
userVisibleOnly: true,
|
|
|
|
applicationServerKey: runtimeConfig.public.vapidPublicKey,
|
|
|
|
});
|
|
|
|
} catch (err) {
|
|
|
|
console.error("Failed to subscribe:" , err);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
console.log("Subscribing with", subscription.value);
|
|
|
|
|
|
|
|
// Tell server about the new subscription.
|
|
|
|
try {
|
|
|
|
await postSubscription(subscription.value.toJSON());
|
|
|
|
} catch (err) {
|
|
|
|
console.log("Failed to post subscription to server", err)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function unsubscribe() {
|
|
|
|
if (!checkSupport())
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Fetch subscription if it hasn't already been fetched.
|
|
|
|
if (!subscription.value) {
|
|
|
|
await getSubscription();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!subscription.value) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
await subscription.value.unsubscribe();
|
|
|
|
subscription.value = null;
|
|
|
|
await postUnsubscription();
|
|
|
|
}
|
|
|
|
|
|
|
|
async function getSubscription() {
|
|
|
|
if (!checkSupport())
|
|
|
|
return;
|
|
|
|
const registration = await navigator.serviceWorker.getRegistration("./sw.js");
|
|
|
|
if (!registration)
|
|
|
|
return;
|
|
|
|
return subscription.value = await registration.pushManager.getSubscription();
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
supported,
|
|
|
|
subscription,
|
|
|
|
getSubscription,
|
|
|
|
subscribe,
|
|
|
|
unsubscribe,
|
|
|
|
}
|
|
|
|
}
|