From 9d5556c7f554877d38f1ac5f85f4ec51490bd1b0 Mon Sep 17 00:00:00 2001
From: binwiederhier <philipp.heckel@gmail.com>
Date: Sat, 10 Jun 2023 20:42:02 -0400
Subject: [PATCH] Rename things, add comments

---
 web/src/app/Prefs.js                         |  4 +--
 web/src/app/SubscriptionManager.js           |  9 +++---
 web/src/app/{WebPushWorker.js => WebPush.js} | 33 ++++++++++++--------
 web/src/components/hooks.js                  |  8 ++---
 4 files changed, 30 insertions(+), 24 deletions(-)
 rename web/src/app/{WebPushWorker.js => WebPush.js} (69%)

diff --git a/web/src/app/Prefs.js b/web/src/app/Prefs.js
index ac1d82db..b4cef0ac 100644
--- a/web/src/app/Prefs.js
+++ b/web/src/app/Prefs.js
@@ -33,8 +33,8 @@ class Prefs {
   }
 
   async webPushEnabled() {
-    const obj = await this.db.prefs.get("webPushEnabled");
-    return obj?.value ?? false;
+    const webPushEnabled = await this.db.prefs.get("webPushEnabled");
+    return webPushEnabled?.value ?? false;
   }
 
   async setWebPushEnabled(enabled) {
diff --git a/web/src/app/SubscriptionManager.js b/web/src/app/SubscriptionManager.js
index 88b95e7b..67b9faa3 100644
--- a/web/src/app/SubscriptionManager.js
+++ b/web/src/app/SubscriptionManager.js
@@ -20,16 +20,15 @@ class SubscriptionManager {
     );
   }
 
+  /** List of topics for which Web Push is enabled, excludes internal topics; returns empty list if Web Push is disabled */
   async webPushTopics() {
     // the Promise.resolve wrapper is not superfluous, without it the live query breaks:
     // https://dexie.org/docs/dexie-react-hooks/useLiveQuery()#calling-non-dexie-apis-from-querier
-    if (!(await Promise.resolve(notifier.pushEnabled()))) {
+    const pushEnabled = await Promise.resolve(notifier.pushEnabled());
+    if (!pushEnabled) {
       return [];
     }
-
     const subscriptions = await this.db.subscriptions.where({ mutedUntil: 0, baseUrl: config.base_url }).toArray();
-
-    // internal is currently a bool, it could be a 0/1 to be indexable, but for now just filter them out here
     return subscriptions.filter(({ internal }) => !internal).map(({ topic }) => topic);
   }
 
@@ -111,7 +110,7 @@ class SubscriptionManager {
     );
   }
 
