Files
mwitnessing/components/PwaManagerNotifications.tsx
2024-06-03 18:44:13 +03:00

139 lines
5.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useEffect, useState } from 'react';
import { useSession } from "next-auth/react";
import common from '../src/helpers/common'; // Ensure this path is correct
import { set } from 'date-fns';
function PwaManagerNotifications() {
const [isPermissionGranted, setIsPermissionGranted] = useState(false);
const [subscription, setSubscription] = useState(null);
const [registration, setRegistration] = useState(null);
const [isSubSaved, setIsSubSaved] = useState(false);
const { data: session } = useSession();
// Check if all required APIs are supported
const isSupported = () =>
'Notification' in window &&
'serviceWorker' in navigator &&
'PushManager' in window;
useEffect(() => {
if (isSupported()) {
requestNotificationPermission(null);
}
}, []);
const requestNotificationPermission = async (e) => {
if (e) {
e.preventDefault();
if (Notification.permission === 'denied') {
console.log('Notification permission denied.');
alert('Известията са забранени. Моля, разрешете известията от браузъра.');
}
}
setIsPermissionGranted(Notification.permission === 'granted');
if (Notification.permission === 'default') {
const permission = await Notification.requestPermission();
if (permission === 'granted') {
console.log('Notification permission granted.');
getSubscription();
} else {
console.log('Notification permission denied.');
}
}
if (Notification.permission === 'granted') {
getSubscription();
}
};
const getSubscription = async () => {
// Handle Push Notification Subscription
if ('serviceWorker' in navigator && 'PushManager' in window) {
navigator.serviceWorker.ready.then(registration => {
registration.pushManager.getSubscription().then(existingSubscription => {
if (existingSubscription) {
console.log('Already subscribed.');
setSubscription(existingSubscription);
sendSubscriptionToServer(existingSubscription);
} else if (Notification.permission === "granted") {
// Permission was already granted but no subscription exists, so subscribe now
subscribeToNotifications(registration);
}
});
});
}
}
const subscribeToNotifications = async () => {
const registration = await navigator.serviceWorker.ready;
let vapidPublicKey = process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY; // Ensure this is configured
if (!vapidPublicKey) {
// Fetch the public key from the server if not present in env variables
const response = await fetch('/api/notify', { method: 'GET' });
const responseData = await response.json();
vapidPublicKey = responseData.pk;
if (!vapidPublicKey) {
throw new Error("Failed to fetch VAPID public key from server.");
}
}
const convertedVapidKey = common.base64ToUint8Array(vapidPublicKey);
try {
const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: convertedVapidKey
});
console.log('Subscribed to push notifications:', subscription);
setSubscription(subscription);
sendSubscriptionToServer(subscription);
} catch (error) {
console.error('Failed to subscribe to push notifications:', error);
}
};
const sendSubscriptionToServer = async (sub) => {
if (isSubSaved) { return; }
if (session.user?.id != null) {
await fetch(`/api/notify`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ subscription: sub, id: session.user.id })
}).then(async response => {
if (!response.ok) {
// throw new Error('Failed to save subscription data on server.');
console.log('Failed to save subscription data on server.');
}
else {
console.log('Subscription data saved on server.');
const s = await response.json();
setSubscription(sub);
setIsSubSaved(true);
console.log('Web push subscribed!');
}
});
}
};
return (
<div>
<button
onClick={isPermissionGranted ? undefined : requestNotificationPermission}
className={`text-xs py-1 px-2 rounded-full focus:outline-none transition duration-150 ease-in-out
${isPermissionGranted ?
'border border-blue-300 text-blue-300 bg-transparent hover:bg-blue-100'
: 'bg-blue-400 text-white'
}`}
disabled={isPermissionGranted}
>
{!isSupported() ? "не поддъжа известия" : (isPermissionGranted && subscription ? 'Известията включени' : 'Включи известията')}
</button>
</div >
);
}
export default PwaManagerNotifications;