Browse Source

Merge branch 'binwiederhier:main' into main

Ziga Zajc 1 month ago
parent
commit
62f3d991b4

+ 12 - 12
docs/install.md

@@ -567,18 +567,18 @@ kubectl apply -k /ntfy
                       cpu: 150m
                       cpu: 150m
                       memory: 150Mi
                       memory: 150Mi
               volumeMounts:
               volumeMounts:
-                  - mountPath: /etc/ntfy
-                    subPath: server.yml
-                    name: config-volume # generated vie configMapGenerator from kustomization file
-                  - mountPath: /var/cache/ntfy
-                    name: cache-volume #cache volume mounted to persistent volume
-            volumes:
-              - name: config-volume
-                configMap:  # uses configmap generator to parse server.yml to configmap
-                  name: server-config
-              - name: cache-volume
-                persistentVolumeClaim: # stores /cache/ntfy in defined pv
-                  claimName: ntfy-pvc
+                - mountPath: /etc/ntfy/server.yml
+                  subPath: server.yml
+                  name: config-volume # generated via configMapGenerator from kustomization file
+                - mountPath: /var/cache/ntfy
+                  name: cache-volume # cache volume mounted to persistent volume
+          volumes:
+            - name: config-volume
+              configMap: # uses configmap generator to parse server.yml to configmap
+                name: server-config
+            - name: cache-volume
+              persistentVolumeClaim: # stores /cache/ntfy in defined pv
+                claimName: ntfy-pvc
     ```
     ```
   
   
 === "ntfy-pvc.yaml"
 === "ntfy-pvc.yaml"

+ 0 - 3
docs/publish.md

@@ -3503,9 +3503,6 @@ Here's an example with a custom message, tags and a priority:
 ## Updating + deleting notifications
 ## Updating + deleting notifications
 _Supported on:_ :material-android: :material-firefox:
 _Supported on:_ :material-android: :material-firefox:
 
 
-!!! info
-    This feature is not fully released yet. The ntfy Android 1.22.x is being released right now. This may take a week or so.
-
 You can **update, clear (mark as read and dismiss), or delete notifications** that have already been delivered. This is useful for scenarios
 You can **update, clear (mark as read and dismiss), or delete notifications** that have already been delivered. This is useful for scenarios
 like download progress updates, replacing outdated information, or dismissing notifications that are no longer relevant.
 like download progress updates, replacing outdated information, or dismissing notifications that are no longer relevant.
 
 

+ 10 - 3
docs/releases.md

