pwa manager in settings
This commit is contained in:
227
components/PwaManager.tsx
Normal file
227
components/PwaManager.tsx
Normal file
@ -0,0 +1,227 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import common from '../src/helpers/common'; // Ensure this path is correct
|
||||
|
||||
function PwaManager() {
|
||||
const [deferredPrompt, setDeferredPrompt] = useState(null);
|
||||
const [isPWAInstalled, setIsPWAInstalled] = useState(false);
|
||||
const [isStandAlone, setIsStandAlone] = useState(false);
|
||||
const [isSubscribed, setIsSubscribed] = useState(false);
|
||||
const [subscription, setSubscription] = useState(null);
|
||||
const [registration, setRegistration] = useState(null);
|
||||
const [notificationPermission, setNotificationPermission] = useState(Notification.permission);
|
||||
|
||||
// Handle PWA installation
|
||||
useEffect(() => {
|
||||
|
||||
setNotificationPermission(Notification.permission);
|
||||
|
||||
// Handle Push Notification Subscription
|
||||
if ('serviceWorker' in navigator && 'PushManager' in window) {
|
||||
navigator.serviceWorker.ready.then(reg => {
|
||||
reg.pushManager.getSubscription().then(sub => {
|
||||
if (sub) {
|
||||
setSubscription(sub);
|
||||
setIsSubscribed(true);
|
||||
}
|
||||
});
|
||||
setRegistration(reg);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Check if the app is running in standalone mode
|
||||
if (window.matchMedia('(display-mode: standalone)').matches) {
|
||||
setIsStandAlone(true);
|
||||
}
|
||||
|
||||
const handleBeforeInstallPrompt = (e) => {
|
||||
e.preventDefault();
|
||||
setDeferredPrompt(e);
|
||||
};
|
||||
|
||||
const handleAppInstalled = () => {
|
||||
setIsPWAInstalled(true);
|
||||
};
|
||||
|
||||
window.addEventListener('beforeinstallprompt', handleBeforeInstallPrompt);
|
||||
window.addEventListener('appinstalled', handleAppInstalled);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('beforeinstallprompt', handleBeforeInstallPrompt);
|
||||
window.removeEventListener('appinstalled', handleAppInstalled);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const installPWA = async (e) => {
|
||||
|
||||
e.preventDefault();
|
||||
if (deferredPrompt) {
|
||||
deferredPrompt.prompt();
|
||||
const { outcome } = await deferredPrompt.userChoice;
|
||||
if (outcome === 'accepted') {
|
||||
setIsPWAInstalled(true);
|
||||
}
|
||||
setDeferredPrompt(null);
|
||||
}
|
||||
};
|
||||
|
||||
// Utility function for converting base64 string to Uint8Array
|
||||
const base64ToUint8Array = base64 => {
|
||||
const padding = '='.repeat((4 - (base64.length % 4)) % 4);
|
||||
const b64 = (base64 + padding).replace(/-/g, '+').replace(/_/g, '/');
|
||||
const rawData = window.atob(b64);
|
||||
const outputArray = new Uint8Array(rawData.length);
|
||||
for (let i = 0; i < rawData.length; ++i) {
|
||||
outputArray[i] = rawData.charCodeAt(i);
|
||||
}
|
||||
return outputArray;
|
||||
};
|
||||
|
||||
const subscribeToNotifications = async (e) => {
|
||||
|
||||
try {
|
||||
e.preventDefault();
|
||||
if (!registration) {
|
||||
console.error('Service worker registration not found.');
|
||||
registration
|
||||
return;
|
||||
}
|
||||
const sub = await registration.pushManager.subscribe({
|
||||
userVisibleOnly: true,
|
||||
applicationServerKey: base64ToUint8Array(process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY)
|
||||
});
|
||||
// Call your API to save subscription data on server
|
||||
setSubscription(sub);
|
||||
setIsSubscribed(true);
|
||||
console.log('Web push subscribed!');
|
||||
console.log(sub);
|
||||
} catch (error) {
|
||||
console.error('Error subscribing to notifications:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const unsubscribeFromNotifications = async (e) => {
|
||||
|
||||
try {
|
||||
e.preventDefault();
|
||||
await subscription.unsubscribe();
|
||||
// Call your API to delete or invalidate subscription data on server
|
||||
setSubscription(null);
|
||||
setIsSubscribed(false);
|
||||
console.log('Web push unsubscribed!');
|
||||
} catch (error) {
|
||||
console.error('Error unsubscribing from notifications:', error);
|
||||
}
|
||||
};
|
||||
|
||||
// Function to request push notification permission
|
||||
const requestNotificationPermission = async (e) => {
|
||||
e.preventDefault();
|
||||
const permission = await Notification.requestPermission();
|
||||
setNotificationPermission(permission);
|
||||
if (permission === "granted") {
|
||||
// User granted permission
|
||||
subscribeToNotifications(null); // Pass the required argument here
|
||||
} else {
|
||||
// User denied or dismissed permission
|
||||
console.log("Push notifications permission denied.");
|
||||
}
|
||||
};
|
||||
|
||||
// Function to toggle push notifications
|
||||
const togglePushNotifications = async (e) => {
|
||||
|
||||
e.preventDefault();
|
||||
if (notificationPermission === "granted") {
|
||||
// If already subscribed, unsubscribe
|
||||
unsubscribeFromNotifications(null); // Pass null as the argument
|
||||
} else if (notificationPermission === "default" || notificationPermission === "denied") {
|
||||
// Request permission if not already granted
|
||||
await requestNotificationPermission(e);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const sendTestNotification = async (e) => {
|
||||
|
||||
e.preventDefault();
|
||||
if (!subscription) {
|
||||
console.error('Web push not subscribed');
|
||||
return;
|
||||
}
|
||||
|
||||
await fetch('/api/notification', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ subscription })
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<h1>PWA Manager</h1>
|
||||
{!isPWAInstalled && (
|
||||
<button
|
||||
onClick={installPWA}
|
||||
className="bg-blue-500 hover:bg-blue-700 text-white text-xs py-1 px-2 rounded-full focus:outline-none focus:shadow-outline transition duration-150 ease-in-out"
|
||||
>
|
||||
Install PWA
|
||||
</button>
|
||||
)}
|
||||
{isPWAInstalled && <p>App is installed!</p>}
|
||||
{isStandAlone && <p>App is running in standalone mode!</p>}
|
||||
<button
|
||||
onClick={subscribeToNotifications}
|
||||
disabled={isSubscribed}
|
||||
className={`text-xs py-1 px-2 rounded-full focus:outline-none transition duration-150 ease-in-out ${isSubscribed ? 'cursor-not-allowed bg-gray-300 text-gray-500' : 'bg-green-500 hover:bg-green-700 text-white'
|
||||
}`}
|
||||
>
|
||||
Subscribe to Notifications
|
||||
</button>
|
||||
<button
|
||||
onClick={unsubscribeFromNotifications}
|
||||
disabled={!isSubscribed}
|
||||
className={`text-xs py-1 px-2 rounded-full focus:outline-none transition duration-150 ease-in-out ${!isSubscribed ? 'cursor-not-allowed bg-gray-300 text-gray-500' : 'bg-red-500 hover:bg-red-700 text-white'
|
||||
}`}
|
||||
>
|
||||
Unsubscribe from Notifications
|
||||
</button>
|
||||
|
||||
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
onClick={sendTestNotification}
|
||||
disabled={!isSubscribed}
|
||||
className={`text-xs py-1 px-2 rounded-full focus:outline-none transition duration-150 ease-in-out ${!isSubscribed ? 'cursor-not-allowed bg-gray-300 text-gray-500' : 'bg-yellow-500 hover:bg-yellow-600 text-white'
|
||||
}`}
|
||||
>
|
||||
Send Test Notification
|
||||
</button>
|
||||
|
||||
{notificationPermission !== "granted" && (
|
||||
<button
|
||||
onClick={togglePushNotifications}
|
||||
className={`text-xs py-1 px-2 rounded-full focus:outline-none transition duration-150 ease-in-out ${notificationPermission === "denied" ? 'bg-red-500 hover:bg-red-700 text-white' : 'bg-green-500 hover:bg-green-700 text-white'
|
||||
}`}
|
||||
>
|
||||
{notificationPermission === "denied" ? 'Notifications Denied!' : 'Enable Notifications'}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<a href="https://t.me/mwhitnessing_bot" className="inline-flex items-center ml-4" target="_blank">
|
||||
<img src="/content/icons/telegram-svgrepo-com.svg" alt="Телеграм" width="32" height="32" className="align-middle" />
|
||||
<span className="align-middle">Телеграм</span>
|
||||
</a>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
export default PwaManager;
|
Reference in New Issue
Block a user