diff --git a/web/src/app/Connection.js b/web/src/app/Connection.js
index 9e479f94..914fcf45 100644
--- a/web/src/app/Connection.js
+++ b/web/src/app/Connection.js
@@ -1,6 +1,6 @@
import {shortTopicUrl, topicUrlWs, topicUrlWsWithSince} from "./utils";
-const retryBackoffSeconds = [5, 10, 15, 20, 30, 45, 60, 120];
+const retryBackoffSeconds = [5, 10, 15, 20, 30, 45];
class Connection {
constructor(subscriptionId, baseUrl, topic, since, onNotification) {
diff --git a/web/src/components/ActionBar.js b/web/src/components/ActionBar.js
new file mode 100644
index 00000000..7ecce8e4
--- /dev/null
+++ b/web/src/components/ActionBar.js
@@ -0,0 +1,36 @@
+import AppBar from "@mui/material/AppBar";
+import Navigation from "./Navigation";
+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 IconSubscribeSettings from "./IconSubscribeSettings";
+import * as React from "react";
+
+const ActionBar = (props) => {
+ const title = (props.selectedSubscription !== null)
+ ? props.selectedSubscription.shortUrl()
+ : "ntfy";
+ return (
+
+
+
+
+
+ {title}
+ {props.selectedSubscription !== null && }
+
+
+ );
+};
+
+export default ActionBar;
diff --git a/web/src/components/App.js b/web/src/components/App.js
index 63055aa3..51097833 100644
--- a/web/src/components/App.js
+++ b/web/src/components/App.js
@@ -1,161 +1,17 @@
import * as React from 'react';
import {useEffect, useState} from 'react';
-import Typography from '@mui/material/Typography';
import Box from '@mui/material/Box';
import {ThemeProvider} from '@mui/material/styles';
import CssBaseline from '@mui/material/CssBaseline';
-import Drawer from '@mui/material/Drawer';
-import AppBar from '@mui/material/AppBar';
import Toolbar from '@mui/material/Toolbar';
-import ChatBubbleOutlineIcon from '@mui/icons-material/ChatBubbleOutline';
-import List from '@mui/material/List';
-import Divider from '@mui/material/Divider';
-import IconButton from '@mui/material/IconButton';
-import MenuIcon from '@mui/icons-material/Menu';
-import ListItemIcon from "@mui/material/ListItemIcon";
-import ListItemText from "@mui/material/ListItemText";
-import ListItemButton from "@mui/material/ListItemButton";
-import SettingsIcon from "@mui/icons-material/Settings";
-import AddIcon from "@mui/icons-material/Add";
-import SubscribeDialog from "./SubscribeDialog";
import NotificationList from "./NotificationList";
-import IconSubscribeSettings from "./IconSubscribeSettings";
import theme from "./theme";
import api from "../app/Api";
import repository from "../app/Repository";
import connectionManager from "../app/ConnectionManager";
import Subscriptions from "../app/Subscriptions";
-
-const drawerWidth = 240;
-
-const NavSubscriptionList = (props) => {
- const subscriptions = props.subscriptions;
- return (
- <>
- {subscriptions.map((id, subscription) =>
- props.onSubscriptionClick(id)}
- />)
- }
- >
- );
-}
-
-const NavSubscriptionItem = (props) => {
- const subscription = props.subscription;
- return (
-
-
-
-
- );
-}
-
-const NavList = (props) => {
- const [subscribeDialogOpen, setSubscribeDialogOpen] = useState(false);
- const handleSubscribeSubmit = (subscription) => {
- setSubscribeDialogOpen(false);
- props.onSubscribeSubmit(subscription);
- }
- return (
- <>
-
-
-
-
-
-
-
-
-
-
-
- setSubscribeDialogOpen(true)}>
-
-
-
-
-
-
- setSubscribeDialogOpen(false)}
- onSubmit={handleSubscribeSubmit}
- />
- >
- );
-};
-
-const ActionBar = (props) => {
- const title = (props.selectedSubscription !== null)
- ? props.selectedSubscription.shortUrl()
- : "ntfy";
- return (
-
-
-
-
-
- {title}
- {props.selectedSubscription !== null && }
-
-
- );
-};
-
-const Sidebar = (props) => {
- const navigationList =
- ;
- return (
- <>
- {/* Mobile drawer; only shown if menu icon clicked (mobile open) and display is small */}
-
- {navigationList}
-
- {/* Big screen drawer; persistent, shown if screen is big */}
-
- {navigationList}
-
- >
- );
-};
+import Navigation from "./Navigation";
+import ActionBar from "./ActionBar";
const App = () => {
console.log(`[App] Rendering main view`);
@@ -222,8 +78,8 @@ const App = () => {
onUnsubscribe={handleUnsubscribe}
onMobileDrawerToggle={() => setMobileDrawerOpen(!mobileDrawerOpen)}
/>
-
-
+ {
sx={{
flexGrow: 1,
p: 3,
- width: {sm: `calc(100% - ${drawerWidth}px)`},
+ width: {sm: `calc(100% - ${Navigation.width}px)`},
height: '100vh',
overflow: 'auto',
backgroundColor: (theme) => theme.palette.mode === 'light' ? theme.palette.grey[100] : theme.palette.grey[900]
diff --git a/web/src/components/Navigation.js b/web/src/components/Navigation.js
new file mode 100644
index 00000000..5d8b6e7e
--- /dev/null
+++ b/web/src/components/Navigation.js
@@ -0,0 +1,121 @@
+import Drawer from "@mui/material/Drawer";
+import * as React from "react";
+import ListItemButton from "@mui/material/ListItemButton";
+import ListItemIcon from "@mui/material/ListItemIcon";
+import ChatBubbleOutlineIcon from "@mui/icons-material/ChatBubbleOutline";
+import ListItemText from "@mui/material/ListItemText";
+import {useState} from "react";
+import Toolbar from "@mui/material/Toolbar";
+import Divider from "@mui/material/Divider";
+import List from "@mui/material/List";
+import SettingsIcon from "@mui/icons-material/Settings";
+import AddIcon from "@mui/icons-material/Add";
+import SubscribeDialog from "./SubscribeDialog";
+
+const navWidth = 240;
+
+const Navigation = (props) => {
+ const navigationList =
+ ;
+ return (
+ <>
+ {/* Mobile drawer; only shown if menu icon clicked (mobile open) and display is small */}
+
+ {navigationList}
+
+ {/* Big screen drawer; persistent, shown if screen is big */}
+
+ {navigationList}
+
+ >
+ );
+};
+Navigation.width = navWidth;
+
+const NavList = (props) => {
+ const [subscribeDialogOpen, setSubscribeDialogOpen] = useState(false);
+ const handleSubscribeSubmit = (subscription) => {
+ setSubscribeDialogOpen(false);
+ props.onSubscribeSubmit(subscription);
+ }
+ return (
+ <>
+
+ {props.subscriptions.size() > 0 &&
+ }
+
+
+
+
+
+
+
+
+
+ setSubscribeDialogOpen(true)}>
+
+
+
+
+
+
+ setSubscribeDialogOpen(false)}
+ onSubmit={handleSubscribeSubmit}
+ />
+ >
+ );
+};
+const NavSubscriptionList = (props) => {
+ const subscriptions = props.subscriptions;
+ return (
+ <>
+ {subscriptions.map((id, subscription) =>
+ props.onSubscriptionClick(id)}
+ />)
+ }
+ >
+ );
+}
+
+const NavSubscriptionItem = (props) => {
+ const subscription = props.subscription;
+ return (
+
+
+
+
+ );
+}
+
+export default Navigation;