Rename things, add comments
parent
1abcc88fce
commit
9d5556c7f5
|
@ -33,8 +33,8 @@ class Prefs {
|
||||||
}
|
}
|
||||||
|
|
||||||
async webPushEnabled() {
|
async webPushEnabled() {
|
||||||
const obj = await this.db.prefs.get("webPushEnabled");
|
const webPushEnabled = await this.db.prefs.get("webPushEnabled");
|
||||||
return obj?.value ?? false;
|
return webPushEnabled?.value ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async setWebPushEnabled(enabled) {
|
async setWebPushEnabled(enabled) {
|
||||||
|
|
|
@ -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() {
|
async webPushTopics() {
|
||||||
// the Promise.resolve wrapper is not superfluous, without it the live query breaks:
|
// 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
|
// 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 [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const subscriptions = await this.db.subscriptions.where({ mutedUntil: 0, baseUrl: config.base_url }).toArray();
|
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);
|
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 topics = presetTopics ?? (await this.webPushTopics());
|
||||||
const browserSubscription = await notifier.getBrowserSubscription();
|
const browserSubscription = await notifier.getBrowserSubscription();
|
||||||
|
|
||||||
|
|
|
@ -3,21 +3,26 @@ import { useLiveQuery } from "dexie-react-hooks";
|
||||||
import notifier from "./Notifier";
|
import notifier from "./Notifier";
|
||||||
import subscriptionManager from "./SubscriptionManager";
|
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 topics = useLiveQuery(() => subscriptionManager.webPushTopics());
|
||||||
const [lastTopics, setLastTopics] = useState();
|
const [lastTopics, setLastTopics] = useState();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!notifier.pushPossible() || JSON.stringify(topics) === JSON.stringify(lastTopics)) {
|
const topicsChanged = JSON.stringify(topics) !== JSON.stringify(lastTopics);
|
||||||
|
if (!notifier.pushPossible() || !topicsChanged) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
console.log("[useWebPushUpdateWorker] Refreshing web push subscriptions");
|
console.log("[useWebPushUpdateWorker] Refreshing web push subscriptions");
|
||||||
|
await subscriptionManager.updateWebPushSubscriptions(topics);
|
||||||
await subscriptionManager.refreshWebPushSubscriptions(topics);
|
|
||||||
|
|
||||||
setLastTopics(topics);
|
setLastTopics(topics);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("[useWebPushUpdateWorker] Error refreshing web push subscriptions", e);
|
console.error("[useWebPushUpdateWorker] Error refreshing web push subscriptions", e);
|
||||||
|
@ -26,10 +31,13 @@ export const useWebPushUpdateWorker = () => {
|
||||||
}, [topics, lastTopics]);
|
}, [topics, lastTopics]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const intervalMillis = 13 * 60 * 1_000; // 13 minutes
|
/**
|
||||||
const updateIntervalMillis = 60 * 60 * 1_000; // 1 hour
|
* Helper class for Web Push that does three things:
|
||||||
|
* 1. Updates the Web Push subscriptions on a schedule
|
||||||
class WebPushRefreshWorker {
|
* 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() {
|
constructor() {
|
||||||
this.timer = null;
|
this.timer = null;
|
||||||
this.lastUpdate = null;
|
this.lastUpdate = null;
|
||||||
|
@ -43,7 +51,6 @@ class WebPushRefreshWorker {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.timer = setInterval(() => this.updateSubscriptions(), intervalMillis);
|
this.timer = setInterval(() => this.updateSubscriptions(), intervalMillis);
|
||||||
|
|
||||||
this.broadcastChannel = new BroadcastChannel("web-push-broadcast");
|
this.broadcastChannel = new BroadcastChannel("web-push-broadcast");
|
||||||
this.broadcastChannel.addEventListener("message", this.messageHandler);
|
this.broadcastChannel.addEventListener("message", this.messageHandler);
|
||||||
|
|
||||||
|
@ -60,7 +67,7 @@ class WebPushRefreshWorker {
|
||||||
}
|
}
|
||||||
|
|
||||||
onMessage() {
|
onMessage() {
|
||||||
notifier.playSound();
|
notifier.playSound(); // Service Worker cannot play sound, so we do it here!
|
||||||
}
|
}
|
||||||
|
|
||||||
onVisibilityChange() {
|
onVisibilityChange() {
|
||||||
|
@ -75,10 +82,10 @@ class WebPushRefreshWorker {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.lastUpdate || Date.now() - this.lastUpdate > updateIntervalMillis) {
|
if (!this.lastUpdate || Date.now() - this.lastUpdate > updateIntervalMillis) {
|
||||||
await subscriptionManager.refreshWebPushSubscriptions();
|
await subscriptionManager.updateWebPushSubscriptions();
|
||||||
this.lastUpdate = Date.now();
|
this.lastUpdate = Date.now();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const webPushRefreshWorker = new WebPushRefreshWorker();
|
export const webPush = new WebPushWorker();
|
|
@ -9,7 +9,7 @@ import pruner from "../app/Pruner";
|
||||||
import session from "../app/Session";
|
import session from "../app/Session";
|
||||||
import accountApi from "../app/AccountApi";
|
import accountApi from "../app/AccountApi";
|
||||||
import { UnauthorizedError } from "../app/errors";
|
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
|
* Wire connectionManager and subscriptionManager so that subscriptions are updated when the connection
|
||||||
|
@ -134,18 +134,18 @@ const stopWorkers = () => {
|
||||||
poller.stopWorker();
|
poller.stopWorker();
|
||||||
pruner.stopWorker();
|
pruner.stopWorker();
|
||||||
accountApi.stopWorker();
|
accountApi.stopWorker();
|
||||||
webPushRefreshWorker.stopWorker();
|
webPush.stopWorker();
|
||||||
};
|
};
|
||||||
|
|
||||||
const startWorkers = () => {
|
const startWorkers = () => {
|
||||||
poller.startWorker();
|
poller.startWorker();
|
||||||
pruner.startWorker();
|
pruner.startWorker();
|
||||||
accountApi.startWorker();
|
accountApi.startWorker();
|
||||||
webPushRefreshWorker.startWorker();
|
webPush.startWorker();
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useBackgroundProcesses = () => {
|
export const useBackgroundProcesses = () => {
|
||||||
useWebPushUpdateWorker();
|
useWebPushTopicListener();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log("[useBackgroundProcesses] mounting");
|
console.log("[useBackgroundProcesses] mounting");
|
||||||
|
|
Loading…
Reference in New Issue