@@ -12,10 +12,10 @@ and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/release
 
 
 Please check out the release notes for [upcoming releases](#not-released-yet) below.
 Please check out the release notes for [upcoming releases](#not-released-yet) below.
 
 
-### ntfy Android app v1.22.2
+## ntfy Android app v1.22.2
 Released January 20, 2026
 Released January 20, 2026
 
 
-This release adds support for [updating and deleting notifications](publish.md#updating--deleting-notifications) (requires server v2.16.0),
+This release adds support for [updating and deleting notifications](publish.md#updating-deleting-notifications) (requires server v2.16.0),
 as well as [certificate management for self-signed certs and mTLS client certificates](subscribe/phone.md#manage-certificates),
 as well as [certificate management for self-signed certs and mTLS client certificates](subscribe/phone.md#manage-certificates),
 and a new connection error dialog to help [troubleshoot connection issues](subscribe/phone.md#troubleshooting).
 and a new connection error dialog to help [troubleshoot connection issues](subscribe/phone.md#troubleshooting).
 
 
@@ -1665,4 +1665,11 @@ and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/release
 
 
 ## Not released yet
 ## Not released yet
 
 
-_Nothing here_
+### ntfy server v2.17.x (UNRELEASED)
+
+**Bug fixes + maintenance:**
+
+* Web: Fix markdown message line height to match plain text (1.5 instead of 1.2) ([#1139](https://github.com/binwiederhier/ntfy/issues/1139), thanks to [@etfz](https://github.com/etfz))
+* Web: Add validation feedback for service URL when adding user ([#1566](https://github.com/binwiederhier/ntfy/issues/1566), thanks to [@jermanuts](https://github.com/jermanuts))
+* Docs: Remove obsolete `version` field from docker-compose examples ([#1333](https://github.com/binwiederhier/ntfy/issues/1333), thanks to [@seals187](https://github.com/seals187) for reporting and [@cyb3rko](https://github.com/cyb3rko) for fixing)
+* Docs: Fix Kustomize config - correct volumeMount path and volumes indentation ([#1367](https://github.com/binwiederhier/ntfy/issues/1367), thanks to [@toby-griffiths](https://github.com/toby-griffiths))

+ 7 - 3
docs/subscribe/phone.md

@@ -82,9 +82,8 @@ you'll see as a permanent notification that looks like this:
   <figcaption>Instant delivery foreground notification</figcaption>
   <figcaption>Instant delivery foreground notification</figcaption>
 </figure>
 </figure>
 
 
-Android does not allow you to dismiss this notification, unless you turn off the notification channel in the settings.
-To do so, long-press on the foreground notification (screenshot above) and navigate to the settings. Then toggle the 
-"Subscription Service" off:
+To turn off this notification, long-press on the foreground notification (screenshot above) and navigate to the 
+settings. Then toggle the "Subscription Service" off:
 
 
 <figure markdown>
 <figure markdown>
   ![foreground service](../static/img/notification-settings.png){ width=500 }
   ![foreground service](../static/img/notification-settings.png){ width=500 }
@@ -102,6 +101,11 @@ notifications. Firebase is overall pretty bad at delivering messages in time, bu
 The ntfy Android app uses Firebase only for the main host `ntfy.sh`, and only in the Google Play flavor of the app.
 The ntfy Android app uses Firebase only for the main host `ntfy.sh`, and only in the Google Play flavor of the app.
 It won't use Firebase for any self-hosted servers, and not at all in the F-Droid flavor.
 It won't use Firebase for any self-hosted servers, and not at all in the F-Droid flavor.
 
 
+!!! info "F-Droid: Always instant delivery"
+    Since the F-Droid build does not include Firebase, **all subscriptions use instant delivery by default**, and 
+    there is no option to disable it. The F-Droid app hides all mentions of "instant delivery" in the UI, since 
+    showing options that can't be changed would only be confusing.
+
 ## Publishing messages
 ## Publishing messages
 _Supported on:_ :material-android:
 _Supported on:_ :material-android:
 
 

+ 1 - 1
web/public/static/langs/bg.json

@@ -75,7 +75,7 @@
     "publish_dialog_attachment_limits_quota_reached": "надвишава квотата, остават {{remainingBytes}}",
     "publish_dialog_attachment_limits_quota_reached": "надвишава квотата, остават {{remainingBytes}}",
     "publish_dialog_priority_high": "Висок приоритет",
     "publish_dialog_priority_high": "Висок приоритет",
     "publish_dialog_priority_default": "Подразбиран приоритет",
     "publish_dialog_priority_default": "Подразбиран приоритет",
-    "publish_dialog_title_placeholder": "Заглавие на известието, напр. Предупреждение за диска",
+    "publish_dialog_title_placeholder": "Заглавие на известието, напр. Предупреждение за дисково пространство",
     "publish_dialog_tags_label": "Етикети",
     "publish_dialog_tags_label": "Етикети",
     "publish_dialog_email_label": "Адрес на електронна поща",
     "publish_dialog_email_label": "Адрес на електронна поща",
     "publish_dialog_priority_max": "Най-висок приоритет",
     "publish_dialog_priority_max": "Най-висок приоритет",

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

@@ -357,6 +357,8 @@
   "prefs_users_dialog_title_add": "Add user",
   "prefs_users_dialog_title_add": "Add user",
   "prefs_users_dialog_title_edit": "Edit user",
   "prefs_users_dialog_title_edit": "Edit user",
   "prefs_users_dialog_base_url_label": "Service URL, e.g. https://ntfy.sh",
   "prefs_users_dialog_base_url_label": "Service URL, e.g. https://ntfy.sh",
+  "prefs_users_dialog_base_url_invalid": "Invalid URL format. Must start with http:// or https://",
+  "prefs_users_dialog_base_url_exists": "A user for this service URL already exists",
   "prefs_users_dialog_username_label": "Username, e.g. phil",
   "prefs_users_dialog_username_label": "Username, e.g. phil",
   "prefs_users_dialog_password_label": "Password",
   "prefs_users_dialog_password_label": "Password",
   "prefs_appearance_title": "Appearance",
   "prefs_appearance_title": "Appearance",

+ 8 - 6
web/public/static/langs/ru.json

@@ -30,11 +30,11 @@
     "publish_dialog_topic_label": "Название темы",
     "publish_dialog_topic_label": "Название темы",
     "publish_dialog_topic_placeholder": "Название темы, например phil_alerts",
     "publish_dialog_topic_placeholder": "Название темы, например phil_alerts",
     "publish_dialog_title_label": "Заголовок",
     "publish_dialog_title_label": "Заголовок",
-    "publish_dialog_title_placeholder": "Заголовок уведомления, например Disk space alert",
+    "publish_dialog_title_placeholder": "Заголовок уведомления, например, Предупреждение о занятости диска",
     "publish_dialog_message_label": "Сообщение",
     "publish_dialog_message_label": "Сообщение",
     "publish_dialog_message_placeholder": "Введите сообщение здесь",
     "publish_dialog_message_placeholder": "Введите сообщение здесь",
     "publish_dialog_tags_label": "Тэги",
     "publish_dialog_tags_label": "Тэги",
-    "publish_dialog_tags_placeholder": "Список тэгов, разделённый запятой, например: warning, srv1-backup",
+    "publish_dialog_tags_placeholder": "Ярлыки, разделенные запятыми, например: warning, srv1-backup",
     "publish_dialog_priority_label": "Приоритет",
     "publish_dialog_priority_label": "Приоритет",
     "publish_dialog_click_label": "Ссылка при открытии",
     "publish_dialog_click_label": "Ссылка при открытии",
     "publish_dialog_click_placeholder": "URL-адрес, который откроется при нажатии на уведомление",
     "publish_dialog_click_placeholder": "URL-адрес, который откроется при нажатии на уведомление",
@@ -242,8 +242,8 @@
     "action_bar_reservation_delete": "Удалить резервирование",
     "action_bar_reservation_delete": "Удалить резервирование",
     "action_bar_profile_title": "Профиль",
     "action_bar_profile_title": "Профиль",
     "action_bar_profile_settings": "Настройки",
     "action_bar_profile_settings": "Настройки",
-    "action_bar_profile_logout": "Выход",
-    "action_bar_sign_in": "Вход",
+    "action_bar_profile_logout": "Выйти",
+    "action_bar_sign_in": "Войти",
     "action_bar_sign_up": "Регистрация",
     "action_bar_sign_up": "Регистрация",
     "action_bar_change_display_name": "Изменить псевдоним",
     "action_bar_change_display_name": "Изменить псевдоним",
     "message_bar_publish": "Опубликовать сообщение",
     "message_bar_publish": "Опубликовать сообщение",
@@ -395,7 +395,7 @@
     "prefs_notifications_web_push_title": "Фоновые уведомления",
     "prefs_notifications_web_push_title": "Фоновые уведомления",
     "prefs_notifications_web_push_enabled_description": "Уведомления приходят даже когда веб-приложение не запущено (через Web Push)",
     "prefs_notifications_web_push_enabled_description": "Уведомления приходят даже когда веб-приложение не запущено (через Web Push)",
     "prefs_notifications_web_push_disabled_description": "Уведомления приходят, когда веб-приложение запущено (через WebSocket)",
     "prefs_notifications_web_push_disabled_description": "Уведомления приходят, когда веб-приложение запущено (через WebSocket)",
-    "prefs_appearance_theme_title": "Тема",
+    "prefs_appearance_theme_title": "Тема оформления",
     "prefs_notifications_web_push_enabled": "Включено для {{server}}",
     "prefs_notifications_web_push_enabled": "Включено для {{server}}",
     "prefs_notifications_web_push_disabled": "Выключено",
     "prefs_notifications_web_push_disabled": "Выключено",
     "notifications_actions_failed_notification": "Неудачное действие",
     "notifications_actions_failed_notification": "Неудачное действие",
@@ -403,5 +403,7 @@
     "subscribe_dialog_subscribe_use_another_background_info": "Уведомления с других серверов не будут получены, когда веб-приложение не открыто",
     "subscribe_dialog_subscribe_use_another_background_info": "Уведомления с других серверов не будут получены, когда веб-приложение не открыто",
     "prefs_appearance_theme_system": "Как в системе (по умолчанию)",
     "prefs_appearance_theme_system": "Как в системе (по умолчанию)",
     "prefs_appearance_theme_dark": "Тёмная",
     "prefs_appearance_theme_dark": "Тёмная",
-    "prefs_appearance_theme_light": "Светлая"
+    "prefs_appearance_theme_light": "Светлая",
+    "account_basics_cannot_edit_or_delete_provisioned_user": "Пользователя, созданного автоматически, нельзя изменить или удалить",
+    "account_tokens_table_cannot_delete_or_edit_provisioned_token": "Автоматически созданный токен нельзя изменить или удалить"
 }
 }

+ 1 - 1
web/src/components/Notifications.jsx

@@ -188,7 +188,7 @@ const MarkdownContainer = styled("div")`
   }
   }
 
 
   p {
   p {
-    line-height: 1.2;
+    line-height: 1.5;
   }
   }
 
 
   blockquote,
   blockquote,

+ 12 - 3
web/src/components/Preferences.jsx

@@ -429,13 +429,14 @@ const UserDialog = (props) => {
   const [password, setPassword] = useState("");
   const [password, setPassword] = useState("");
   const fullScreen = useMediaQuery(theme.breakpoints.down("sm"));
   const fullScreen = useMediaQuery(theme.breakpoints.down("sm"));
   const editMode = props.user !== null;
   const editMode = props.user !== null;
+  const baseUrlValid = baseUrl.length === 0 || validUrl(baseUrl);
+  const baseUrlExists = props.users?.map((user) => user.baseUrl).includes(baseUrl);
+  const baseUrlError = baseUrl.length > 0 && (!baseUrlValid || baseUrlExists);
   const addButtonEnabled = (() => {
   const addButtonEnabled = (() => {
     if (editMode) {
     if (editMode) {
       return username.length > 0 && password.length > 0;
       return username.length > 0 && password.length > 0;
     }
     }
-    const baseUrlValid = validUrl(baseUrl);
-    const baseUrlExists = props.users?.map((user) => user.baseUrl).includes(baseUrl);
-    return baseUrlValid && !baseUrlExists && username.length > 0 && password.length > 0;
+    return validUrl(baseUrl) && !baseUrlExists && username.length > 0 && password.length > 0;
   })();
   })();
   const handleSubmit = async () => {
   const handleSubmit = async () => {
     props.onSubmit({
     props.onSubmit({
@@ -467,6 +468,14 @@ const UserDialog = (props) => {
             type="url"
             type="url"
             fullWidth
             fullWidth
             variant="standard"
             variant="standard"
+            error={baseUrlError}
+            helperText={
+              baseUrl.length > 0 && !baseUrlValid
+                ? t("prefs_users_dialog_base_url_invalid")
+                : baseUrlExists
+                ? t("prefs_users_dialog_base_url_exists")
+                : ""
+            }
           />
           />
         )}
         )}
         <TextField
         <TextField