Correctly handle standalone (PWA) mode changes
- Also handle notification permission changes - Remove web push schedule worker since this complicates things and doesn’t do _that_ much. We have the reminder notification if the user truly doesn’t reload ntfy in more than a week.
This commit is contained in:
parent
532fd3c560
commit
a8d3297c4e
6 changed files with 91 additions and 90 deletions
|
@ -15,7 +15,7 @@ import userManager from "../app/UserManager";
|
|||
import { expandUrl } from "../app/utils";
|
||||
import ErrorBoundary from "./ErrorBoundary";
|
||||
import routes from "./routes";
|
||||
import { useAccountListener, useBackgroundProcesses, useConnectionListeners } from "./hooks";
|
||||
import { useAccountListener, useBackgroundProcesses, useConnectionListeners, useWebPushTopics } from "./hooks";
|
||||
import PublishDialog from "./PublishDialog";
|
||||
import Messaging from "./Messaging";
|
||||
import Login from "./Login";
|
||||
|
@ -68,7 +68,7 @@ const Layout = () => {
|
|||
const [sendDialogOpenMode, setSendDialogOpenMode] = useState("");
|
||||
const users = useLiveQuery(() => userManager.all());
|
||||
const subscriptions = useLiveQuery(() => subscriptionManager.all());
|
||||
const webPushTopics = useLiveQuery(() => subscriptionManager.webPushTopics());
|
||||
const webPushTopics = useWebPushTopics();
|
||||
const subscriptionsWithoutInternal = subscriptions?.filter((s) => !s.internal);
|
||||
const newNotificationsCount = subscriptionsWithoutInternal?.reduce((prev, cur) => prev + cur.new, 0) || 0;
|
||||
const [selected] = (subscriptionsWithoutInternal || []).filter(
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { useParams } from "react-router-dom";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useLiveQuery } from "dexie-react-hooks";
|
||||
import subscriptionManager from "../app/SubscriptionManager";
|
||||
import { disallowedTopic, expandSecureUrl, topicUrl } from "../app/utils";
|
||||
import { disallowedTopic, expandSecureUrl, isLaunchedPWA, topicUrl } from "../app/utils";
|
||||
import routes from "./routes";
|
||||
import connectionManager from "../app/ConnectionManager";
|
||||
import poller from "../app/Poller";
|
||||
|
@ -9,7 +10,8 @@ import pruner from "../app/Pruner";
|
|||
import session from "../app/Session";
|
||||
import accountApi from "../app/AccountApi";
|
||||
import { UnauthorizedError } from "../app/errors";
|
||||
import { webPush, useWebPushTopicListener } from "../app/WebPush";
|
||||
import useWebPushListener from "../app/WebPush";
|
||||
import notifier from "../app/Notifier";
|
||||
|
||||
/**
|
||||
* Wire connectionManager and subscriptionManager so that subscriptions are updated when the connection
|
||||
|
@ -133,6 +135,54 @@ export const useAutoSubscribe = (subscriptions, selected) => {
|
|||
}, [params, subscriptions, selected, hasRun]);
|
||||
};
|
||||
|
||||
export const useWebPushTopics = () => {
|
||||
const matchMedia = window.matchMedia("(display-mode: standalone)");
|
||||
|
||||
const [isStandalone, setIsStandalone] = useState(isLaunchedPWA());
|
||||
const [pushPossible, setPushPossible] = useState(notifier.pushPossible());
|
||||
|
||||
useEffect(() => {
|
||||
const handler = (evt) => {
|
||||
console.log(`[useWebPushTopics] App is now running ${evt.matches ? "standalone" : "in the browser"}`);
|
||||
setIsStandalone(evt.matches);
|
||||
};
|
||||
|
||||
matchMedia.addEventListener("change", handler);
|
||||
|
||||
return () => {
|
||||
matchMedia.removeEventListener("change", handler);
|
||||
};
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const handler = () => {
|
||||
const newPushPossible = notifier.pushPossible();
|
||||
console.log(`[useWebPushTopics] Notification Permission changed`, { pushPossible: newPushPossible });
|
||||
setPushPossible(newPushPossible);
|
||||
};
|
||||
|
||||
if ("permissions" in navigator) {
|
||||
navigator.permissions.query({ name: "notifications" }).then((permission) => {
|
||||
permission.addEventListener("change", handler);
|
||||
|
||||
return () => {
|
||||
permission.removeEventListener("change", handler);
|
||||
};
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const topics = useLiveQuery(
|
||||
async () => subscriptionManager.webPushTopics(isStandalone, pushPossible),
|
||||
// invalidate (reload) query when these values change
|
||||
[isStandalone, pushPossible]
|
||||
);
|
||||
|
||||
useWebPushListener(topics);
|
||||
|
||||
return topics;
|
||||
};
|
||||
|
||||
/**
|
||||
* Start the poller and the pruner. This is done in a side effect as opposed to just in Pruner.js
|
||||
* and Poller.js, because side effect imports are not a thing in JS, and "Optimize imports" cleans
|
||||
|
@ -143,19 +193,15 @@ const startWorkers = () => {
|
|||
poller.startWorker();
|
||||
pruner.startWorker();
|
||||
accountApi.startWorker();
|
||||
webPush.startWorker();
|
||||
};
|
||||
|
||||
const stopWorkers = () => {
|
||||
poller.stopWorker();
|
||||
pruner.stopWorker();
|
||||
accountApi.stopWorker();
|
||||
webPush.stopWorker();
|
||||
};
|
||||
|
||||
export const useBackgroundProcesses = () => {
|
||||
useWebPushTopicListener();
|
||||
|
||||
useEffect(() => {
|
||||
console.log("[useBackgroundProcesses] mounting");
|
||||
startWorkers();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue