diff --git a/web/src/components/App.js b/web/src/components/App.js index 7df7691..3e93b6a 100644 --- a/web/src/components/App.js +++ b/web/src/components/App.js @@ -1,6 +1,5 @@ import * as React from 'react'; import {useEffect, useState} from 'react'; -import Container from '@mui/material/Container'; import Typography from '@mui/material/Typography'; import Box from '@mui/material/Box'; import WsConnection from '../app/WsConnection'; @@ -13,19 +12,16 @@ 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 Badge from '@mui/material/Badge'; -import Grid from '@mui/material/Grid'; import MenuIcon from '@mui/icons-material/Menu'; import ChevronLeftIcon from '@mui/icons-material/ChevronLeft'; -import NotificationsIcon from '@mui/icons-material/Notifications'; 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 Card from "@mui/material/Card"; -import {CardContent, Stack} from "@mui/material"; import AddDialog from "./AddDialog"; +import NotificationList from "./NotificationList"; +import DetailSettingsIcon from "./DetailSettingsIcon"; import theme from "./theme"; import LocalStorage from "../app/Storage"; @@ -102,34 +98,6 @@ const SubscriptionNavItem = (props) => { ); } -const NotificationList = (props) => { - return ( - - {props.notifications.map(notification => - )} - - ); -} - -const NotificationItem = (props) => { - const notification = props.notification; - return ( - - - - {notification.time} - - {notification.title && - {notification.title} - } - - {notification.message} - - - - ); -} - const App = () => { console.log("Launching App component"); @@ -149,11 +117,11 @@ const App = () => { connection.start(); }; const handleAddCancel = () => { - console.log(`Cancel clicked`) + console.log(`Cancel clicked`); setAddDialogOpen(false); } const handleSubscriptionClick = (subscriptionId) => { - console.log(`Selected subscription ${subscriptionId}`) + console.log(`Selected subscription ${subscriptionId}`); setSelectedSubscription(subscriptions[subscriptionId]); }; const notifications = (selectedSubscription !== null) ? selectedSubscription.notifications : []; @@ -183,15 +151,10 @@ const App = () => { }, [subscriptions]); return ( + - - + { noWrap sx={{ flexGrow: 1 }} > - ntfy + {(selectedSubscription != null) ? selectedSubscription.shortUrl() : "ntfy.sh"} - - - - - + @@ -268,11 +227,7 @@ const App = () => { }} > - - - - - + { + 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); + }; + + function 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}) => ( + + + + + Send test notification + Unsubscribe + + + + + )} + + + ); +} + +export default DetailSettingsIcon; diff --git a/web/src/components/NotificationList.js b/web/src/components/NotificationList.js new file mode 100644 index 0000000..c2c02c5 --- /dev/null +++ b/web/src/components/NotificationList.js @@ -0,0 +1,36 @@ +import Container from "@mui/material/Container"; +import {CardContent, Stack} from "@mui/material"; +import Card from "@mui/material/Card"; +import Typography from "@mui/material/Typography"; +import * as React from "react"; + +const NotificationList = (props) => { + const sortedNotifications = props.notifications.sort((a, b) => a.time < b.time); + return ( + + + {sortedNotifications.map(notification => + )} + + + ); +} + +const NotificationItem = (props) => { + const notification = props.notification; + const date = new Intl.DateTimeFormat('default', {dateStyle: 'short', timeStyle: 'short'}) + .format(new Date(notification.time * 1000)); + const tags = (notification.tags && notification.tags.length > 0) ? notification.tags.join(', ') : null; + return ( + + + {date} + {notification.title && {notification.title}} + {notification.message} + {tags && Tags: {tags}} + + + ); +} + +export default NotificationList;