Web app: Show "notifications not supported" alert on HTTP

pull/327/head
Philipp Heckel 2022-06-12 16:38:33 -04:00
parent cf0f002bfa
commit feef15c485
4 changed files with 48 additions and 6 deletions

View File

@ -13,6 +13,10 @@ and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/release
## ntfy server v1.26.0 (UNRELEASED) ## ntfy server v1.26.0 (UNRELEASED)
**Bugs:**
* Web app: Show "notifications not supported" alert on HTTP ([#323](https://github.com/binwiederhier/ntfy/issues/323), thanks to [@milksteakjellybeans](https://github.com/milksteakjellybeans) for reporting)
**Features:** **Features:**
* Windows CLI is now available via [Scoop](https://scoop.sh) ([ScoopInstaller#3594](https://github.com/ScoopInstaller/Main/pull/3594), [#311](https://github.com/binwiederhier/ntfy/pull/311), [#269](https://github.com/binwiederhier/ntfy/issues/269), thanks to [@kzshantonu](https://github.com/kzshantonu)) * Windows CLI is now available via [Scoop](https://scoop.sh) ([ScoopInstaller#3594](https://github.com/ScoopInstaller/Main/pull/3594), [#311](https://github.com/binwiederhier/ntfy/pull/311), [#269](https://github.com/binwiederhier/ntfy/issues/269), thanks to [@kzshantonu](https://github.com/kzshantonu))

View File

@ -24,6 +24,7 @@
"alert_grant_button": "Grant now", "alert_grant_button": "Grant now",
"alert_not_supported_title": "Notifications not supported", "alert_not_supported_title": "Notifications not supported",
"alert_not_supported_description": "Notifications are not supported in your browser.", "alert_not_supported_description": "Notifications are not supported in your browser.",
"alert_not_supported_context_description": "Notifications are only supported over HTTPS. This is a limitation of the <mdnLink>Notifications API</mdnLink>.",
"notifications_list": "Notifications list", "notifications_list": "Notifications list",
"notifications_list_item": "Notification", "notifications_list_item": "Notification",
"notifications_mark_read": "Mark as read", "notifications_mark_read": "Mark as read",

View File

@ -74,8 +74,22 @@ class Notifier {
} }
supported() { supported() {
return this.browserSupported() && this.contextSupported();
}
browserSupported() {
return 'Notification' in window; return 'Notification' in window;
} }
/**
* Returns true if this is a HTTPS site, or served over localhost. Otherwise the Notification API
* is not supported, see https://developer.mozilla.org/en-US/docs/Web/API/notification
*/
contextSupported() {
return location.protocol === 'https:'
|| location.hostname.match('^127.')
|| location.hostname === 'localhost';
}
} }
const notifier = new Notifier(); const notifier = new Notifier();

View File

@ -11,7 +11,7 @@ import List from "@mui/material/List";
import SettingsIcon from "@mui/icons-material/Settings"; import SettingsIcon from "@mui/icons-material/Settings";
import AddIcon from "@mui/icons-material/Add"; import AddIcon from "@mui/icons-material/Add";
import SubscribeDialog from "./SubscribeDialog"; import SubscribeDialog from "./SubscribeDialog";
import {Alert, AlertTitle, Badge, CircularProgress, ListSubheader} from "@mui/material"; import {Alert, AlertTitle, Badge, CircularProgress, Link, ListSubheader} from "@mui/material";
import Button from "@mui/material/Button"; import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import {openUrl, topicShortUrl, topicUrl} from "../app/utils"; import {openUrl, topicShortUrl, topicUrl} from "../app/utils";
@ -24,7 +24,7 @@ import Box from "@mui/material/Box";
import notifier from "../app/Notifier"; import notifier from "../app/Notifier";
import config from "../app/config"; import config from "../app/config";
import ArticleIcon from '@mui/icons-material/Article'; import ArticleIcon from '@mui/icons-material/Article';
import {useTranslation} from "react-i18next"; import {Trans, useTranslation} from "react-i18next";
const navWidth = 280; const navWidth = 280;
@ -91,14 +91,17 @@ const NavList = (props) => {
}; };
const showSubscriptionsList = props.subscriptions?.length > 0; const showSubscriptionsList = props.subscriptions?.length > 0;
const showNotificationNotSupportedBox = !notifier.supported(); const showNotificationBrowserNotSupportedBox = !notifier.browserSupported();
const showNotificationContextNotSupportedBox = notifier.browserSupported() && !notifier.contextSupported(); // Only show if notifications are generally supported in the browser
const showNotificationGrantBox = notifier.supported() && props.subscriptions?.length > 0 && !props.notificationsGranted; const showNotificationGrantBox = notifier.supported() && props.subscriptions?.length > 0 && !props.notificationsGranted;
const navListPadding = (showNotificationGrantBox || showNotificationBrowserNotSupportedBox || showNotificationContextNotSupportedBox) ? '0' : '';
return ( return (
<> <>
<Toolbar sx={{ display: { xs: 'none', sm: 'block' } }}/> <Toolbar sx={{ display: { xs: 'none', sm: 'block' } }}/>
<List component="nav" sx={{ paddingTop: (showNotificationGrantBox || showNotificationNotSupportedBox) ? '0' : '' }}> <List component="nav" sx={{ paddingTop: navListPadding }}>
{showNotificationNotSupportedBox && <NotificationNotSupportedAlert/>} {showNotificationBrowserNotSupportedBox && <NotificationBrowserNotSupportedAlert/>}
{showNotificationContextNotSupportedBox && <NotificationContextNotSupportedAlert/>}
{showNotificationGrantBox && <NotificationGrantAlert onRequestPermissionClick={handleRequestNotificationPermission}/>} {showNotificationGrantBox && <NotificationGrantAlert onRequestPermissionClick={handleRequestNotificationPermission}/>}
{!showSubscriptionsList && {!showSubscriptionsList &&
<ListItemButton onClick={() => navigate(routes.root)} selected={location.pathname === config.appRoot}> <ListItemButton onClick={() => navigate(routes.root)} selected={location.pathname === config.appRoot}>
@ -211,7 +214,7 @@ const NotificationGrantAlert = (props) => {
); );
}; };
const NotificationNotSupportedAlert = () => { const NotificationBrowserNotSupportedAlert = () => {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<> <>
@ -224,4 +227,24 @@ const NotificationNotSupportedAlert = () => {
); );
}; };
const NotificationContextNotSupportedAlert = () => {
const { t } = useTranslation();
return (
<>
<Alert severity="warning" sx={{paddingTop: 2}}>
<AlertTitle>{t("alert_not_supported_title")}</AlertTitle>
<Typography gutterBottom>
<Trans
i18nKey="alert_not_supported_context_description"
components={{
mdnLink: <Link href="https://developer.mozilla.org/en-US/docs/Web/API/notification" target="_blank" rel="noopener"/>
}}
/>
</Typography>
</Alert>
<Divider/>
</>
);
};
export default Navigation; export default Navigation;