From 6733b77ec1930942679f5c476462726cbed4e7da Mon Sep 17 00:00:00 2001 From: Parsa Nazer Date: Wed, 26 Mar 2025 11:03:44 +0330 Subject: [PATCH] add use push notif ts form p project --- .../global/usePushNotifications.ts | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 frontend/composables/global/usePushNotifications.ts diff --git a/frontend/composables/global/usePushNotifications.ts b/frontend/composables/global/usePushNotifications.ts new file mode 100644 index 0000000..11cdf50 --- /dev/null +++ b/frontend/composables/global/usePushNotifications.ts @@ -0,0 +1,65 @@ +// composables/usePushNotifications.ts +import { useLocalStorage, usePermission } from "@vueuse/core"; +import { onMounted, ref } from "vue"; +import useSubscribeNotification from "../api/useSubscribeNotification"; + +interface VapidKeys { + publicKey: string; +} + +export const usePushNotifications = () => { + const isSupported = ref(false); + const permission = usePermission("notifications"); + const subscription = useLocalStorage( + "push-subscription", + null + ); + const vapid = ref(null); + + const { mutateAsync: subscribeNotification } = useSubscribeNotification(); + const toast = useToast(); + + // Only run in client-side + onMounted(async () => { + if (typeof window !== "undefined" && "serviceWorker" in navigator) { + isSupported.value = true; + vapid.value = await $fetch("/api/vapid"); + } + }); + + const subscribe = async () => { + if (!isSupported.value || !vapid.value?.publicKey) { + throw new Error("Push notifications not supported"); + } + + const swRegistration = await navigator.serviceWorker.ready; + + const applicationServerKey = vapid.value.publicKey + .replace(/-/g, "+") + .replace(/_/g, "/"); + + const convertedKey = Uint8Array.from(atob(applicationServerKey), (c) => + c.charCodeAt(0) + ); + + const pushSubscription = await swRegistration.pushManager.subscribe({ + userVisibleOnly: true, + applicationServerKey: convertedKey, + }); + + const subscriptionJson = pushSubscription.toJSON(); + + subscribeNotification({ + body: subscriptionJson, + }); + + subscription.value = subscriptionJson; + }; + + return { + isSupported, + permission, + subscribe, + subscription, + }; +};