93 lines
2.7 KiB
TypeScript
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,
|
|
};
|
|
};
|