-  async refreshWebPushSubscriptions(presetTopics) {
+  async updateWebPushSubscriptions(presetTopics) {
     const topics = presetTopics ?? (await this.webPushTopics());
     const browserSubscription = await notifier.getBrowserSubscription();
 
diff --git a/web/src/app/WebPushWorker.js b/web/src/app/WebPush.js
similarity index 69%
rename from web/src/app/WebPushWorker.js
rename to web/src/app/WebPush.js
index b0d319c7..1a9b59eb 100644
--- a/web/src/app/WebPushWorker.js
+++ b/web/src/app/WebPush.js
@@ -3,21 +3,26 @@ import { useLiveQuery } from "dexie-react-hooks";
 import notifier from "./Notifier";
 import subscriptionManager from "./SubscriptionManager";
 
-export const useWebPushUpdateWorker = () => {
+const intervalMillis = 13 * 60 * 1_000; // 13 minutes
+const updateIntervalMillis = 60 * 60 * 1_000; // 1 hour
+
+/**
+ * Updates the Web Push subscriptions when the list of topics changes.
+ */
+export const useWebPushTopicListener = () => {
   const topics = useLiveQuery(() => subscriptionManager.webPushTopics());
   const [lastTopics, setLastTopics] = useState();
 
   useEffect(() => {
-    if (!notifier.pushPossible() || JSON.stringify(topics) === JSON.stringify(lastTopics)) {
+    const topicsChanged = JSON.stringify(topics) !== JSON.stringify(lastTopics);
+    if (!notifier.pushPossible() || !topicsChanged) {
       return;
     }
 
     (async () => {
       try {
         console.log("[useWebPushUpdateWorker] Refreshing web push subscriptions");
-
-        await subscriptionManager.refreshWebPushSubscriptions(topics);
-
+        await subscriptionManager.updateWebPushSubscriptions(topics);
         setLastTopics(topics);
       } catch (e) {
         console.error("[useWebPushUpdateWorker] Error refreshing web push subscriptions", e);
@@ -26,10 +31,13 @@ export const useWebPushUpdateWorker = () => {
   }, [topics, lastTopics]);
 };
 
-const intervalMillis = 13 * 60 * 1_000; // 13 minutes
-const updateIntervalMillis = 60 * 60 * 1_000; // 1 hour
-
-class WebPushRefreshWorker {
+/**
+ * Helper class for Web Push that does three things:
+ * 1. Updates the Web Push subscriptions on a schedule
+ * 2. Updates the Web Push subscriptions when the window is minimised / app switched
+ * 3. Listens to the broadcast channel from the service worker to play a sound when a message comes in
+ */
+class WebPushWorker {
   constructor() {
     this.timer = null;
     this.lastUpdate = null;
@@ -43,7 +51,6 @@ class WebPushRefreshWorker {
     }
 
     this.timer = setInterval(() => this.updateSubscriptions(), intervalMillis);
-
     this.broadcastChannel = new BroadcastChannel("web-push-broadcast");
     this.broadcastChannel.addEventListener("message", this.messageHandler);
 
@@ -60,7 +67,7 @@ class WebPushRefreshWorker {
   }
 
   onMessage() {
-    notifier.playSound();
+    notifier.playSound(); // Service Worker cannot play sound, so we do it here!
   }
 
   onVisibilityChange() {
@@ -75,10 +82,10 @@ class WebPushRefreshWorker {
     }
 
     if (!this.lastUpdate || Date.now() - this.lastUpdate > updateIntervalMillis) {
-      await subscriptionManager.refreshWebPushSubscriptions();
+      await subscriptionManager.updateWebPushSubscriptions();
       this.lastUpdate = Date.now();
     }
   }
 }
 
-export const webPushRefreshWorker = new WebPushRefreshWorker();
+export const webPush = new WebPushWorker();
diff --git a/web/src/components/hooks.js b/web/src/components/hooks.js
index 815f0596..8da8fdf0 100644
--- a/web/src/components/hooks.js
+++ b/web/src/components/hooks.js
@@ -9,7 +9,7 @@ import pruner from "../app/Pruner";
 import session from "../app/Session";
 import accountApi from "../app/AccountApi";
 import { UnauthorizedError } from "../app/errors";
-import { webPushRefreshWorker, useWebPushUpdateWorker } from "../app/WebPushWorker";
+import { webPush, useWebPushTopicListener } from "../app/WebPush";
 
 /**
  * Wire connectionManager and subscriptionManager so that subscriptions are updated when the connection
@@ -134,18 +134,18 @@ const stopWorkers = () => {
   poller.stopWorker();
   pruner.stopWorker();
   accountApi.stopWorker();
-  webPushRefreshWorker.stopWorker();
+  webPush.stopWorker();
 };
 
 const startWorkers = () => {
   poller.startWorker();
   pruner.startWorker();
   accountApi.startWorker();
-  webPushRefreshWorker.startWorker();
+  webPush.startWorker();
 };
 
 export const useBackgroundProcesses = () => {
-  useWebPushUpdateWorker();
+  useWebPushTopicListener();
 
   useEffect(() => {
     console.log("[useBackgroundProcesses] mounting");