From d1c31a5080d24a8ab8e8224233249dc9ddd60ddd Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Thu, 17 Jun 2021 16:00:20 +0200 Subject: [PATCH] Handle going to notification URL on click Signed-off-by: Thomas Citharel --- js/src/service-worker.ts | 42 +++++++++++++++++++++++++------ js/src/types/push-notification.ts | 7 ------ 2 files changed, 34 insertions(+), 15 deletions(-) delete mode 100644 js/src/types/push-notification.ts diff --git a/js/src/service-worker.ts b/js/src/service-worker.ts index 826bc56a8..7ff855658 100644 --- a/js/src/service-worker.ts +++ b/js/src/service-worker.ts @@ -11,7 +11,12 @@ import { CacheableResponsePlugin } from "workbox-cacheable-response"; import { ExpirationPlugin } from "workbox-expiration"; import { precacheAndRoute } from "workbox-precaching"; -import { IPushNotification } from "./types/push-notification"; + +/// + +// export empty type because of tsc --isolatedModules flag +export type {}; +declare const self: ServiceWorkerGlobalScope; // Use with precache injection // eslint-disable-next-line @typescript-eslint/ban-ts-comment @@ -77,24 +82,45 @@ registerRoute( }) ); -self.addEventListener("push", async (event: any) => { - const payload = event.data.json() as IPushNotification; +self.addEventListener("push", async (event: PushEvent) => { + if (!event.data) return; + const payload = event.data.json(); console.log("received push", payload); const options = { - title: payload.title, body: payload.body, icon: "/img/icons/android-chrome-512x512.png", badge: "/img/icons/badge-128x128.png", - timestamp: new Date(payload.timestamp), + timestamp: new Date(payload.timestamp).getTime(), lang: payload.locale, data: { dateOfArrival: Date.now(), + url: payload.url, }, }; + event.waitUntil(self.registration.showNotification(payload.title, options)); +}); + +self.addEventListener("notificationclick", function (event: NotificationEvent) { + const url = event.notification.data.url; + event.notification.close(); + + // This looks to see if the current is already open and + // focuses if it is event.waitUntil( - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - self.registration.showNotification(payload.title, options) + (async () => { + const clientList = await self.clients.matchAll({ + type: "window", + }); + for (let i = 0; i < clientList.length; i++) { + const client = clientList[i] as WindowClient; + if (client.url == url && "focus" in client) { + return client.focus(); + } + } + if (self.clients.openWindow) { + return self.clients.openWindow(url); + } + })() ); }); diff --git a/js/src/types/push-notification.ts b/js/src/types/push-notification.ts deleted file mode 100644 index bfcaf652d..000000000 --- a/js/src/types/push-notification.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface IPushNotification { - title: string; - body: string; - url: string; - timestamp: string; - locale: string; -}