From ff97d441b16b146fc59042c19f604b1d7fc6c399 Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Mon, 8 Apr 2024 12:47:29 +0300 Subject: [PATCH] pwa manager in settings --- components/PwaManager.tsx | 227 ++++++++++++++++++++++++++ components/publisher/PublisherForm.js | 18 +- 2 files changed, 241 insertions(+), 4 deletions(-) create mode 100644 components/PwaManager.tsx diff --git a/components/PwaManager.tsx b/components/PwaManager.tsx new file mode 100644 index 0000000..f4bdb1b --- /dev/null +++ b/components/PwaManager.tsx @@ -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 ( + <> +
+

PWA Manager

+ {!isPWAInstalled && ( + + )} + {isPWAInstalled &&

App is installed!

} + {isStandAlone &&

App is running in standalone mode!

} + + + + +
+
+ + + {notificationPermission !== "granted" && ( + + )} +
+
+ + Телеграм + Телеграм + +
+ + ); + +} + +export default PwaManager; diff --git a/components/publisher/PublisherForm.js b/components/publisher/PublisherForm.js index 93c8f9c..f7c1f39 100644 --- a/components/publisher/PublisherForm.js +++ b/components/publisher/PublisherForm.js @@ -6,6 +6,7 @@ import Link from "next/link"; import axiosInstance from '../../src/axiosSecure'; //import { getDate } from "date-fns"; +import PwaManager from "../PwaManager"; import { monthNamesBG, GetTimeFormat, GetDateFormat } from "../../src/helpers/const" import PublisherSearchBox from './PublisherSearchBox'; import AvailabilityList from "../availability/AvailabilityList"; @@ -241,16 +242,28 @@ export default function PublisherForm({ item, me }) {
+ {/* notifications */}
+ {/* prompt to install PWA */}
+ {/* button to install PWA */} + {/*
+
*/} + + {/* ADMINISTRATORS ONLY */} + + +
@@ -292,10 +305,7 @@ export default function PublisherForm({ item, me }) { {/* Add other roles as needed */}
- - Телеграм - Телеграм - +
{/* ---------------------------- Actions --------------------------------- */}