diff --git a/web/src/components/ActionBar.js b/web/src/components/ActionBar.js
index 73cf5db..994cd4e 100644
--- a/web/src/components/ActionBar.js
+++ b/web/src/components/ActionBar.js
@@ -4,11 +4,20 @@ import Toolbar from "@mui/material/Toolbar";
import IconButton from "@mui/material/IconButton";
import MenuIcon from "@mui/icons-material/Menu";
import Typography from "@mui/material/Typography";
-import SubscribeSettings from "./SubscribeSettings";
import * as React from "react";
+import {useEffect, useRef, useState} from "react";
import Box from "@mui/material/Box";
-import {topicShortUrl} from "../app/utils";
-import {useLocation} from "react-router-dom";
+import {subscriptionRoute, topicShortUrl} from "../app/utils";
+import {useLocation, useNavigate} from "react-router-dom";
+import ClickAwayListener from '@mui/material/ClickAwayListener';
+import Grow from '@mui/material/Grow';
+import Paper from '@mui/material/Paper';
+import Popper from '@mui/material/Popper';
+import MenuItem from '@mui/material/MenuItem';
+import MenuList from '@mui/material/MenuList';
+import MoreVertIcon from "@mui/icons-material/MoreVert";
+import api from "../app/Api";
+import subscriptionManager from "../app/SubscriptionManager";
const ActionBar = (props) => {
const location = useLocation();
@@ -41,7 +50,7 @@ const ActionBar = (props) => {
{title}
- {props.selectedSubscription && }
@@ -50,4 +59,111 @@ const ActionBar = (props) => {
);
};
+// Originally from https://mui.com/components/menus/#MenuListComposition.js
+const SettingsIcon = (props) => {
+ const navigate = useNavigate();
+ const [open, setOpen] = useState(false);
+ const anchorRef = useRef(null);
+
+ const handleToggle = () => {
+ setOpen((prevOpen) => !prevOpen);
+ };
+
+ const handleClose = (event) => {
+ if (anchorRef.current && anchorRef.current.contains(event.target)) {
+ return;
+ }
+ setOpen(false);
+ };
+
+ const handleClearAll = async (event) => {
+ handleClose(event);
+ console.log(`[ActionBar] Deleting all notifications from ${props.subscription.id}`);
+ await subscriptionManager.deleteNotifications(props.subscription.id);
+ };
+
+ const handleUnsubscribe = async (event) => {
+ console.log(`[ActionBar] Unsubscribing from ${props.subscription.id}`);
+ handleClose(event);
+ await subscriptionManager.remove(props.subscription.id);
+ const newSelected = await subscriptionManager.first(); // May be undefined
+ if (newSelected) {
+ navigate(subscriptionRoute(newSelected));
+ }
+ };
+
+ const handleSendTestMessage = () => {
+ const baseUrl = props.subscription.baseUrl;
+ const topic = props.subscription.topic;
+ api.publish(baseUrl, topic,
+ `This is a test notification sent by the ntfy Web UI at ${new Date().toString()}.`); // FIXME result ignored
+ setOpen(false);
+ }
+
+ const handleListKeyDown = (event) => {
+ if (event.key === 'Tab') {
+ event.preventDefault();
+ setOpen(false);
+ } else if (event.key === 'Escape') {
+ setOpen(false);
+ }
+ }
+
+ // return focus to the button when we transitioned from !open -> open
+ const prevOpen = useRef(open);
+ useEffect(() => {
+ if (prevOpen.current === true && open === false) {
+ anchorRef.current.focus();
+ }
+ prevOpen.current = open;
+ }, [open]);
+
+ return (
+ <>
+
+
+
+
+ {({TransitionProps, placement}) => (
+
+
+
+
+
+
+
+ )}
+
+ >
+ );
+};
+
export default ActionBar;
diff --git a/web/src/components/App.js b/web/src/components/App.js
index 119deca..182df34 100644
--- a/web/src/components/App.js
+++ b/web/src/components/App.js
@@ -47,31 +47,21 @@ const Root = () => {
const subscriptions = useLiveQuery(() => subscriptionManager.all());
const selectedSubscription = findSelected(location, subscriptions);
- const handleSubscriptionClick = async (subscriptionId) => {
- const subscription = await subscriptionManager.get(subscriptionId);
- navigate(subscriptionRoute(subscription));
- }
const handleSubscribeSubmit = async (subscription) => {
console.log(`[App] New subscription: ${subscription.id}`, subscription);
navigate(subscriptionRoute(subscription));
handleRequestPermission();
};
- const handleUnsubscribe = async (subscriptionId) => {
- console.log(`[App] Unsubscribing from ${subscriptionId}`);
- const newSelected = await subscriptionManager.first(); // May be undefined
- if (newSelected) {
- navigate(subscriptionRoute(newSelected));
- }
- };
+
const handleRequestPermission = () => {
notificationManager.maybeRequestPermission(granted => setNotificationsGranted(granted));
};
- // Define hooks: Note that the order of the hooks is important. The "loading" hooks
- // must be before the "saving" hooks.
+
useEffect(() => {
poller.startWorker();
pruner.startWorker();
}, [/* initial render */]);
+
useEffect(() => {
const handleNotification = async (subscriptionId, notification) => {
try {
@@ -93,14 +83,17 @@ const Root = () => {
// This is for the use of 'navigate' // FIXME
//eslint-disable-next-line
}, [/* initial render */]);
- useEffect(() => { connectionManager.refresh(subscriptions, users) }, [subscriptions, users]); // Dangle!
+
+ useEffect(() => {
+ connectionManager.refresh(subscriptions, users);
+ }, [subscriptions, users]); // Dangle!
+
return (
setMobileDrawerOpen(!mobileDrawerOpen)}
/>
@@ -110,7 +103,6 @@ const Root = () => {
mobileDrawerOpen={mobileDrawerOpen}
notificationsGranted={notificationsGranted}
onMobileDrawerToggle={() => setMobileDrawerOpen(!mobileDrawerOpen)}
- onSubscriptionClick={handleSubscriptionClick}
onSubscribeSubmit={handleSubscribeSubmit}
onRequestPermissionClick={handleRequestPermission}
/>
diff --git a/web/src/components/Navigation.js b/web/src/components/Navigation.js
index eb98914..c8f9fd5 100644
--- a/web/src/components/Navigation.js
+++ b/web/src/components/Navigation.js
@@ -58,16 +58,20 @@ const NavList = (props) => {
const location = useLocation();
const [subscribeDialogKey, setSubscribeDialogKey] = useState(0);
const [subscribeDialogOpen, setSubscribeDialogOpen] = useState(false);
+
const handleSubscribeReset = () => {
setSubscribeDialogOpen(false);
setSubscribeDialogKey(prev => prev+1);
}
+
const handleSubscribeSubmit = (subscription) => {
handleSubscribeReset();
props.onSubscribeSubmit(subscription);
}
+
const showSubscriptionsList = props.subscriptions?.length > 0;
const showGrantPermissionsBox = props.subscriptions?.length > 0 && !props.notificationsGranted;
+
return (
<>
diff --git a/web/src/components/SubscribeSettings.js b/web/src/components/SubscribeSettings.js
deleted file mode 100644
index 1c1a4e3..0000000
--- a/web/src/components/SubscribeSettings.js
+++ /dev/null
@@ -1,116 +0,0 @@
-import * as React from 'react';
-import {useEffect, useRef, useState} from 'react';
-import ClickAwayListener from '@mui/material/ClickAwayListener';
-import Grow from '@mui/material/Grow';
-import Paper from '@mui/material/Paper';
-import Popper from '@mui/material/Popper';
-import MenuItem from '@mui/material/MenuItem';
-import MenuList from '@mui/material/MenuList';
-import IconButton from "@mui/material/IconButton";
-import MoreVertIcon from "@mui/icons-material/MoreVert";
-import api from "../app/Api";
-import subscriptionManager from "../app/SubscriptionManager";
-
-// Originally from https://mui.com/components/menus/#MenuListComposition.js
-const SubscribeSettings = (props) => {
- const [open, setOpen] = useState(false);
- const anchorRef = useRef(null);
-
- const handleToggle = () => {
- setOpen((prevOpen) => !prevOpen);
- };
-
- const handleClose = (event) => {
- if (anchorRef.current && anchorRef.current.contains(event.target)) {
- return;
- }
- setOpen(false);
- };
-
- const handleClearAll = async (event) => {
- handleClose(event);
- console.log(`[IconSubscribeSettings] Deleting all notifications from ${props.subscription.id}`);
- await subscriptionManager.deleteNotifications(props.subscription.id);
- };
-
- const handleUnsubscribe = async (event) => {
- handleClose(event);
- await subscriptionManager.remove(props.subscription.id);
- props.onUnsubscribe(props.subscription.id);
- };
-
- const handleSendTestMessage = () => {
- const baseUrl = props.subscription.baseUrl;
- const topic = props.subscription.topic;
- api.publish(baseUrl, topic,
- `This is a test notification sent by the ntfy Web UI at ${new Date().toString()}.`); // FIXME result ignored
- setOpen(false);
- }
-
- const handleListKeyDown = (event) => {
- if (event.key === 'Tab') {
- event.preventDefault();
- setOpen(false);
- } else if (event.key === 'Escape') {
- setOpen(false);
- }
- }
-
- // return focus to the button when we transitioned from !open -> open
- const prevOpen = useRef(open);
- useEffect(() => {
- if (prevOpen.current === true && open === false) {
- anchorRef.current.focus();
- }
- prevOpen.current = open;
- }, [open]);
-
- return (
- <>
-
-
-
-
- {({TransitionProps, placement}) => (
-
-
-
-
-
-
-
- )}
-
- >
- );
-}
-
-export default SubscribeSettings;