diff --git a/docs/releases.md b/docs/releases.md index 1dfc1232..b4793da9 100644 --- a/docs/releases.md +++ b/docs/releases.md @@ -2,6 +2,16 @@ Binaries for all releases can be found on the GitHub releases pages for the [ntfy server](https://github.com/binwiederhier/ntfy/releases) and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/releases). +## ntfy server v1.17.0 +Released Mar 11, 2022 + +**Features & bug fixes:** + +* Replace [web app](https://ntfy.sh/app) with a React/MUI-based web app from the 21st century (#111) +* Web UI broken with auth (#132, thanks for reporting @arminus) +* Send static web resources as `Content-Encoding: gzip`, i.e. docs and web app (no ticket) +* Add support for auth via `?auth=...` query param, used by WebSocket in web app (no ticket) + ## ntfy server v1.16.0 Released Feb 27, 2022 diff --git a/web/public/index.html b/web/public/index.html index 93aa4af5..2c9751f3 100644 --- a/web/public/index.html +++ b/web/public/index.html @@ -34,7 +34,7 @@
diff --git a/web/public/static/css/home.css b/web/public/static/css/home.css index 9ca00e52..a0451824 100644 --- a/web/public/static/css/home.css +++ b/web/public/static/css/home.css @@ -265,29 +265,6 @@ figcaption { text-decoration: underline; } -/* Subscribe box */ - -button { - background: #3a9784; - border: none; - border-radius: 3px; - padding: 3px 5px; - color: white; - cursor: pointer; -} - -button:hover { - background: #317f6f; - padding: 5px; -} - -ul { - padding-left: 1em; - list-style-type: circle; - padding-bottom: 0; - margin: 0; -} - li { padding: 4px 0; margin: 4px 0; diff --git a/web/public/static/js/home.js b/web/public/static/js/home.js index e867c459..80b14055 100644 --- a/web/public/static/js/home.js +++ b/web/public/static/js/home.js @@ -1,12 +1,4 @@ -/** - * Hello, dear curious visitor. I am not a web-guy, so please don't judge my horrible JS code. - * In fact, please do tell me about all the things I did wrong and that I could improve. I've been trying - * to read up on modern JS, but it's just a little much. - * - * Feel free to open tickets at https://github.com/binwiederhier/ntfy/issues. Thank you! - */ - /* All the things */ let currentUrl = window.location.hostname; diff --git a/web/src/app/Connection.js b/web/src/app/Connection.js index c8814897..55778023 100644 --- a/web/src/app/Connection.js +++ b/web/src/app/Connection.js @@ -2,6 +2,12 @@ import {basicAuth, encodeBase64Url, topicShortUrl, topicUrlWs} from "./utils"; const retryBackoffSeconds = [5, 10, 15, 20, 30]; +/** + * A connection contains a single WebSocket connection for one topic. It handles its connection + * status itself, including reconnect attempts and backoff. + * + * Incoming messages and state changes are forwarded via listeners. + */ class Connection { constructor(connectionId, subscriptionId, baseUrl, topic, user, since, onNotification, onStateChanged) { this.connectionId = connectionId; diff --git a/web/src/app/ConnectionManager.js b/web/src/app/ConnectionManager.js index 5b56e556..6e5037ce 100644 --- a/web/src/app/ConnectionManager.js +++ b/web/src/app/ConnectionManager.js @@ -1,6 +1,12 @@ import Connection from "./Connection"; import {sha256} from "./utils"; +/** + * The connection manager keeps track of active connections (WebSocket connections, see Connection). + * + * Its refresh() method reconciles state changes with the target state by closing/opening connections + * as required. This is done pretty much exactly the same way as in the Android app. + */ class ConnectionManager { constructor() { this.connections = new Map(); // ConnectionId -> Connection (hash, see below) diff --git a/web/src/app/Notifier.js b/web/src/app/Notifier.js index 3317a59b..3c4a5e0d 100644 --- a/web/src/app/Notifier.js +++ b/web/src/app/Notifier.js @@ -3,6 +3,10 @@ import prefs from "./Prefs"; import subscriptionManager from "./SubscriptionManager"; import logo from "../img/ntfy.png"; +/** + * The notifier is responsible for displaying desktop notifications. Note that not all modern browsers + * support this; most importantly, all iOS browsers do not support window.Notification. + */ class Notifier { async notify(subscriptionId, notification, onClickFallback) { if (!this.supported()) { diff --git a/web/src/components/SubscribeDialog.js b/web/src/components/SubscribeDialog.js index d7713ae7..4c37d0fc 100644 --- a/web/src/components/SubscribeDialog.js +++ b/web/src/components/SubscribeDialog.js @@ -85,7 +85,7 @@ const SubscribePage = (props) => { const isExistingTopicUrl = existingTopicUrls.includes(topicUrl(baseUrl, topic)); return validTopic(topic) && validUrl(baseUrl) && !isExistingTopicUrl; } else { - const isExistingTopicUrl = existingTopicUrls.includes(topicUrl(window.location.origin, topic)); // FIXME + const isExistingTopicUrl = existingTopicUrls.includes(topicUrl(window.location.origin, topic)); return validTopic(topic) && !isExistingTopicUrl; } })(); diff --git a/web/src/components/hooks.js b/web/src/components/hooks.js index f3299856..cb66cbe5 100644 --- a/web/src/components/hooks.js +++ b/web/src/components/hooks.js @@ -66,6 +66,10 @@ export const useAutoSubscribe = (subscriptions, selected) => { }, [params, subscriptions, selected, hasRun]); }; +/** + * Migrate the 'topics' item in localStorage to the subscriptionManager. This is only done once to migrate away + * from the old web UI. + */ export const useLocalStorageMigration = () => { const [hasRun, setHasRun] = useState(false); useEffect(() => {