Refactor push subscription logic into a composable
This commit is contained in:
parent
52dfde95d1
commit
b2a5b67096
3 changed files with 128 additions and 97 deletions
109
composables/push-notification.ts
Normal file
109
composables/push-notification.ts
Normal file
|
@ -0,0 +1,109 @@
|
|||
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,
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue