Przeglądaj źródła

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

Philipp Heckel 3 lat temu
rodzic
commit
feef15c485

+ 4 - 0
docs/releases.md

@@ -13,6 +13,10 @@ and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/release
 
 ## 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:**
 
 * 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))

+ 1 - 0
web/public/static/langs/en.json

@@ -24,6 +24,7 @@
   "alert_grant_button": "Grant now",
   "alert_not_supported_title": "Notifications not supported",
   "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_item": "Notification",
   "notifications_mark_read": "Mark as read",

+ 14 - 0
web/src/app/Notifier.js

@@ -74,8 +74,22 @@ class Notifier {
     }
 
     supported() {
+        return this.browserSupported() && this.contextSupported();
+    }
+
+    browserSupported() {
         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();

+ 29 - 6
web/src/components/Navigation.js

@@ -11,7 +11,7 @@ import List from "@mui/material/List";
 import SettingsIcon from "@mui/icons-material/Settings";
 import AddIcon from "@mui/icons-material/Add";
 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 Typography from "@mui/material/Typography";
 import {openUrl, topicShortUrl, topicUrl} from "../app/utils";
@@ -24,7 +24,7 @@ import Box from "@mui/material/Box";
 import notifier from "../app/Notifier";
 import config from "../app/config";
 import ArticleIcon from '@mui/icons-material/Article';
-import {useTranslation} from "react-i18next";
+import {Trans, useTranslation} from "react-i18next";
 
 const navWidth = 280;
 
@@ -91,14 +91,17 @@ const NavList = (props) => {
     };
 
     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 navListPadding = (showNotificationGrantBox || showNotificationBrowserNotSupportedBox || showNotificationContextNotSupportedBox) ? '0' : '';
 
     return (
         <>
             <Toolbar sx={{ display: { xs: 'none', sm: 'block' } }}/>
-            <List component="nav" sx={{ paddingTop: (showNotificationGrantBox || showNotificationNotSupportedBox) ? '0' : '' }}>
-                {showNotificationNotSupportedBox && <NotificationNotSupportedAlert/>}
+            <List component="nav" sx={{ paddingTop: navListPadding }}>
+                {showNotificationBrowserNotSupportedBox && <NotificationBrowserNotSupportedAlert/>}
+                {showNotificationContextNotSupportedBox && <NotificationContextNotSupportedAlert/>}
                 {showNotificationGrantBox && <NotificationGrantAlert onRequestPermissionClick={handleRequestNotificationPermission}/>}
                 {!showSubscriptionsList &&
                     <ListItemButton onClick={() => navigate(routes.root)} selected={location.pathname === config.appRoot}>
@@ -211,7 +214,7 @@ const NotificationGrantAlert = (props) => {
     );
 };
 
-const NotificationNotSupportedAlert = () => {
+const NotificationBrowserNotSupportedAlert = () => {
     const { t } = useTranslation();
     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;