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
|
@ -1,14 +1,14 @@
|
|||
<template>
|
||||
<section>
|
||||
Notifications are: <b>{{ subscription ? "Enabled" : "Disabled" }}</b>
|
||||
Notifications are: <b>{{ subscribed ? "Enabled" : "Disabled" }}</b>
|
||||
<br />
|
||||
<button
|
||||
:disabled="unsupported"
|
||||
:disabled="!supported"
|
||||
@click="onClick"
|
||||
>
|
||||
{{ unsupported === undefined ? "Checking for support" : null }}
|
||||
{{ unsupported === true ? "Notifications are not supported :(." : null }}
|
||||
{{ unsupported === false ? (subscription ? "Disable notifications" : "Enable notifications") : null }}
|
||||
{{ supported === undefined ? "Checking for support" : null }}
|
||||
{{ supported === false ? "Notifications are not supported :(." : null }}
|
||||
{{ supported === true ? (subscribed ? "Disable notifications" : "Enable notifications") : null }}
|
||||
</button>
|
||||
<details>
|
||||
<summary>Debug</summary>
|
||||
|
@ -18,102 +18,18 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
function notificationUnsupported() {
|
||||
return (
|
||||
!("serviceWorker" in navigator)
|
||||
|| !("PushManager" in window)
|
||||
|| !("showNotification" in ServiceWorkerRegistration.prototype)
|
||||
)
|
||||
}
|
||||
|
||||
async function registerAndSubscribe(
|
||||
vapidPublicKey: string,
|
||||
onSubscribe: (subs: PushSubscription | null ) => void,
|
||||
) {
|
||||
try {
|
||||
await navigator.serviceWorker.register("/sw.js");
|
||||
await subscribe(vapidPublicKey, onSubscribe);
|
||||
} catch (err) {
|
||||
console.error("Failed to register service worker:", err);
|
||||
}
|
||||
}
|
||||
|
||||
async function subscribe(
|
||||
vapidPublicKey: string,
|
||||
onSubscribe: (subs: PushSubscription | null) => void
|
||||
) {
|
||||
try {
|
||||
const registration = await navigator.serviceWorker.ready;
|
||||
const subscription = await registration.pushManager.subscribe({
|
||||
userVisibleOnly: true,
|
||||
applicationServerKey: vapidPublicKey,
|
||||
});
|
||||
console.log("Got subscription object", subscription.toJSON());
|
||||
await submitSubscription(subscription);
|
||||
onSubscribe(subscription);
|
||||
} catch (err) {
|
||||
console.error("Failed to subscribe:" , err);
|
||||
}
|
||||
}
|
||||
|
||||
async function unsubscribe(
|
||||
subscription: PushSubscription,
|
||||
onUnsubscribed: () => void,
|
||||
) {
|
||||
const body = JSON.stringify({ subscription });
|
||||
await subscription.unsubscribe();
|
||||
const res = await fetch("/api/unsubscribe", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body,
|
||||
});
|
||||
const result = await res.json();
|
||||
console.log("/api/unsubscribe returned", result);
|
||||
onUnsubscribed();
|
||||
}
|
||||
|
||||
async function submitSubscription(subscription: PushSubscription) {
|
||||
const res = await fetch("/api/subscribe", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ subscription }),
|
||||
});
|
||||
const result = await res.json();
|
||||
console.log("/api/subscribe returned", result);
|
||||
}
|
||||
|
||||
async function getSubscription(
|
||||
onSubscribe: (subs: PushSubscription | null) => void,
|
||||
) {
|
||||
const registration = await navigator.serviceWorker.ready;
|
||||
const subscription = await registration.pushManager.getSubscription();
|
||||
if (subscription) {
|
||||
onSubscribe(subscription);
|
||||
}
|
||||
}
|
||||
|
||||
const unsupported = ref<boolean | undefined>(undefined);
|
||||
const subscription = ref<PushSubscription | null>(null);
|
||||
const runtimeConfig = useRuntimeConfig();
|
||||
const { refresh: refreshSession } = useAccountSession();
|
||||
|
||||
const { data: session, refresh: refreshSession } = await useAccountSession();
|
||||
const { supported, subscription, getSubscription, subscribe, unsubscribe } = usePushNotification();
|
||||
const subscribed = computed(() => Boolean(subscription.value && session.value?.push))
|
||||
async function onClick() {
|
||||
if (!subscription.value)
|
||||
await registerAndSubscribe(runtimeConfig.public.vapidPublicKey, (subs) => { subscription.value = subs })
|
||||
if (!subscribed.value)
|
||||
await subscribe();
|
||||
else
|
||||
await unsubscribe(subscription.value, () => { subscription.value = null })
|
||||
refreshSession();
|
||||
await unsubscribe();
|
||||
await refreshSession();
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
unsupported.value = notificationUnsupported()
|
||||
if (unsupported.value) {
|
||||
return;
|
||||
}
|
||||
getSubscription(subs => { subscription.value = subs });
|
||||
getSubscription();
|
||||
})
|
||||
</script>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue