Compare commits

..
Author SHA1 Message Date
dependabot[bot] edace52827 Bump eslint-plugin-react-hooks from 4.6.2 to 7.1.1 in /web
Bumps [eslint-plugin-react-hooks](https://github.com/facebook/react/tree/HEAD/packages/eslint-plugin-react-hooks) from 4.6.2 to 7.1.1.
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/react/react/blob/main/packages/eslint-plugin-react-hooks/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/eslint-plugin-react-hooks@7.1.1/packages/eslint-plugin-react-hooks)

---
updated-dependencies:
- dependency-name: eslint-plugin-react-hooks
  dependency-version: 7.1.1
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-08 21:23:49 +00:00
binwiederhier ce01b357d8 Bump prettier 2026-07-08 23:21:23 +02:00
binwiederhier c40a2ce0a7 Update android release notes 2026-07-08 23:07:41 +02:00
binwiederhier 88e598d8b8 RElease notes 2026-07-08 22:44:57 +02:00
binwiederhier 6869d166ae fmt 2026-07-08 22:42:42 +02:00
binwiederhier 08d81a3645 Merge branch 'main' of github.com:binwiederhier/ntfy 2026-07-08 22:23:40 +02:00
Philipp C. Heckel 202d858826 Merge pull request #1814 from binwiederhier/dependabot/npm_and_yarn/web/i18next-browser-languagedetector-8.2.1
Bump i18next-browser-languagedetector from 6.1.8 to 8.2.1 in /web
2026-07-08 22:23:27 +02:00
Philipp C. Heckel 73e9d46b49 Merge pull request #1822 from binwiederhier/dependabot/go_modules/golang.org/x/text-0.39.0
Bump golang.org/x/text from 0.38.0 to 0.39.0
2026-07-08 22:23:10 +02:00
binwiederhier 9a021aba2d Merge branch 'main' of https://hosted.weblate.org/git/ntfy/web 2026-07-08 22:15:47 +02:00
Philipp C. Heckel 812dc4cded Merge pull request #1826 from binwiederhier/template-execute-context
Template execution rework
2026-07-08 22:15:37 +02:00
Philipp C. Heckel 9f6c4743b3 Merge pull request #1817 from binwiederhier/dependabot/github_actions/all-9e904a7c11
Bump the all group across 1 directory with 2 updates
2026-07-08 22:14:47 +02:00
109247019824 bde864756e Translated using Weblate (Bulgarian)
Currently translated at 100.0% (459 of 459 strings)

Translation: ntfy/Web app
Translate-URL: https://hosted.weblate.org/projects/ntfy/web/bg/
2026-07-08 00:01:19 +02:00
dependabot[bot] b6d21415bb Bump the all group across 1 directory with 2 updates
Bumps the all group with 2 updates in the / directory: [actions/checkout](https://github.com/actions/checkout) and [actions/setup-go](https://github.com/actions/setup-go).


Updates `actions/checkout` from 6.0.3 to 7.0.0
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/df4cb1c069e1874edd31b4311f1884172cec0e10...9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0)

Updates `actions/setup-go` from 6.4.0 to 6.5.0
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/4a3601121dd01d1626a1e23e37211e3254c1c06c...924ae3a1cded613372ab5595356fb5720e22ba16)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all
- dependency-name: actions/setup-go
  dependency-version: 6.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-07 21:44:06 +00:00
