133 lines
5.2 KiB
TypeScript
133 lines
5.2 KiB
TypeScript
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 { 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);
|
||
} 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 (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.');
|
||
}
|
||
else {
|
||
console.log('Subscription data saved on server.');
|
||
const s = await response.json();
|
||
setSubscription(sub);
|
||
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 ? 'bg-blue-400 text-white'
|
||
: 'border border-blue-300 text-blue-300 bg-transparent hover:bg-blue-100'
|
||
}`}
|
||
disabled={isPermissionGranted}
|
||
>
|
||
{!isSupported() ? "не поддъжа известия" : (isPermissionGranted ? 'Известията включени' : 'Включи известията')}
|
||
</button>
|
||
</div >
|
||
);
|
||
}
|
||
|
||
|
||
export default PwaManagerNotifications;
|