Files
2025-03-27 14:15:14 +03:30

93 lines
2.7 KiB
TypeScript

import { API_ENDPOINTS } from "~/constants";
import useSubscribeNotification from "~/composables/api/notifications/useSubscribeNotification";
import { useToast } from "~/composables/global/useToast";
interface VapidKeys {
publicKey: string;
}
export const usePushNotifications = () => {
const isSupported = ref(false);
const permission = usePermission("notifications");
const subscription = useLocalStorage<PushSubscriptionJSON | null>(
"push-subscription",
null
);
const vapid = ref<VapidKeys | null>(null);
const { mutateAsync: subscribeNotification } = useSubscribeNotification();
const { addToast } = useToast();
const unsubscribe = async () => {
const swRegistration = await navigator.serviceWorker.ready;
const existingSubscription =
await swRegistration.pushManager.getSubscription();
if (existingSubscription) {
await existingSubscription.unsubscribe();
}
};
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;
await unsubscribe();
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,
},
{
onSuccess: () => {
addToast({
message: "اعلانات برای دستگاه شما فعال شد",
});
},
onError: () => {
addToast({
message: "خطایی در فعال شدن اعلانات رخ داد",
options: {
status: "error",
},
});
},
}
);
subscription.value = subscriptionJson;
};
return {
isSupported,
permission,
subscribe,
unsubscribe,
subscription,
};
};