From b61ad3758eb3d31094c8ef457b5751cd7dcf22b7 Mon Sep 17 00:00:00 2001 From: Yann Bizeul Date: Wed, 9 Oct 2024 09:57:09 +0200 Subject: [PATCH] Start separate notification code --- .../YBNotificationToggleComponent.tsx | 18 ++++---- web/ui/src/notifications.ts | 41 +++++++++++++++++++ 2 files changed, 52 insertions(+), 7 deletions(-) create mode 100644 web/ui/src/notifications.ts diff --git a/web/ui/src/YBFeed/Components/YBNotificationToggleComponent.tsx b/web/ui/src/YBFeed/Components/YBNotificationToggleComponent.tsx index 1dbfd53..7555fa5 100644 --- a/web/ui/src/YBFeed/Components/YBNotificationToggleComponent.tsx +++ b/web/ui/src/YBFeed/Components/YBNotificationToggleComponent.tsx @@ -8,6 +8,8 @@ import { YBFeedConnector } from '../' import { defaultNotificationProps } from '../config'; +import { Subscribe } from '../../notifications'; + interface NotificationToggleProps { vapid: string feedName: string @@ -112,19 +114,21 @@ export function YBNotificationToggleComponent(props:NotificationToggleProps) { if (subscription === null) { setLoading(true) console.log("subscribing") - subscribe() - .then((b) => { - console.log("done",b) - + Subscribe(vapid) + .then((subscription) => { setLoading(false) - if (b) { + const s = subscription as PushSubscription + console.log("got subscription", subscription) + if (s.endpoint) { setNotificationsOn(true) + return } + throw new Error("Unable to subscribe") }) .catch(e => { setLoading(false) console.log(e) - notifications.show({message:"Error", color:"red", ...defaultNotificationProps}) + notifications.show({message:"Unable to subscribe", color:"red", ...defaultNotificationProps}) }) return } @@ -159,7 +163,7 @@ export function YBNotificationToggleComponent(props:NotificationToggleProps) { } useEffect(() => { - if ('serviceWorker' in navigator) { + if ('serviceWorker' in navigator && feedName) { console.log("registering service worker") navigator.serviceWorker.register('/service-worker.js',{scope: "/" + feedName}) .then((registration) => { diff --git a/web/ui/src/notifications.ts b/web/ui/src/notifications.ts new file mode 100644 index 0000000..a1274e3 --- /dev/null +++ b/web/ui/src/notifications.ts @@ -0,0 +1,41 @@ +export function Subscribe(vapid: string) { + return new Promise((resolve, reject) => { + if (!vapid) { + reject("VAPID not declared") + } + + console.log("getting registration for", window.location.href) + navigator.serviceWorker.getRegistration(window.location.href) + .then((registration) => { + if (!registration) { + console.log("no registration") + return + } + console.log("subscribing",vapid) + return registration.pushManager.subscribe({ + userVisibleOnly: true, + applicationServerKey: urlBase64ToUint8Array(vapid), + }); + }) + .then((subscription) => { + console.log("got subscription", subscription) + if (!subscription) { + reject("Unable to subscribe (empty subscription)") + } + resolve(subscription) + console.log("adding subscription to backend", subscription) + }) + .catch((err) => { + reject(err) + }); + }) +} + +function urlBase64ToUint8Array(base64String: string) { + const padding = '='.repeat((4 - (base64String.length % 4)) % 4); + const base64 = (base64String + padding) + .replace(/-/g, '+') + .replace(/_/g, '/'); + const rawData = window.atob(base64); + return Uint8Array.from([...rawData].map(char => char.charCodeAt(0))); +} \ No newline at end of file