ntfy/web/src/components/ActionBar.js

184 lines
6.7 KiB
JavaScript
Raw Normal View History

2022-02-25 17:46:22 +00:00
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 * as React from "react";
2023-01-05 03:47:12 +00:00
import {useState} from "react";
2022-02-28 21:56:38 +00:00
import Box from "@mui/material/Box";
2023-02-01 02:39:30 +00:00
import {topicDisplayName} from "../app/utils";
2022-12-28 20:51:09 +00:00
import db from "../app/db";
2022-03-06 03:33:34 +00:00
import {useLocation, useNavigate} from "react-router-dom";
import MenuItem from '@mui/material/MenuItem';
import MoreVertIcon from "@mui/icons-material/MoreVert";
2022-03-08 21:56:41 +00:00
import NotificationsIcon from '@mui/icons-material/Notifications';
import NotificationsOffIcon from '@mui/icons-material/NotificationsOff';
import routes from "./routes";
2022-03-06 03:33:34 +00:00
import subscriptionManager from "../app/SubscriptionManager";
2022-03-10 20:37:50 +00:00
import logo from "../img/ntfy.svg";
2022-04-08 14:44:35 +00:00
import {useTranslation} from "react-i18next";
2022-12-02 20:37:48 +00:00
import session from "../app/Session";
import AccountCircleIcon from '@mui/icons-material/AccountCircle';
import Button from "@mui/material/Button";
2022-12-15 04:43:43 +00:00
import Divider from "@mui/material/Divider";
import {Logout, Person, Settings} from "@mui/icons-material";
import ListItemIcon from "@mui/material/ListItemIcon";
2023-02-01 02:39:30 +00:00
import accountApi from "../app/AccountApi";
import PopupMenu from "./PopupMenu";
2023-02-01 02:39:30 +00:00
import SubscriptionPopup from "./SubscriptionPopup";
2022-02-25 17:46:22 +00:00
const ActionBar = (props) => {
2022-04-08 14:44:35 +00:00
const { t } = useTranslation();
2022-03-04 21:10:04 +00:00
const location = useLocation();
let title = "ntfy";
if (props.selected) {
2022-06-29 19:57:56 +00:00
title = topicDisplayName(props.selected);
2023-01-05 03:47:12 +00:00
} else if (location.pathname === routes.settings) {
2022-04-08 14:44:35 +00:00
title = t("action_bar_settings");
2023-01-05 03:47:12 +00:00
} else if (location.pathname === routes.account) {
title = t("action_bar_account");
2022-03-04 21:10:04 +00:00
}
2022-02-25 17:46:22 +00:00
return (
2022-02-26 19:22:21 +00:00
<AppBar position="fixed" sx={{
width: '100%',
2022-02-26 19:36:23 +00:00
zIndex: { sm: 1250 }, // > Navigation (1200), but < Dialog (1300)
2022-02-26 19:22:21 +00:00
ml: { sm: `${Navigation.width}px` }
}}>
2022-12-30 15:31:52 +00:00
<Toolbar sx={{
pr: '24px',
background: "linear-gradient(150deg, rgba(51,133,116,1) 0%, rgba(86,189,168,1) 100%)"
}}>
2022-02-25 17:46:22 +00:00
<IconButton
color="inherit"
edge="start"
2022-05-02 23:30:29 +00:00
aria-label={t("action_bar_show_menu")}
2022-02-25 17:46:22 +00:00
onClick={props.onMobileDrawerToggle}
sx={{ mr: 2, display: { sm: 'none' } }}
>
<MenuIcon />
</IconButton>
2022-05-02 23:30:29 +00:00
<Box
component="img"
src={logo}
alt={t("action_bar_logo_alt")}
sx={{
display: { xs: 'none', sm: 'block' },
marginRight: '10px',
height: '28px'
}}
/>
2022-02-26 19:22:21 +00:00
<Typography variant="h6" noWrap component="div" sx={{ flexGrow: 1 }}>
{title}
</Typography>
2022-03-08 21:56:41 +00:00
{props.selected &&
<SettingsIcons
subscription={props.selected}
onUnsubscribe={props.onUnsubscribe}
/>}
2022-12-02 20:37:48 +00:00
<ProfileIcon/>
2022-02-25 17:46:22 +00:00
</Toolbar>
</AppBar>
);
};
2022-03-08 21:56:41 +00:00
const SettingsIcons = (props) => {
2022-04-08 14:44:35 +00:00
const { t } = useTranslation();
2022-12-29 07:32:05 +00:00
const [anchorEl, setAnchorEl] = useState(null);
2022-03-08 21:56:41 +00:00
const subscription = props.subscription;
2022-03-06 03:33:34 +00:00
2022-03-08 21:56:41 +00:00
const handleToggleMute = async () => {
const mutedUntil = (subscription.mutedUntil) ? 0 : 1; // Make this a timestamp in the future
await subscriptionManager.setMutedUntil(subscription.id, mutedUntil);
}
2022-03-06 03:33:34 +00:00
return (
<>
2022-12-26 03:29:55 +00:00
<IconButton color="inherit" size="large" edge="end" onClick={handleToggleMute} aria-label={t("action_bar_toggle_mute")}>
2022-03-08 21:56:41 +00:00
{subscription.mutedUntil ? <NotificationsOffIcon/> : <NotificationsIcon/>}
</IconButton>
2023-02-01 02:39:30 +00:00
<IconButton color="inherit" size="large" edge="end" onClick={(ev) => setAnchorEl(ev.currentTarget)} aria-label={t("action_bar_toggle_action_menu")}>
2022-03-06 03:33:34 +00:00
<MoreVertIcon/>
</IconButton>
2023-02-01 02:39:30 +00:00
<SubscriptionPopup
subscription={subscription}
anchor={anchorEl}
placement="right"
onClose={() => setAnchorEl(null)}
/>
2022-03-06 03:33:34 +00:00
</>
);
};
2022-12-29 07:32:05 +00:00
const ProfileIcon = () => {
2022-12-02 20:37:48 +00:00
const { t } = useTranslation();
2022-12-15 04:43:43 +00:00
const [anchorEl, setAnchorEl] = useState(null);
const open = Boolean(anchorEl);
2022-12-08 01:44:20 +00:00
const navigate = useNavigate();
2022-12-02 20:37:48 +00:00
2022-12-15 04:43:43 +00:00
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
2022-12-02 20:37:48 +00:00
};
2022-12-29 07:32:05 +00:00
2022-12-15 04:43:43 +00:00
const handleClose = () => {
setAnchorEl(null);
2022-12-02 20:37:48 +00:00
};
2022-12-29 07:32:05 +00:00
2022-12-08 01:44:20 +00:00
const handleLogout = async () => {
2022-12-25 16:59:44 +00:00
try {
await accountApi.logout();
2022-12-28 20:51:09 +00:00
await db.delete();
2022-12-25 16:59:44 +00:00
} finally {
session.resetAndRedirect(routes.app);
2022-12-25 16:59:44 +00:00
}
2022-12-02 20:37:48 +00:00
};
2022-12-29 07:32:05 +00:00
2022-12-02 20:37:48 +00:00
return (
<>
2022-12-08 01:44:20 +00:00
{session.exists() &&
2022-12-29 07:32:05 +00:00
<IconButton color="inherit" size="large" edge="end" onClick={handleClick} aria-label={t("action_bar_profile_title")}>
2022-12-02 20:37:48 +00:00
<AccountCircleIcon/>
</IconButton>
}
2023-01-05 03:47:12 +00:00
{!session.exists() && config.enable_login &&
2022-12-29 07:32:05 +00:00
<Button color="inherit" variant="text" onClick={() => navigate(routes.login)} sx={{m: 1}} aria-label={t("action_bar_sign_in")}>
{t("action_bar_sign_in")}
</Button>
2022-12-21 18:19:07 +00:00
}
2023-01-05 03:47:12 +00:00
{!session.exists() && config.enable_signup &&
2022-12-29 07:32:05 +00:00
<Button color="inherit" variant="outlined" onClick={() => navigate(routes.signup)} aria-label={t("action_bar_sign_up")}>
{t("action_bar_sign_up")}
</Button>
2022-12-02 20:37:48 +00:00
}
2022-12-29 07:32:05 +00:00
<PopupMenu
horizontal="right"
2022-12-15 04:43:43 +00:00
anchorEl={anchorEl}
2022-12-02 20:37:48 +00:00
open={open}
2022-12-15 04:43:43 +00:00
onClose={handleClose}
2022-12-02 20:37:48 +00:00
>
2022-12-16 03:07:04 +00:00
<MenuItem onClick={() => navigate(routes.account)}>
2022-12-15 04:43:43 +00:00
<ListItemIcon>
<Person />
</ListItemIcon>
<b>{session.username()}</b>
</MenuItem>
<Divider />
2022-12-16 03:07:04 +00:00
<MenuItem onClick={() => navigate(routes.settings)}>
2022-12-15 04:43:43 +00:00
<ListItemIcon>
<Settings fontSize="small" />
</ListItemIcon>
2022-12-29 07:32:05 +00:00
{t("action_bar_profile_settings")}
2022-12-15 04:43:43 +00:00
</MenuItem>
<MenuItem onClick={handleLogout}>
<ListItemIcon>
<Logout fontSize="small" />
</ListItemIcon>
2022-12-29 07:32:05 +00:00
{t("action_bar_profile_logout")}
2022-12-15 04:43:43 +00:00
</MenuItem>
2022-12-29 07:32:05 +00:00
</PopupMenu>
2022-12-02 20:37:48 +00:00
</>
);
};
2022-02-25 17:46:22 +00:00
export default ActionBar;