dependabot[bot] 2e3d5babc8 Bump golang.org/x/text from 0.38.0 to 0.39.0
Bumps [golang.org/x/text](https://github.com/golang/text) from 0.38.0 to 0.39.0.
- [Release notes](https://github.com/golang/text/releases)
- [Commits](https://github.com/golang/text/compare/v0.38.0...v0.39.0)

---
updated-dependencies:
- dependency-name: golang.org/x/text
  dependency-version: 0.39.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-07 21:42:37 +00:00
NooB9496 b16efd2cb6 Translated using Weblate (Polish)
Currently translated at 100.0% (459 of 459 strings)

Translation: ntfy/Web app
Translate-URL: https://hosted.weblate.org/projects/ntfy/web/pl/
2026-07-06 07:01:20 +02:00
Antonio 24f991c6d7 Translated using Weblate (Spanish)
Currently translated at 92.1% (423 of 459 strings)

Translation: ntfy/Web app
Translate-URL: https://hosted.weblate.org/projects/ntfy/web/es/
2026-07-06 07:01:19 +02:00
dependabot[bot] 6ed57ec064 Bump i18next-browser-languagedetector from 6.1.8 to 8.2.1 in /web
Bumps [i18next-browser-languagedetector](https://github.com/i18next/i18next-browser-languageDetector) from 6.1.8 to 8.2.1.
- [Changelog](https://github.com/i18next/i18next-browser-languageDetector/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next-browser-languageDetector/compare/v6.1.8...v8.2.1)

---
updated-dependencies:
- dependency-name: i18next-browser-languagedetector
  dependency-version: 8.2.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-30 21:42:51 +00:00
30 changed files with 210 additions and 96 deletions
+2 -2
View File
@@ -8,9 +8,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Install Go
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
with:
go-version-file: '.go-version'
- name: Install node
+2 -2
View File
@@ -9,10 +9,10 @@ jobs:
steps:
-
name: Checkout ntfy code
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
-
name: Checkout docs pages code
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
repository: binwiederhier/ntfy-docs.github.io
path: build/ntfy-docs.github.io
+2 -2
View File
@@ -25,9 +25,9 @@ jobs:
NTFY_TEST_S3_URL: ${{ secrets.NTFY_TEST_S3_URL }}
steps:
- name: Checkout code
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Install Go
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
with:
go-version-file: '.go-version'
- name: Install node
+2 -2
View File
@@ -25,9 +25,9 @@ jobs:
NTFY_TEST_S3_URL: ${{ secrets.NTFY_TEST_S3_URL }}
steps:
- name: Checkout code
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Install Go
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
with:
go-version-file: '.go-version'
- name: Install node
+11 -13
View File
@@ -37,7 +37,6 @@ since I do have to reset accounts on a regular basis.
**Bug fixes + maintenance:**
* Prevent a CPU denial of service via message templates (`Template: yes`) ([GHSA-rhwf-xgc9-m9fp](https://github.com/binwiederhier/ntfy/security/advisories/GHSA-rhwf-xgc9-m9fp))
* `X-Email: yes` (also `true`/`1`) now sends to your primary verified email regardless of the `smtp-sender-verify` setting (previously it was rejected unless verification was enabled); it requires being logged in with a verified address
* Grant users full access to their own sync topic (`st_...`) so cross-device subscription sync works under `auth-default-access: deny-all` ([#733](https://github.com/binwiederhier/ntfy/issues/733), [#1795](https://github.com/binwiederhier/ntfy/pull/1795), thanks to [@lmorchard](https://github.com/lmorchard) for the contribution)
* Support HTTP (non-TLS) S3-compatible endpoints by preserving the endpoint scheme, e.g. for a local MinIO instance ([#1794](https://github.com/binwiederhier/ntfy/pull/1794), [#1734](https://github.com/binwiederhier/ntfy/issues/1734), thanks to [@sskender](https://github.com/sskender) for the contribution, and [@Kernald](https://github.com/Kernald) for reporting)
@@ -1986,6 +1985,10 @@ and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/release
### ntfy server v2.26.x (UNRELEASED)
**Security:**
* Prevent a CPU denial of service via message templates (`Template: yes`) ([GHSA-rhwf-xgc9-m9fp](https://github.com/binwiederhier/ntfy/security/advisories/GHSA-rhwf-xgc9-m9fp), [#1826](https://github.com/binwiederhier/ntfy/pull/1826), thanks to [@alanturing881](https://github.com/alanturing881) for reporting)
**Features:**
* Web app: Add "Date format" and "Time format" settings (Settings -> Appearance), with ISO 8601, day/month/year (slash or dot) and month/day/year date options and a 12-/24-hour clock option, and base the default format on your browser/system locale rather than the selected display language. When logged in, both settings sync across devices via your account ([#1647](https://github.com/binwiederhier/ntfy/issues/1647), thanks to [@wsw70](https://github.com/wsw70) for reporting)
@@ -1999,19 +2002,12 @@ and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/release
### ntfy Android v1.25.1 (UNRELEASED)
**Bug fixes + maintenance:**
* Fix instant delivery not resuming after the network returns on Android 12+: the app now keeps the foreground service alive and shows a "Waiting for network" state while offline, instead of stopping the service and failing to restart it ([#1709](https://github.com/binwiederhier/ntfy/issues/1709), thanks to [@isaitgirl](https://github.com/isaitgirl) for reporting)
* Fix the "connection lost" alert repeatedly waking the screen while a server stayed unreachable, by no longer re-posting the alert once it is already showing
* Fix the "connection lost" alert firing late, erratically, or not at all when a connection kept dropping (e.g. a flaky server) rather than being refused outright, by tracking how long the connection has been down independently of whether the drop warrants a UI error
### ntfy Android v1.25.x (UNRELEASED)
This release makes the "connection lost" alert configurable and turns it off by default. Folks did not like it and many reached out
or even gave ntfy bad reviews. I heard you! You can re-enable the alert in the advanced settings.
The release also tries to be smarter about not retrying the connection at all if the app is in flight mode, or has no network. If there
is no network, ntfy will now stop the foreground service entirely.
is no network, ntfy now keeps the foreground service alive and shows a "Waiting for network" notification, then resumes automatically
once connectivity returns.
Another change related to the networking is that we now force-reconnect when the connection is changed, e.g. during transitions
from Wi-Fi to cellular network, or vice versa. That should allow for faster transitions during hand-overs.
@@ -2021,16 +2017,18 @@ especially when paired with increaseing the server-side `keepalive-interval` in
**Features:**
* Add configurable "Alert when connection is lost" setting ([#1665](https://github.com/binwiederhier/ntfy/issues/1665), [#1662](https://github.com/binwiederhier/ntfy/issues/1662), [#1652](https://github.com/binwiederhier/ntfy/issues/1652), [#1655](https://github.com/binwiederhier/ntfy/issues/1655), thanks to [@tintamarre](https://github.com/tintamarre), [@sjozs](https://github.com/sjozs), [@TheRealOne78](https://github.com/TheRealOne78), and [@DAE51D](https://github.com/DAE51D) for reporting)
* Suppress connection alerts and stop foreground service when there is no network ([ntfy-android#165](https://github.com/binwiederhier/ntfy-android/pull/165), thanks to [@tintamarre](https://github.com/tintamarre) for the contribution)
* Restart the foreground service immediately when network returns, even if the app process was killed while offline
* Add configurable "Alert when connection is lost" setting, turned off by default ([#1665](https://github.com/binwiederhier/ntfy/issues/1665), [#1662](https://github.com/binwiederhier/ntfy/issues/1662), [#1652](https://github.com/binwiederhier/ntfy/issues/1652), [#1655](https://github.com/binwiederhier/ntfy/issues/1655), thanks to [@tintamarre](https://github.com/tintamarre), [@sjozs](https://github.com/sjozs), [@TheRealOne78](https://github.com/TheRealOne78), and [@DAE51D](https://github.com/DAE51D) for reporting)
* Handle "no network" gracefully: when the device is offline or in airplane mode, ntfy now stops retrying, suppresses the connection-lost alert, and keeps the foreground service alive with a "Waiting for network" notification, resuming instant delivery automatically when connectivity returns ([ntfy-android#165](https://github.com/binwiederhier/ntfy-android/pull/165), thanks to [@tintamarre](https://github.com/tintamarre) for the contribution, and [#1709](https://github.com/binwiederhier/ntfy/issues/1709), thanks to [@isaitgirl](https://github.com/isaitgirl) for reporting)
* Improve battery life by increasing WebSocket client ping interval from 1 min to 3 min, and reconnect instantly on Wi-Fi/cellular/VPN transitions ([ntfy-android#113](https://github.com/binwiederhier/ntfy-android/pull/113), thanks to [@ftilde](https://github.com/ftilde) for the investigation)
* Disable UnifiedPush components when UnifiedPush is disabled in settings ([ntfy-android#168](https://github.com/binwiederhier/ntfy-android/pull/168), thanks to [@p1gp1g](https://github.com/p1gp1g) for the contribution)
**Bug fixes + maintenance:**
* Fix the "connection lost" alert repeatedly waking the screen while a server stayed unreachable, by no longer re-posting the alert once it is already showing
* Fix the "connection lost" alert firing late, erratically, or not at all when a connection kept dropping (e.g. a flaky server) rather than being refused outright, by tracking how long the connection has been down independently of whether the drop warrants a UI error
* Undo automatic phone number linking for numbers in message body ([ntfy-android#170](https://github.com/binwiederhier/ntfy-android/pull/170), thanks to [@acortelyou](https://github.com/acortelyou) for the contribution)
* Fix subscription icons disappearing after a few days due to Android clearing cache ([#1322](https://github.com/binwiederhier/ntfy/issues/1322), thanks to [@mcanning](https://github.com/mcanning) for reporting)
* Fix UnifiedPush `failed_reason` being sent as an enum instead of a string, which caused an exception in receiving apps that read it as a string extra ([ntfy-android#182](https://github.com/binwiederhier/ntfy-android/pull/182), thanks to [@p1gp1g](https://github.com/p1gp1g) for the contribution)
### ntfy iOS app v1.8.0 (UNRELEASED)
+1 -1
View File
@@ -35,7 +35,7 @@ require (
github.com/prometheus/client_golang v1.23.2
github.com/stripe/stripe-go/v74 v74.30.0
golang.org/x/sys v0.46.0
golang.org/x/text v0.38.0
golang.org/x/text v0.39.0
)
require (
+2 -2
View File
@@ -260,8 +260,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/text v0.38.0 h1:sXmwo9DwP3OK9EZ7PqAdaooSGozfl/3a6/xJcbzPRhE=
golang.org/x/text v0.38.0/go.mod h1:YXZt3QhHUKYT53r2lLKFIVi6Ao1jdzrTR/KQ09qyxF4=
golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus=
golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM=
golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+1 -1
View File
@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
+66 -19
View File
@@ -16,10 +16,10 @@
"dexie": "^4.4.4",
"dexie-react-hooks": "^4.4.0",
"i18next": "^21.6.14",
"i18next-browser-languagedetector": "^6.1.4",
"i18next-browser-languagedetector": "^8.2.1",
"i18next-http-backend": "^4.0.0",
"react": "latest",
"react-dom": "latest",
"react": "*",
"react-dom": "*",
"react-i18next": "^11.16.2",
"react-infinite-scroll-component": "^7.2.1",
"react-remark": "^2.1.0",
@@ -35,8 +35,8 @@
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"prettier": "^2.8.8",
"eslint-plugin-react-hooks": "^7.1.1",
"prettier": "^3.9.4",
"vite": "^8.0.16",
"vite-plugin-pwa": "^1.0.0",
"vitest": "^4.1.9"
@@ -4902,16 +4902,23 @@
}
},
"node_modules/eslint-plugin-react-hooks": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz",
"integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==",
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.1.1.tgz",
"integrity": "sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/core": "^7.24.4",
"@babel/parser": "^7.24.4",
"hermes-parser": "^0.25.1",
"zod": "^3.25.0 || ^4.0.0",
"zod-validation-error": "^3.5.0 || ^4.0.0"
},
"engines": {
"node": ">=10"
"node": ">=18"
},
"peerDependencies": {
"eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0"
"eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0"
}
},
"node_modules/eslint-plugin-react/node_modules/doctrine": {
@@ -5646,6 +5653,23 @@
"url": "https://opencollective.com/unified"
}
},
"node_modules/hermes-estree": {
"version": "0.25.1",
"resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz",
"integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==",
"dev": true,
"license": "MIT"
},
"node_modules/hermes-parser": {
"version": "0.25.1",
"resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz",
"integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==",
"dev": true,
"license": "MIT",
"dependencies": {
"hermes-estree": "0.25.1"
}
},
"node_modules/hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
@@ -5694,12 +5718,12 @@
}
},
"node_modules/i18next-browser-languagedetector": {
"version": "6.1.8",
"resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-6.1.8.tgz",
"integrity": "sha512-Svm+MduCElO0Meqpj1kJAriTC6OhI41VhlT/A0UPjGoPZBhAHIaGE5EfsHlTpgdH09UVX7rcc72pSDDBeKSQQA==",
"version": "8.2.1",
"resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.2.1.tgz",
"integrity": "sha512-bZg8+4bdmaOiApD7N7BPT9W8MLZG+nPTOFlLiJiT8uzKXFjhxw4v2ierCXOwB5sFDMtuA5G4kgYZ0AznZxQ/cw==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.19.0"
"@babel/runtime": "^7.23.2"
}
},
"node_modules/i18next-http-backend": {
@@ -7576,16 +7600,16 @@
}
},
"node_modules/prettier": {
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
"version": "3.9.4",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.4.tgz",
"integrity": "sha512-yWG/o/4oJfo036EKAfK6ACAoDOfHeRHx4tuxkfBZiauURiaSmYwlpOr5LQqKtIkRD2z1PLteme2WoxEnj4tHTg==",
"dev": true,
"license": "MIT",
"bin": {
"prettier": "bin-prettier.js"
"prettier": "bin/prettier.cjs"
},
"engines": {
"node": ">=10.13.0"
"node": ">=14"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
@@ -9937,6 +9961,29 @@
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/zod": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz",
"integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
},
"node_modules/zod-validation-error": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz",
"integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"zod": "^3.25.0 || ^4.0.0"
}
}
}
}
+3 -3
View File
@@ -21,7 +21,7 @@
"dexie": "^4.4.4",
"dexie-react-hooks": "^4.4.0",
"i18next": "^21.6.14",
"i18next-browser-languagedetector": "^6.1.4",
"i18next-browser-languagedetector": "^8.2.1",
"i18next-http-backend": "^4.0.0",
"react": "latest",
"react-dom": "latest",
@@ -40,8 +40,8 @@
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"prettier": "^2.8.8",
"eslint-plugin-react-hooks": "^7.1.1",
"prettier": "^3.9.4",
"vite": "^8.0.16",
"vite-plugin-pwa": "^1.0.0",
"vitest": "^4.1.9"
+12 -4
View File
@@ -5,7 +5,9 @@
font-family: "Roboto";
font-style: normal;
font-weight: 300;
src: local(""), url("../fonts/roboto-v29-latin-300.woff2") format("woff2");
src:
local(""),
url("../fonts/roboto-v29-latin-300.woff2") format("woff2");
}
/* roboto-regular - latin */
@@ -13,7 +15,9 @@
font-family: "Roboto";
font-style: normal;
font-weight: 400;
src: local(""), url("../fonts/roboto-v29-latin-regular.woff2") format("woff2");
src:
local(""),
url("../fonts/roboto-v29-latin-regular.woff2") format("woff2");
}
/* roboto-500 - latin */
@@ -21,7 +25,9 @@
font-family: "Roboto";
font-style: normal;
font-weight: 500;
src: local(""), url("../fonts/roboto-v29-latin-500.woff2") format("woff2");
src:
local(""),
url("../fonts/roboto-v29-latin-500.woff2") format("woff2");
}
/* roboto-700 - latin */
@@ -29,5 +35,7 @@
font-family: "Roboto";
font-style: normal;
font-weight: 700;
src: local(""), url("../fonts/roboto-v29-latin-700.woff2") format("woff2");
src:
local(""),
url("../fonts/roboto-v29-latin-700.woff2") format("woff2");
}
+45 -4
View File
@@ -243,8 +243,8 @@
"account_basics_password_description": "Промяна на паролата на профила",
"account_basics_tier_title": "Вид на профила",
"account_basics_tier_admin": "Администратор",
"account_basics_tier_admin_suffix_with_tier": "(с {{tier}} ниво)",
"account_basics_tier_admin_suffix_no_tier": "(без ниво)",
"account_basics_tier_admin_suffix_with_tier": "с {{tier}} ниво",
"account_basics_tier_admin_suffix_no_tier": "без ниво",
"account_basics_tier_free": "безплатен",
"account_basics_tier_basic": "базов",
"account_basics_tier_change_button": "Променяне",
@@ -373,7 +373,7 @@
"prefs_reservations_table_everyone_read_write": "Всички могат да публикуват и да се абонират",
"reservation_delete_dialog_submit_button": "Премахване на резервирането",
"account_tokens_description": "Използвайте код за достъп когато публикувате или се абонирате през ППИ на ntfy, за да не се налага да изпращате потребителско име и парола. Прочетете <Link>документацията</Link> за повече информация.",
"account_tokens_delete_dialog_description": "Преди да премахвате код за достъп се уверете, че не се използва от приложения или скриптове. <strong>Действието е необратимо.</strong>",
"account_tokens_delete_dialog_description": "Преди да премахвате код за достъп се уверете, че не се използва от приложения или скриптове. <strong>Действието е необратимо.</strong>.",
"prefs_reservations_dialog_description": "Резервирането ви осигурява собственост върху темата и ви дава възможност да определяте права за достъп от други потребители.",
"reservation_delete_dialog_action_keep_title": "Пазене на съобщения и прикачени файлове",
"reservation_delete_dialog_action_keep_description": "Съобщенията и прикачените файлове, които са във временната памет на сървъра ще бъдат достъпни за всеки, който знае името на темата.",
@@ -418,5 +418,46 @@
"version_update_available_description": "Сървърът на ntfy е обновен. Презаредете страницата.",
"signup_form_email": "Адрес на ел. поща (по желание, с цел възстановяване)",
"login_link_forgot_password": "Забравена парола",
"reset_password_request_title": "Нулиране на парола"
"reset_password_request_title": "Нулиране на парола",
"reset_password_request_description": "Въведете потребителско име или адрес на ел. поща. Ако такъв профил съществува по пощата ще бъде изпратена препратка, от която да смените паролата си.",
"reset_password_request_primary_required": "Работи само в случай, че сте задали и потвърдили основен адрес на ел. поща.",
"reset_password_request_identifier_label": "Потребителско име или ел. поща",
"reset_password_request_button_submit": "Изпращане",
"reset_password_sent_title": "Проверете входящата поща",
"reset_password_sent_description": "Ако такъв профил съществува на пощата е изпратена препратка, от която да смените паролата си.",
"reset_password_back_to_login": "Към вписване",
"reset_password_disabled": "Смяната на парола е изключена",
"reset_password_title": "Задаване на нова парола",
"reset_password_form_password": "Нова парола",
"reset_password_form_confirm": "Потвърждаване на новата парола",
"reset_password_form_button_submit": "Задаване на парола",
"reset_password_form_error_invalid": "Препратката е неприемлива или изтекла. Поискайте нова.",
"reset_password_success_title": "Паролата е променена",
"reset_password_success_description": "Паролата е сменена. Можете да се впишете с нея.",
"action_bar_reload": "Презареждане на приложението",
"account_basics_emails_title": "Адреси на ел. поща",
"account_basics_emails_description": "За известия и промяна на праролата",
"account_basics_emails_no_emails_yet": "Не са зададени ел. адреси",
"account_basics_emails_copied_to_clipboard": "Адресът на ел. поща е копиран",
"account_basics_emails_chip_actions_primary": "Основен адрес, използван като ел. адрес по подразбиране. Щракнете за действия.",
"account_basics_emails_chip_actions_verified": "Може да бъде използван за известия. Щракнете за действия.",
"account_basics_emails_chip_actions_unverified": "Непотвърден адрес, проверете входящата поща. Щракнете за действия.",
"account_basics_emails_unverified": "непотвърден",
"account_basics_emails_set_primary": "Задаване като основен",
"account_basics_emails_delete": "Премахване",
"account_basics_emails_resend": "Повторно изпращане на писмо за потвърждаване",
"account_basics_emails_resent": "Писмото е изпратено, проверете входящата поща",
"account_basics_emails_primary_elsewhere": "Този адрес на ел. поща е използван като основен адрес на друг профил",
"account_basics_emails_no_recovery_warning": "Добавете адрес на ел. поща, за да можете да възстановите профила ако забравите паролата.",
"account_basics_emails_no_primary_warning": "Добавете основен адрес на ел. поща, за да можете да възстановите профила ако забравите паролата.",
"account_basics_emails_dialog_title": "Добавяне адреси на ел. поща",
"account_basics_emails_dialog_description": "Въведете адрес на ел. поща, който да бъде добавен към профила. Ще бъде изпратена препратка за потвърждение.",
"account_basics_emails_dialog_email_label": "Адрес на ел. поща",
"account_basics_emails_dialog_email_placeholder": "напр. user@example.com",
"account_basics_emails_dialog_verify_button": "Препратка за потвърждаване",
"account_basics_emails_dialog_check_inbox": "Проверете входящата поща и посетете препратката за потвърждаване. Докато не го направите адресът ще стои непотвърден.",
"account_basics_tier_provisioned": "Потребител от външна система",
"account_usage_emails_none": "Профилът не може да изпраща известия по ел. поща",
"prefs_users_dialog_base_url_invalid": "Неприемлив формат на адрес. Трябва да започва с http:// или https://",
"prefs_users_dialog_base_url_exists": "Потребител за този адрес на услуга вече съществува"
}
+21 -1
View File
@@ -406,5 +406,25 @@
"web_push_unknown_notification_title": "Notificación desconocida recibida del servidor",
"web_push_unknown_notification_body": "Puede que necesites actualizar ntfy abriendo la aplicación web",
"account_basics_cannot_edit_or_delete_provisioned_user": "Un usuario provisionado no se puede editar o eliminar",
"account_tokens_table_cannot_delete_or_edit_provisioned_token": "No se puede editar o eliminar un token provisionado"
"account_tokens_table_cannot_delete_or_edit_provisioned_token": "No se puede editar o eliminar un token provisionado",
"common_refresh": "Recargar",
"email_verify_progress_title": "Verificando tu correo...",
"email_verify_success_title": "Correo verificado",
"email_verify_success_description": "Tu correo electronico ha sido verificado y añadido a tu cuenta.",
"email_verify_error_title": "La verificacion falló",
"email_verify_error_description": "Este enlace de verificacion es invalido o ha expirado. Puedes solicitar unon nuevo desde los ajustes de tu cuenta.",
"email_verify_button_account": "Ir a cuenta",
"version_update_available_title": "Nueva versión disponible",
"version_update_available_description": "El servidor ntfy ha sido actualizado. Por favor recarga la página.",
"signup_form_email": "Correo (opcional, para recuperación de cuenta)",
"login_link_forgot_password": "Olvidé mi contraseña",
"reset_password_request_title": "Reiniciar contraseña",
"reset_password_request_description": "Introduce tu usuario o correo electrónico. Si una cuenta existe, un enlace para reiniciar tu contraseña será enviado a tu correo.",
"reset_password_request_primary_required": "Esto solo funciona si ya añadiste un correo eletrónico primario y lo verificaste.",
"reset_password_request_identifier_label": "Usuario o correo",
"reset_password_request_button_submit": "Enviar enlace de reinicio",
"reset_password_sent_title": "Checa tu bandeja de entrada",
"reset_password_sent_description": "Si una cuenta existe, un enlace para reiniciar tu contraseña se acaba de enviar a tu correo.",
"reset_password_back_to_login": "Regresar a iniciar sesión",
"reset_password_disabled": "Reinicio de contraseña ha sido deshabilitado"
}
+3 -3
View File
@@ -329,11 +329,11 @@
"account_basics_phone_numbers_dialog_verify_button_sms": "Wyślij SMS",
"account_tokens_dialog_expires_never": "Token nigdy nie wygasa",
"account_tokens_dialog_expires_x_days": "Token wygasa za {{days}} dni",
"account_basics_phone_numbers_dialog_description": "Aby używać funkcji powiadomień telefonicznych, musisz dodać i zweryfikować no najmniej jeden numer telefonu. Weryfikacja może być dokonana przez SMS lub połączenie telefoniczne.",
"account_basics_phone_numbers_dialog_description": "Aby korzystać z funkcji powiadomień o połączeniach, należy dodać i zweryfikować co najmniej jeden numer telefonu. Weryfikacji można dokonać za pomocą wiadomości SMS lub połączenia telefonicznego.",
"account_upgrade_dialog_tier_features_messages_other": "Dzienne wiadomości: {{messages}}",
"account_basics_phone_numbers_no_phone_numbers_yet": "Brak numerów telefonów",
"account_tokens_delete_dialog_title": "Usuń token dostępu",
"publish_dialog_chip_call_label": "Rozmowa telefoniczna",
"publish_dialog_chip_call_label": "Połączenie telefoniczne",
"account_basics_phone_numbers_dialog_title": "Dodaj numer telefonu",
"account_upgrade_dialog_tier_features_reservations_other": "Zarezerwowane tematy: {{reservations}}",
"account_upgrade_dialog_reservations_warning_one": "Wybrany plan zezwala na mniejszą liczbę zarezerwowanych tematów niż obecny. Przed zmianą planu, <strong>usuń co najmniej jedną rezerwację</strong>. Rezerwacje możesz usunąć w <Link>Ustawieniach</Link>.",
@@ -341,7 +341,7 @@
"account_upgrade_dialog_cancel_warning": "To <strong>anuluje Twoją subskrypcję</strong> i obniży status Twojego konta {{date}}. Tego dnia rezerwacja tematów oraz wiadomości przechowywane na serwerze <strong>zostaną usunięte</strong>.",
"account_tokens_dialog_expires_x_hours": "Token wygasa za {{hours}} godzin(y)",
"publish_dialog_chip_call_no_verified_numbers_tooltip": "Brak zweryfikowanych numerów telefonów",
"publish_dialog_call_label": "Rozmowa telefoniczna",
"publish_dialog_call_label": "Połączenie telefoniczne",
"account_usage_calls_title": "Wykonane połączenia telefoniczne",
"account_basics_phone_numbers_copied_to_clipboard": "Numer telefonu skopiowany do schowka",
"account_basics_phone_numbers_dialog_number_placeholder": "np. +1222333444",
+3 -3
View File
@@ -61,7 +61,7 @@ const handlePushMessage = async (data) => {
topicRoute: new URL(message.topic, self.location.origin).toString(),
baseUrl: subscription.baseUrl,
topic: subscription.topic,
})
}),
);
// Delete existing notification with same sequence ID (if any)
@@ -417,7 +417,7 @@ self.addEventListener("notificationclick", (event) => {
// [{"revision":"aaabbbcccdddeeefff12345","url":"/index.html"},...]
precacheAndRoute(
// eslint-disable-next-line no-underscore-dangle
self.__WB_MANIFEST
self.__WB_MANIFEST,
);
// Claim all open windows
@@ -441,7 +441,7 @@ if (!import.meta.env.DEV) {
// the app root itself, could be /, or not
new RegExp(`^${config.app_root}$`),
],
})
}),
);
// the manifest excludes config.js (see vite.config.js) since the dist-file differs from the
+2 -2
View File
@@ -65,7 +65,7 @@ describe("AccountApi.create", () => {
await accountApi.create("phil", "pw");
expect(fetchMock).toHaveBeenCalledWith(
"https://ntfy.sh/v1/account",
expect.objectContaining({ method: "POST", body: JSON.stringify({ username: "phil", password: "pw", email: "" }) })
expect.objectContaining({ method: "POST", body: JSON.stringify({ username: "phil", password: "pw", email: "" }) }),
);
});
});
@@ -195,7 +195,7 @@ describe("AccountApi.sync", () => {
notification: { sound: "ding", delete_after: 3600, min_priority: 3 },
subscriptions: [{ topic: "t" }],
reservations: [{ topic: "t" }],
})
}),
);
await accountApi.sync();
+3 -3
View File
@@ -57,7 +57,7 @@ describe("Api.publish", () => {
expect.objectContaining({
method: "PUT",
body: JSON.stringify({ topic: "mytopic", message: "Hello", priority: 5, tags: ["warning"] }),
})
}),
);
});
@@ -109,7 +109,7 @@ describe("Api web push", () => {
expect.objectContaining({
method: "POST",
body: JSON.stringify({ endpoint: "https://push.example/abc", auth: "AUTH", p256dh: "P256", topics: ["topicA", "topicB"] }),
})
}),
);
});
@@ -121,7 +121,7 @@ describe("Api web push", () => {
expect.objectContaining({
method: "DELETE",
body: JSON.stringify({ endpoint: "https://push.example/abc" }),
})
}),
);
});
});
+1 -1
View File
@@ -67,7 +67,7 @@ class Connection {
this.ws.onclose = (event) => {
if (event.wasClean) {
console.log(
`[Connection, ${this.shortUrl}, ${this.connectionId}] Connection closed cleanly, code=${event.code} reason=${event.reason}`
`[Connection, ${this.shortUrl}, ${this.connectionId}] Connection closed cleanly, code=${event.code} reason=${event.reason}`,
);
this.ws = null;
} else {
+2 -2
View File
@@ -70,13 +70,13 @@ class ConnectionManager {
user,
since,
(subId, notification) => this.notificationReceived(subId, notification),
(subId, state) => this.stateChanged(subId, state)
(subId, state) => this.stateChanged(subId, state),
);
this.connections.set(connectionId, connection);
console.log(
`[ConnectionManager] Starting new connection ${connectionId} (subscription ${subscriptionId} with user ${
user ? user.username : "anonymous"
})`
})`,
);
connection.start();
}
+1 -1
View File
@@ -30,7 +30,7 @@ class Notifier {
topicRoute: new URL(routes.forSubscription(subscription), window.location.origin).toString(),
baseUrl: subscription.baseUrl,
topic: subscription.topic,
})
}),
);
}
+2 -2
View File
@@ -35,7 +35,7 @@ class Poller {
} catch (e) {
console.log(`[Poller] Error polling ${s.id}`, e);
}
})
}),
);
}
@@ -61,7 +61,7 @@ class Poller {
if (deletedSequenceIds.length > 0) {
console.log(`[Poller] Deleting notifications with deleted sequence IDs for ${subscription.id}`, deletedSequenceIds);
await Promise.all(
deletedSequenceIds.map((sequenceId) => subscriptionManager.deleteNotificationBySequenceId(subscription.id, sequenceId))
deletedSequenceIds.map((sequenceId) => subscriptionManager.deleteNotificationBySequenceId(subscription.id, sequenceId)),
);
}
+4 -4
View File
@@ -18,7 +18,7 @@ export class SubscriptionManager {
subscriptions.map(async (s) => ({
...s,
new: await this.db.notifications.where({ subscriptionId: s.id, new: 1 }).count(),
}))
})),
);
}
@@ -122,7 +122,7 @@ export class SubscriptionManager {
});
return local.id;
})
}),
);
// Remove local subscriptions that do not exist remotely
@@ -134,7 +134,7 @@ export class SubscriptionManager {
if (!local.internal && !remoteExists) {
await this.remove(local);
}
})
}),
);
}
@@ -144,7 +144,7 @@ export class SubscriptionManager {
if (!browserSubscription) {
console.log(
"[SubscriptionManager] No browser subscription currently exists, so web push was never enabled or the notification permission was removed. Skipping."
"[SubscriptionManager] No browser subscription currently exists, so web push was never enabled or the notification permission was removed. Skipping.",
);
return;
}
+3 -3
View File
@@ -56,7 +56,7 @@ describe("throwAppError", () => {
await expect(throwAppError(fakeResponse(409, { code: UserExistsError.CODE }))).rejects.toBeInstanceOf(UserExistsError);
await expect(throwAppError(fakeResponse(409, { code: TopicReservedError.CODE }))).rejects.toBeInstanceOf(TopicReservedError);
await expect(throwAppError(fakeResponse(429, { code: AccountActionLimitReachedError.CODE }))).rejects.toBeInstanceOf(
AccountActionLimitReachedError
AccountActionLimitReachedError,
);
});
@@ -78,7 +78,7 @@ describe("fetchOrThrow", () => {
const response = { status: 200 };
vi.stubGlobal(
"fetch",
vi.fn(async () => response)
vi.fn(async () => response),
);
await expect(fetchOrThrow("https://ntfy.sh/mytopic/json")).resolves.toBe(response);
});
@@ -86,7 +86,7 @@ describe("fetchOrThrow", () => {
it("throws on a non-200 response", async () => {
vi.stubGlobal(
"fetch",
vi.fn(async () => fakeResponse(401))
vi.fn(async () => fakeResponse(401)),
);
await expect(fetchOrThrow("https://ntfy.sh/mytopic/json")).rejects.toBeInstanceOf(UnauthorizedError);
});
+1 -1
View File
@@ -130,7 +130,7 @@ const Layout = () => {
const [selected] = (subscriptionsWithoutInternal || []).filter(
(s) =>
(params.baseUrl && expandUrl(params.baseUrl).includes(s.baseUrl) && params.topic === s.topic) ||
(config.base_url === s.baseUrl && params.topic === s.topic)
(config.base_url === s.baseUrl && params.topic === s.topic),
);
useConnectionListeners(account, subscriptions, users, webPushTopics);
+3 -3
View File
@@ -80,7 +80,7 @@ const SingleSubscriptionList = (props) => {
// getAllNotifications() filtered by id), so topic switches are instant.
const notifications = useMemo(
() => allNotifications.filter((notification) => notification.subscriptionId === subscription.id),
[allNotifications, subscription.id]
[allNotifications, subscription.id],
);
if (notifications.length === 0) {
return <NoNotifications subscription={subscription} />;
@@ -104,7 +104,7 @@ const NotificationList = (props) => {
main.scrollTo(0, 0);
}
},
[props.id]
[props.id],
);
return (
@@ -319,7 +319,7 @@ const Attachment = (props) => {
infos.push(
t("notifications_attachment_link_expires", {
date: formatDateTime(attachment.expires, dateFormat, timeFormat),
})
}),
);
}
if (expired) {
+4 -4
View File
@@ -168,7 +168,7 @@ const PublishDialog = (props) => {
loaded: formatBytes(ev.loaded),
total: formatBytes(ev.total),
percent: Math.round((ev.loaded * 100.0) / ev.total),
})
}),
);
} else {
setStatus(t("publish_dialog_progress_uploading"));
@@ -201,19 +201,19 @@ const PublishDialog = (props) => {
t("publish_dialog_attachment_limits_file_and_quota_reached", {
fileSizeLimit: formatBytes(fileSizeLimit),
remainingBytes: formatBytes(remainingBytes),
})
}),
);
} else if (fileSizeLimitReached) {
setAttachFileError(
t("publish_dialog_attachment_limits_file_reached", {
fileSizeLimit: formatBytes(fileSizeLimit),
})
}),
);
} else if (quotaReached) {
setAttachFileError(
t("publish_dialog_attachment_limits_quota_reached", {
remainingBytes: formatBytes(remainingBytes),
})
}),
);
} else {
setAttachFileError("");
+2 -2
View File
@@ -93,7 +93,7 @@ const SubscribePage = (props) => {
const { topic } = props;
const existingTopicUrls = props.subscriptions.map((s) => topicUrl(s.baseUrl, s.topic));
const existingBaseUrls = Array.from(new Set([publicBaseUrl, ...props.subscriptions.map((s) => s.baseUrl)])).filter(
(s) => s !== config.base_url
(s) => s !== config.base_url,
);
const showReserveTopicCheckbox = config.enable_reservations && !anotherServerVisible && (config.enable_payments || account);
const reserveTopicEnabled =
@@ -113,7 +113,7 @@ const SubscribePage = (props) => {
setError(
t("subscribe_dialog_error_user_not_authorized", {
username,
})
}),
);
return;
}
+2 -2
View File
@@ -120,14 +120,14 @@ export const SubscriptionPopup = (props) => {
`Hello friend, this is a test notification from ntfy web. It's ${formatDateTime(
nowSeconds,
dateFormat,
timeFormat
timeFormat,
)} right now. Is that early or late?`,
`So I heard you like ntfy? If that's true, go to GitHub and star it, or to the Play store and rate it. Thanks! Oh yeah, this is a test notification.`,
`It's almost like you want to hear what I have to say. I'm not even a machine. I'm just a sentence that Phil typed on a random Thursday.`,
`Alright then, it's ${formatDateTime(
nowSeconds,
dateFormat,
timeFormat
timeFormat,
)} already. Boy oh boy, where did the time go? I hope you're alright, friend.`,
`There are nine million bicycles in Beijing That's a fact; It's a thing we can't deny. I wonder if that's true ...`,
`I'm really excited that you're trying out ntfy. Did you know that there are a few public topics, such as ntfy.sh/stats and ntfy.sh/announcements.`,
+3 -3
View File
@@ -30,7 +30,7 @@ export const useConnectionListeners = (account, subscriptions, users, webPushTop
// wsSubscriptions should stay stable unless the list of subscription IDs changes. Without the memo, the connection
// listener calls a refresh for no reason. This isn't a problem due to the makeConnectionId, but it triggers an
// unnecessary recomputation for every received message.
[JSON.stringify({ subscriptions: subscriptions?.map(({ id }) => id), webPushTopics })]
[JSON.stringify({ subscriptions: subscriptions?.map(({ id }) => id), webPushTopics })],
);
// Register listeners for incoming messages, and connection state changes
@@ -103,7 +103,7 @@ export const useConnectionListeners = (account, subscriptions, users, webPushTop
},
// We have to disable dep checking for "navigate". This is fine, it never changes.
[]
[],
);
// Sync topic listener: For accounts with sync_topic, subscribe to an internal topic
@@ -233,7 +233,7 @@ export const useWebPushTopics = () => {
const topics = useLiveQuery(
async () => subscriptionManager.webPushTopics(pushPossible),
// invalidate (reload) query when these values change
[pushPossible]
[pushPossible],
);
useWebPushListener(topics);
+1 -1
View File
@@ -39,7 +39,7 @@ export default defineConfig(({ mode }) => ({
...entry,
url: "app.html",
}
: entry
: entry,
),
}),
],