| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- import {useNavigate, useParams} from "react-router-dom";
- import {useEffect, useState} from "react";
- import subscriptionManager from "../app/SubscriptionManager";
- import {disallowedTopic, expandSecureUrl, topicUrl} from "../app/utils";
- import notifier from "../app/Notifier";
- import routes from "./routes";
- import connectionManager from "../app/ConnectionManager";
- import poller from "../app/Poller";
- import pruner from "../app/Pruner";
- /**
- * Wire connectionManager and subscriptionManager so that subscriptions are updated when the connection
- * state changes. Conversely, when the subscription changes, the connection is refreshed (which may lead
- * to the connection being re-established).
- */
- export const useConnectionListeners = (subscriptions, users) => {
- const navigate = useNavigate();
- useEffect(() => {
- const handleNotification = async (subscriptionId, notification) => {
- const added = await subscriptionManager.addNotification(subscriptionId, notification);
- if (added) {
- const defaultClickAction = (subscription) => navigate(routes.forSubscription(subscription));
- await notifier.notify(subscriptionId, notification, defaultClickAction)
- }
- };
- connectionManager.registerStateListener(subscriptionManager.updateState);
- connectionManager.registerNotificationListener(handleNotification);
- return () => {
- connectionManager.resetStateListener();
- connectionManager.resetNotificationListener();
- }
- },
- // We have to disable dep checking for "navigate". This is fine, it never changes.
- // eslint-disable-next-line
- []
- );
- useEffect(() => {
- connectionManager.refresh(subscriptions, users); // Dangle
- }, [subscriptions, users]);
- };
- /**
- * Automatically adds a subscription if we navigate to a page that has not been subscribed to.
- * This will only be run once after the initial page load.
- */
- export const useAutoSubscribe = (subscriptions, selected) => {
- const [hasRun, setHasRun] = useState(false);
- const params = useParams();
- useEffect(() => {
- const loaded = subscriptions !== null && subscriptions !== undefined;
- if (!loaded || hasRun) {
- return;
- }
- setHasRun(true);
- const eligible = params.topic && !selected && !disallowedTopic(params.topic);
- if (eligible) {
- const baseUrl = (params.baseUrl) ? expandSecureUrl(params.baseUrl) : window.location.origin;
- console.log(`[App] Auto-subscribing to ${topicUrl(baseUrl, params.topic)}`);
- (async () => {
- const subscription = await subscriptionManager.add(baseUrl, params.topic);
- poller.pollInBackground(subscription); // Dangle!
- })();
- }
- }, [params, subscriptions, selected, hasRun]);
- };
- /**
- * 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
- * up "unused" imports. See https://github.com/binwiederhier/ntfy/issues/186.
- */
- export const useBackgroundProcesses = () => {
- useEffect(() => {
- poller.startWorker();
- pruner.startWorker();
- }, []);
- }
|