Compare commits

...

848 Commits

Author SHA1 Message Date
Athou
f195eb6d0d release 7.0.0 2026-02-21 22:26:40 +01:00
renovate[bot]
2aeadc8f67 chore(deps): update dependency org.apache.maven.plugins:maven-surefire-plugin to v3.5.5 2026-02-21 17:05:08 +00:00
renovate[bot]
ee3eaa1166 chore(deps): update dependency org.apache.maven.plugins:maven-failsafe-plugin to v3.5.5 2026-02-21 12:54:17 +00:00
Athou
5dce143756 rename thunk for consistency 2026-02-20 17:24:31 +01:00
Athou
33a0568895 delay task so that it doesn't run at the same time at OrphanedContentsCleanupTask 2026-02-20 15:55:09 +01:00
Athou
721d728906 prevent SSRF by blocking redirects from public websites to local addresses 2026-02-20 15:07:11 +01:00
Athou
c55cbaf373 add missing translations 2026-02-20 15:05:35 +01:00
Athou
3fd5cfdecd add a setting to mark entries of a feed as read after a number of days (#2041) 2026-02-20 13:24:40 +01:00
Jérémie Panzer
f87d3359c2 Merge pull request #2054 from canoine/patch-10
Update fr/messages.po
2026-02-20 10:12:49 +01:00
canoine
37f27849bd Update fr/messages.po
Not sure for the "Topic" translation...
2026-02-20 09:48:29 +01:00
Athou
6fe326f052 cleanup 2026-02-19 23:21:09 +01:00
Athou
de7e4e9c69 add a button for testing push notification settings 2026-02-19 22:50:34 +01:00
Athou
6861fe303b add a small description for push notifications 2026-02-19 18:01:52 +01:00
Athou
ba3214bf10 remove the possibility to receive notifications when subscribing because that sends a lot of notifications, one for each entry in the feed 2026-02-19 16:08:54 +01:00
Athou
bcce77495a bump dependencies 2026-02-19 14:49:18 +01:00
Athou
a165d2b27e Merge remote-tracking branch 'origin/renovate/patch-quarkus.version' 2026-02-18 21:02:48 +01:00
renovate[bot]
e63714cab0 chore(deps): update dependency @biomejs/biome to ^2.4.0 2026-02-18 21:02:32 +01:00
renovate[bot]
390c21dd91 fix(deps): update quarkus.version to v3.31.4 2026-02-18 19:55:53 +00:00
Jérémie Panzer
9defea9c8e Merge pull request #2052 from Athou/renovate/biomejs-biome-2.x
chore(deps): update dependency @biomejs/biome to v2.4.0
2026-02-18 20:54:35 +01:00
Athou
5906173de7 Merge branch 'lpoirothattermann-master' 2026-02-18 20:53:50 +01:00
Athou
a81de48cfb change the default value of blockLocalAddresses 2026-02-18 20:53:23 +01:00
Athou
2be61e8b1c refactor 2026-02-18 20:37:11 +01:00
renovate[bot]
4d7fc9f354 chore(deps): update dependency @biomejs/biome to v2.4.0 2026-02-18 17:35:31 +00:00
renovate[bot]
e11fd7b3a1 chore(deps): update dependency jsdom to ^28.1.0 2026-02-18 04:37:15 +00:00
renovate[bot]
cc0348b113 chore(deps): update ibm-semeru-runtimes:open-jdk-25.0.2_10-jre docker digest to b02e4cd 2026-02-18 01:48:45 +00:00
Athou
77bb948bf2 remove unnecessary divider 2026-02-17 20:34:24 +01:00
Athou
8e2adcbce4 fix wrong merge conflict resolve 2026-02-17 20:34:06 +01:00
Athou
bb141203a8 fix missing translations 2026-02-17 20:33:59 +01:00
Jérémie Panzer
579c22df65 Merge pull request #2049 from canoine/patch-9
Update fr/messages.po
2026-02-16 21:34:53 +01:00
canoine
694e8291de Update fr/messages.po
New filtering entries translated.
2026-02-16 18:26:03 +01:00
renovate[bot]
367259fd31 chore(deps): lock file maintenance 2026-02-16 02:10:12 +00:00
Louis POIROT--HATTERMANN
e54151d2eb feat: send notification for new entries with Gotify, ntfy or Pushover, configurable per feed. 2026-02-15 18:45:28 +01:00
Jérémie Panzer
ca2c687f26 Merge pull request #2044 from Athou/renovate/npm-11.x
chore(deps): update dependency npm to v11.10.0
2026-02-15 16:20:37 +01:00
Athou
d444a7080d migrate filtering expressions to safer CEL and add a query builder 2026-02-15 16:13:10 +01:00
renovate[bot]
08bfcded7f chore(deps): update dependency @biomejs/biome to v2.3.15 2026-02-15 12:35:42 +00:00
renovate[bot]
1c9e4f978b chore(deps): update dependency vite-tsconfig-paths to ^6.1.1 2026-02-15 01:06:08 +00:00
renovate[bot]
a5f1fba6ee chore(deps): update dependency npm to v11.10.0 2026-02-14 17:37:17 +00:00
renovate[bot]
88f1cf1913 chore(deps): update dependency @types/react to ^19.2.14 2026-02-14 13:35:26 +00:00
renovate[bot]
1fb69d2861 fix(deps): update linguijs monorepo to ^5.9.1 2026-02-14 10:09:00 +00:00
renovate[bot]
3aeff66522 chore(deps): update dependency @vitejs/plugin-react to ^5.1.4 2026-02-13 09:48:06 +00:00
renovate[bot]
114cbe0ec5 chore(deps): update docker/build-push-action digest to 10e90e3 2026-02-12 17:55:15 +00:00
renovate[bot]
bfe94222b7 fix(deps): update quarkus.version to v3.31.3 2026-02-11 21:00:14 +00:00
renovate[bot]
30061abc54 chore(deps): update docker/build-push-action digest to 601a80b 2026-02-11 18:48:17 +00:00
renovate[bot]
126e07489b fix(deps): update dependency axios to ^1.13.5 2026-02-11 13:48:03 +00:00
renovate[bot]
bd2577c089 chore(deps): update docker/build-push-action digest to ee4ca42 2026-02-11 13:15:00 +00:00
renovate[bot]
5039c61e98 chore(deps): update node.js to v24.13.1 2026-02-10 20:28:00 +00:00
renovate[bot]
5f34ab3d7e chore(deps): update dependency vite-tsconfig-paths to ^6.1.0 2026-02-10 17:49:55 +00:00
Athou
fee47427cf verify i18n extraction has been run before committing 2026-02-10 11:32:24 +01:00
renovate[bot]
15c8289a01 chore(deps): update ibm-semeru-runtimes docker tag to open-jdk-25.0.2_10-jre 2026-02-10 00:25:53 +00:00
Athou
141a863079 release 6.2.0 2026-02-09 19:32:22 +01:00
Athou
6fa8d4be34 keep starred entries (#1581) 2026-02-09 06:59:41 +01:00
renovate[bot]
984e8a44d5 chore(deps): lock file maintenance 2026-02-09 01:33:44 +00:00
renovate[bot]
bdb296bce2 chore(deps): update dependency @types/react to ^19.2.13 2026-02-08 14:02:01 +00:00
Jérémie Panzer
955a9084c3 Merge pull request #2042 from Athou/renovate/npm-11.x
chore(deps): update dependency npm to v11.9.0
2026-02-08 05:23:05 +01:00
renovate[bot]
70f486b0eb chore(deps): update dependency npm to v11.9.0 2026-02-07 21:45:56 +00:00
renovate[bot]
0bc383c6a8 chore(deps): update dependency @types/react to ^19.2.11 2026-02-07 13:12:20 +00:00
renovate[bot]
0bb2b36585 chore(deps): update dependency @biomejs/biome to v2.3.14 2026-02-06 16:48:35 +00:00
Jérémie Panzer
9e3a24753a Merge pull request #2040 from Athou/renovate/com.puppycrawl.tools-checkstyle-13.x
chore(deps): update dependency com.puppycrawl.tools:checkstyle to v13.2.0
2026-02-06 02:20:48 +01:00
renovate[bot]
f2c400799e chore(deps): update dependency com.puppycrawl.tools:checkstyle to v13.2.0 2026-02-05 21:38:36 +00:00
renovate[bot]
25a8c8a7e3 chore(deps): update dependency @vitejs/plugin-react to ^5.1.3 2026-02-05 10:32:18 +00:00
Jérémie Panzer
8f95d89fc6 Merge pull request #2039 from Athou/renovate/jsdom-28.x
chore(deps): update dependency jsdom to v28
2026-02-05 11:30:07 +01:00
renovate[bot]
39b0cdb9d5 chore(deps): update dependency jsdom to v28 2026-02-05 09:42:39 +00:00
renovate[bot]
42e06b848e fix(deps): update quarkus.version to v3.31.2 2026-02-04 17:56:35 +00:00
renovate[bot]
7c3a13b1c4 fix(deps): update mantine monorepo to ^8.3.14 2026-02-04 12:45:49 +00:00
Jérémie Panzer
151248fce2 Merge pull request #2038 from xmgz/master
Update gl messages.po
2026-02-04 07:13:01 +01:00
ghose
6e8d6fe063 Update gl messages.po
up to date gl translation
2026-02-04 04:09:30 +00:00
renovate[bot]
ca2da5e631 chore(deps): update actions/checkout digest to de0fac2 2026-02-03 16:36:24 +00:00
renovate[bot]
6cd3b70201 chore(deps): update debian:13.3 docker digest to 2c91e48 2026-02-03 14:08:51 +00:00
renovate[bot]
2dcfba75b5 chore(deps): update jaywcjlove/markdown-to-html-cli action to v5.0.4 2026-02-03 09:32:58 +00:00
Jérémie Panzer
44a51b03d3 Merge pull request #2037 from Athou/renovate/org.apache.maven.plugins-maven-compiler-plugin-3.x
chore(deps): update dependency org.apache.maven.plugins:maven-compiler-plugin to v3.15.0
2026-02-02 06:14:39 +01:00
renovate[bot]
6ee9e9831e chore(deps): lock file maintenance 2026-02-02 01:56:05 +00:00
renovate[bot]
68c717cee8 chore(deps): update dependency org.apache.maven.plugins:maven-compiler-plugin to v3.15.0 2026-02-01 21:36:26 +00:00
Jérémie Panzer
b15fc02c34 Merge pull request #2035 from Athou/renovate/com.puppycrawl.tools-checkstyle-13.x
chore(deps): update dependency com.puppycrawl.tools:checkstyle to v13.1.0
2026-02-01 07:38:58 +01:00
renovate[bot]
033ebfb497 chore(deps): update dependency com.puppycrawl.tools:checkstyle to v13.1.0 2026-01-31 20:23:47 +00:00
renovate[bot]
4cceaa7650 fix(deps): update dependency axios to ^1.13.4 2026-01-30 21:51:52 +00:00
renovate[bot]
5df47f1396 chore(deps): update dependency @types/react to ^19.2.10 2026-01-30 12:33:18 +00:00
renovate[bot]
903f35c01b fix(deps): update react monorepo to ^19.2.4 2026-01-29 20:53:17 +00:00
renovate[bot]
6a34f94277 chore(deps): update dependency @biomejs/biome to v2.3.13 2026-01-29 17:09:33 +00:00
Athou
dcc143eb7d upgrade to quarkus 3.31 2026-01-28 18:04:16 +01:00
renovate[bot]
fb47bf27e8 fix(deps): update dependency axios to ^1.13.3 2026-01-28 16:39:42 +00:00
renovate[bot]
dcf969ff2e chore(deps): update docker/login-action digest to c94ce9f 2026-01-28 13:35:35 +00:00
renovate[bot]
32c1318355 chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v3.2.1 2026-01-27 22:36:42 +00:00
Jérémie Panzer
8ca6b89da4 Merge pull request #2033 from Athou/renovate/patch-react-router-monorepo
fix(deps): update dependency react-router-dom to ^7.13.0
2026-01-27 07:21:39 +01:00
renovate[bot]
b46c3a15f3 fix(deps): update dependency react-router-dom to ^7.13.0 2026-01-27 04:49:15 +00:00
renovate[bot]
cbc5e014f7 chore(deps): update dependency vite-tsconfig-paths to ^6.0.5 (#2032)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-27 04:48:45 +00:00
renovate[bot]
8925b248e4 fix(deps): update linguijs monorepo to ^5.9.0 2026-01-26 22:16:14 +00:00
renovate[bot]
cc6aa2bbc5 chore(deps): update dependency @biomejs/biome to v2.3.12 2026-01-26 17:45:44 +00:00
Athou
1989aaf8b4 release 6.1.1 2026-01-26 15:47:39 +01:00
Athou
c90c91b748 fix old starred entries not loading if they were marked as read (#2031) 2026-01-26 15:45:50 +01:00
Athou
bca23db213 remvoe unused jacoco plugin 2026-01-26 13:39:50 +01:00
renovate[bot]
c9a92d2043 chore(deps): lock file maintenance 2026-01-26 05:00:06 +00:00
renovate[bot]
c48e06fa46 fix(deps): update dependency io.dropwizard.metrics:metrics-json to v4.2.38 2026-01-26 02:10:23 +00:00
renovate[bot]
5529eced91 chore(deps): update dependency vitest to ^4.0.18 2026-01-25 20:53:59 +00:00
Athou
2a0d935471 release 6.1.0 2026-01-25 10:58:32 +01:00
Athou
6c68fda572 make "disable pull to refresh" false by default (#2030) 2026-01-25 10:49:11 +01:00
Jérémie Panzer
861c1fc3dc Merge pull request #2029 from Athou/renovate/npm-11.x
chore(deps): update dependency npm to v11.8.0
2026-01-25 05:04:32 +01:00
renovate[bot]
5971bb4255 chore(deps): update dependency npm to v11.8.0 2026-01-25 01:59:43 +00:00
renovate[bot]
76ba360631 chore(deps): update dependency @types/react to ^19.2.9 2026-01-23 19:59:17 +00:00
renovate[bot]
89d3ff3c90 fix(deps): update quarkus.version to v3.30.8 2026-01-23 12:23:43 +00:00
renovate[bot]
34024a913d fix(deps): update mantine monorepo to ^8.3.13 2026-01-23 10:50:58 +00:00
Athou
a858380121 cleanup 2026-01-23 08:34:10 +01:00
Jérémie Panzer
e1dc870005 Merge pull request #2028 from Athou/renovate/com.diffplug.spotless-spotless-maven-plugin-3.x
chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v3.2.0
2026-01-23 02:04:25 +01:00
renovate[bot]
2fc1cac869 chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v3.2.0 2026-01-23 00:39:57 +00:00
renovate[bot]
f627ff4958 chore(deps): update dependency @testing-library/react to ^16.3.2 2026-01-22 13:07:35 +00:00
renovate[bot]
5ff8e51948 chore(deps): update dependency io.quarkiverse.playwright:quarkus-playwright to v2.3.2 2026-01-21 22:06:21 +00:00
renovate[bot]
538f25c6bb fix(deps): update quarkus.version to v3.30.7 2026-01-21 15:56:51 +00:00
Jérémie Panzer
65100ba279 Merge pull request #2026 from WangLei1993/master
add Chinese translation for new entry
2026-01-20 20:55:40 +01:00
WangLei1993
79fd470bbf add Chinese translation for new entry 2026-01-21 01:32:16 +08:00
Jérémie Panzer
866d74665b Merge pull request #2025 from canoine/patch-8
Update fr/messages.po
2026-01-20 14:13:04 +01:00
canoine
29da74f038 Update fr/messages.po
New etries translated
2026-01-20 13:56:59 +01:00
Athou
3c8ac35a46 make password match rule reusable 2026-01-20 08:54:48 +01:00
Athou
afe957ba59 create a dedicated password reset page (#2023) 2026-01-19 20:55:26 +01:00
renovate[bot]
7e50e99351 fix(deps): update linguijs monorepo to ^5.8.0 2026-01-19 10:48:25 +00:00
renovate[bot]
62ce462cc8 chore(deps): lock file maintenance 2026-01-19 03:48:36 +00:00
Jérémie Panzer
108cb06f43 Merge pull request #2024 from Athou/renovate/org.codehaus.mojo-properties-maven-plugin-1.x
chore(deps): update dependency org.codehaus.mojo:properties-maven-plugin to v1.3.0
2026-01-19 04:47:18 +01:00
renovate[bot]
95a38675bc chore(deps): update dependency org.codehaus.mojo:properties-maven-plugin to v1.3.0 2026-01-19 00:35:24 +00:00
Athou
714681bc50 don't set "en" as the default language, use the preferred language of the browser (#2018) 2026-01-17 20:09:23 +01:00
Athou
0f8d91d997 close profile menu on scroll (#2019) 2026-01-16 15:53:40 +01:00
Jérémie Panzer
562297a82f Merge pull request #2022 from WangLei1993/master
add Chinese translation for new entry
2026-01-16 15:40:53 +01:00
WangLei1993
b108bf06e5 add Chinese translation for new entry 2026-01-16 22:21:00 +08:00
renovate[bot]
3c819066fd chore(deps): update ibm-semeru-runtimes:open-jdk-25.0.1_8-jre docker digest to e12d5f2 2026-01-16 02:15:00 +00:00
Athou
5f30cb7e2e reuse validation rule 2026-01-16 01:08:25 +01:00
Athou
5a95b95801 validate password in the frontend too (#2017) 2026-01-15 21:36:00 +01:00
renovate[bot]
eb573fdc8b chore(deps): update dependency vitest to ^4.0.17 2026-01-15 14:58:31 +00:00
Jérémie Panzer
238ea54e98 Merge pull request #2020 from canoine/patch-7
Update fr/messages.po
2026-01-15 08:56:05 +01:00
canoine
e4dfc47fb8 Update fr/messages.po
Translation of the new entries.
2026-01-15 07:28:50 +01:00
Jérémie Panzer
a1491c779a Merge pull request #2015 from WangLei1993/master
add Chinese translation for new entry
2026-01-14 20:08:02 +01:00
WangLei1993
dabd7552be add Chinese translation for new entry 2026-01-15 01:06:19 +08:00
Jérémie Panzer
0a4c56af1f Merge pull request #2014 from Athou/renovate/node-24.x
chore(deps): update node.js to v24.13.0
2026-01-13 19:44:55 +01:00
renovate[bot]
c3dae5b92c chore(deps): update node.js to v24.13.0 2026-01-13 14:11:32 +00:00
renovate[bot]
2c3105b526 chore(deps): update debian:13.3 docker digest to 5cf544f 2026-01-13 14:11:28 +00:00
renovate[bot]
20f5081ac8 chore(deps): update dependency @types/react to ^19.2.8 2026-01-13 10:49:24 +00:00
Jérémie Panzer
3091eb9d14 Merge pull request #2013 from Athou/renovate/debian-13.x
chore(deps): update debian docker tag to v13.3
2026-01-13 06:52:42 +01:00
renovate[bot]
5bdda42239 chore(deps): update debian docker tag to v13.3 2026-01-13 04:51:00 +00:00
renovate[bot]
7eda8b7662 chore(deps): update dependency vite-tsconfig-paths to ^6.0.4 2026-01-13 02:08:08 +00:00
renovate[bot]
fc94ce5d2b fix(deps): update mantine monorepo to ^8.3.12 2026-01-12 14:23:32 +00:00
renovate[bot]
e5d7161ab7 chore(deps): lock file maintenance 2026-01-12 01:10:34 +00:00
Jérémie Panzer
f725cb7fa4 Merge pull request #2012 from Athou/renovate/react-router-monorepo
fix(deps): update dependency react-router-dom to ^7.12.0
2026-01-10 21:35:47 +01:00
renovate[bot]
830e689fe8 fix(deps): update dependency react-router-dom to ^7.12.0 2026-01-10 20:02:47 +00:00
Athou
2832e8c638 release 6.0.0 2026-01-10 21:01:59 +01:00
Athou
d711cbab49 requiring an email address for users is now configurable (#1914) 2026-01-10 18:11:35 +01:00
Athou
2e8fd737af remove complex password requirements (#1916) 2026-01-10 17:53:48 +01:00
Athou
a080ede15b add a setup landing page instead of creating a default admin account 2026-01-10 17:30:22 +01:00
renovate[bot]
ab3d41508f chore(deps): update dependency vite to ^7.3.1 2026-01-10 08:41:14 +00:00
Jérémie Panzer
1ab4a5e925 Merge pull request #2010 from Athou/renovate/com.ibm.icu-icu4j-78.x
fix(deps): update dependency com.ibm.icu:icu4j to v78.2
2026-01-09 05:03:28 +01:00
renovate[bot]
543ce08be6 fix(deps): update dependency com.ibm.icu:icu4j to v78.2 2026-01-08 21:59:38 +00:00
renovate[bot]
21829056ba fix(deps): update mantine monorepo to ^8.3.11 2026-01-08 05:55:36 +00:00
renovate[bot]
1af59c87d0 fix(deps): update quarkus.version to v3.30.6 2026-01-07 18:36:59 +00:00
Athou
799e6c082c cleanup 2026-01-06 22:53:37 +01:00
renovate[bot]
09635cf0fd chore(deps): update dependency @biomejs/biome to v2.3.11 2026-01-06 18:14:17 +00:00
renovate[bot]
1dfbd30471 chore(deps): update graalvm/setup-graalvm digest to 54b4f5a 2026-01-05 20:54:23 +00:00
renovate[bot]
48e0a77d1f chore(deps): lock file maintenance 2026-01-05 08:03:28 +00:00
Jérémie Panzer
7ae8594c00 Merge pull request #2009 from Athou/renovate/com.puppycrawl.tools-checkstyle-13.x
chore(deps): update dependency com.puppycrawl.tools:checkstyle to v13
2026-01-05 09:02:06 +01:00
Athou
19663b0f38 Java 25+ is now required 2026-01-05 07:25:26 +01:00
renovate[bot]
4bcb9adb83 chore(deps): update dependency com.puppycrawl.tools:checkstyle to v13 2026-01-05 01:41:55 +00:00
Athou
f7505298d7 postgresql 18+ changed the docker mount point (#2008) 2026-01-03 10:26:59 +01:00
Athou
df722ffa8b fix typo (#2007) 2026-01-02 22:00:36 +01:00
renovate[bot]
2a852fe08d fix(deps): update dependency io.github.hakky54:ayza-for-apache5 to v10.0.3 2026-01-02 09:36:08 +00:00
Jérémie Panzer
540f796200 Merge pull request #2006 from Athou/renovate/org.jsoup-jsoup-1.x
fix(deps): update dependency org.jsoup:jsoup to v1.22.1
2026-01-01 08:42:47 +01:00
renovate[bot]
b726ac84fe fix(deps): update dependency org.jsoup:jsoup to v1.22.1 2026-01-01 07:02:22 +00:00
renovate[bot]
61ac2bb6a3 chore(deps): update dependency com.puppycrawl.tools:checkstyle to v12.3.1 2025-12-31 16:00:34 +00:00
Athou
5d702b3992 release 5.12.1 2025-12-31 08:51:22 +01:00
Athou
3bf4a004d4 ReadKit sends the md5 hash of the password in uppercase (#1602) 2025-12-30 20:22:41 +01:00
renovate[bot]
7ac5876d2d chore(deps): update debian:13.2 docker digest to c71b05e 2025-12-30 08:26:00 +00:00
renovate[bot]
0f18c612af chore(deps): update dependency jsdom to ^27.4.0 2025-12-29 14:33:16 +00:00
renovate[bot]
03f4a3c478 chore(deps): lock file maintenance 2025-12-29 01:32:07 +00:00
Jérémie Panzer
7069343cf4 Merge pull request #2005 from xmgz/master
Update po.gl
2025-12-27 17:13:41 +01:00
ghose
7fae79f2c5 Update po.gl
new strings and minor fixes
2025-12-27 15:48:49 +00:00
Jérémie Panzer
66b714ed39 Merge pull request #2004 from aniol/patch-4
Update messages.po
2025-12-25 09:35:36 +01:00
Aniol
d371ebe354 Update messages.po 2025-12-25 09:14:10 +01:00
renovate[bot]
9093d0d5e5 fix(deps): update quarkus.version to v3.30.5 2025-12-24 14:26:55 +00:00
Athou
1139df0637 use existing constants 2025-12-24 07:02:01 +01:00
Athou
c1810de316 use a brotli decoder that uses java and not native code 2025-12-23 17:01:19 +01:00
Athou
863ced57f8 specify explicitly what encoders we support, don't rely on httpclient5 autodetection 2025-12-23 16:21:10 +01:00
Athou
2147aeb4ae some client seems to send an empty since_id param 2025-12-23 11:16:07 +01:00
Athou
a810b4fc9a add a test for brotli decompression 2025-12-23 08:53:18 +01:00
Athou
abcbb61b4c make quarkus add brotli4j to the native image 2025-12-23 08:07:46 +01:00
Athou
83332223ef httpclient now uses brotli4j 2025-12-23 08:04:53 +01:00
renovate[bot]
fd8d981ea0 chore(deps): lock file maintenance 2025-12-22 00:50:14 +00:00
renovate[bot]
03e3ade09d chore(deps): update dependency org.codehaus.mojo:exec-maven-plugin to v3.6.3 2025-12-21 22:07:09 +00:00
renovate[bot]
68305f2e00 chore(deps): update dependency vite-tsconfig-paths to ^6.0.3 2025-12-21 14:30:18 +00:00
Jérémie Panzer
b7d6b06242 Merge pull request #2003 from canoine/patch-6
Update fr/messages.po
2025-12-21 09:08:02 +01:00
canoine
9098050c5a Update fr/messages.po
New entries translated
2025-12-21 07:24:01 +01:00
Jérémie Panzer
0147ec0a6a Merge pull request #2000 from Athou/renovate/org.apache.httpcomponents.client5-httpclient5-5.x
fix(deps): update dependency org.apache.httpcomponents.client5:httpclient5 to v5.6
2025-12-20 22:26:40 +01:00
Jérémie Panzer
c6b71605d0 Merge pull request #2002 from Athou/renovate/react-router-monorepo
fix(deps): update dependency react-router-dom to ^7.11.0
2025-12-20 22:05:01 +01:00
Jérémie Panzer
64009c82e9 Merge pull request #2001 from WangLei1993/master
add Chinese translation for new entry
2025-12-20 22:03:51 +01:00
renovate[bot]
5b24cb370f fix(deps): update dependency react-router-dom to ^7.11.0 2025-12-20 18:08:18 +00:00
renovate[bot]
2d261cd97b chore(deps): update dependency @biomejs/biome to ^2.3.10 2025-12-20 18:08:10 +00:00
WangLei1993
9455d91b3d add Chinese translation for new entry 2025-12-20 21:32:08 +08:00
renovate[bot]
cb645c56b4 fix(deps): update dependency org.apache.httpcomponents.client5:httpclient5 to v5.6 2025-12-20 12:47:34 +00:00
renovate[bot]
1a6b91dee5 chore(deps): update dependency vite-tsconfig-paths to ^6.0.2 2025-12-20 07:40:42 +00:00
Jérémie Panzer
8d2edad488 Merge pull request #1999 from Athou/renovate/com.github.eirslett-frontend-maven-plugin-2.x
chore(deps): update dependency com.github.eirslett:frontend-maven-plugin to v2
2025-12-20 08:39:50 +01:00
renovate[bot]
522e26b1fa chore(deps): update dependency com.github.eirslett:frontend-maven-plugin to v2 2025-12-19 22:06:14 +00:00
renovate[bot]
259b22c255 fix(deps): update dependency org.apache.httpcomponents.client5:httpclient5 to v5.5.2 2025-12-19 22:06:11 +00:00
renovate[bot]
b61cf82b46 chore(deps): update dependency vitest to ^4.0.16 2025-12-19 15:47:32 +00:00
renovate[bot]
4f06f7424c chore(deps): update docker/setup-buildx-action digest to 8d2750c 2025-12-19 14:33:40 +00:00
Athou
d2d65437f8 add a description to indicate that scrolling issues can occur with this setting (closes #1998) 2025-12-19 07:47:22 +01:00
renovate[bot]
3ae0f7558e chore(deps): update dependency @biomejs/biome to v2.3.9 2025-12-18 18:38:22 +00:00
renovate[bot]
604801686d chore(deps): update dependency @testing-library/react to ^16.3.1 2025-12-18 14:01:55 +00:00
Jérémie Panzer
554d4190ff Merge pull request #1997 from Athou/renovate/vite-7.x
chore(deps): update dependency vite to ^7.3.0
2025-12-18 11:25:17 +01:00
renovate[bot]
1d71390349 chore(deps): update dependency vite to ^7.3.0 2025-12-18 10:03:19 +00:00
Jérémie Panzer
fe24c6d682 Merge pull request #1996 from Athou/renovate/vite-tsconfig-paths-6.x
chore(deps): update dependency vite-tsconfig-paths to v6
2025-12-18 06:56:19 +01:00
renovate[bot]
4359d91a23 chore(deps): update dependency vite-tsconfig-paths to v6 2025-12-18 02:55:58 +00:00
renovate[bot]
ae42eac7fd fix(deps): update dependency @reduxjs/toolkit to ^2.11.2 2025-12-18 02:55:48 +00:00
renovate[bot]
37a8888a32 fix(deps): update quarkus.version to v3.30.4 2025-12-17 17:47:52 +00:00
renovate[bot]
2d7e065d39 chore(deps): update dependency io.quarkiverse.playwright:quarkus-playwright to v2.3.1 2025-12-17 14:02:45 +00:00
renovate[bot]
35cf640691 chore(deps): update dependency maven to v3.9.12 2025-12-17 00:14:05 +00:00
renovate[bot]
b308fbe0ad fix(deps): update linguijs monorepo to ^5.7.0 2025-12-15 18:05:24 +00:00
renovate[bot]
d5e2b51b6d chore(deps): lock file maintenance 2025-12-15 00:45:30 +00:00
renovate[bot]
9b7844542d fix(deps): update react monorepo to ^19.2.3 2025-12-15 00:10:13 +00:00
Jérémie Panzer
9f6fac0d58 Merge pull request #1994 from Athou/renovate/com.puppycrawl.tools-checkstyle-12.x
chore(deps): update dependency com.puppycrawl.tools:checkstyle to v12.3.0
2025-12-13 23:15:06 +01:00
renovate[bot]
f6011dc3f2 chore(deps): update dependency com.puppycrawl.tools:checkstyle to v12.3.0 2025-12-13 18:11:46 +00:00
Jérémie Panzer
fdb7fa21f6 Merge pull request #1993 from Athou/renovate/major-github-artifact-actions
chore(deps): update github artifact actions (major)
2025-12-13 00:00:15 +01:00
Jérémie Panzer
29bbe41e51 Merge pull request #1992 from Athou/renovate/npm-11.x
chore(deps): update dependency npm to v11.7.0
2025-12-12 23:47:40 +01:00
renovate[bot]
004ada8204 chore(deps): update github artifact actions 2025-12-12 22:26:38 +00:00
renovate[bot]
9a2894944c chore(deps): update dependency npm to v11.7.0 2025-12-12 22:26:33 +00:00
Athou
dfcff5029b add a section in the readme about the public instance 2025-12-12 14:23:24 +01:00
renovate[bot]
853fc600dd fix(deps): update mantine monorepo to ^8.3.10 2025-12-12 10:13:22 +00:00
Jérémie Panzer
a546b21755 Merge pull request #1991 from Athou/renovate/vite-plugin-checker-0.x
chore(deps): update dependency vite-plugin-checker to ^0.12.0
2025-12-11 22:12:22 +01:00
renovate[bot]
e40c4e3779 chore(deps): update dependency vite-plugin-checker to ^0.12.0 2025-12-11 18:31:01 +00:00
Jérémie Panzer
60cbf6cff3 Merge pull request #1990 from Athou/renovate/jsdom-27.x
chore(deps): update dependency jsdom to ^27.3.0
2025-12-11 19:29:50 +01:00
renovate[bot]
6d3f4b98d7 chore(deps): update dependency jsdom to ^27.3.0 2025-12-11 13:54:40 +00:00
renovate[bot]
4812a2b401 chore(deps): update dependency @vitejs/plugin-react to ^5.1.2 2025-12-11 13:54:34 +00:00
renovate[bot]
5f99376d58 fix(deps): update dependency @reduxjs/toolkit to ^2.11.1 2025-12-11 06:44:06 +00:00
renovate[bot]
3e76c142c3 chore(deps): update dependency vite to ^7.2.7 2025-12-11 03:42:05 +00:00
renovate[bot]
28f23a73af fix(deps): update quarkus.version to v3.30.3 2025-12-10 21:09:55 +00:00
Jérémie Panzer
68b94fed8e Merge pull request #1988 from Athou/renovate/node-24.x
chore(deps): update node.js to v24.12.0
2025-12-10 22:09:07 +01:00
renovate[bot]
657b02727c chore(deps): update node.js to v24.12.0 2025-12-10 19:34:28 +00:00
Jérémie Panzer
7d7a10073c Merge pull request #1986 from WangLei1993/master
add Chinese translation for new entry
2025-12-10 14:00:35 +01:00
WangLei1993
9d5f0c791c add Chinese translation for new entry 2025-12-10 18:03:29 +08:00
renovate[bot]
212493e4ff chore(deps): update debian:13.2 docker digest to 0d01188 2025-12-09 06:31:22 +00:00
renovate[bot]
9fc8e9c6d7 fix(deps): update dependency tss-react to ^4.9.20 2025-12-08 21:07:55 +00:00
Jérémie Panzer
f69ddb71a0 Merge pull request #1985 from Athou/renovate/io.quarkiverse.playwright-quarkus-playwright-2.x
chore(deps): update dependency io.quarkiverse.playwright:quarkus-playwright to v2.3.0
2025-12-08 22:07:18 +01:00
renovate[bot]
290beec0c5 chore(deps): update dependency io.quarkiverse.playwright:quarkus-playwright to v2.3.0 2025-12-08 19:23:38 +00:00
renovate[bot]
dcb2f6f8cd chore(deps): lock file maintenance (#1984)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-08 12:57:56 +00:00
renovate[bot]
d200845906 fix(deps): update dependency react-router-dom to ^7.10.1 2025-12-07 17:56:45 +00:00
renovate[bot]
a52e02695d fix(deps): update react monorepo to ^19.2.1 2025-12-06 17:05:09 +00:00
renovate[bot]
febd7c3063 fix(deps): update dependency react-router-dom to ^7.10.0 2025-12-05 20:52:10 +00:00
renovate[bot]
d5ae0b99f0 chore(deps): update dependency vitest to ^4.0.15 2025-12-05 16:42:10 +00:00
Athou
8b10c608fc add data-feed-id to articles (#1983) 2025-12-05 08:07:02 +01:00
renovate[bot]
0d49b91cc6 chore(deps): update dependency vite to ^7.2.6 2025-12-04 06:10:37 +00:00
renovate[bot]
2af4b83e09 fix(deps): update quarkus.version to v3.30.2 2025-12-03 18:20:55 +00:00
Jérémie Panzer
cde3ca3d9e Merge pull request #1982 from Athou/renovate/lock-file-maintenance
chore(deps): lock file maintenance
2025-12-03 19:18:23 +01:00
renovate[bot]
429798190a chore(deps): lock file maintenance 2025-12-03 17:52:25 +00:00
renovate[bot]
583db4c70f chore(deps): update dependency yaml to ^2.8.2 2025-12-03 09:41:05 +00:00
renovate[bot]
3ec35eec91 chore(deps): update actions/checkout digest to 8e8c483 2025-12-02 18:57:36 +00:00
Jérémie Panzer
65bfbfc7fd Merge pull request #1980 from Athou/renovate/graalvm-setup-graalvm-digest
chore(deps): update graalvm/setup-graalvm digest to 790e289
2025-12-02 15:27:11 +01:00
renovate[bot]
1b93701df2 chore(deps): update graalvm/setup-graalvm digest to 790e289 2025-12-02 13:45:00 +00:00
Athou
d6debc55f5 remove unused sonar config 2025-12-02 14:44:18 +01:00
renovate[bot]
87fd9ae686 chore(deps): update ibm-semeru-runtimes:open-jdk-25.0.1_8-jre docker digest to d88c854 2025-12-02 02:57:02 +00:00
renovate[bot]
3225a3b337 fix(deps): update linguijs monorepo to ^5.6.1 2025-12-01 13:02:27 +00:00
Jérémie Panzer
4eb98a6c31 Merge pull request #1979 from Athou/renovate/com.puppycrawl.tools-checkstyle-12.x
chore(deps): update dependency com.puppycrawl.tools:checkstyle to v12.2.0
2025-12-01 07:50:28 +01:00
renovate[bot]
38a6e2fc98 chore(deps): update dependency com.puppycrawl.tools:checkstyle to v12.2.0 2025-11-30 16:34:53 +00:00
renovate[bot]
c171cf1487 chore(deps): update dependency @biomejs/biome to ^2.3.8 2025-11-30 13:00:00 +00:00
Jérémie Panzer
b64a0f1d55 Merge pull request #1978 from mortenfyhn/svg-favicon
Add SVG favicon option
2025-11-29 16:19:17 +01:00
Morten Fyhn Amundsen
3ab124b2db Add SVG favicon option
The existing 16x16 pixel favicon looks a bit pixelated. This adds an SVG favicon option based on the existing SVG logo file but cropped tighter similar to the existing favicon. That makes it nice and crisp.
2025-11-29 15:08:54 +01:00
Jérémie Panzer
d710f3995f Merge pull request #1977 from Athou/renovate/org.apache.maven.plugins-maven-resources-plugin-3.x
chore(deps): update dependency org.apache.maven.plugins:maven-resources-plugin to v3.4.0
2025-11-29 06:07:29 +01:00
Jérémie Panzer
f53c209082 Merge pull request #1976 from Athou/renovate/org.apache.maven.plugins-maven-assembly-plugin-3.x
chore(deps): update dependency org.apache.maven.plugins:maven-assembly-plugin to v3.8.0
2025-11-29 06:07:07 +01:00
renovate[bot]
9997be3462 chore(deps): update dependency org.apache.maven.plugins:maven-resources-plugin to v3.4.0 2025-11-29 01:14:50 +00:00
renovate[bot]
c3b06e375c chore(deps): update dependency org.apache.maven.plugins:maven-assembly-plugin to v3.8.0 2025-11-29 01:14:46 +00:00
renovate[bot]
1476c5a932 chore(deps): update dependency vitest to ^4.0.14 2025-11-28 18:05:45 +00:00
renovate[bot]
8e1c9b9703 chore(deps): update dependency @biomejs/biome to v2.3.8 2025-11-27 13:47:14 +00:00
renovate[bot]
27c89f7cc7 chore(deps): update dependency @types/react to ^19.2.7 2025-11-27 10:58:30 +00:00
Jérémie Panzer
9210198766 Merge pull request #1973 from Athou/renovate/reduxjs-toolkit-2.x
fix(deps): update dependency @reduxjs/toolkit to ^2.11.0
2025-11-27 05:46:41 +01:00
renovate[bot]
ce6fa0bf8f fix(deps): update dependency @reduxjs/toolkit to ^2.11.0 2025-11-27 04:07:51 +00:00
Jérémie Panzer
cd6629b424 Merge pull request #1972 from Athou/renovate/quarkus.version
fix(deps): update quarkus.version to v3.30.1 (minor)
2025-11-26 17:38:55 +01:00
renovate[bot]
f25a62ad71 fix(deps): update quarkus.version to v3.30.1 2025-11-26 16:02:56 +00:00
renovate[bot]
cec3c872b6 chore(deps): update graalvm/setup-graalvm digest to dec5790 2025-11-26 12:38:46 +00:00
Athou
e666e71281 remove unused rollup-plugin-visualizer 2025-11-26 08:53:10 +01:00
renovate[bot]
3d0c303d41 chore(deps): update dependency npm to v11.6.4 2025-11-25 21:52:24 +00:00
renovate[bot]
d70a97cf77 fix(deps): update mantine monorepo to ^8.3.9 2025-11-25 13:35:39 +00:00
renovate[bot]
c67c433258 chore(deps): update dependency vitest to ^4.0.13 2025-11-24 17:46:02 +00:00
renovate[bot]
0da6bd5ab6 chore(deps): update dependency @biomejs/biome to ^2.3.7 2025-11-24 09:47:58 +00:00
Jérémie Panzer
e5cdb1580e Merge pull request #1970 from Athou/renovate/monaco-editor-0.x
fix(deps): update dependency monaco-editor to ^0.55.1
2025-11-24 04:54:35 +01:00
renovate[bot]
2c10292073 fix(deps): update dependency monaco-editor to ^0.55.1 2025-11-23 20:50:57 +00:00
Athou
30036a456e Merge branch 'dcelasun-chore/jdk-25' 2025-11-23 21:36:56 +01:00
Athou
6349ae9e2b fix for java.lang.NoClassDefFoundError: Could not initialize class org.jboss.threads.JDKSpecific$ThreadAccess 2025-11-23 17:53:00 +01:00
Athou
8d746669c3 Merge branch 'chore/jdk-25' of https://github.com/dcelasun/commafeed into dcelasun-chore/jdk-25 2025-11-23 17:46:35 +01:00
renovate[bot]
0081abc9a7 chore(deps): update dependency vitest to ^4.0.12 2025-11-23 13:01:25 +00:00
renovate[bot]
a2f9ac05fe chore(deps): update dependency vite to ^7.2.4 2025-11-23 08:44:04 +00:00
renovate[bot]
6c1f24bad7 chore(deps): update dependency @biomejs/biome to v2.3.7 2025-11-21 08:53:14 +00:00
Jérémie Panzer
77cd01e91f Merge pull request #1969 from Athou/renovate/actions-checkout-6.x
chore(deps): update actions/checkout action to v6
2025-11-21 08:03:07 +01:00
renovate[bot]
5487aac81d fix(deps): update dependency io.github.hakky54:ayza-for-apache5 to v10.0.2 2025-11-20 21:47:01 +00:00
renovate[bot]
8a6257dc63 chore(deps): update actions/checkout action to v6 2025-11-20 18:06:19 +00:00
Athou
8146c69ebf release 5.12.0 2025-11-20 06:58:55 +01:00
renovate[bot]
78ece1abf2 chore(deps): update dependency npm to v11.6.3 2025-11-20 01:58:00 +00:00
renovate[bot]
baab35c4c5 fix(deps): update quarkus.version to v3.29.4 2025-11-19 21:01:43 +00:00
Athou
357f9d46f9 enable the disablePullToRefresh setting by default to mimic what was done before the setting was added 2025-11-19 15:10:29 +01:00
Jérémie Panzer
4eb26302a7 Merge pull request #1967 from Athou/renovate/com.diffplug.spotless-spotless-maven-plugin-3.x
chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v3.1.0
2025-11-19 09:06:06 +01:00
renovate[bot]
a2071d9527 chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v3.1.0 2025-11-19 01:30:34 +00:00
Jérémie Panzer
65c32c52ff Merge pull request #1966 from Athou/renovate/debian-13.x
chore(deps): update debian docker tag to v13.2
2025-11-18 08:08:02 +01:00
renovate[bot]
fa4353f47d chore(deps): update debian docker tag to v13.2 2025-11-18 06:13:55 +00:00
renovate[bot]
46fea1a3e5 chore(deps): update dependency vitest to ^4.0.10 2025-11-18 04:25:51 +00:00
renovate[bot]
497cf111d1 chore(deps): update dependency @types/react to ^19.2.6 2025-11-18 03:19:16 +00:00
renovate[bot]
b1f2fd26e3 chore(deps): update actions/checkout digest to 93cb6ef 2025-11-17 22:43:16 +00:00
renovate[bot]
ae60d4a60f chore(deps): update dependency @biomejs/biome to v2.3.6 2025-11-17 11:13:56 +00:00
Athou
ae78e4691d make "disable pull to refresh" a setting (#1168) 2025-11-17 09:02:52 +01:00
Athou
9c058cf6d6 disable xml entity expansion limits enabled in JDK24+ (#1961) 2025-11-17 06:43:55 +01:00
renovate[bot]
1ac9af23c5 chore(deps): lock file maintenance 2025-11-17 02:41:41 +00:00
renovate[bot]
f783bb660e fix(deps): update dependency style-to-object to ^1.0.14 2025-11-16 12:42:51 +00:00
Athou
e5c271ca1c add support for more emojis (#1955) 2025-11-16 09:37:36 +01:00
renovate[bot]
f927247955 fix(deps): update mantine monorepo to ^8.3.8 2025-11-15 13:36:11 +00:00
renovate[bot]
087e38bec8 chore(deps): update dependency @types/react to ^19.2.5 2025-11-14 23:57:15 +00:00
renovate[bot]
bab3c8e6b0 fix(deps): update quarkus.version to v3.29.3 2025-11-14 16:35:26 +00:00
renovate[bot]
54ac5d9e27 chore(deps): update dependency vitest to ^4.0.9 2025-11-14 10:05:26 +00:00
renovate[bot]
36519d9053 chore(deps): update ibm-semeru-runtimes:open-jdk-25.0.1_8-jre docker digest to 015afe2 2025-11-14 05:49:21 +00:00
renovate[bot]
ccce4c622d fix(deps): update dependency react-router-dom to ^7.9.6 2025-11-13 21:02:11 +00:00
renovate[bot]
4cbf677e55 chore(deps): update react monorepo 2025-11-12 22:05:12 +00:00
renovate[bot]
1dbac44a93 chore(deps): update dependency @vitejs/plugin-react to ^5.1.1 2025-11-12 13:33:44 +00:00
Jérémie Panzer
7e1cfb5cd2 Merge pull request #1965 from Athou/renovate/linguijs-monorepo
fix(deps): update linguijs monorepo to ^5.6.0 (minor)
2025-11-12 22:32:10 +09:00
renovate[bot]
df9fb956fa fix(deps): update linguijs monorepo to ^5.6.0 2025-11-12 11:35:12 +00:00
Jérémie Panzer
16dc383f2b Merge pull request #1964 from Athou/renovate/jsdom-27.x
chore(deps): update dependency jsdom to ^27.2.0
2025-11-12 20:33:53 +09:00
Jérémie Panzer
0dd7c4851b Merge pull request #1963 from Athou/renovate/com.puppycrawl.tools-checkstyle-12.1.x
chore(deps): update dependency com.puppycrawl.tools:checkstyle to v12.1.2
2025-11-12 20:33:28 +09:00
renovate[bot]
fce4e75eef chore(deps): update dependency jsdom to ^27.2.0 2025-11-12 09:09:24 +00:00
renovate[bot]
16b578a76d chore(deps): update dependency com.puppycrawl.tools:checkstyle to v12.1.2 2025-11-12 09:09:16 +00:00
renovate[bot]
483db9881e chore(deps): update node.js to v24.11.1 2025-11-12 02:53:15 +00:00
renovate[bot]
a4053c6084 chore(deps): update dependency @types/react to ^19.2.3 2025-11-11 23:57:09 +00:00
renovate[bot]
e4f4b46047 chore(deps): update dependency @biomejs/biome to v2.3.5 2025-11-11 18:32:41 +00:00
Jérémie Panzer
36f77d5408 Merge pull request #1962 from Athou/renovate/org.sonarsource.scanner.maven-sonar-maven-plugin-5.x
chore(deps): update dependency org.sonarsource.scanner.maven:sonar-maven-plugin to v5.3.0.6276
2025-11-11 06:43:39 +09:00
renovate[bot]
b3533771dc chore(deps): update dependency org.sonarsource.scanner.maven:sonar-maven-plugin to v5.3.0.6276 2025-11-10 19:41:32 +00:00
renovate[bot]
45372cba92 chore(deps): lock file maintenance 2025-11-10 01:01:27 +00:00
renovate[bot]
dd7fb5bb0d fix(deps): update mantine monorepo to ^8.3.7 2025-11-09 13:53:33 +00:00
renovate[bot]
41bdc19a22 chore(deps): update dependency io.quarkus.platform:quarkus-maven-plugin to v3.29.2 2025-11-08 17:02:37 +00:00
renovate[bot]
8b7f22021a chore(deps): update dependency vitest to ^4.0.8 2025-11-07 16:13:57 +00:00
renovate[bot]
f0160e4d2b chore(deps): update dependency vite to ^7.2.2 2025-11-07 10:47:20 +00:00
renovate[bot]
39d727f98f fix(deps): update quarkus.version to v3.29.1 2025-11-06 22:57:39 +00:00
renovate[bot]
13cc8ac70d chore(deps): update dependency vite to ^7.2.1 (#1960)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-06 18:07:54 +00:00
renovate[bot]
eb2a219ec8 fix(deps): update dependency axios to ^1.13.2 2025-11-05 23:07:57 +00:00
renovate[bot]
4a59565b20 chore(deps): update docker/setup-qemu-action digest to c7c5346 2025-11-05 19:42:18 +00:00
renovate[bot]
4b7fa96308 chore(deps): update dependency @biomejs/biome to v2.3.4 2025-11-05 14:44:25 +00:00
Jérémie Panzer
1ebc8a1e7b Merge pull request #1959 from Athou/renovate/vite-7.x
chore(deps): update dependency vite to ^7.2.0
2025-11-05 23:43:30 +09:00
renovate[bot]
df2a9aae20 chore(deps): update dependency vite to ^7.2.0 2025-11-05 13:03:49 +00:00
renovate[bot]
dd8287c9d7 chore(deps): update ibm-semeru-runtimes docker tag to open-jdk-25.0.1_8-jre 2025-11-05 07:06:59 +00:00
renovate[bot]
22fcb08dad fix(deps): update dependency @reduxjs/toolkit to ^2.10.1 2025-11-05 03:04:14 +00:00
renovate[bot]
8c2cf181bd chore(deps): update dependency vitest to ^4.0.7 2025-11-04 21:31:09 +00:00
renovate[bot]
69adae36b6 chore(deps): update debian:13.1 docker digest to 01a723b 2025-11-04 16:45:27 +00:00
Jérémie Panzer
8ab700dfa9 Merge pull request #1957 from Athou/renovate/reduxjs-toolkit-2.x
fix(deps): update dependency @reduxjs/toolkit to ^2.10.0
2025-11-04 10:33:02 +01:00
renovate[bot]
0177529b45 fix(deps): update dependency @reduxjs/toolkit to ^2.10.0 2025-11-04 07:57:22 +00:00
renovate[bot]
4c6ae3364e chore(deps): update dependency @biomejs/biome to v2.3.3 2025-11-03 11:48:29 +00:00
renovate[bot]
6df8511a6d chore(deps): lock file maintenance 2025-11-03 00:39:22 +00:00
renovate[bot]
6fa39517f8 fix(deps): update dependency react-router-dom to ^7.9.5 2025-11-01 01:44:03 +00:00
renovate[bot]
c69ce39424 chore(deps): update dependency vitest to ^4.0.6 2025-10-31 20:23:24 +00:00
Jérémie Panzer
a47f6736ac Merge pull request #1956 from Athou/renovate/jsdom-27.x
chore(deps): update dependency jsdom to ^27.1.0
2025-10-31 21:22:17 +01:00
renovate[bot]
79bd7cfff3 chore(deps): update dependency jsdom to ^27.1.0 2025-10-31 11:51:25 +00:00
renovate[bot]
bc02f23f0f fix(deps): update dependency dayjs to ^1.11.19 2025-10-31 11:51:10 +00:00
renovate[bot]
715dffb6c8 chore(deps): update ibm-semeru-runtimes:open-jdk-25.0.0_36-jre docker digest to 7cee2dc 2025-10-31 04:41:07 +00:00
renovate[bot]
702b3eb971 chore(deps): update dependency vitest to ^4.0.5 2025-10-30 21:52:45 +00:00
Jérémie Panzer
17f62bf491 Merge pull request #1954 from Athou/renovate/com.ibm.icu-icu4j-78.x
fix(deps): update dependency com.ibm.icu:icu4j to v78
2025-10-30 22:51:40 +01:00
renovate[bot]
28471302ee fix(deps): update dependency com.ibm.icu:icu4j to v78 2025-10-30 20:32:35 +00:00
renovate[bot]
d8bfdd5d3b fix(deps): update linguijs monorepo to ^5.5.2 2025-10-30 15:58:30 +00:00
Jérémie Panzer
a36e68e9c3 Merge pull request #1953 from Athou/renovate/quarkus.version
fix(deps): update quarkus.version to v3.29.0 (minor)
2025-10-29 20:46:30 +01:00
renovate[bot]
343aed16fb fix(deps): update quarkus.version to v3.29.0 2025-10-29 17:06:51 +00:00
renovate[bot]
142d873c8b fix(deps): update mantine monorepo to ^8.3.6 2025-10-29 10:10:47 +00:00
renovate[bot]
a94b3e05d3 fix(deps): update dependency axios to ^1.13.1 2025-10-29 03:13:02 +00:00
Jérémie Panzer
26a79d58f0 Merge pull request #1952 from Athou/renovate/node-24.x
chore(deps): update node.js to v24
2025-10-29 04:12:10 +01:00
renovate[bot]
7c5e68e47d chore(deps): update node.js to v24 2025-10-28 20:36:14 +00:00
renovate[bot]
ba68627060 chore(deps): update dependency @biomejs/biome to v2.3.2 2025-10-28 20:36:01 +00:00
renovate[bot]
5bb6a7d4d4 chore(deps): update dependency vitest to ^4.0.4 2025-10-27 20:42:25 +00:00
Jérémie Panzer
76f7999046 Merge pull request #1951 from Athou/renovate/querydsl.version
fix(deps): update querydsl.version to v7.1 (minor)
2025-10-27 21:41:31 +01:00
renovate[bot]
547693df4f fix(deps): update querydsl.version to v7.1 2025-10-27 20:06:14 +00:00
Jérémie Panzer
0206f8211a Merge pull request #1950 from Athou/renovate/axios-1.x
fix(deps): update dependency axios to ^1.13.0
2025-10-27 21:05:06 +01:00
renovate[bot]
e061f2e259 fix(deps): update dependency axios to ^1.13.0 2025-10-27 18:12:02 +00:00
renovate[bot]
560ccff04a chore(deps): update graalvm/setup-graalvm digest to eec4810 2025-10-27 09:49:45 +00:00
renovate[bot]
2f0a84557b chore(deps): lock file maintenance 2025-10-27 00:39:04 +00:00
renovate[bot]
3ae7318ded chore(deps): update dependency @biomejs/biome to v2.3.1 2025-10-26 21:53:19 +00:00
renovate[bot]
6b7d66e833 chore(deps): update dependency com.puppycrawl.tools:checkstyle to v12.1.1 2025-10-26 18:28:31 +00:00
renovate[bot]
ec8e594a5c fix(deps): update dependency style-to-object to ^1.0.12 2025-10-25 02:16:11 +00:00
renovate[bot]
858041772e chore(deps): update dependency vitest to ^4.0.3 2025-10-24 22:17:14 +00:00
Jérémie Panzer
b355c04d87 Merge pull request #1948 from Athou/renovate/major-github-artifact-actions
chore(deps): update github artifact actions (major)
2025-10-25 00:15:30 +02:00
renovate[bot]
4918eaf752 chore(deps): update github artifact actions 2025-10-24 19:37:52 +00:00
Jérémie Panzer
80706f006d Merge pull request #1947 from Athou/renovate/vitejs-plugin-react-5.x
chore(deps): update dependency @vitejs/plugin-react to ^5.1.0
2025-10-24 21:37:11 +02:00
Jérémie Panzer
8a7fec1207 Merge pull request #1946 from Athou/renovate/biomejs-biome-2.x
chore(deps): update dependency @biomejs/biome to v2.3.0
2025-10-24 21:36:43 +02:00
renovate[bot]
22a5b6e85e chore(deps): update dependency @vitejs/plugin-react to ^5.1.0 2025-10-24 16:33:16 +00:00
renovate[bot]
a51c533712 chore(deps): update dependency @biomejs/biome to v2.3.0 2025-10-24 16:33:08 +00:00
renovate[bot]
1f74674a11 chore(deps): update dependency vitest to ^4.0.2 2025-10-24 00:56:41 +00:00
renovate[bot]
2eada58ce5 chore(deps): update dependency vite to ^7.1.12 2025-10-23 13:30:21 +00:00
Jérémie Panzer
31e74bd4a8 Merge pull request #1945 from Athou/renovate/patch-quarkus.version
fix(deps): update quarkus.version to v3.28.5 (patch)
2025-10-23 15:29:26 +02:00
renovate[bot]
903f73ee78 fix(deps): update quarkus.version to v3.28.5 2025-10-23 04:51:46 +00:00
renovate[bot]
b21198b239 fix(deps): update dependency io.github.hakky54:ayza-for-apache5 to v10.0.1 2025-10-23 00:49:27 +00:00
renovate[bot]
e20ff09457 fix(deps): update dependency @reduxjs/toolkit to ^2.9.2 2025-10-22 23:07:16 +00:00
Jérémie Panzer
674393eabc Merge pull request #1944 from Athou/renovate/major-vitest-monorepo
chore(deps): update dependency vitest to v4
2025-10-23 01:06:24 +02:00
renovate[bot]
d78a131713 chore(deps): update dependency vitest to v4 2025-10-22 22:10:33 +00:00
renovate[bot]
e3816bf05b chore(deps): update dependency @biomejs/biome to v2.2.7 2025-10-22 11:53:45 +00:00
renovate[bot]
37fe1c60cc chore(deps): update debian:13.1 docker digest to 72547dd 2025-10-21 05:50:15 +00:00
Jérémie Panzer
e705a0d32b Merge pull request #1942 from Athou/renovate/node-22.x
chore(deps): update node.js to v22.21.0
2025-10-21 04:01:46 +02:00
renovate[bot]
eb658a644b chore(deps): update node.js to v22.21.0 2025-10-21 00:52:29 +00:00
Jérémie Panzer
cb905bfc8c Merge pull request #1941 from Athou/renovate/io.quarkiverse.playwright-quarkus-playwright-2.x
chore(deps): update dependency io.quarkiverse.playwright:quarkus-playwright to v2.2.1
2025-10-21 01:49:14 +02:00
renovate[bot]
d0accf6a84 chore(deps): update dependency io.quarkiverse.playwright:quarkus-playwright to v2.2.1 2025-10-20 21:50:57 +00:00
renovate[bot]
55e6f89fc1 chore(deps): update dependency vite to ^7.1.11 2025-10-20 09:34:48 +00:00
renovate[bot]
60695a0ffc chore(deps): lock file maintenance 2025-10-20 02:37:10 +00:00
Jérémie Panzer
8a8e4655cd Merge pull request #1940 from Athou/renovate/com.puppycrawl.tools-checkstyle-12.x
chore(deps): update dependency com.puppycrawl.tools:checkstyle to v12.1.0
2025-10-19 20:16:35 +02:00
renovate[bot]
2f4b390be1 chore(deps): update dependency com.puppycrawl.tools:checkstyle to v12.1.0 2025-10-19 17:55:02 +00:00
renovate[bot]
31146cc713 chore(deps): update dependency org.codehaus.mojo:exec-maven-plugin to v3.6.2 2025-10-19 08:44:03 +00:00
renovate[bot]
9e020ff268 chore(deps): update dependency jsdom to ^27.0.1 2025-10-18 09:56:15 +00:00
Athou
7e825192d0 enforce user password validation when created in the admin view (#1937) 2025-10-17 10:19:02 +02:00
Athou
8871ae894f handle invalid relative urls (#1939) 2025-10-17 09:04:38 +02:00
renovate[bot]
2808f4b1a2 fix(deps): update dependency @reduxjs/toolkit to ^2.9.1 2025-10-17 06:05:31 +00:00
renovate[bot]
0324c22061 fix(deps): update quarkus.version to v3.28.4 2025-10-16 18:47:22 +00:00
D. Can Celasun
57227f9544 chore: Switch to GraalVM 25
JDK 25 is the new LTS after 21.
2025-10-16 18:04:50 +01:00
renovate[bot]
59c5131f1a chore(deps): update dependency rollup-plugin-visualizer to ^6.0.5 2025-10-16 13:58:50 +00:00
Athou
ccbc07d7d8 don't show "Star/Unstar" in the context menu if the entry is not markable (#1935) 2025-10-15 07:11:48 +02:00
renovate[bot]
a0247f0036 fix(deps): update mantine monorepo to ^8.3.5 2025-10-14 21:01:50 +00:00
renovate[bot]
0979c2767b chore(deps): update dependency vite to ^7.1.10 2025-10-14 17:07:41 +00:00
renovate[bot]
9a9613bba3 chore(deps): update dependency @types/react-dom to ^19.2.2 2025-10-13 16:44:29 +00:00
Jérémie Panzer
6451f5f3b7 Merge pull request #1931 from Athou/renovate/biomejs-biome-2.2.x
chore(deps): update dependency @biomejs/biome to v2.2.6
2025-10-13 15:34:10 +02:00
Athou
4a4430ce9b fix build 2025-10-13 13:45:03 +02:00
renovate[bot]
a38d3dcf72 chore(deps): update dependency @biomejs/biome to v2.2.6 2025-10-13 10:35:05 +00:00
renovate[bot]
60e1e0d037 chore(deps): lock file maintenance 2025-10-13 01:48:54 +00:00
Athou
8071b85b3d remove unused workflows 2025-10-12 14:53:25 +02:00
Jérémie Panzer
c867bfb846 Merge pull request #1929 from aniol/patch-3
Update messages.po
2025-10-12 13:51:59 +02:00
Aniol
24b32ab69b Update messages.po
The translation has been reviewed, and some tweaks have been applied.
2025-10-12 09:20:09 +02:00
renovate[bot]
b1fc65262f chore(deps): update dependency org.jacoco:jacoco-maven-plugin to v0.8.14 2025-10-12 01:05:50 +00:00
renovate[bot]
5af3fea74c chore(deps): update dependency com.puppycrawl.tools:checkstyle to v12.0.1 2025-10-11 21:37:13 +00:00
Athou
dde38985e4 use stable react compiler 2025-10-11 13:24:07 +02:00
Athou
3f0084fa1c make the app appear as "commafeed" when listing processes 2025-10-11 13:23:23 +02:00
renovate[bot]
8936d4fdce chore(deps): update github/codeql-action digest to f443b60 2025-10-10 18:40:20 +00:00
renovate[bot]
4c47b7d838 fix(deps): update linguijs monorepo to ^5.5.1 2025-10-10 12:34:48 +00:00
Jérémie Panzer
093a9cb8e4 Merge pull request #1927 from xmgz/master
Complete, Fix and Review galician (gl) translation
2025-10-10 14:33:46 +02:00
ghose
f27b3f8933 fixing line breaks not needed
there were many line breaks which did not were needed. Now  removed.
2025-10-10 12:13:41 +00:00
ghose
74a9e48e55 adding back header info 2025-10-10 05:36:38 +00:00
ghose
bafef26ffc Update messages.po
cleaning header
2025-10-10 05:33:53 +00:00
ghose
f8e66170bf consistency and fixes
first review
2025-10-10 05:33:01 +00:00
renovate[bot]
00bf99fe5a fix(deps): update mantine monorepo to ^8.3.4 2025-10-10 00:52:58 +00:00
renovate[bot]
05dd66177f chore(deps): update ibm-semeru-runtimes:open-jdk-25.0.0_36-jre docker digest to f31cc59 2025-10-09 22:58:37 +00:00
renovate[bot]
d5a9e6401e fix(deps): update quarkus.version to v3.28.3 2025-10-09 17:51:36 +00:00
Jérémie Panzer
660ba67433 Merge pull request #1925 from Athou/renovate/com.puppycrawl.tools-checkstyle-12.x
chore(deps): update dependency com.puppycrawl.tools:checkstyle to v12
2025-10-09 19:50:55 +02:00
renovate[bot]
7ad948065b chore(deps): update dependency com.puppycrawl.tools:checkstyle to v12 2025-10-09 16:59:22 +00:00
ghose
40fcb85c93 missing text chains
there were about 80 text chains missing.
2025-10-09 12:52:45 +00:00
renovate[bot]
dcddb80f7b fix(deps): update dependency react-router-dom to ^7.9.4 2025-10-09 01:06:10 +00:00
renovate[bot]
8e349aea19 chore(deps): update dependency npm to v11.6.2 2025-10-08 21:03:39 +00:00
Jérémie Panzer
3d72725ae0 Merge pull request #1924 from Athou/renovate/github-codeql-action-4.x
chore(deps): update github/codeql-action action to v4
2025-10-08 06:36:34 +02:00
renovate[bot]
270cb340f5 chore(deps): update github/codeql-action action to v4 2025-10-07 19:00:38 +00:00
Jérémie Panzer
42b5462889 Merge pull request #1892 from Athou/renovate/monaco-editor-0.x
fix(deps): update dependency monaco-editor to ^0.54.0
2025-10-07 20:59:58 +02:00
renovate[bot]
b98ab8d011 fix(deps): update dependency monaco-editor to ^0.54.0 2025-10-07 12:51:51 +00:00
renovate[bot]
b4264a8ba3 chore(deps): update react monorepo 2025-10-07 10:14:49 +00:00
renovate[bot]
a395246d1e chore(deps): update dependency @types/react to ^19.2.1 2025-10-06 21:11:32 +00:00
renovate[bot]
4b7a2afd07 chore(deps): lock file maintenance 2025-10-06 03:45:30 +00:00
renovate[bot]
7f49ff20cf chore(deps): update dependency org.codehaus.mojo:exec-maven-plugin to v3.6.1 2025-10-06 02:13:46 +00:00
renovate[bot]
4e9995e610 fix(deps): update dependency style-to-object to ^1.0.11 (#1923)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-03 16:35:01 +00:00
renovate[bot]
9f61442cec chore(deps): update dependency vite to ^7.1.9 2025-10-03 05:30:16 +00:00
renovate[bot]
9339847d09 fix(deps): update mantine monorepo to ^8.3.3 2025-10-02 20:21:36 +00:00
Athou
39e57cb3ef fix warning 2025-10-02 22:06:24 +02:00
Athou
f3a574d05c reformat table 2025-10-02 22:02:28 +02:00
Athou
297c76006a use more records 2025-10-02 21:54:40 +02:00
renovate[bot]
62d025d827 chore(deps): update dependency vite to ^7.1.8 2025-10-02 16:37:35 +00:00
renovate[bot]
999799ea68 chore(deps): update github/codeql-action digest to 64d10c1 2025-10-02 15:25:23 +00:00
renovate[bot]
331f68253e chore(deps): update dependency rollup-plugin-visualizer to ^6.0.4 2025-10-02 13:54:43 +00:00
renovate[bot]
70d3c7a4be chore(deps): update dependency @biomejs/biome to v2.2.5 2025-10-02 13:00:18 +00:00
renovate[bot]
b3c75a0286 chore(deps): update ibm-semeru-runtimes:open-jdk-25.0.0_36-jre docker digest to 8ae0733 2025-10-02 11:54:35 +00:00
renovate[bot]
9946120304 chore(deps): update graalvm/setup-graalvm digest to 2a24120 2025-10-02 09:03:55 +00:00
Athou
7030a67389 Merge branch 'renovate/ibm-semeru-runtimes-25.x' 2025-10-02 06:24:06 +02:00
Jérémie Panzer
eda5ef6965 Merge pull request #1921 from Athou/renovate/patch-testing-library-monorepo
chore(deps): update dependency @testing-library/jest-dom to ^6.9.1
2025-10-02 06:18:06 +02:00
Jérémie Panzer
0324479fda Merge pull request #1922 from Athou/renovate/react-monorepo
fix(deps): update react monorepo to ^19.2.0 (minor)
2025-10-02 06:18:00 +02:00
Athou
aeafecb88d update semeru pattern 2025-10-02 06:17:52 +02:00
renovate[bot]
fde7fbe21a chore(deps): update ibm-semeru-runtimes docker tag to v25 2025-10-02 00:34:50 +00:00
renovate[bot]
7116efc490 fix(deps): update react monorepo to ^19.2.0 2025-10-02 00:34:44 +00:00
renovate[bot]
1ac6058200 chore(deps): update dependency @testing-library/jest-dom to ^6.9.1 2025-10-02 00:34:27 +00:00
renovate[bot]
32b80b64f4 chore(deps): update react monorepo 2025-10-01 19:24:44 +00:00
Jérémie Panzer
9e348767dc Merge pull request #1920 from Athou/renovate/peter-evans-dockerhub-description-5.x
chore(deps): update peter-evans/dockerhub-description action to v5
2025-10-01 21:23:52 +02:00
Jérémie Panzer
bce72e1152 Merge pull request #1904 from Athou/renovate/quarkus.version
fix(deps): update quarkus.version to v3.28.2 (minor)
2025-10-01 21:23:45 +02:00
renovate[bot]
64aba75be2 chore(deps): update peter-evans/dockerhub-description action to v5 2025-10-01 18:13:24 +00:00
renovate[bot]
ca65e13f9a fix(deps): update quarkus.version to v3.28.2 2025-10-01 18:13:15 +00:00
renovate[bot]
54797607c6 chore(deps): update dependency typescript to ^5.9.3 2025-10-01 03:33:28 +00:00
Jérémie Panzer
e174254a95 Merge pull request #1918 from Athou/renovate/testing-library-monorepo
chore(deps): update dependency @testing-library/jest-dom to ^6.9.0
2025-09-30 22:03:33 +02:00
renovate[bot]
4378e24b49 chore(deps): update dependency @testing-library/jest-dom to ^6.9.0 2025-09-30 19:28:02 +00:00
renovate[bot]
35d276ea98 chore(deps): update debian:13.1 docker digest to fd8f5a1 2025-09-30 11:44:47 +00:00
Jérémie Panzer
678c89d9c0 Merge pull request #1917 from Athou/renovate/org.codehaus.mojo-exec-maven-plugin-3.x
chore(deps): update dependency org.codehaus.mojo:exec-maven-plugin to v3.6.0
2025-09-30 13:44:11 +02:00
renovate[bot]
0a42223de0 chore(deps): update dependency org.codehaus.mojo:exec-maven-plugin to v3.6.0 2025-09-30 10:39:26 +00:00
renovate[bot]
54d3f3b007 chore(deps): update dependency @types/react to ^19.1.16 2025-09-30 06:14:38 +00:00
renovate[bot]
3ee58ee464 chore(deps): update debian:13.1 docker digest to 9dfe31a 2025-09-30 01:58:58 +00:00
renovate[bot]
3b5ff016fe chore(deps): update docker/login-action digest to 5e57cd1 2025-09-29 12:55:55 +00:00
Jérémie Panzer
8a8e786f5e Merge pull request #1913 from Athou/renovate/vite-plugin-checker-0.x
chore(deps): update dependency vite-plugin-checker to ^0.11.0
2025-09-29 12:30:24 +02:00
renovate[bot]
2a15f68ffb chore(deps): update dependency vite-plugin-checker to ^0.11.0 2025-09-29 10:10:00 +00:00
renovate[bot]
9387e014c1 chore(deps): lock file maintenance 2025-09-29 02:12:14 +00:00
renovate[bot]
1ef37fcaff chore(deps): update dependency @types/react to ^19.1.15 2025-09-28 15:23:14 +00:00
Jérémie Panzer
c5906a481f Merge pull request #1910 from Athou/renovate/com.puppycrawl.tools-checkstyle-11.x
chore(deps): update dependency com.puppycrawl.tools:checkstyle to v11.1.0
2025-09-28 17:21:38 +02:00
renovate[bot]
ac0bc916a1 chore(deps): update dependency com.puppycrawl.tools:checkstyle to v11.1.0 2025-09-28 13:57:20 +00:00
Athou
5bbe76d56e remove log.trace calls 2025-09-28 07:36:12 +02:00
Athou
1e6195d74c add coverage for in-page url fallback 2025-09-28 07:36:12 +02:00
Athou
85acea7e64 fix warning 2025-09-28 07:36:12 +02:00
renovate[bot]
0e4ff99602 fix(deps): update dependency org.apache.httpcomponents.client5:httpclient5 to v5.5.1 2025-09-28 01:39:52 +00:00
renovate[bot]
575d2a0940 chore(deps): update dependency @vitejs/plugin-react to ^5.0.4 2025-09-27 20:22:58 +00:00
Athou
c548462eef cleanup 2025-09-27 19:10:41 +02:00
Jérémie Panzer
3b4cc66b24 Merge pull request #1909 from RazyAnas/master
Fix off-by-one error in HttpGetter.toByteArray response size check
2025-09-27 19:07:19 +02:00
AnasRazy /
6d7273f822 Merge pull request #1 from RazyAnas/RazyAnas-patch-1
What this PR does:
Fixes an off-by-one error in HttpGetter.toByteArray where responses of exactly maxBytes were being rejected. Now allows responses up to maxBytes, and only throws if the response is larger.

Why this change is needed:
Some feeds return responses exactly equal to the limit. Current implementation incorrectly throws an exception, breaking parsing.

How it works:
Reads up to maxBytes + 1 bytes.
If actual size exceeds maxBytes, throws exception. Otherwise returns full content.

Other notes:
No breaking API changes.
Safe for existing usage.
2025-09-27 15:35:16 +05:30
AnasRazy /
65014d330a Fix off-by-one bug in HttpGetter.toByteArray()
What this PR does:
Fixes an off-by-one error in HttpGetter.toByteArray where responses of exactly maxBytes were being rejected.
Now allows responses up to maxBytes, and only throws if the response is larger.

Why this change is needed:
Some feeds return responses exactly equal to the limit.
Current implementation incorrectly throws an exception, breaking parsing.

How it works:
Reads up to maxBytes + 1 bytes.
If actual size exceeds maxBytes, throws exception.
Otherwise returns full content.

Other notes:
No breaking API changes.
Safe for existing usage.
2025-09-27 15:32:31 +05:30
renovate[bot]
d9e3cf0190 fix(deps): update dependency react-router-dom to ^7.9.3 2025-09-27 04:27:25 +00:00
renovate[bot]
2d8ee54d28 chore(deps): update dependency @types/react to ^19.1.14 2025-09-27 01:45:49 +00:00
renovate[bot]
98c3bb780d chore(deps): update github/codeql-action digest to 3599b3b 2025-09-26 21:56:48 +00:00
renovate[bot]
7247c10615 chore(deps): update dependency com.github.eirslett:frontend-maven-plugin to v1.15.4 2025-09-26 04:52:35 +00:00
Athou
0787284d80 mvn wrapper update 2025-09-26 06:51:52 +02:00
renovate[bot]
1c73bffc95 chore(deps): update github/codeql-action digest to 303c0ae 2025-09-25 12:31:52 +00:00
Jérémie Panzer
6f79815933 Merge pull request #1905 from Athou/renovate/patch-react-router-monorepo
fix(deps): update dependency react-router-dom to ^7.9.2
2025-09-25 08:37:03 +02:00
renovate[bot]
bb108d594a fix(deps): update dependency react-router-dom to ^7.9.2 2025-09-25 05:08:53 +00:00
Jérémie Panzer
f7716c8834 Merge pull request #1906 from Athou/renovate/com.diffplug.spotless-spotless-maven-plugin-3.x
chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v3
2025-09-25 07:07:51 +02:00
Jérémie Panzer
5ba076b1dd Merge pull request #1907 from Athou/renovate/npm-11.6.x
chore(deps): update dependency npm to v11.6.1
2025-09-25 07:04:47 +02:00
renovate[bot]
7861b5a414 chore(deps): update dependency npm to v11.6.1 2025-09-25 05:04:27 +00:00
Athou
f36a5988d8 quarkus build is not yet stable with java 25 2025-09-25 07:03:48 +02:00
renovate[bot]
8b57240db3 chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v3 2025-09-24 21:05:17 +00:00
Jérémie Panzer
7b52efd2d1 Merge pull request #1903 from Athou/renovate/node-22.x
chore(deps): update node.js to v22.20.0
2025-09-24 16:42:26 +02:00
renovate[bot]
4901b838e2 chore(deps): update node.js to v22.20.0 2025-09-24 14:10:30 +00:00
Jérémie Panzer
2313a60f32 Merge pull request #1902 from Athou/renovate/patch-mantine-monorepo
fix(deps): update mantine monorepo to ^8.3.2 (patch)
2025-09-24 07:25:17 +02:00
renovate[bot]
c38e958588 fix(deps): update mantine monorepo to ^8.3.2 2025-09-23 23:39:27 +00:00
Jérémie Panzer
43b1e14f41 Merge pull request #1901 from Athou/renovate/graalvm-setup-graalvm-digest
chore(deps): update graalvm/setup-graalvm digest to e140024
2025-09-23 16:18:56 +02:00
renovate[bot]
1e23b3c355 chore(deps): update graalvm/setup-graalvm digest to e140024 2025-09-23 10:35:05 +00:00
Jérémie Panzer
85e1556148 Merge pull request #1900 from Athou/renovate/vite-7.1.x
chore(deps): update dependency vite to ^7.1.7
2025-09-22 16:07:12 +02:00
renovate[bot]
b65f333a89 chore(deps): update dependency vite to ^7.1.7 2025-09-22 06:54:21 +00:00
renovate[bot]
3dbcbb8280 chore(deps): update dependency org.apache.maven.plugins:maven-compiler-plugin to v3.14.1 2025-09-22 05:17:18 +00:00
renovate[bot]
06e464854a chore(deps): lock file maintenance 2025-09-22 01:55:24 +00:00
Athou
f7a944a78a release 5.11.1 2025-09-22 03:53:07 +02:00
Athou
7f53531489 filter cannot be converted to lowercase (#1899) 2025-09-22 03:47:06 +02:00
renovate[bot]
8386c2889f chore(deps): update dependency vite to ^7.1.6 2025-09-18 05:15:43 +00:00
Jérémie Panzer
13d2332984 Merge pull request #1898 from Athou/renovate/org.projectlombok-lombok-1.18.x
fix(deps): update dependency org.projectlombok:lombok to v1.18.42
2025-09-18 07:14:44 +02:00
renovate[bot]
ce496c205a fix(deps): update dependency org.projectlombok:lombok to v1.18.42 2025-09-18 02:32:36 +00:00
renovate[bot]
66547661b5 fix(deps): update quarkus.version to v3.26.4 2025-09-17 18:53:21 +00:00
renovate[bot]
8568a29461 fix(deps): update dependency @fontsource/open-sans to ^5.2.7 2025-09-17 09:44:18 +00:00
renovate[bot]
5d42229aec chore(deps): update dependency @vitejs/plugin-react to ^5.0.3 2025-09-17 08:49:14 +00:00
Athou
ad8c928cf1 run CI with java 25 2025-09-16 19:09:40 +02:00
renovate[bot]
cc90883342 chore(deps): update graalvm/setup-graalvm digest to aba6a07 2025-09-16 16:45:34 +00:00
renovate[bot]
a4071da5de fix(deps): update dependency io.dropwizard.metrics:metrics-json to v4.2.37 2025-09-16 05:34:48 +00:00
renovate[bot]
c65dbf978b chore(deps): update ibm-semeru-runtimes:open-21.0.8_9-jre docker digest to 0d2e27e 2025-09-16 03:56:11 +00:00
renovate[bot]
c4ea804fee chore(deps): lock file maintenance 2025-09-15 02:03:39 +00:00
renovate[bot]
f71720c809 fix(deps): update dependency axios to ^1.12.2 2025-09-14 18:13:58 +00:00
renovate[bot]
03ba601491 fix(deps): update dependency axios to ^1.12.1 2025-09-14 01:35:06 +00:00
renovate[bot]
bdee3fc1b5 chore(deps): update dependency org.apache.maven.plugins:maven-surefire-plugin to v3.5.4 2025-09-13 17:48:07 +00:00
renovate[bot]
2e472fa90d chore(deps): update dependency org.apache.maven.plugins:maven-failsafe-plugin to v3.5.4 2025-09-13 16:06:11 +00:00
Jérémie Panzer
aad7e896f2 Merge pull request #1897 from Athou/renovate/jsdom-27.x
chore(deps): update dependency jsdom to v27
2025-09-13 10:43:45 +02:00
renovate[bot]
2478fc2967 chore(deps): update dependency jsdom to v27 2025-09-13 07:06:06 +00:00
Jérémie Panzer
2db96c968d Merge pull request #1896 from Athou/renovate/linguijs-monorepo
fix(deps): update linguijs monorepo to ^5.5.0 (minor)
2025-09-13 09:05:54 +02:00
Jérémie Panzer
9bc1a69ace Merge pull request #1895 from Athou/renovate/react-router-monorepo
fix(deps): update dependency react-router-dom to ^7.9.1
2025-09-13 09:05:46 +02:00
renovate[bot]
cca74e9e54 fix(deps): update linguijs monorepo to ^5.5.0 2025-09-13 02:57:55 +00:00
renovate[bot]
8185411071 fix(deps): update dependency react-router-dom to ^7.9.1 2025-09-13 02:57:46 +00:00
renovate[bot]
c89addab2e chore(deps): update dependency @types/react to ^19.1.13 2025-09-13 02:57:32 +00:00
Jérémie Panzer
6c617bf9e7 Merge pull request #1894 from Athou/renovate/axios-1.x
fix(deps): update dependency axios to ^1.12.0
2025-09-12 06:31:12 +02:00
renovate[bot]
5847e340bf fix(deps): update dependency axios to ^1.12.0 2025-09-12 03:56:31 +00:00
renovate[bot]
5a5fd8f425 chore(deps): update github/codeql-action digest to 192325c 2025-09-10 21:07:58 +00:00
renovate[bot]
d6283e326d fix(deps): update mantine monorepo to ^8.3.1 2025-09-10 17:43:17 +00:00
renovate[bot]
c63deb70dd chore(deps): update dependency @biomejs/biome to v2.2.4 2025-09-10 14:34:03 +00:00
renovate[bot]
c071781099 fix(deps): update quarkus.version to v3.26.3 2025-09-10 06:47:48 +00:00
renovate[bot]
0820b4b70a chore(deps): update github/codeql-action digest to d3678e2 2025-09-09 11:57:33 +00:00
Jérémie Panzer
ac42d11251 Merge pull request #1893 from Athou/renovate/debian-13.x
chore(deps): update debian docker tag to v13.1
2025-09-09 05:57:31 +02:00
renovate[bot]
324248ff1e chore(deps): update debian docker tag to v13.1 2025-09-09 02:03:08 +00:00
Jérémie Panzer
f32e83d43b Merge pull request #1891 from Athou/renovate/mantine-monorepo
fix(deps): update mantine monorepo to ^8.3.0 (minor)
2025-09-08 21:50:19 +02:00
renovate[bot]
3820aaed21 fix(deps): update mantine monorepo to ^8.3.0 2025-09-08 14:18:59 +00:00
renovate[bot]
a45ef79c6f chore(deps): update dependency vite to ^7.1.5 2025-09-08 10:15:30 +00:00
renovate[bot]
9b9266a6c9 chore(deps): lock file maintenance 2025-09-08 02:40:28 +00:00
renovate[bot]
06e22030c3 chore(deps): update dependency @biomejs/biome to v2.2.3 2025-09-05 16:49:16 +00:00
renovate[bot]
ca146c977b chore(deps): update github/codeql-action digest to f1f6e5f 2025-09-05 14:15:06 +00:00
renovate[bot]
6a96a3617f fix(deps): update dependency org.projectlombok:lombok to v1.18.40 2025-09-05 03:01:33 +00:00
Jérémie Panzer
6dd6e05e0c Merge pull request #1890 from Athou/renovate/npm-11.x
chore(deps): update dependency npm to v11.6.0
2025-09-04 07:19:20 +02:00
renovate[bot]
1fb33d51d3 chore(deps): update dependency npm to v11.6.0 2025-09-03 21:33:32 +00:00
renovate[bot]
4841f2d7f6 fix(deps): update quarkus.version to v3.26.2 2025-09-03 17:54:08 +00:00
Athou
ad388ae056 remove search limit (#1887) 2025-09-03 07:45:15 +02:00
Jérémie Panzer
a80769fae3 Merge pull request #1889 from Athou/renovate/reduxjs-toolkit-2.x
fix(deps): update dependency @reduxjs/toolkit to ^2.9.0
2025-09-03 07:21:04 +02:00
renovate[bot]
b34c6f4c34 fix(deps): update dependency @reduxjs/toolkit to ^2.9.0 2025-09-03 04:53:28 +00:00
renovate[bot]
d6d084fbd1 chore(deps): update ncipollo/release-action digest to b7eabc9 2025-09-02 20:40:56 +00:00
renovate[bot]
1fca44c0da chore(deps): update graalvm/setup-graalvm digest to 7a1da54 2025-09-02 17:05:28 +00:00
renovate[bot]
8bf1d0b776 chore(deps): update ibm-semeru-runtimes:open-21.0.8_9-jre docker digest to ffcc837 2025-09-02 04:55:08 +00:00
renovate[bot]
484412514f chore(deps): update ncipollo/release-action digest to 1c89adf 2025-09-01 18:32:51 +00:00
renovate[bot]
6987449a7e chore(deps): update github/codeql-action digest to 2d92b76 2025-09-01 16:24:31 +00:00
renovate[bot]
18dac92fc1 chore(deps): update dependency vite to ^7.1.4 2025-09-01 12:34:29 +00:00
renovate[bot]
54774fcfe5 fix(deps): update dependency io.dropwizard.metrics:metrics-json to v4.2.36 2025-08-31 20:34:06 +00:00
Athou
b431229273 sslcontext-kickstart was renamed ayza 2025-08-31 21:27:23 +02:00
renovate[bot]
658dde158e fix(deps): update mantine monorepo to ^8.2.8 2025-08-31 16:33:54 +00:00
renovate[bot]
ced3ada6fc chore(deps): update dependency com.puppycrawl.tools:checkstyle to v11.0.1 2025-08-31 14:22:18 +00:00
renovate[bot]
0db236639b fix(deps): update quarkus.version to v3.26.1 2025-08-30 05:59:50 +00:00
renovate[bot]
036ce7f94f fix(deps): update dependency io.dropwizard.metrics:metrics-json to v4.2.35 2025-08-29 20:09:03 +00:00
renovate[bot]
68c887ffe0 fix(deps): update dependency dayjs to ^1.11.17 2025-08-29 19:04:58 +00:00
renovate[bot]
e96da49d0a chore(deps): update react monorepo 2025-08-29 15:51:22 +00:00
Jérémie Panzer
794684bc4e Merge pull request #1884 from Athou/renovate/node-22.x
chore(deps): update node.js to v22.19.0
2025-08-29 17:31:29 +02:00
Jérémie Panzer
dd944c5293 Merge pull request #1883 from Athou/renovate/org.sonarsource.scanner.maven-sonar-maven-plugin-5.x
chore(deps): update dependency org.sonarsource.scanner.maven:sonar-maven-plugin to v5.2.0.4988
2025-08-29 17:31:22 +02:00
renovate[bot]
be878454a9 chore(deps): update node.js to v22.19.0 2025-08-29 14:22:59 +00:00
renovate[bot]
e567f81046 chore(deps): update dependency org.sonarsource.scanner.maven:sonar-maven-plugin to v5.2.0.4988 2025-08-29 14:22:56 +00:00
Jérémie Panzer
6164ca5f91 Merge pull request #1882 from Athou/renovate/quarkus.version
chore(deps): update dependency io.quarkus.platform:quarkus-maven-plugin to v3.26.0
2025-08-28 13:54:04 +02:00
renovate[bot]
655332e3fd chore(deps): update dependency io.quarkus.platform:quarkus-maven-plugin to v3.26.0 2025-08-28 11:24:18 +00:00
renovate[bot]
7e300fea87 fix(deps): update dependency dayjs to ^1.11.15 2025-08-28 06:57:43 +00:00
renovate[bot]
cea3e0aba8 chore(deps): update dependency @vitejs/plugin-react to ^5.0.2 2025-08-28 05:13:54 +00:00
renovate[bot]
459e270561 chore(deps): update dependency @types/react to ^19.1.12 2025-08-27 18:09:22 +00:00
renovate[bot]
cba660e785 fix(deps): update dependency dayjs to ^1.11.14 2025-08-27 11:32:31 +00:00
Jérémie Panzer
758301a39d Merge pull request #1881 from Athou/renovate/patch-react-monorepo
chore(deps): update dependency @types/react-dom to ^19.1.8
2025-08-27 07:37:09 +02:00
renovate[bot]
a8d0bae16e chore(deps): update dependency @types/react-dom to ^19.1.8 2025-08-26 12:15:08 +00:00
renovate[bot]
583cc39849 chore(deps): update dependency vite-plugin-checker to ^0.10.3 2025-08-25 13:09:11 +00:00
renovate[bot]
3585bd3d2d chore(deps): lock file maintenance 2025-08-25 05:13:37 +00:00
renovate[bot]
3a895b6418 fix(deps): update dependency org.jsoup:jsoup to v1.21.2 2025-08-25 00:25:27 +00:00
renovate[bot]
bb67733723 fix(deps): update dependency io.dropwizard.metrics:metrics-json to v4.2.34 2025-08-24 22:28:11 +00:00
renovate[bot]
f380fd553f chore(deps): update dependency @biomejs/biome to v2.2.2 2025-08-23 13:07:39 +00:00
Jérémie Panzer
d22ef12adf Merge pull request #1880 from Athou/renovate/actions-upload-pages-artifact-4.x
chore(deps): update actions/upload-pages-artifact action to v4
2025-08-23 07:58:22 +02:00
renovate[bot]
eaec088348 fix(deps): update mantine monorepo to ^8.2.7 2025-08-23 01:33:04 +00:00
renovate[bot]
fa1d0b9151 fix(deps): update dependency react-router-dom to ^7.8.2 2025-08-22 21:23:18 +00:00
renovate[bot]
c0a418b8b1 chore(deps): update actions/upload-pages-artifact action to v4 2025-08-22 17:46:43 +00:00
renovate[bot]
1a4f633a28 chore(deps): update dependency @types/react to ^19.1.11 2025-08-22 17:46:33 +00:00
renovate[bot]
c92ae40db6 chore(deps): update github/codeql-action digest to 3c3833e 2025-08-21 12:52:05 +00:00
Jérémie Panzer
0b42bea600 Merge pull request #1879 from Athou/renovate/actions-setup-java-5.x
chore(deps): update actions/setup-java action to v5
2025-08-21 14:49:28 +02:00
renovate[bot]
d8565cb3d3 chore(deps): update actions/setup-java action to v5 2025-08-21 05:06:59 +00:00
Jérémie Panzer
f68798c10e Merge pull request #1878 from Athou/renovate/testing-library-monorepo
chore(deps): update dependency @testing-library/jest-dom to ^6.8.0
2025-08-21 07:06:32 +02:00
renovate[bot]
a2ab927433 chore(deps): update dependency @testing-library/jest-dom to ^6.8.0 2025-08-20 22:07:26 +00:00
renovate[bot]
c7eae71c56 fix(deps): update quarkus.version to v3.25.4 2025-08-20 22:07:14 +00:00
renovate[bot]
c3784c2606 chore(deps): update dependency vite to ^7.1.3 2025-08-19 08:49:58 +00:00
renovate[bot]
60fe263b53 chore(deps): update dependency @vitejs/plugin-react to ^5.0.1 2025-08-19 05:51:51 +00:00
renovate[bot]
aaa0cfd0c8 chore(deps): update github/codeql-action digest to 96f518a 2025-08-18 13:51:18 +00:00
renovate[bot]
a209b2774a chore(deps): lock file maintenance 2025-08-18 00:24:47 +00:00
renovate[bot]
84d67b6166 fix(deps): update mantine monorepo to ^8.2.5 2025-08-16 16:45:14 +00:00
renovate[bot]
a7a215e6c7 fix(deps): update dependency react-router-dom to ^7.8.1 2025-08-15 21:28:14 +00:00
Athou
8686fe4e97 add support for NoRouteToHostException (fixes #1876) 2025-08-14 20:41:27 +02:00
Jérémie Panzer
afe2e8f95b Merge pull request #1877 from Athou/renovate/biomejs-biome-2.x
chore(deps): update dependency @biomejs/biome to v2.2.0
2025-08-14 14:49:32 +02:00
renovate[bot]
f580226c27 chore(deps): update dependency @biomejs/biome to v2.2.0 2025-08-14 12:49:28 +00:00
renovate[bot]
e93db46e0a chore(deps): update ibm-semeru-runtimes:open-21.0.8_9-jre docker digest to a0585f5 2025-08-14 11:41:28 +00:00
renovate[bot]
daea4b7f84 chore(deps): update ibm-semeru-runtimes:open-21.0.8_9-jre docker digest to e8efb84 2025-08-14 05:08:35 +00:00
Jérémie Panzer
eb942b07b1 Merge pull request #1875 from Athou/renovate/testing-library-monorepo
chore(deps): update dependency @testing-library/jest-dom to ^6.7.0
2025-08-14 07:08:01 +02:00
renovate[bot]
804ca38db7 fix(deps): update quarkus.version to v3.25.3 (#1874)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-14 00:36:35 +00:00
renovate[bot]
7278c0beae chore(deps): update dependency @testing-library/jest-dom to ^6.7.0 2025-08-13 20:13:24 +00:00
renovate[bot]
096e3a0f5f chore(deps): update ibm-semeru-runtimes:open-21.0.8_9-jre docker digest to d1bc86c 2025-08-13 20:13:05 +00:00
renovate[bot]
5090c15f20 chore(deps): update ibm-semeru-runtimes:open-21.0.8_9-jre docker digest to cb42f22 2025-08-13 05:50:29 +00:00
Jérémie Panzer
cb7e74fc21 Merge pull request #1873 from Athou/renovate/debian-13.x
chore(deps): update debian docker tag to v13
2025-08-13 07:50:02 +02:00
renovate[bot]
ff90041ed4 chore(deps): update debian docker tag to v13 2025-08-13 03:52:10 +00:00
renovate[bot]
f8fbe1844a chore(deps): update dependency vite to ^7.1.2 2025-08-12 11:31:12 +00:00
renovate[bot]
1902172a04 chore(deps): update github/codeql-action digest to df55935 2025-08-12 10:50:16 +00:00
renovate[bot]
2df384b847 chore(deps): update dependency @types/react to ^19.1.10 2025-08-11 20:14:30 +00:00
Jérémie Panzer
65bb35b4de Merge pull request #1871 from Athou/renovate/lock-file-maintenance
chore(deps): lock file maintenance
2025-08-11 22:13:56 +02:00
Athou
97516100f5 fix npm ci after renovate lock file maintenance 2025-08-11 21:41:57 +02:00
renovate[bot]
009ec7a59b chore(deps): lock file maintenance 2025-08-11 18:37:47 +00:00
Jérémie Panzer
02890c2b69 Merge pull request #1872 from Athou/renovate/actions-checkout-5.x
chore(deps): update actions/checkout action to v5
2025-08-11 20:36:39 +02:00
renovate[bot]
0f690bf00e chore(deps): update actions/checkout action to v5 2025-08-11 17:14:57 +00:00
Athou
cfe427b34c babel-plugin-macros is not needed anymore since we now use @lingui/babel-plugin-lingui-macro 2025-08-11 14:47:48 +02:00
renovate[bot]
a44c76cdc3 chore(deps): update actions/checkout digest to 08eba0b 2025-08-11 12:14:42 +00:00
renovate[bot]
730bde3d0d fix(deps): update linguijs monorepo to ^5.4.1 2025-08-11 09:55:32 +00:00
renovate[bot]
aa006fe22a fix(deps): update quarkus.version to v3.25.2 2025-08-08 21:31:29 +00:00
renovate[bot]
ca77090ecd chore(deps): update github/codeql-action digest to 76621b6 2025-08-08 12:26:20 +00:00
renovate[bot]
5619d1a4c5 chore(deps): update dependency vite to ^7.1.1 2025-08-08 05:13:13 +00:00
Jérémie Panzer
b7c80c397d Merge pull request #1870 from Athou/renovate/react-router-monorepo
fix(deps): update dependency react-router-dom to ^7.8.0
2025-08-07 23:47:12 +02:00
renovate[bot]
d1e7cd2f85 fix(deps): update dependency react-router-dom to ^7.8.0 2025-08-07 21:14:23 +00:00
renovate[bot]
7da7aeb796 chore(deps): update dependency @biomejs/biome to v2.1.4 2025-08-07 16:32:14 +00:00
Jérémie Panzer
26b46166aa Merge pull request #1869 from Athou/renovate/com.puppycrawl.tools-checkstyle-11.x
chore(deps): update dependency com.puppycrawl.tools:checkstyle to v11
2025-08-07 18:31:21 +02:00
renovate[bot]
6d5eb51a5d fix(deps): update mantine monorepo to ^8.2.4 2025-08-07 11:33:53 +00:00
renovate[bot]
917b6b318f chore(deps): update dependency com.puppycrawl.tools:checkstyle to v11 2025-08-07 11:33:12 +00:00
Jérémie Panzer
bfd95687b8 Merge pull request #1868 from Athou/renovate/vitejs-plugin-react-5.x
chore(deps): update dependency @vitejs/plugin-react to v5
2025-08-07 13:32:43 +02:00
Jérémie Panzer
4198ee1af1 Merge pull request #1867 from Athou/renovate/vite-7.x
chore(deps): update dependency vite to ^7.1.0
2025-08-07 13:32:30 +02:00
renovate[bot]
e9b1280ae6 chore(deps): update dependency @vitejs/plugin-react to v5 2025-08-07 09:49:36 +00:00
renovate[bot]
3c42831db0 chore(deps): update dependency vite to ^7.1.0 2025-08-07 09:49:27 +00:00
renovate[bot]
b8482006b9 fix(deps): update quarkus.version to v3.25.1 2025-08-07 00:23:05 +00:00
Athou
53f0c33c1d release 5.11.0 2025-08-06 22:51:34 +02:00
Jérémie Panzer
563516901e Merge pull request #1866 from Athou/renovate/major-github-artifact-actions
chore(deps): update actions/download-artifact action to v5
2025-08-06 10:41:11 +02:00
renovate[bot]
73b40fd8b7 chore(deps): update actions/download-artifact action to v5 2025-08-06 03:42:33 +00:00
renovate[bot]
08224a8486 fix(deps): update mantine monorepo to ^8.2.3 2025-08-06 03:42:29 +00:00
Jérémie Panzer
993f3d3aa8 Merge pull request #1865 from Athou/renovate/lock-file-maintenance
chore(deps): lock file maintenance
2025-08-04 23:07:56 +02:00
renovate[bot]
3a975de136 chore(deps): lock file maintenance 2025-08-04 22:12:32 +02:00
renovate[bot]
48b5195798 chore(deps): update docker/login-action digest to 184bdaa 2025-08-04 16:28:14 +00:00
Jérémie Panzer
8eb34c7539 Merge pull request #1864 from Athou/renovate/linguijs-monorepo
fix(deps): update linguijs monorepo to ^5.4.0 (minor)
2025-08-01 17:41:33 +02:00
renovate[bot]
d75d7a9209 fix(deps): update linguijs monorepo to ^5.4.0 2025-08-01 14:49:38 +00:00
Jérémie Panzer
ddf851f1eb Merge pull request #1863 from Athou/renovate/node-22.x
chore(deps): update node.js to v22.18.0
2025-08-01 07:14:50 +02:00
renovate[bot]
889dd00c23 chore(deps): update node.js to v22.18.0 2025-08-01 03:24:10 +00:00
Jérémie Panzer
c5ea2a1aa1 Merge pull request #1862 from Athou/renovate/typescript-5.x
chore(deps): update dependency typescript to ^5.9.2
2025-08-01 00:00:50 +02:00
renovate[bot]
1489aff78e chore(deps): update dependency typescript to ^5.9.2 2025-07-31 21:37:49 +00:00
renovate[bot]
640296d42f chore(deps): update dependency npm to v11.5.2 2025-07-30 21:41:05 +00:00
renovate[bot]
3b12b2a5f6 fix(deps): update mantine monorepo to ^8.2.2 2025-07-30 17:02:31 +00:00
Jérémie Panzer
d5c41a5167 Merge pull request #1861 from Athou/renovate/quarkus.version
fix(deps): update quarkus.version to v3.25.0 (minor)
2025-07-30 14:11:33 +02:00
Athou
58bf86d25d remove warnings 2025-07-30 13:30:27 +02:00
renovate[bot]
d73034d6d9 fix(deps): update quarkus.version to v3.25.0 2025-07-30 10:46:35 +00:00
renovate[bot]
151a613dcc chore(deps): update github/codeql-action digest to 51f7732 2025-07-30 00:24:09 +00:00
renovate[bot]
4bb741a42f chore(deps): update dependency @biomejs/biome to v2.1.3 2025-07-29 14:31:22 +00:00
renovate[bot]
cc9c8d3db3 chore(deps): update dependency vite-plugin-checker to ^0.10.2 2025-07-29 13:47:55 +00:00
Athou
c3d4831550 fix sonar warnings 2025-07-29 15:28:52 +02:00
renovate[bot]
31e385fbfb chore(deps): update react monorepo 2025-07-29 10:41:04 +00:00
Athou
a8c47d717c remove unused google analytics support 2025-07-29 12:35:53 +02:00
Athou
9a25157d3f make sonar scan client files too 2025-07-29 10:28:22 +02:00
renovate[bot]
9176e0f7b7 fix(deps): update react monorepo to ^19.1.1 2025-07-28 20:24:38 +00:00
Athou
ff7aa890a6 fix build warning 2025-07-28 19:55:36 +02:00
Jérémie Panzer
03312c1592 Merge pull request #1855 from Athou/renovate/patch-testing-library-monorepo
chore(deps): update dependency @testing-library/jest-dom to ^6.6.4
2025-07-28 09:38:33 +02:00
renovate[bot]
9d1ec2c636 chore(deps): update dependency @testing-library/jest-dom to ^6.6.4 2025-07-28 06:35:05 +00:00
Athou
c49c31a44e let quarkus generate the documentation 2025-07-28 08:33:34 +02:00
renovate[bot]
947c1f562f chore(deps): lock file maintenance 2025-07-28 03:57:26 +00:00
Jérémie Panzer
2d1dbb6988 Merge pull request #1857 from aniol/patch-2
Update messages.po
2025-07-27 17:45:19 +02:00
Aniol
622e46ff67 Update messages.po 2025-07-27 11:46:17 +02:00
renovate[bot]
4ff45a65c3 chore(deps): update ibm-semeru-runtimes docker tag to open-21.0.8_9-jre 2025-07-25 22:54:42 +00:00
Jérémie Panzer
a62676061b Merge pull request #1853 from Athou/renovate/patch-react-router-monorepo
fix(deps): update dependency react-router-dom to ^7.7.1
2025-07-25 11:49:59 +02:00
renovate[bot]
11d77d2265 fix(deps): update dependency react-router-dom to ^7.7.1 2025-07-25 11:21:11 +02:00
Jérémie Panzer
1e7d44b250 Merge pull request #1852 from Athou/renovate/npm-11.x
chore(deps): update dependency npm to v11.5.1
2025-07-24 23:01:56 +02:00
renovate[bot]
ffd86c6d8c chore(deps): update dependency npm to v11.5.1 2025-07-24 20:10:26 +00:00
renovate[bot]
a566c9460d chore(deps): update dependency vite to ^7.0.6 2025-07-24 06:37:44 +00:00
renovate[bot]
24edae3d58 fix(deps): update quarkus.version to v3.24.5 2025-07-23 22:10:27 +00:00
renovate[bot]
97876344c4 chore(deps): update github/codeql-action digest to 4e828ff 2025-07-23 18:03:54 +00:00
Jérémie Panzer
95dbeb9a47 Merge pull request #1851 from Athou/renovate/axios-1.x
fix(deps): update dependency axios to ^1.11.0
2025-07-23 20:03:14 +02:00
renovate[bot]
3fc64859b1 fix(deps): update dependency axios to ^1.11.0 2025-07-23 12:47:09 +00:00
renovate[bot]
896fe3b5b2 chore(deps): update graalvm/setup-graalvm digest to 7f488cf 2025-07-23 12:46:47 +00:00
Jérémie Panzer
85404781a3 Merge pull request #1850 from Athou/renovate/debian-12.11
chore(deps): update debian:12.11 docker digest to b6507e3
2025-07-22 11:39:19 +02:00
renovate[bot]
efe2abc86e chore(deps): update debian:12.11 docker digest to b6507e3 2025-07-22 07:58:53 +00:00
renovate[bot]
b70b7a0b40 chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v2.46.1 2025-07-21 22:55:20 +00:00
Athou
865c80f87b add more integration tests 2025-07-21 20:21:20 +02:00
Athou
23a91aab12 providers can now return multiple urls 2025-07-21 16:57:10 +02:00
Athou
085a3cbb50 unwanted entries are already filtered at the dao level 2025-07-21 16:57:10 +02:00
Athou
fb9d875c31 extract image proxying from FeedUtils 2025-07-21 16:57:10 +02:00
Athou
5ee15c6f68 we no longer need to generate OPML 1.1 files 2025-07-21 16:57:10 +02:00
Athou
9853205849 remove workaround for #39 as it's not valid rdf 0.9 according to the spec 2025-07-21 16:57:10 +02:00
Athou
2c9ce7e8fc remove workaround for #140 that is no longer needed 2025-07-21 16:57:10 +02:00
Jérémie Panzer
9753ae60e2 Merge pull request #1848 from Athou/renovate/mantine-monorepo
fix(deps): update mantine monorepo to ^8.2.1 (minor)
2025-07-21 16:57:04 +02:00
renovate[bot]
bd66f1e682 fix(deps): update mantine monorepo to ^8.2.1 2025-07-21 14:20:33 +00:00
renovate[bot]
ed6a45c119 chore(deps): update dependency vite-plugin-checker to ^0.10.1 2025-07-21 14:20:25 +00:00
renovate[bot]
8f53ce27fc chore(deps): update github/codeql-action digest to d6bbdef 2025-07-21 12:47:08 +00:00
Athou
f7ae2e6689 add even more integration tests 2025-07-21 11:50:10 +02:00
Jérémie Panzer
c6cc47192c Merge pull request #1847 from Athou/renovate/com.diffplug.spotless-spotless-maven-plugin-2.x
chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v2.46.0
2025-07-21 07:39:56 +02:00
renovate[bot]
1c447fe369 chore(deps): lock file maintenance 2025-07-21 03:02:54 +00:00
renovate[bot]
6b5c92db48 chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v2.46.0 2025-07-20 22:32:09 +00:00
Athou
427e020d27 add category integration tests 2025-07-20 23:20:30 +02:00
Athou
18084995b2 fix integration tests code coverage not taken into account 2025-07-20 09:58:01 +02:00
Athou
f894fdf564 extract url utils from FeedUtils 2025-07-20 07:26:43 +02:00
Athou
0b0a964a90 enums are now supported by openapi, allowableValues is no longer required 2025-07-20 01:08:27 +02:00
Athou
d6df979d0d remove more warnings 2025-07-19 23:47:22 +02:00
renovate[bot]
c366c37afe fix(deps): update dependency tss-react to ^4.9.19 2025-07-19 10:06:55 +00:00
Jérémie Panzer
20cbd239b2 Merge pull request #1846 from Athou/alert-autofix-26
fix for code scanning alert no. 26: Workflow does not contain permissions
2025-07-19 12:06:00 +02:00
Jérémie Panzer
a9c7595ee7 Potential fix for code scanning alert no. 26: Workflow does not contain permissions
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2025-07-19 11:58:48 +02:00
Athou
3f09e3ca64 remove warnings 2025-07-19 11:33:38 +02:00
Jérémie Panzer
ed42db7a0d Merge pull request #1845 from Athou/renovate/pin-dependencies
chore(deps): pin actions/setup-java action to c5195ef
2025-07-19 11:14:58 +02:00
renovate[bot]
c85daeb46e chore(deps): pin actions/setup-java action to c5195ef 2025-07-19 09:13:57 +00:00
Athou
3f2b93f1f8 run sonarqube as part of the CI 2025-07-19 11:13:10 +02:00
Athou
78d2e66c56 generate code coverage 2025-07-19 09:19:14 +02:00
Athou
0f2de651ff remove more warnings 2025-07-18 23:07:40 +02:00
Jérémie Panzer
2eb7c7237e Merge pull request #1844 from Athou/sonar-warnings
fix sonar warnings
2025-07-18 22:06:04 +02:00
Athou
3b8f62ff11 fix sonar warnings 2025-07-18 21:49:00 +02:00
Athou
f8bf9370de update SECURITY.md 2025-07-18 09:29:31 +02:00
Jérémie Panzer
30cd0ec089 Merge pull request #1843 from Athou/renovate/vitejs-plugin-react-4.x
chore(deps): update dependency @vitejs/plugin-react to ^4.7.0
2025-07-18 09:04:59 +02:00
Athou
e984be9289 update actions 2025-07-18 08:56:35 +02:00
Jérémie Panzer
8069787754 Merge pull request #1842 from Athou/renovate/pin-dependencies
chore(deps): pin github/codeql-action action to 181d5ee
2025-07-18 08:54:15 +02:00
renovate[bot]
343e442dff chore(deps): update dependency @vitejs/plugin-react to ^4.7.0 2025-07-18 06:35:48 +00:00
renovate[bot]
313ccdeae9 chore(deps): pin github/codeql-action action to 181d5ee 2025-07-18 06:35:21 +00:00
Jérémie Panzer
fdec8ebfd3 Create scorecard.yml 2025-07-18 08:34:40 +02:00
renovate[bot]
efddd86263 fix(deps): update quarkus.version to v3.24.4 2025-07-17 19:53:26 +00:00
renovate[bot]
7d18bde40b chore(deps): update dependency @biomejs/biome to v2.1.2 2025-07-17 15:58:18 +00:00
renovate[bot]
7fee410be4 chore(deps): update dependency vite to ^7.0.5 2025-07-17 05:32:53 +00:00
Jérémie Panzer
ebc2516a53 Merge pull request #1841 from Athou/renovate/react-router-monorepo
fix(deps): update dependency react-router-dom to ^7.7.0
2025-07-17 07:31:48 +02:00
renovate[bot]
ade4d1d782 fix(deps): update dependency react-router-dom to ^7.7.0 2025-07-16 20:58:30 +00:00
renovate[bot]
07f7a288d2 chore(deps): update ibm-semeru-runtimes:open-21.0.7_6-jre docker digest to a51c2a5 2025-07-16 16:43:24 +00:00
Jérémie Panzer
380ed16caf Merge pull request #1840 from Athou/renovate/node-22.17.x
chore(deps): update node.js to v22.17.1
2025-07-16 14:05:42 +02:00
renovate[bot]
db654a10d1 chore(deps): update node.js to v22.17.1 2025-07-16 06:49:48 +00:00
renovate[bot]
2cf84d35cd chore(deps): update dependency maven to v3.9.11 2025-07-16 05:03:29 +00:00
renovate[bot]
a4eac86913 chore(deps): update ibm-semeru-runtimes:open-21.0.7_6-jre docker digest to 7b6e1ee 2025-07-16 03:04:56 +00:00
renovate[bot]
5168be45a8 chore(deps): lock file maintenance 2025-07-14 00:41:04 +00:00
Athou
163ab43da3 lingui documentation mentions that their plugin should be declared before the react compiler plugin 2025-07-11 16:56:06 +02:00
Jérémie Panzer
e5fa517270 Merge pull request #1830 from Athou/renovate/vite-7.x
chore(deps): update dependency vite to v7
2025-07-11 16:15:48 +02:00
renovate[bot]
b8b8ea5ce2 chore(deps): update dependency vite to v7 2025-07-11 13:50:21 +00:00
renovate[bot]
991b147af5 fix(deps): update linguijs monorepo to ^5.3.3 2025-07-11 13:25:53 +00:00
renovate[bot]
ecff62d0fa fix(deps): update quarkus.version to v3.24.3 2025-07-09 17:05:02 +00:00
renovate[bot]
cdec4c0879 chore(deps): update dependency @biomejs/biome to v2.1.1 2025-07-08 17:03:55 +00:00
Jérémie Panzer
e8085ac4cf Merge pull request #1838 from Athou/renovate/biomejs-biome-2.x
chore(deps): update dependency @biomejs/biome to v2.1.0
2025-07-08 14:00:21 +02:00
renovate[bot]
327062112b chore(deps): update dependency @biomejs/biome to v2.1.0 2025-07-08 11:36:19 +00:00
Jérémie Panzer
6dfc23c33a Merge pull request #1837 from Athou/renovate/com.diffplug.spotless-spotless-maven-plugin-2.x
chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v2.45.0
2025-07-08 07:16:20 +02:00
renovate[bot]
a601b0ab35 chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v2.45.0 2025-07-08 03:07:19 +00:00
Jérémie Panzer
a48c8ca87a Merge pull request #1836 from Athou/renovate/vite-plugin-checker-0.x
chore(deps): update dependency vite-plugin-checker to ^0.10.0
2025-07-07 22:25:17 +02:00
renovate[bot]
b59e64a3d1 chore(deps): update dependency vite-plugin-checker to ^0.10.0 2025-07-07 16:57:19 +00:00
renovate[bot]
5fc62dd06d fix(deps): update mantine monorepo to ^8.1.3 2025-07-07 16:57:10 +00:00
renovate[bot]
d81a0cae91 chore(deps): lock file maintenance 2025-07-07 01:52:36 +00:00
Jérémie Panzer
50e31c6b69 Merge pull request #1834 from Athou/renovate/patch-quarkus.version
fix(deps): update quarkus.version to v3.24.2 (patch)
2025-07-02 22:36:15 +02:00
Jérémie Panzer
92d3d88127 Merge pull request #1833 from Athou/renovate/ibm-semeru-runtimes-open-21.0.7_6-jre
chore(deps): update ibm-semeru-runtimes:open-21.0.7_6-jre docker digest to 17a67d7
2025-07-02 22:36:09 +02:00
renovate[bot]
517fdb2095 fix(deps): update quarkus.version to v3.24.2 2025-07-02 11:42:24 +00:00
renovate[bot]
d16ebb02b4 chore(deps): update ibm-semeru-runtimes:open-21.0.7_6-jre docker digest to 17a67d7 2025-07-02 11:42:21 +00:00
renovate[bot]
a5c64c8b7b chore(deps): update debian:12.11 docker digest to d42b86d 2025-07-01 08:39:24 +00:00
renovate[bot]
5287a93484 chore(deps): update dependency io.quarkiverse.playwright:quarkus-playwright to v2.1.3 2025-06-30 15:45:38 +00:00
renovate[bot]
06e84d9032 chore(deps): lock file maintenance 2025-06-30 06:50:33 +00:00
Jérémie Panzer
3a63dd032a Merge pull request #1832 from Athou/renovate/io.quarkiverse.playwright-quarkus-playwright-2.1.x
chore(deps): update dependency io.quarkiverse.playwright:quarkus-playwright to v2.1.2
2025-06-30 08:48:51 +02:00
renovate[bot]
889e227523 chore(deps): update dependency io.quarkiverse.playwright:quarkus-playwright to v2.1.2 2025-06-30 06:12:02 +00:00
Athou
57d895daf5 fix playwright tests 2025-06-30 08:08:01 +02:00
renovate[bot]
a744394faa chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.26.1 2025-06-30 01:01:56 +00:00
renovate[bot]
64e3c25bad chore(deps): update ncipollo/release-action digest to bcfe547 2025-06-29 21:05:27 +00:00
renovate[bot]
75f85e1fb2 chore(deps): update ncipollo/release-action digest to 9128f23 2025-06-29 02:27:25 +00:00
renovate[bot]
00bd4cab37 fix(deps): update dependency react-router-dom to ^7.6.3 2025-06-27 22:26:32 +00:00
Athou
a9527f59a9 add @/ prefix for absolute imports 2025-06-27 16:29:31 +02:00
renovate[bot]
77661930f0 chore(deps): update dependency @biomejs/biome to v2.0.6 2025-06-27 13:14:09 +00:00
Athou
80a09bd9a0 use quarkus-playwright to simplify tests 2025-06-26 21:30:29 +02:00
Jérémie Panzer
6eb7cfbdc2 Merge pull request #1831 from Athou/renovate/react-draggable-4.x
fix(deps): update dependency react-draggable to ^4.5.0
2025-06-26 06:11:08 +02:00
renovate[bot]
fb186530aa fix(deps): update dependency react-draggable to ^4.5.0 2025-06-25 20:36:05 +00:00
renovate[bot]
6c121ccb90 fix(deps): update mantine monorepo to ^8.1.2 2025-06-25 17:40:13 +00:00
renovate[bot]
c08ad3b365 chore(deps): update graalvm/setup-graalvm digest to e1df20a 2025-06-25 17:00:47 +00:00
Jérémie Panzer
1668bc88ad Merge pull request #1828 from Athou/renovate/node-22.x
chore(deps): update node.js to v22.17.0
2025-06-25 19:00:06 +02:00
Jérémie Panzer
3a43f62460 Merge pull request #1829 from Athou/renovate/quarkus.version
fix(deps): update quarkus.version to v3.24.1 (minor)
2025-06-25 18:44:04 +02:00
renovate[bot]
bfba5179d1 fix(deps): update quarkus.version to v3.24.1 2025-06-25 15:15:03 +00:00
renovate[bot]
78bf7856dc chore(deps): update node.js to v22.17.0 2025-06-25 15:14:58 +00:00
Jérémie Panzer
e0c708f677 Merge pull request #1827 from Athou/renovate/com.puppycrawl.tools-checkstyle-10.x
chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.26.0
2025-06-25 17:13:36 +02:00
renovate[bot]
794d6824e8 chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.26.0 2025-06-25 12:44:58 +00:00
renovate[bot]
15573a7bee chore(deps): update dependency @biomejs/biome to v2.0.5 2025-06-23 16:46:39 +00:00
Jérémie Panzer
31c61a79c6 Merge pull request #1824 from Athou/renovate/org.jsoup-jsoup-1.x
fix(deps): update dependency org.jsoup:jsoup to v1.21.1
2025-06-23 08:18:44 +02:00
Jérémie Panzer
87ca427094 Merge pull request #1823 from Athou/renovate/vitejs-plugin-react-4.x
chore(deps): update dependency @vitejs/plugin-react to ^4.6.0
2025-06-23 08:18:30 +02:00
renovate[bot]
99bdc904e0 fix(deps): update dependency org.jsoup:jsoup to v1.21.1 2025-06-23 05:28:26 +00:00
renovate[bot]
2fdee68feb chore(deps): update dependency @vitejs/plugin-react to ^4.6.0 2025-06-23 05:28:23 +00:00
renovate[bot]
7be014f83e chore(deps): lock file maintenance 2025-06-23 02:43:32 +00:00
renovate[bot]
5668fe0a33 chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.25.1 2025-06-21 16:33:29 +00:00
Jérémie Panzer
32c07efe19 Merge pull request #1821 from Athou/renovate/biomejs-biome-2.0.x
chore(deps): update dependency @biomejs/biome to v2.0.4
2025-06-21 14:03:28 +02:00
renovate[bot]
21b23d0f79 chore(deps): update dependency @biomejs/biome to v2.0.4 2025-06-21 10:03:08 +00:00
Jérémie Panzer
793d0dd13f Merge pull request #1822 from c-cesar/patch-1
Update pt translations
2025-06-21 09:53:12 +02:00
ccesar
14e8ff4c1b Update pt translations
Some fixes and translated the remaining strings.
2025-06-20 23:51:38 -03:00
renovate[bot]
416ab06997 fix(deps): update swagger.version to v2.2.34 2025-06-20 12:09:56 +00:00
renovate[bot]
493cd60dae fix(deps): update dependency io.dropwizard.metrics:metrics-json to v4.2.33 2025-06-20 00:44:19 +00:00
Jérémie Panzer
e0948e1e9e Merge pull request #1819 from Athou/renovate/patch-quarkus.version
fix(deps): update quarkus.version to v3.23.4 (patch)
2025-06-20 00:21:57 +02:00
renovate[bot]
5776b8c044 fix(deps): update quarkus.version to v3.23.4 2025-06-19 16:55:06 +00:00
Athou
38ab4105d8 noUnusedImports and noUnusedVariables are now enabled by default 2025-06-18 20:46:56 +02:00
renovate[bot]
5ed9dadcc2 chore(deps): update docker/setup-buildx-action digest to e468171 2025-06-18 14:10:38 +00:00
renovate[bot]
357d7e2381 chore(deps): update ibm-semeru-runtimes:open-21.0.7_6-jre docker digest to c5b834e 2025-06-17 23:51:09 +00:00
renovate[bot]
8cfaab3e9f chore(deps): update dependency vitest to ^3.2.4 2025-06-17 18:15:47 +00:00
Athou
fef2404357 update biome to v2 2025-06-17 20:14:38 +02:00
renovate[bot]
1aa1bce8c8 fix(deps): update mantine monorepo to ^8.1.1 2025-06-16 22:14:42 +00:00
renovate[bot]
124b2761f6 chore(deps): update docker/setup-buildx-action digest to 18ce135 2025-06-16 17:11:47 +00:00
renovate[bot]
066ca1af7c chore(deps): lock file maintenance 2025-06-16 02:29:40 +00:00
Jérémie Panzer
c20520879b Merge pull request #1817 from Athou/renovate/axios-1.x
fix(deps): update dependency axios to ^1.10.0
2025-06-14 17:35:48 +02:00
renovate[bot]
4fa5b2b856 fix(deps): update dependency axios to ^1.10.0 2025-06-14 14:05:49 +00:00
renovate[bot]
5c1b1fad76 fix(deps): update swagger.version to v2.2.33 2025-06-14 09:46:23 +00:00
renovate[bot]
c18d248c06 chore(deps): update dependency npm to v11.4.2 2025-06-14 07:26:37 +00:00
Athou
d46ee7f673 remove deprecated usage of saveOrUpdate in preparation of hibernate 7 2025-06-13 14:49:22 +02:00
renovate[bot]
f2c0d99bd9 fix(deps): update quarkus.version to v3.23.3 2025-06-12 00:04:22 +00:00
renovate[bot]
60ee0b9185 chore(deps): update dependency @types/react to ^19.1.8 2025-06-11 17:51:58 +00:00
renovate[bot]
4b3e660ae7 chore(deps): update debian:12.11 docker digest to 0d8498a 2025-06-11 03:06:07 +00:00
renovate[bot]
0b42392bfc chore(deps): update dependency vitest to ^3.2.3 2025-06-10 07:21:05 +00:00
renovate[bot]
a94d7ce235 chore(deps): update dependency @vitejs/plugin-react to ^4.5.2 2025-06-10 06:24:42 +00:00
Jérémie Panzer
72aec432ed Merge pull request #1814 from WangLei1993/master
add Chinese translation for new entry
2025-06-10 08:23:18 +02:00
WangLei1993
0e5db8d604 add Chinese translation for new entry 2025-06-10 13:34:56 +08:00
Jérémie Panzer
dc45fb4b84 Merge pull request #1812 from Athou/renovate/mantine-monorepo
fix(deps): update mantine monorepo to ^8.1.0 (minor)
2025-06-10 07:06:50 +02:00
Jérémie Panzer
6503d38fe3 Merge pull request #1813 from canoine/patch-5
Update fr/messages.po
2025-06-10 07:06:35 +02:00
canoine
32c89d9a11 Update fr/messages.po
Translation of the new messages.
2025-06-10 06:04:09 +02:00
renovate[bot]
f279465750 fix(deps): update mantine monorepo to ^8.1.0 2025-06-09 21:31:32 +00:00
renovate[bot]
58ec1b022a chore(deps): update dependency @types/react to ^19.1.7 2025-06-09 21:31:12 +00:00
Athou
612199429e fix custom css code documentation link (#1811) 2025-06-09 22:36:17 +02:00
Jérémie Panzer
e5482f9051 Merge pull request #1810 from Athou/renovate/major-querydsl.version
fix(deps): update querydsl.version to v7 (major)
2025-06-09 18:31:14 +02:00
renovate[bot]
05df14fda2 fix(deps): update querydsl.version to v7 2025-06-09 15:52:21 +00:00
renovate[bot]
29898ba1ba fix(deps): update dependency @fontsource/open-sans to ^5.2.6 2025-06-09 08:55:10 +00:00
renovate[bot]
93d1cec503 chore(deps): update dependency rollup-plugin-visualizer to ^6.0.3 2025-06-07 14:00:43 +00:00
renovate[bot]
9884f44122 fix(deps): update dependency style-to-object to ^1.0.9 2025-06-07 02:54:31 +00:00
renovate[bot]
d400456685 chore(deps): update dependency vitest to ^3.2.2 2025-06-06 23:49:01 +00:00
renovate[bot]
c39069cafd chore(deps): update dependency maven to v3.9.10 2025-06-06 12:01:14 +00:00
Jérémie Panzer
5fb0edc318 Merge pull request #1808 from Athou/renovate/patch-quarkus.version
fix(deps): update quarkus.version to v3.23.2 (patch)
2025-06-05 07:06:42 +02:00
renovate[bot]
21a6b2d780 fix(deps): update quarkus.version to v3.23.2 2025-06-04 22:32:20 +00:00
renovate[bot]
40c9063a54 chore(deps): update dependency @types/react-dom to ^19.1.6 2025-06-04 15:57:40 +00:00
Athou
59b0103ed5 add an option to navigate to the next unread category/feed when marking all as read (#1807) 2025-06-04 09:10:03 +02:00
Athou
f4730e9338 redirect to 'all' if no unread categories or feeds found or if we reached the end of the list (#1807) 2025-06-04 08:40:22 +02:00
Athou
b7b520ca3c faster integration tests execution by truncating tables instead of dropping and recreating tables 2025-06-04 08:35:03 +02:00
renovate[bot]
21d44e6a55 fix(deps): update dependency react-router-dom to ^7.6.2 2025-06-04 00:47:19 +00:00
renovate[bot]
607886f0f0 chore(deps): update dependency vitest to ^3.2.1 2025-06-03 18:19:26 +00:00
Jérémie Panzer
7cd3c68256 Merge pull request #1806 from Athou/renovate/vitejs-plugin-react-4.5.x
chore(deps): update dependency @vitejs/plugin-react to ^4.5.1
2025-06-03 12:02:04 +02:00
renovate[bot]
6e37c1bd86 chore(deps): update dependency @vitejs/plugin-react to ^4.5.1 2025-06-03 06:04:05 +00:00
Jérémie Panzer
5db1a0748f Merge pull request #1805 from Athou/renovate/vitest-monorepo
chore(deps): update dependency vitest to ^3.2.0
2025-06-02 20:20:24 +02:00
renovate[bot]
a7584df4f4 chore(deps): update dependency vitest to ^3.2.0 2025-06-02 13:57:05 +00:00
Athou
4421197403 remove unused variable 2025-06-02 07:42:19 +02:00
renovate[bot]
15b59467fb chore(deps): lock file maintenance 2025-06-02 01:17:56 +00:00
Jérémie Panzer
c95ff0a2ce Merge pull request #1804 from Athou/renovate/com.puppycrawl.tools-checkstyle-10.x
chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.25.0
2025-05-31 20:48:46 +02:00
renovate[bot]
7eff9df025 chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.25.0 2025-05-31 18:22:52 +00:00
Athou
2f05e53e14 remove feed/refresh rest endpoint as it's unused and does not honor the force-refresh-cooldown-duration setting (#1802) 2025-05-30 11:19:26 +02:00
renovate[bot]
6089fe4036 fix(deps): update linguijs monorepo to ^5.3.2 2025-05-28 14:38:20 +00:00
renovate[bot]
10d9af0d86 chore(deps): update dependency rollup-plugin-visualizer to ^6.0.1 2025-05-28 13:12:40 +00:00
Jérémie Panzer
c119d5062a Merge pull request #1800 from Athou/renovate/quarkus.version
fix(deps): update quarkus.version to v3.23.0 (minor)
2025-05-28 15:11:46 +02:00
renovate[bot]
324609ee60 fix(deps): update quarkus.version to v3.23.0 2025-05-28 11:39:17 +00:00
renovate[bot]
a0a65f2b45 chore(deps): update dependency org.codehaus.mojo:exec-maven-plugin to v3.5.1 2025-05-28 07:28:55 +00:00
renovate[bot]
45e5ca704c chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v2.44.5 2025-05-28 05:10:12 +00:00
307 changed files with 18179 additions and 10367 deletions

View File

@@ -7,7 +7,7 @@ on:
pull_request:
env:
JAVA_VERSION: 21
JAVA_VERSION: 25
DOCKER_BUILD_SUMMARY: false
jobs:
@@ -23,13 +23,13 @@ jobs:
steps:
# Checkout
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 0
# Setup
- name: Set up GraalVM
uses: graalvm/setup-graalvm@01ed653ac833fe80569f1ef9f25585ba2811baab # v1
uses: graalvm/setup-graalvm@54b4f5a65c1a84b2fdfdc2078fe43df32819e4b1 # v1
with:
java-version: ${{ env.JAVA_VERSION }}
distribution: "graalvm"
@@ -48,39 +48,39 @@ jobs:
run: mkdir -p target/pages/documentation/custom-css
- name: Convert readme file to html
uses: jaywcjlove/markdown-to-html-cli@d2c8ffd676de1801e2586904bc540a938e4bc480 # v5.0.3
uses: jaywcjlove/markdown-to-html-cli@cff9330af4ca8048b197a76d9eb1db189c2a7cee # v5.0.4
with:
source: README.md
output: target/pages/index.html
- name: Convert config documentation to html
uses: jaywcjlove/markdown-to-html-cli@d2c8ffd676de1801e2586904bc540a938e4bc480 # v5.0.3
uses: jaywcjlove/markdown-to-html-cli@cff9330af4ca8048b197a76d9eb1db189c2a7cee # v5.0.4
with:
source: commafeed-server/target/quarkus-generated-doc/config/commafeed-server.md
output: target/pages/documentation/index.html
- name: Convert custom css documentation to html
uses: jaywcjlove/markdown-to-html-cli@d2c8ffd676de1801e2586904bc540a938e4bc480 # v5.0.3
uses: jaywcjlove/markdown-to-html-cli@cff9330af4ca8048b197a76d9eb1db189c2a7cee # v5.0.4
with:
source: documentation/CUSTOMCSS.md
output: target/pages/documentation/custom-css/index.html
# Upload artifacts
- name: Upload cross-platform app
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
if: matrix.os == 'ubuntu-latest' # we only need to upload the cross-platform artifact once per database
with:
name: commafeed-${{ matrix.database }}-jvm
path: commafeed-server/target/commafeed-*.zip
- name: Upload native executable
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
with:
name: commafeed-${{ matrix.database }}-${{ runner.os }}-${{ runner.arch }}
path: commafeed-server/target/commafeed-*-runner*
- name: Upload pages
uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3
uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4
if: matrix.os == 'ubuntu-latest' && matrix.database == 'h2' # we only need to upload the pages once
with:
path: target/pages
@@ -98,23 +98,23 @@ jobs:
steps:
# Checkout
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 0
# Setup
- name: Set up QEMU
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
- name: Install required packages
run: sudo apt-get install -y rename unzip
# Prepare artifacts
- name: Download artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
with:
pattern: commafeed-${{ matrix.database }}-*
path: ./artifacts
@@ -135,7 +135,7 @@ jobs:
# Docker
- name: Login to Container Registry
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
if: ${{ env.DOCKERHUB_USERNAME != '' }}
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
@@ -143,7 +143,7 @@ jobs:
## build but don't push for PRs and renovate
- name: Docker build - native
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
with:
context: .
file: commafeed-server/src/main/docker/Dockerfile.native
@@ -151,7 +151,7 @@ jobs:
platforms: linux/amd64,linux/arm64/v8
- name: Docker build - jvm
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
with:
context: .
file: commafeed-server/src/main/docker/Dockerfile.jvm
@@ -160,7 +160,7 @@ jobs:
## build and push tag
- name: Docker build and push tag - native
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
if: ${{ github.ref_type == 'tag' }}
with:
context: .
@@ -172,7 +172,7 @@ jobs:
athou/commafeed:${{ github.ref_name }}-${{ matrix.database }}
- name: Docker build and push tag - jvm
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
if: ${{ github.ref_type == 'tag' }}
with:
context: .
@@ -185,7 +185,7 @@ jobs:
## build and push master
- name: Docker build and push master - native
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
if: ${{ github.ref_name == 'master' }}
with:
context: .
@@ -195,7 +195,7 @@ jobs:
tags: athou/commafeed:master-${{ matrix.database }}
- name: Docker build and push master - jvm
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
if: ${{ github.ref_name == 'master' }}
with:
context: .
@@ -215,12 +215,12 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 0
- name: Download artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
with:
pattern: commafeed-*
path: ./artifacts
@@ -236,7 +236,7 @@ jobs:
version: ${{ github.ref_name }}
- name: Create GitHub release
uses: ncipollo/release-action@440c8c1cb0ed28b9f43e4d1d670870f059653174 # v1
uses: ncipollo/release-action@b7eabc95ff50cbeeedec83973935c8f306dfcd0b # v1
with:
name: CommaFeed ${{ github.ref_name }}
body: ${{ steps.changelog_reader.outputs.changes }}
@@ -249,12 +249,12 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 0
- name: Update Docker Hub Description
uses: peter-evans/dockerhub-description@432a30c9e07499fd01da9f8a49f0faf9e0ca5b77 # v4
uses: peter-evans/dockerhub-description@1b9a80c056b620d92cedb9d9b5a223409c68ddfa # v5
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

View File

@@ -1,18 +1,3 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
wrapperVersion=3.3.4
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.12/apache-maven-3.9.12-bin.zip

View File

@@ -1,5 +1,60 @@
# Changelog
## [7.0.0]
- Replaced the JEXL filter expression for marking feed entries as read automatically with a user-friendly visual query builder. Expressions are now evaluated with Common Expression Language, which is safer than JEXL and sanboxed by default.
- Added a per-feed setting for sending push notifications to ntfy, Gotify or Pushover when new feed entries are discovered (#1610)
- Added a per-feed setting for marking entries as read after a number of days (#2041)
- The default value of `commafeed.http-client.block-local-addresses` is now false, allowing users to subscribe to feeds only available on their local network. This may be a security risk (SSRF) if your instance is accessible by untrusted users, so you may want to set it to true if you host a public instance of CommaFeed with user registeration enabled.
- When `commafeed.http-client.block-local-addresses` is enabled, SSRF is now also mitigated by blocking public websites redirecting to local ones.
## [6.2.0]
- Starred entries are no longer deleted after a certain amount of time, they are now kept indefinitely. The new `commafeed.database.cleanup.keep-starred-entries` setting can be disabled to restore the previous behavior if you want to keep deleting starred entries during normal entries cleanup (#1581)
## [6.1.1]
- Fix old starred entries not loading if they were marked as read (#2031)
## [6.1.0]
- When clicking on the password reset link, a random password is no longer generated automatically. The user is now redirected to a page where they can set their own password (#2023)
- Use browser preferred language instead of English when using CommaFeed for the first time (#2018)
- The profile menu is now closed when scrolling the page (#2019)
- The "disable pull to refresh" feature is now disabled by default (#2030)
## [6.0.0]
- When booting CommaFeed for the first time, the default "admin" account is no longer created automatically. A setup wizard will guide you through the creation of an admin account
- Default password complexity requirements have been lowered for local network deployments, where strict password rules are often unnecessary. The `commafeed.users.strict-password-policy` setting has been replaced by `commafeed.users.minimum-password-length` with a default value of `4` (#1916)
- Email addresses are no longer required when creating users and when they update their profile. The `commafeed.users.email-address-required` setting has been added to restore the previous behavior (#1914)
- Java 25+ is now required to build and run CommaFeed
## [5.12.1]
- The favicon is now crispier (#1978)
- The ReadKit iOS app now works via the Fever API (#1602)
## [5.12.0]
- Added a setting to disable the "disable pull to refresh" feature because it messes with some browsers (#1168)
- Emojis in feeds are now correctly displayed (#1955)
- Don't show "Star/Unstar" in the context menu if the entry is too old to be starred (#1935)
- Invalid relative urls in feeds no longer prevent those feeds from being parsed (#1939)
- Fix an issue that could prevent large feeds from being parsed when using Java 24+ (#1961)
- Enforce user password validation when created in the admin view (#1937)
- The process in the docker native image is now called "commafeed" instead of "application"
## [5.11.1]
- The search limit of 3 characters has been removed (#1887)
- Fix an issue that caused feed filtering expressions to be incorrectly converted to lowercase when saving them (#1899)
## [5.11.0]
- Add an option to navigate to the next unread category/feed when marking all entries as read (#1807)
- Google Analytics support has been removed
## [5.10.0]
- Add an indicator next to each feed's unread count in the tree to show when new entries are discovered while the app is open (#1762)

View File

@@ -17,6 +17,7 @@ Google Reader inspired self-hosted RSS reader, based on Quarkus and React/TypeSc
- REST API
- Fever-compatible API for native mobile apps
- Can automatically mark articles as read based on user-defined rules
- Push notifications when new articles are published
- Highly customizable with [custom CSS](https://athou.github.io/commafeed/documentation/custom-css) and JavaScript
- [Browser extension](https://github.com/Athou/commafeed-browser-extension)
- Compiles to native code for blazing fast startup and low memory usage
@@ -26,11 +27,18 @@ Google Reader inspired self-hosted RSS reader, based on Quarkus and React/TypeSc
- MySQL
- MariaDB
## Deployment
## Usage
### Public instance
A free public instance is available at https://www.commafeed.com.
It has no ads, no tracking, and your data is never exploited or sold to third parties. The service is funded entirely through donations.
However, this public instance does have a few limitations compared to self-hosted setups, outlined [here](https://github.com/Athou/commafeed/discussions/1567).
### Docker
Docker is the easiest way to get started with CommaFeed.
Docker is the easiest way to get started with self-hosted CommaFeed.
Docker images are built automatically and are available at https://hub.docker.com/r/athou/commafeed
@@ -103,7 +111,7 @@ There are multiple ways to configure CommaFeed:
- Environment variables (keys in UPPER_CASE)
- a `.env` file in the working directory (keys in UPPER_CASE)
The properties file is recommended because CommaFeed will be able to warn about invalid properties and typos.
When in doubt, the properties file is recommended because CommaFeed will be able to warn about invalid properties and typos.
All [CommaFeed settings](https://athou.github.io/commafeed/documentation) are optional and have sensible default values.
@@ -113,7 +121,6 @@ meaning that you will have to log back in after each restart of the application.
All other Quarkus settings can be found [here](https://quarkus.io/guides/all-config).
When started, the server will listen on http://localhost:8082.
The default user is `admin` and the default password is `admin`.
### Updates

View File

@@ -2,5 +2,4 @@
## Reporting a Vulnerability
If you found a vulnerability that you deem too sensitive to disclose publicly in a Github issue, please send an email at jeremiepanzer at gmail dot com.
Thanks !
If you found a vulnerability that you deem too sensitive to disclose publicly in a Github issue, please create a private security advisory here: https://github.com/Athou/commafeed/security/advisories

View File

@@ -23,9 +23,6 @@ dist-ssr
*.sln
*.sw?
# rollup-plugin-visualizer
/stats.html
# vite
vite.config.ts.timestamp-*.mjs

View File

@@ -0,0 +1 @@
cd commafeed-client && npx lint-staged

View File

@@ -1,5 +1,5 @@
{
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
"$schema": "https://biomejs.dev/schemas/2.4.2/schema.json",
"formatter": {
"indentStyle": "space",
"indentWidth": 4,
@@ -13,15 +13,7 @@
"arrowParentheses": "asNeeded"
}
},
"linter": {
"rules": {
"correctness": {
"noUnusedImports": "error",
"noUnusedVariables": "error"
}
}
},
"files": {
"ignore": ["dist", "node_modules", "target", "target-ide"]
"includes": ["**", "!**/dist", "!**/node_modules", "!**/target", "!**/target-ide"]
}
}

View File

@@ -2,6 +2,7 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="favicon.svg" />
<link rel="icon" type="image/x-icon" href="favicon.ico" />
<link rel="manifest" href="manifest.json" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />

View File

@@ -0,0 +1,3 @@
export default {
"src/**/*.{js,jsx,ts,tsx}": () => ["npm run i18n:extract", "git diff --exit-code commafeed-client/src/locales/en/messages.po"],
}

File diff suppressed because it is too large Load Diff

View File

@@ -12,74 +12,75 @@
"test:ci": "vitest run",
"lint": "biome check",
"lint:fix": "biome check --write",
"i18n:extract": "lingui extract --clean"
"i18n:extract": "lingui extract --clean",
"prepare": "cd .. && husky ./commafeed-client/.husky"
},
"dependencies": {
"@emotion/react": "^11.14.0",
"@fontsource/open-sans": "^5.2.5",
"@lingui/core": "^5.3.1",
"@lingui/react": "^5.3.1",
"@mantine/core": "^8.0.2",
"@mantine/form": "^8.0.2",
"@mantine/hooks": "^8.0.2",
"@mantine/modals": "^8.0.2",
"@mantine/notifications": "^8.0.2",
"@mantine/spotlight": "^8.0.2",
"@fontsource/open-sans": "^5.2.7",
"@lingui/core": "^5.9.1",
"@lingui/react": "^5.9.1",
"@mantine/core": "^8.3.15",
"@mantine/form": "^8.3.15",
"@mantine/hooks": "^8.3.15",
"@mantine/modals": "^8.3.15",
"@mantine/notifications": "^8.3.15",
"@mantine/spotlight": "^8.3.15",
"@monaco-editor/react": "^4.7.0",
"@reduxjs/toolkit": "^2.8.2",
"axios": "^1.9.0",
"dayjs": "^1.11.13",
"@react-querybuilder/mantine": "^8.14.0",
"@reduxjs/toolkit": "^2.11.2",
"axios": "^1.13.5",
"dayjs": "^1.11.19",
"escape-string-regexp": "^5.0.0",
"interweave": "^13.1.1",
"monaco-editor": "^0.52.2",
"monaco-editor": "^0.55.1",
"mousetrap": "^1.6.5",
"react": "^19.1.0",
"react": "^19.2.4",
"react-async-hook": "^4.0.0",
"react-contexify": "^6.0.0",
"react-device-detect": "^2.2.3",
"react-dom": "^19.1.0",
"react-draggable": "^4.4.6",
"react-ga4": "^2.1.0",
"react-dom": "^19.2.4",
"react-draggable": "^4.5.0",
"react-icons": "^5.5.0",
"react-infinite-scroller": "^1.2.6",
"react-querybuilder": "^8.14.0",
"react-redux": "^9.2.0",
"react-router-dom": "^7.6.1",
"react-router-dom": "^7.13.0",
"react-swipeable": "^7.0.2",
"redoc": "^2.5.0",
"style-to-object": "^1.0.8",
"style-to-object": "^1.0.14",
"throttle-debounce": "^5.0.2",
"tinycon": "^0.6.8",
"tss-react": "^4.9.18",
"tss-react": "^4.9.20",
"websocket-heartbeat-js": "^1.1.3"
},
"devDependencies": {
"@biomejs/biome": "^1.9.4",
"@lingui/babel-plugin-lingui-macro": "^5.3.1",
"@lingui/cli": "^5.3.1",
"@lingui/vite-plugin": "^5.3.1",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.3.0",
"@biomejs/biome": "^2.4.2",
"@lingui/babel-plugin-lingui-macro": "^5.9.1",
"@lingui/cli": "^5.9.1",
"@lingui/vite-plugin": "^5.9.1",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "^14.6.1",
"@types/mousetrap": "^1.6.15",
"@types/react": "^19.1.6",
"@types/react-dom": "^19.1.5",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@types/react-infinite-scroller": "^1.2.5",
"@types/throttle-debounce": "^5.0.2",
"@types/tinycon": "^0.6.7",
"@vitejs/plugin-react": "^4.5.0",
"babel-plugin-macros": "^3.1.0",
"babel-plugin-react-compiler": "^19.1.0-rc.2",
"jsdom": "^26.1.0",
"rollup-plugin-visualizer": "^6.0.0",
"typescript": "^5.8.3",
"vite": "^6.3.5",
"vite-plugin-checker": "^0.9.3",
"vite-tsconfig-paths": "^5.1.4",
"vitest": "^3.1.4"
"@vitejs/plugin-react": "^5.1.4",
"babel-plugin-react-compiler": "1.0.0",
"husky": "^9.1.7",
"jsdom": "^28.1.0",
"lint-staged": "^16.2.7",
"typescript": "^5.9.3",
"vite": "^7.3.1",
"vite-plugin-checker": "^0.12.0",
"vite-tsconfig-paths": "^6.1.1",
"vitest": "^4.0.18",
"yaml": "^2.8.2"
},
"overrides": {
"react-infinite-scroller": {
"react": "^19.1.0"
"react": "^19.2.4"
}
}
}

View File

@@ -6,16 +6,16 @@
<parent>
<groupId>com.commafeed</groupId>
<artifactId>commafeed</artifactId>
<version>5.10.0</version>
<version>7.0.0</version>
</parent>
<artifactId>commafeed-client</artifactId>
<name>CommaFeed Client</name>
<properties>
<!-- renovate: datasource=node-version depName=node -->
<node.version>v22.16.0</node.version>
<node.version>v24.13.1</node.version>
<!-- renovate: datasource=npm depName=npm -->
<npm.version>11.4.1</npm.version>
<npm.version>11.10.0</npm.version>
</properties>
<build>
@@ -23,7 +23,7 @@
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.15.1</version>
<version>2.0.0</version>
<?m2e ignore?>
<executions>
<execution>
@@ -72,7 +72,7 @@
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.3.1</version>
<version>3.4.0</version>
<executions>
<execution>
<id>copy web interface to resources</id>

View File

@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="393.84613"
width="393.84613"
viewBox="0 0 5.0480766 5.0480766"
version="1.1"
id="svg3"
sodipodi:docname="favicon.svg"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs3" />
<sodipodi:namedview
id="namedview3"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="1.21875"
inkscape:cx="207.17949"
inkscape:cy="187.07692"
inkscape:window-width="1440"
inkscape:window-height="855"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg3" />
<rect
fill="#f88a14"
rx="0.53846151"
ry="0.53846151"
height="5.0480766"
width="5.0480766"
id="rect1"
x="0"
y="0"
style="stroke-width:0.769231" />
<path
d="m 1.3450904,0.64548657 c 2.9002,0 2.9002,2.91010003 2.9002,2.91010003"
fill="none"
stroke="#ffffff"
stroke-linecap="round"
stroke-width="0.78125"
id="path1" />
<path
d="m 1.3377904,1.9915866 c 1.5705,-0.00908 1.5705,1.5639 1.5705,1.5639"
fill="none"
stroke="#ffffff"
stroke-linecap="round"
stroke-width="0.78125"
id="path2" />
<path
d="m 2.0192904,3.5227866 c 0,0.23366 -0.10712,0.47418 -0.24663,0.6537 -0.1814,0.2333 -0.5705,0.5618 -0.6913,0.5653 0.0402,-0.0662 0.263,-0.5654 0.2563,-0.5654 -0.36423004,0 -0.65950004,-0.29265 -0.65950004,-0.65365 0,-0.361 0.29527,-0.65365 0.65950004,-0.65365 0.36423,0 0.68159,0.29265 0.68159,0.65365 z"
fill="#ffffff"
id="path3" />
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -3,40 +3,46 @@ import { I18nProvider } from "@lingui/react"
import { MantineProvider } from "@mantine/core"
import { ModalsProvider } from "@mantine/modals"
import { Notifications } from "@mantine/notifications"
import { Constants } from "app/constants"
import { redirectTo } from "app/redirect/slice"
import { reloadServerInfos } from "app/server/thunks"
import { useAppDispatch, useAppSelector } from "app/store"
import { categoryUnreadCount } from "app/utils"
import { DisablePullToRefresh } from "components/DisablePullToRefresh"
import { ErrorBoundary } from "components/ErrorBoundary"
import { Header } from "components/header/Header"
import { Tree } from "components/sidebar/Tree"
import { useAppLoading } from "hooks/useAppLoading"
import { useBrowserExtension } from "hooks/useBrowserExtension"
import { useI18n } from "i18n"
import { WelcomePage } from "pages/WelcomePage"
import { AdminUsersPage } from "pages/admin/AdminUsersPage"
import { MetricsPage } from "pages/admin/MetricsPage"
import { AboutPage } from "pages/app/AboutPage"
import { AddPage } from "pages/app/AddPage"
import { CategoryDetailsPage } from "pages/app/CategoryDetailsPage"
import { DonatePage } from "pages/app/DonatePage"
import { FeedDetailsPage } from "pages/app/FeedDetailsPage"
import { FeedEntriesPage } from "pages/app/FeedEntriesPage"
import Layout from "pages/app/Layout"
import { SettingsPage } from "pages/app/SettingsPage"
import { TagDetailsPage } from "pages/app/TagDetailsPage"
import { LoginPage } from "pages/auth/LoginPage"
import { PasswordRecoveryPage } from "pages/auth/PasswordRecoveryPage"
import { RegistrationPage } from "pages/auth/RegistrationPage"
import React, { useEffect, useState } from "react"
import { isSafari } from "react-device-detect"
import ReactGA from "react-ga4"
import { HashRouter, Navigate, Route, Routes, useLocation, useNavigate } from "react-router-dom"
import type React from "react"
import { useEffect, useState } from "react"
import { HashRouter, Navigate, Route, Routes, useNavigate } from "react-router-dom"
import Tinycon from "tinycon"
import { Constants } from "@/app/constants"
import { redirectTo } from "@/app/redirect/slice"
import { redirectToInitialSetup } from "@/app/redirect/thunks"
import { reloadServerInfos } from "@/app/server/thunks"
import { useAppDispatch, useAppSelector } from "@/app/store"
import { categoryUnreadCount } from "@/app/utils"
import { DisablePullToRefresh } from "@/components/DisablePullToRefresh"
import { ErrorBoundary } from "@/components/ErrorBoundary"
import { Header } from "@/components/header/Header"
import { Tree } from "@/components/sidebar/Tree"
import { useAppLoading } from "@/hooks/useAppLoading"
import { useBrowserExtension } from "@/hooks/useBrowserExtension"
import { useI18n } from "@/i18n"
import { AdminUsersPage } from "@/pages/admin/AdminUsersPage"
import { MetricsPage } from "@/pages/admin/MetricsPage"
import { AboutPage } from "@/pages/app/AboutPage"
import { AddPage } from "@/pages/app/AddPage"
import { CategoryDetailsPage } from "@/pages/app/CategoryDetailsPage"
import { DonatePage } from "@/pages/app/DonatePage"
import { FeedDetailsPage } from "@/pages/app/FeedDetailsPage"
import { FeedEntriesPage } from "@/pages/app/FeedEntriesPage"
import Layout from "@/pages/app/Layout"
import { SettingsPage } from "@/pages/app/SettingsPage"
import { TagDetailsPage } from "@/pages/app/TagDetailsPage"
import { InitialSetupPage } from "@/pages/auth/InitialSetupPage"
import { LoginPage } from "@/pages/auth/LoginPage"
import { PasswordRecoveryPage } from "@/pages/auth/PasswordRecoveryPage"
import { PasswordResetPage } from "@/pages/auth/PasswordResetPage"
import { RegistrationPage } from "@/pages/auth/RegistrationPage"
import { WelcomePage } from "@/pages/WelcomePage"
function Providers(props: { children: React.ReactNode }) {
function Providers(
props: Readonly<{
children: React.ReactNode
}>
) {
const primaryColor = useAppSelector(state => state.user.settings?.primaryColor) || Constants.theme.defaultPrimaryColor
return (
<I18nProvider i18n={i18n}>
@@ -72,9 +78,6 @@ function Providers(props: { children: React.ReactNode }) {
)
}
// api documentation page is very large, load only on-demand
const ApiDocumentationPage = React.lazy(async () => await import("pages/app/ApiDocumentationPage"))
function AppRoutes() {
const sidebarVisible = useAppSelector(state => state.tree.sidebarVisible)
@@ -82,10 +85,11 @@ function AppRoutes() {
<Routes>
<Route path="/" element={<Navigate to={`/app/category/${Constants.categories.all.id}`} replace />} />
<Route path="welcome" element={<WelcomePage />} />
<Route path="setup" element={<InitialSetupPage />} />
<Route path="login" element={<LoginPage />} />
<Route path="register" element={<RegistrationPage />} />
<Route path="passwordRecovery" element={<PasswordRecoveryPage />} />
<Route path="api" element={<ApiDocumentationPage />} />
<Route path="passwordReset" element={<PasswordResetPage />} />
<Route path="app" element={<Layout header={<Header />} sidebar={<Tree />} sidebarVisible={sidebarVisible} />}>
<Route path="category">
<Route path=":id" element={<FeedEntriesPage sourceType="category" />} />
@@ -113,6 +117,18 @@ function AppRoutes() {
)
}
function InitialSetupHandler() {
const serverInfos = useAppSelector(state => state.server.serverInfos)
const dispatch = useAppDispatch()
useEffect(() => {
if (serverInfos?.initialSetupRequired) {
dispatch(redirectToInitialSetup())
}
}, [serverInfos, dispatch])
return null
}
function RedirectHandler() {
const target = useAppSelector(state => state.redirect.to)
const dispatch = useAppDispatch()
@@ -128,22 +144,11 @@ function RedirectHandler() {
return null
}
function GoogleAnalyticsHandler() {
const location = useLocation()
const googleAnalyticsCode = useAppSelector(state => state.server.serverInfos?.googleAnalyticsCode)
useEffect(() => {
if (googleAnalyticsCode) ReactGA.initialize(googleAnalyticsCode)
}, [googleAnalyticsCode])
useEffect(() => {
if (ReactGA.isInitialized) ReactGA.send({ hitType: "pageview", page: location.pathname })
}, [location])
return null
}
function UnreadCountTitleHandler({ enabled }: { enabled?: boolean }) {
function UnreadCountTitleHandler({
enabled,
}: Readonly<{
enabled?: boolean
}>) {
const root = useAppSelector(state => state.tree.rootCategory)
const unreadCount = categoryUnreadCount(root)
return <title>{enabled && unreadCount > 0 ? `(${unreadCount}) CommaFeed` : "CommaFeed"}</title>
@@ -190,6 +195,8 @@ function CustomJsHandler() {
document.body.appendChild(script)
setScriptLoaded(true)
return () => script.remove()
}, [scriptLoaded, loading])
return null
@@ -202,6 +209,8 @@ function CustomCssHandler() {
link.type = "text/css"
link.href = "custom_css.css"
document.head.appendChild(link)
return () => link.remove()
}, [])
return null
@@ -211,6 +220,7 @@ export function App() {
useI18n()
const unreadCountTitle = useAppSelector(state => state.user.settings?.unreadCountTitle)
const unreadCountFavicon = useAppSelector(state => state.user.settings?.unreadCountFavicon)
const disablePullToRefresh = useAppSelector(state => state.user.settings?.disablePullToRefresh)
const dispatch = useAppDispatch()
useEffect(() => {
@@ -219,25 +229,18 @@ export function App() {
return (
<Providers>
<>
<UnreadCountTitleHandler enabled={unreadCountTitle} />
<UnreadCountFaviconHandler enabled={unreadCountFavicon} />
<BrowserExtensionBadgeUnreadCountHandler />
<CustomJsHandler />
<CustomCssHandler />
<UnreadCountTitleHandler enabled={unreadCountTitle} />
<UnreadCountFaviconHandler enabled={unreadCountFavicon} />
<BrowserExtensionBadgeUnreadCountHandler />
<CustomJsHandler />
<CustomCssHandler />
<DisablePullToRefresh enabled={disablePullToRefresh} />
{/* disable pull-to-refresh as it messes with vertical scrolling
safari behaves weirdly when overscroll-behavior is set to none so we disable it only for other browsers
https://github.com/Athou/commafeed/issues/1168
*/}
{!isSafari && <DisablePullToRefresh />}
<HashRouter>
<GoogleAnalyticsHandler />
<RedirectHandler />
<AppRoutes />
</HashRouter>
</>
<HashRouter>
<InitialSetupHandler />
<RedirectHandler />
<AppRoutes />
</HashRouter>
</Providers>
)
}

View File

@@ -1,5 +1,5 @@
import { createAsyncThunk } from "@reduxjs/toolkit"
import type { AppDispatch, RootState } from "app/store"
import type { AppDispatch, RootState } from "@/app/store"
export const createAppAsyncThunk = createAsyncThunk.withTypes<{
state: RootState

View File

@@ -12,12 +12,15 @@ import type {
FeedModificationRequest,
GetEntriesPaginatedRequest,
IDRequest,
InitialSetupRequest,
LoginRequest,
MarkRequest,
Metrics,
MultipleMarkRequest,
PasswordResetConfirmationRequest,
PasswordResetRequest,
ProfileModificationRequest,
PushNotificationSettings,
RegistrationRequest,
ServerInfo,
Settings,
@@ -32,16 +35,17 @@ const axiosInstance = axios.create({ baseURL: "./rest", withCredentials: true })
axiosInstance.interceptors.response.use(
response => response,
error => {
if (isAuthenticationError(error)) {
if (isAuthenticationError(error) && window.location.hash !== "#/login") {
const data = error.response?.data
window.location.hash = data?.allowRegistrations ? "/welcome" : "/login"
window.location.reload()
}
throw error
}
)
function isAuthenticationError(error: unknown): error is AxiosError<AuthenticationError> {
return axios.isAxiosError(error) && !!error.response && [401, 403].includes(error.response.status)
return axios.isAxiosError(error) && error.response?.status === 401
}
export const client = {
@@ -93,9 +97,13 @@ export const client = {
})
},
register: async (req: RegistrationRequest) => await axiosInstance.post("user/register", req),
initialSetup: async (req: InitialSetupRequest) => await axiosInstance.post("user/initialSetup", req),
passwordReset: async (req: PasswordResetRequest) => await axiosInstance.post("user/passwordReset", req),
passwordResetCallback: async (req: PasswordResetConfirmationRequest) => await axiosInstance.post("user/passwordResetCallback", req),
getSettings: async () => await axiosInstance.get<Settings>("user/settings"),
saveSettings: async (settings: Settings) => await axiosInstance.post("user/settings", settings),
sendTestPushNotification: async (settings: PushNotificationSettings) =>
await axiosInstance.post("user/pushNotificationTest", settings),
getProfile: async () => await axiosInstance.get<UserModel>("user/profile"),
saveProfile: async (req: ProfileModificationRequest) => await axiosInstance.post("user/profile", req),
deleteProfile: async () => await axiosInstance.post("user/profile/deleteAccount"),
@@ -105,7 +113,7 @@ export const client = {
},
admin: {
getAllUsers: async () => await axiosInstance.get<UserModel[]>("admin/user/getAll"),
saveUser: async (req: AdminSaveUserRequest) => await axiosInstance.post("admin/user/save", req),
saveUser: async (req: AdminSaveUserRequest) => await axiosInstance.post<number>("admin/user/save", req),
deleteUser: async (req: IDRequest) => await axiosInstance.post("admin/user/delete", req),
getMetrics: async () => await axiosInstance.get<Metrics>("admin/metrics"),
},

View File

@@ -87,17 +87,15 @@ export const Constants = {
headerHeight: 60,
entryMaxWidth: 650,
isTopVisible: (div: HTMLElement) => {
const header = document.getElementById(Constants.dom.headerId)?.getBoundingClientRect()
const header = document.getElementsByTagName("header").item(0)?.getBoundingClientRect()
return div.getBoundingClientRect().top >= (header?.bottom ?? 0)
},
isBottomVisible: (div: HTMLElement) => {
const footer = document.getElementById(Constants.dom.footerId)?.getBoundingClientRect()
const footer = document.getElementsByTagName("footer").item(0)?.getBoundingClientRect()
return div.getBoundingClientRect().bottom <= (footer?.top ?? window.innerHeight)
},
},
dom: {
headerId: "header",
footerId: "footer",
entryId: (entry: Entry) => `entry-id-${entry.id}`,
entryContextMenuId: (entry: Entry) => entry.id,
},

View File

@@ -1,12 +1,12 @@
import { configureStore } from "@reduxjs/toolkit"
import { client } from "app/client"
import { loadEntries, loadMoreEntries, markAllEntries, markEntry } from "app/entries/thunks"
import { type RootState, reducers } from "app/store"
import type { Entries, Entry } from "app/types"
import type { AxiosResponse } from "axios"
import { beforeEach, describe, expect, it, vi } from "vitest"
import { client } from "@/app/client"
import { loadEntries, loadMoreEntries, markAllEntries, markEntry } from "@/app/entries/thunks"
import { type RootState, reducers } from "@/app/store"
import type { Entries, Entry } from "@/app/types"
vi.mock(import("app/client"))
vi.mock(import("@/app/client"))
describe("entries", () => {
beforeEach(() => {
@@ -27,7 +27,12 @@ describe("entries", () => {
} as AxiosResponse<Entries>)
const store = configureStore({ reducer: reducers })
const promise = store.dispatch(loadEntries({ source: { type: "feed", id: "feed-id" }, clearSearch: true }))
const promise = store.dispatch(
loadEntries({
source: { type: "feed", id: "feed-id" },
clearSearch: true,
})
)
expect(store.getState().entries.source.type).toBe("feed")
expect(store.getState().entries.source.id).toBe("feed-id")
@@ -130,11 +135,19 @@ describe("entries", () => {
} as RootState,
})
store.dispatch(markAllEntries({ sourceType: "category", req: { id: "all", read: true } }))
store.dispatch(
markAllEntries({
sourceType: "category",
req: { id: "all", read: true },
})
)
expect(store.getState().entries.entries).toStrictEqual([
{ id: "3", read: true },
{ id: "4", read: true },
])
expect(client.category.markEntries).toHaveBeenCalledWith({ id: "all", read: true })
expect(client.category.markEntries).toHaveBeenCalledWith({
id: "all",
read: true,
})
})
})

View File

@@ -1,7 +1,7 @@
import { type PayloadAction, createSlice } from "@reduxjs/toolkit"
import { Constants } from "app/constants"
import { loadEntries, loadMoreEntries, markAllEntries, markEntry, markMultipleEntries, starEntry, tagEntry } from "app/entries/thunks"
import type { Entry } from "app/types"
import { createSlice, type PayloadAction } from "@reduxjs/toolkit"
import { Constants } from "@/app/constants"
import { loadEntries, loadMoreEntries, markAllEntries, markEntry, markMultipleEntries, starEntry, tagEntry } from "@/app/entries/thunks"
import type { Entry } from "@/app/types"
export type EntrySourceType = "category" | "feed" | "tag"

View File

@@ -1,13 +1,19 @@
import { createAppAsyncThunk } from "app/async-thunk"
import { client } from "app/client"
import { Constants } from "app/constants"
import { type EntrySource, type EntrySourceType, entriesSlice, setMarkAllAsReadConfirmationDialogOpen, setSearch } from "app/entries/slice"
import type { RootState } from "app/store"
import { reloadTree } from "app/tree/thunks"
import type { Entry, MarkRequest, TagRequest } from "app/types"
import { reloadTags } from "app/user/thunks"
import { scrollToWithCallback } from "app/utils"
import { flushSync } from "react-dom"
import { createAppAsyncThunk } from "@/app/async-thunk"
import { client } from "@/app/client"
import { Constants } from "@/app/constants"
import {
type EntrySource,
type EntrySourceType,
entriesSlice,
setMarkAllAsReadConfirmationDialogOpen,
setSearch,
} from "@/app/entries/slice"
import type { RootState } from "@/app/store"
import { reloadTree, selectNextUnreadTreeItem } from "@/app/tree/thunks"
import type { Entry, MarkRequest, TagRequest } from "@/app/types"
import { reloadTags } from "@/app/user/thunks"
import { scrollToWithCallback } from "@/app/utils"
const getEndpoint = (sourceType: EntrySourceType) =>
sourceType === "category" || sourceType === "tag" ? client.category.getEntries : client.feed.getEntries
@@ -34,7 +40,9 @@ export const loadMoreEntries = createAppAsyncThunk("entries/loadMore", async (_,
const state = thunkApi.getState()
const { source } = state.entries
const offset =
state.user.settings?.readingMode === "all" ? state.entries.entries.length : state.entries.entries.filter(e => !e.read).length
state.user.settings?.readingMode === "all" || (source.type === "category" && source.id === "starred")
? state.entries.entries.length
: state.entries.entries.filter(e => !e.read).length
const endpoint = getEndpoint(state.entries.source.type)
const result = await endpoint(buildGetEntriesPaginatedRequest(state, source, offset))
return result.data
@@ -130,11 +138,12 @@ export const markAllAsReadWithConfirmationIfRequired = createAppAsyncThunk(
const source = state.entries.source
const entriesTimestamp = state.entries.timestamp ?? Date.now()
const markAllAsReadConfirmation = state.user.settings?.markAllAsReadConfirmation
const markAllAsReadNavigateToNextUnread = state.user.settings?.markAllAsReadNavigateToNextUnread
if (markAllAsReadConfirmation) {
thunkApi.dispatch(setMarkAllAsReadConfirmationDialogOpen(true))
} else {
thunkApi.dispatch(
await thunkApi.dispatch(
markAllEntries({
sourceType: source.type,
req: {
@@ -145,6 +154,9 @@ export const markAllAsReadWithConfirmationIfRequired = createAppAsyncThunk(
},
})
)
const isAllCategorySelected = source.type === "category" && source.id === Constants.categories.all.id
if (markAllAsReadNavigateToNextUnread && !isAllCategorySelected)
await thunkApi.dispatch(selectNextUnreadTreeItem({ direction: "forward" }))
}
}
)
@@ -230,7 +242,7 @@ export const selectEntry = createAppAsyncThunk(
)
const scrollToEntry = (entryElement: HTMLElement, margin: number, scrollSpeed: number | undefined, onScrollEnded: () => void) => {
const header = document.getElementById(Constants.dom.headerId)?.getBoundingClientRect()
const header = document.getElementsByTagName("header").item(0)?.getBoundingClientRect()
const offset = (header?.bottom ?? 0) + margin
scrollToWithCallback({
options: {

View File

@@ -1,6 +1,6 @@
import { redirectToCategory } from "app/redirect/thunks"
import { store } from "app/store"
import { describe, expect, it } from "vitest"
import { redirectToCategory } from "@/app/redirect/thunks"
import { store } from "@/app/store"
describe("redirects", () => {
it("redirects to category", async () => {

View File

@@ -1,4 +1,4 @@
import { type PayloadAction, createSlice } from "@reduxjs/toolkit"
import { createSlice, type PayloadAction } from "@reduxjs/toolkit"
interface RedirectState {
to?: string

View File

@@ -1,12 +1,16 @@
import { createAppAsyncThunk } from "app/async-thunk"
import { Constants } from "app/constants"
import { redirectTo } from "app/redirect/slice"
import { createAppAsyncThunk } from "@/app/async-thunk"
import { Constants } from "@/app/constants"
import { redirectTo } from "@/app/redirect/slice"
export const redirectToLogin = createAppAsyncThunk("redirect/login", (_, thunkApi) => thunkApi.dispatch(redirectTo("/login")))
export const redirectToRegistration = createAppAsyncThunk("redirect/register", (_, thunkApi) => thunkApi.dispatch(redirectTo("/register")))
export const redirectToApiDocumentation = createAppAsyncThunk("redirect/api", (_, thunkApi) => thunkApi.dispatch(redirectTo("/api")))
export const redirectToInitialSetup = createAppAsyncThunk("redirect/initialSetup", (_, thunkApi) => thunkApi.dispatch(redirectTo("/setup")))
export const redirectToApiDocumentation = createAppAsyncThunk("redirect/api", () => {
window.location.href = "api-documentation/"
})
export const redirectToSelectedSource = createAppAsyncThunk("redirect/selectedSource", (_, thunkApi) => {
const { source } = thunkApi.getState().entries

View File

@@ -1,6 +1,6 @@
import { type PayloadAction, createSlice } from "@reduxjs/toolkit"
import { reloadServerInfos } from "app/server/thunks"
import type { ServerInfo } from "app/types"
import { createSlice, type PayloadAction } from "@reduxjs/toolkit"
import { reloadServerInfos } from "@/app/server/thunks"
import type { ServerInfo } from "@/app/types"
interface ServerState {
serverInfos?: ServerInfo

View File

@@ -1,4 +1,4 @@
import { createAppAsyncThunk } from "app/async-thunk"
import { client } from "app/client"
import { createAppAsyncThunk } from "@/app/async-thunk"
import { client } from "@/app/client"
export const reloadServerInfos = createAppAsyncThunk("server/infos", async () => await client.server.getServerInfos().then(r => r.data))

View File

@@ -1,11 +1,11 @@
import { configureStore } from "@reduxjs/toolkit"
import { entriesSlice } from "app/entries/slice"
import { redirectSlice } from "app/redirect/slice"
import { serverSlice } from "app/server/slice"
import { treeSlice } from "app/tree/slice"
import type { LocalSettings } from "app/types"
import { initialLocalSettings, userSlice } from "app/user/slice"
import { type TypedUseSelectorHook, useDispatch, useSelector } from "react-redux"
import { entriesSlice } from "@/app/entries/slice"
import { redirectSlice } from "@/app/redirect/slice"
import { serverSlice } from "@/app/server/slice"
import { treeSlice } from "@/app/tree/slice"
import type { LocalSettings } from "@/app/types"
import { initialLocalSettings, userSlice } from "@/app/user/slice"
export const reducers = {
entries: entriesSlice.reducer,

View File

@@ -1,9 +1,9 @@
import { type PayloadAction, createSlice } from "@reduxjs/toolkit"
import { loadEntries, markEntry } from "app/entries/thunks"
import { redirectTo } from "app/redirect/slice"
import { collapseTreeCategory, reloadTree } from "app/tree/thunks"
import type { Category, Subscription } from "app/types"
import { flattenCategoryTree, visitCategoryTree } from "app/utils"
import { createSlice, type PayloadAction } from "@reduxjs/toolkit"
import { loadEntries, markEntry } from "@/app/entries/thunks"
import { redirectTo } from "@/app/redirect/slice"
import { collapseTreeCategory, reloadTree } from "@/app/tree/thunks"
import type { Category, Subscription } from "@/app/types"
import { flattenCategoryTree, visitCategoryTree } from "@/app/utils"
export interface TreeSubscription extends Subscription {
// client-side only flag

View File

@@ -1,9 +1,10 @@
import { createAppAsyncThunk } from "app/async-thunk"
import { client } from "app/client"
import { redirectToCategory, redirectToFeed } from "app/redirect/thunks"
import { incrementUnreadCount } from "app/tree/slice"
import type { CollapseRequest, Subscription } from "app/types"
import { flattenCategoryTree, visitCategoryTree } from "app/utils"
import { createAppAsyncThunk } from "@/app/async-thunk"
import { client } from "@/app/client"
import { Constants } from "@/app/constants"
import { redirectToCategory, redirectToFeed } from "@/app/redirect/thunks"
import { incrementUnreadCount } from "@/app/tree/slice"
import type { CollapseRequest, Subscription } from "@/app/types"
import { flattenCategoryTree, visitCategoryTree } from "@/app/utils"
export const reloadTree = createAppAsyncThunk("tree/reload", async () => await client.category.getRoot().then(r => r.data))
@@ -53,6 +54,9 @@ export const selectNextUnreadTreeItem = createAppAsyncThunk(
}
}
}
// redirect to 'all' if no unread categories or feeds found or if we reached the end of the list
thunkApi.dispatch(redirectToCategory(Constants.categories.all.id))
}
)

View File

@@ -1,13 +1,13 @@
import { configureStore } from "@reduxjs/toolkit"
import { client } from "app/client"
import { loadEntries } from "app/entries/thunks"
import { type RootState, reducers } from "app/store"
import { newFeedEntriesDiscovered, selectNextUnreadTreeItem } from "app/tree/thunks"
import type { Category, Entries, Entry, Subscription } from "app/types"
import type { AxiosResponse } from "axios"
import { beforeEach, describe, expect, it, vi } from "vitest"
import { client } from "@/app/client"
import { loadEntries } from "@/app/entries/thunks"
import { type RootState, reducers } from "@/app/store"
import { newFeedEntriesDiscovered, selectNextUnreadTreeItem } from "@/app/tree/thunks"
import type { Category, Entries, Entry, Subscription } from "@/app/types"
vi.mock(import("app/client"))
vi.mock(import("@/app/client"))
const createCategory = (id: string): Category => ({
id,
@@ -27,6 +27,7 @@ const createFeed = (id: number, unread: number): Subscription => ({
feedUrl: "",
feedLink: "",
iconUrl: "",
pushNotificationsEnabled: true,
})
const root = createCategory("root")

View File

@@ -28,6 +28,9 @@ export interface Subscription {
position: number
newestItemTime?: number
filter?: string
filterLegacy?: string
pushNotificationsEnabled: boolean
autoMarkAsReadAfterDays?: number
}
export interface Category {
@@ -109,6 +112,8 @@ export interface FeedModificationRequest {
categoryId?: string
position?: number
filter?: string
pushNotificationsEnabled: boolean
autoMarkAsReadAfterDays?: number
}
export interface GetEntriesRequest {
@@ -196,6 +201,12 @@ export interface PasswordResetRequest {
email: string
}
export interface PasswordResetConfirmationRequest {
email: string
token: string
password: string
}
export interface ProfileModificationRequest {
currentPassword: string
email: string
@@ -209,18 +220,27 @@ export interface RegistrationRequest {
email: string
}
export interface InitialSetupRequest {
name: string
password: string
email?: string
}
export interface ServerInfo {
announcement?: string
version: string
gitCommit: string
allowRegistrations: boolean
googleAnalyticsCode?: string
emailAddressRequired: boolean
smtpEnabled: boolean
demoAccountEnabled: boolean
websocketEnabled: boolean
websocketPingInterval: number
treeReloadInterval: number
forceRefreshCooldownDuration: number
initialSetupRequired: boolean
minimumPasswordLength: number
pushNotificationsEnabled: boolean
}
export interface SharingSettings {
@@ -234,8 +254,18 @@ export interface SharingSettings {
buffer: boolean
}
export type PushNotificationType = "ntfy" | "gotify" | "pushover"
export interface PushNotificationSettings {
type?: PushNotificationType
serverUrl?: string
userId?: string
userSecret?: string
topic?: string
}
export interface Settings {
language: string
language?: string
readingMode: ReadingMode
readingOrder: ReadingOrder
showRead: boolean
@@ -248,12 +278,15 @@ export interface Settings {
starIconDisplayMode: IconDisplayMode
externalLinkIconDisplayMode: IconDisplayMode
markAllAsReadConfirmation: boolean
markAllAsReadNavigateToNextUnread: boolean
customContextMenu: boolean
mobileFooter: boolean
unreadCountTitle: boolean
unreadCountFavicon: boolean
disablePullToRefresh: boolean
primaryColor?: string
sharingSettings: SharingSettings
pushNotificationSettings: PushNotificationSettings
}
export interface LocalSettings {

View File

@@ -1,15 +1,18 @@
import { t } from "@lingui/core/macro"
import { showNotification } from "@mantine/notifications"
import { type PayloadAction, createSlice, isAnyOf } from "@reduxjs/toolkit"
import type { LocalSettings, Settings, UserModel, ViewMode } from "app/types"
import { createSlice, isAnyOf, type PayloadAction } from "@reduxjs/toolkit"
import type { LocalSettings, Settings, UserModel, ViewMode } from "@/app/types"
import {
changeCustomContextMenu,
changeDisablePullToRefresh,
changeEntriesToKeepOnTopWhenScrolling,
changeExternalLinkIconDisplayMode,
changeLanguage,
changeMarkAllAsReadConfirmation,
changeMarkAllAsReadNavigateToUnread,
changeMobileFooter,
changePrimaryColor,
changePushNotificationSettings,
changeReadingMode,
changeReadingOrder,
changeScrollMarks,
@@ -114,6 +117,10 @@ export const userSlice = createSlice({
if (!state.settings) return
state.settings.markAllAsReadConfirmation = action.meta.arg
})
builder.addCase(changeMarkAllAsReadNavigateToUnread.pending, (state, action) => {
if (!state.settings) return
state.settings.markAllAsReadNavigateToNextUnread = action.meta.arg
})
builder.addCase(changeCustomContextMenu.pending, (state, action) => {
if (!state.settings) return
state.settings.customContextMenu = action.meta.arg
@@ -130,6 +137,10 @@ export const userSlice = createSlice({
if (!state.settings) return
state.settings.unreadCountFavicon = action.meta.arg
})
builder.addCase(changeDisablePullToRefresh.pending, (state, action) => {
if (!state.settings) return
state.settings.disablePullToRefresh = action.meta.arg
})
builder.addCase(changePrimaryColor.pending, (state, action) => {
if (!state.settings) return
state.settings.primaryColor = action.meta.arg
@@ -138,6 +149,11 @@ export const userSlice = createSlice({
if (!state.settings) return
state.settings.sharingSettings[action.meta.arg.site] = action.meta.arg.value
})
builder.addCase(changePushNotificationSettings.pending, (state, action) => {
if (!state.settings) return
state.settings.pushNotificationSettings = action.meta.arg
})
builder.addMatcher(
isAnyOf(
changeLanguage.fulfilled,
@@ -149,12 +165,15 @@ export const userSlice = createSlice({
changeStarIconDisplayMode.fulfilled,
changeExternalLinkIconDisplayMode.fulfilled,
changeMarkAllAsReadConfirmation.fulfilled,
changeMarkAllAsReadNavigateToUnread.fulfilled,
changeCustomContextMenu.fulfilled,
changeMobileFooter.fulfilled,
changeUnreadCountTitle.fulfilled,
changeUnreadCountFavicon.fulfilled,
changeDisablePullToRefresh.fulfilled,
changePrimaryColor.fulfilled,
changeSharingSetting.fulfilled
changeSharingSetting.fulfilled,
changePushNotificationSettings.fulfilled
),
() => {
showNotification({

View File

@@ -1,7 +1,7 @@
import { createAppAsyncThunk } from "app/async-thunk"
import { client } from "app/client"
import { reloadEntries } from "app/entries/thunks"
import type { IconDisplayMode, ReadingMode, ReadingOrder, ScrollMode, SharingSettings } from "app/types"
import { createAppAsyncThunk } from "@/app/async-thunk"
import { client } from "@/app/client"
import { reloadEntries } from "@/app/entries/thunks"
import type { IconDisplayMode, PushNotificationSettings, ReadingMode, ReadingOrder, ScrollMode, SharingSettings } from "@/app/types"
export const reloadSettings = createAppAsyncThunk("settings/reload", async () => await client.user.getSettings().then(r => r.data))
@@ -89,6 +89,15 @@ export const changeMarkAllAsReadConfirmation = createAppAsyncThunk(
}
)
export const changeMarkAllAsReadNavigateToUnread = createAppAsyncThunk(
"settings/markAllAsReadNavigateToUnread",
(markAllAsReadNavigateToNextUnread: boolean, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
client.user.saveSettings({ ...settings, markAllAsReadNavigateToNextUnread })
}
)
export const changeCustomContextMenu = createAppAsyncThunk("settings/customContextMenu", (customContextMenu: boolean, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
@@ -113,6 +122,15 @@ export const changeUnreadCountFavicon = createAppAsyncThunk("settings/unreadCoun
client.user.saveSettings({ ...settings, unreadCountFavicon })
})
export const changeDisablePullToRefresh = createAppAsyncThunk(
"settings/disablePullToRefresh",
(disablePullToRefresh: boolean, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
client.user.saveSettings({ ...settings, disablePullToRefresh })
}
)
export const changePrimaryColor = createAppAsyncThunk("settings/primaryColor", (primaryColor: string, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
@@ -139,3 +157,15 @@ export const changeSharingSetting = createAppAsyncThunk(
})
}
)
export const changePushNotificationSettings = createAppAsyncThunk(
"settings/pushNotificationSettings",
(pushNotificationSettings: PushNotificationSettings, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
client.user.saveSettings({
...settings,
pushNotificationSettings,
})
}
)

View File

@@ -1,5 +1,5 @@
import type { TreeCategory } from "app/tree/slice"
import { throttle } from "throttle-debounce"
import type { TreeCategory } from "@/app/tree/slice"
import type { Category } from "./types"
export function visitCategoryTree(

View File

@@ -1,8 +1,8 @@
import type { I18nContext } from "@lingui/react"
import { MantineProvider } from "@mantine/core"
import { fireEvent, render, screen, waitFor } from "@testing-library/react"
import { useActionButton } from "hooks/useActionButton"
import { describe, expect, it, vi } from "vitest"
import { useActionButton } from "@/hooks/useActionButton"
import { ActionButton } from "./ActionButton"
vi.mock(import("@lingui/react"), () => ({
@@ -10,7 +10,7 @@ vi.mock(import("@lingui/react"), () => ({
_: msg => msg,
} as I18nContext),
}))
vi.mock(import("hooks/useActionButton"))
vi.mock(import("@/hooks/useActionButton"))
const label = "Test Label"
const icon = "Test Icon"
@@ -18,7 +18,9 @@ describe("ActionButton", () => {
it("renders Button with label on desktop", () => {
vi.mocked(useActionButton).mockReturnValue({ mobile: false, spacing: 0 })
render(<ActionButton label={label} icon={icon} />, { wrapper: MantineProvider })
render(<ActionButton label={label} icon={icon} />, {
wrapper: MantineProvider,
})
expect(screen.getByText(label)).toBeInTheDocument()
expect(screen.getByText(icon)).toBeInTheDocument()
})
@@ -26,7 +28,9 @@ describe("ActionButton", () => {
it("renders ActionIcon with tooltip on mobile", async () => {
vi.mocked(useActionButton).mockReturnValue({ mobile: true, spacing: 0 })
render(<ActionButton label={label} icon={icon} />, { wrapper: MantineProvider })
render(<ActionButton label={label} icon={icon} />, {
wrapper: MantineProvider,
})
expect(screen.queryByText(label)).not.toBeInTheDocument()
expect(screen.getByText(icon)).toBeInTheDocument()
@@ -39,7 +43,9 @@ describe("ActionButton", () => {
vi.mocked(useActionButton).mockReturnValue({ mobile: false, spacing: 0 })
const clickListener = vi.fn()
render(<ActionButton label={label} icon={icon} onClick={clickListener} />, { wrapper: MantineProvider })
render(<ActionButton label={label} icon={icon} onClick={clickListener} />, {
wrapper: MantineProvider,
})
fireEvent.click(screen.getByRole("button"))
expect(clickListener).toHaveBeenCalled()

View File

@@ -2,9 +2,9 @@ import type { MessageDescriptor } from "@lingui/core"
import { useLingui } from "@lingui/react"
import { ActionIcon, Box, Button, type ButtonVariant, Tooltip, useMantineTheme } from "@mantine/core"
import type { ActionIconVariant } from "@mantine/core/lib/components/ActionIcon/ActionIcon"
import { Constants } from "app/constants"
import { useActionButton } from "hooks/useActionButton"
import { type MouseEventHandler, type ReactNode, forwardRef } from "react"
import { forwardRef, type MouseEventHandler, type ReactNode } from "react"
import { Constants } from "@/app/constants"
import { useActionButton } from "@/hooks/useActionButton"
interface ActionButtonProps {
icon: ReactNode

View File

@@ -10,7 +10,7 @@ export interface ErrorsAlertProps {
messages: string[]
}
export function Alert(props: ErrorsAlertProps) {
export function Alert(props: Readonly<ErrorsAlertProps>) {
let title: React.ReactNode
let color: string
let icon: React.ReactNode

View File

@@ -1,9 +1,9 @@
import { Trans } from "@lingui/react/macro"
import { Box, Dialog, Text } from "@mantine/core"
import { useAppDispatch, useAppSelector } from "app/store"
import { setAnnouncementHash } from "app/user/slice"
import { Content } from "components/content/Content"
import { useAsync } from "react-async-hook"
import { useAppDispatch, useAppSelector } from "@/app/store"
import { setAnnouncementHash } from "@/app/user/slice"
import { Content } from "@/components/content/Content"
const sha256Hex = async (input: string | undefined) => {
const data = new TextEncoder().encode(input)

View File

@@ -1,4 +0,0 @@
html,
body {
overscroll-behavior: none;
}

View File

@@ -1,4 +1,3 @@
export const DisablePullToRefresh = () => {
import("./DisablePullToRefresh.css")
return <></>
export const DisablePullToRefresh = ({ enabled }: { enabled: boolean | undefined }) => {
return enabled ? <style>{`html, body { overscroll-behavior: none; }`}</style> : null
}

View File

@@ -1,5 +1,5 @@
import { ErrorPage } from "pages/ErrorPage"
import React, { type ReactNode } from "react"
import { ErrorPage } from "@/pages/ErrorPage"
interface ErrorBoundaryProps {
children?: ReactNode

View File

@@ -1,7 +1,7 @@
import { Box, Center } from "@mantine/core"
import { useState } from "react"
import { TbPhoto } from "react-icons/tb"
import { tss } from "tss"
import { tss } from "@/tss"
interface ImageWithPlaceholderWhileLoadingProps {
src: string
@@ -44,7 +44,7 @@ export function ImageWithPlaceholderWhileLoading({
title,
width,
style,
}: ImageWithPlaceholderWhileLoadingProps) {
}: Readonly<ImageWithPlaceholderWhileLoadingProps>) {
const { classes } = useStyles({
placeholderWidth,
placeholderHeight,

View File

@@ -1,7 +1,7 @@
import { Trans } from "@lingui/react/macro"
import { Anchor, Box, Kbd, Stack, Table } from "@mantine/core"
import { useOs } from "@mantine/hooks"
import { Constants } from "app/constants"
import { Constants } from "@/app/constants"
export function KeyboardShortcutsHelp() {
const isMacOS = useOs() === "macos"

View File

@@ -1,10 +1,10 @@
import { Image } from "@mantine/core"
import logo from "assets/logo.svg"
import logo from "@/assets/logo.svg"
export interface LogoProps {
size: number
}
export function Logo(props: LogoProps) {
export function Logo(props: Readonly<LogoProps>) {
return <Image src={logo} w={props.size} />
}

View File

@@ -1,9 +1,11 @@
import { Trans } from "@lingui/react/macro"
import { Button, Code, Group, Modal, Slider, Stack, Text } from "@mantine/core"
import { setMarkAllAsReadConfirmationDialogOpen } from "app/entries/slice"
import { markAllEntries } from "app/entries/thunks"
import { useAppDispatch, useAppSelector } from "app/store"
import { useState } from "react"
import { Constants } from "@/app/constants"
import { setMarkAllAsReadConfirmationDialogOpen } from "@/app/entries/slice"
import { markAllEntries } from "@/app/entries/thunks"
import { useAppDispatch, useAppSelector } from "@/app/store"
import { selectNextUnreadTreeItem } from "@/app/tree/thunks"
export function MarkAllAsReadConfirmationDialog() {
const [threshold, setThreshold] = useState(0)
@@ -11,10 +13,12 @@ export function MarkAllAsReadConfirmationDialog() {
const source = useAppSelector(state => state.entries.source)
const sourceLabel = useAppSelector(state => state.entries.sourceLabel)
const entriesTimestamp = useAppSelector(state => state.entries.timestamp) ?? Date.now()
const markAllAsReadNavigateToNextUnread = useAppSelector(state => state.user.settings?.markAllAsReadNavigateToNextUnread)
const dispatch = useAppDispatch()
const onConfirm = () => {
dispatch(
const onConfirm = async () => {
dispatch(setMarkAllAsReadConfirmationDialogOpen(false))
await dispatch(
markAllEntries({
sourceType: source.type,
req: {
@@ -25,7 +29,9 @@ export function MarkAllAsReadConfirmationDialog() {
},
})
)
dispatch(setMarkAllAsReadConfirmationDialogOpen(false))
const isAllCategorySelected = source.type === "category" && source.id === Constants.categories.all.id
if (markAllAsReadNavigateToNextUnread && !isAllCategorySelected) await dispatch(selectNextUnreadTreeItem({ direction: "forward" }))
}
return (

View File

@@ -0,0 +1,19 @@
import { Trans } from "@lingui/react/macro"
import { Checkbox, type CheckboxProps } from "@mantine/core"
import type { ReactNode } from "react"
import { useAppSelector } from "@/app/store"
export const ReceivePushNotificationsChechbox = (props: CheckboxProps) => {
const pushNotificationsEnabled = useAppSelector(state => state.server.serverInfos?.pushNotificationsEnabled)
const pushNotificationsConfigured = useAppSelector(state => !!state.user.settings?.pushNotificationSettings.type)
const disabled = !pushNotificationsEnabled || !pushNotificationsConfigured
let description: ReactNode = ""
if (!pushNotificationsEnabled) {
description = <Trans>Push notifications are not enabled on this CommaFeed instance.</Trans>
} else if (!pushNotificationsConfigured) {
description = <Trans>Push notifications are not configured in your user settings.</Trans>
}
return <Checkbox label={<Trans>Receive push notifications</Trans>} disabled={disabled} description={description} {...props} />
}

View File

@@ -1,10 +1,14 @@
import { Trans } from "@lingui/react/macro"
import { Tooltip } from "@mantine/core"
import { Constants } from "app/constants"
import dayjs from "dayjs"
import { useNow } from "hooks/useNow"
import { Constants } from "@/app/constants"
import { useNow } from "@/hooks/useNow"
export function RelativeDate(props: { date: Date | number | undefined }) {
export function RelativeDate(
props: Readonly<{
date: Date | number | undefined
}>
) {
const now = useNow(60 * 1000)
if (!props.date) return <Trans>N/A</Trans>

View File

@@ -1,11 +1,11 @@
import { Trans } from "@lingui/react/macro"
import { Box, Button, Checkbox, Group, PasswordInput, Stack, TextInput } from "@mantine/core"
import { useForm } from "@mantine/form"
import { client, errorToStrings } from "app/client"
import type { AdminSaveUserRequest, UserModel } from "app/types"
import { Alert } from "components/Alert"
import { useAsyncCallback } from "react-async-hook"
import { TbDeviceFloppy } from "react-icons/tb"
import { client, errorToStrings } from "@/app/client"
import type { AdminSaveUserRequest, UserModel } from "@/app/types"
import { Alert } from "@/components/Alert"
interface UserEditProps {
user?: UserModel
@@ -13,7 +13,7 @@ interface UserEditProps {
onSave: () => void
}
export function UserEdit(props: UserEditProps) {
export function UserEdit(props: Readonly<UserEditProps>) {
const form = useForm<AdminSaveUserRequest>({
initialValues: props.user ?? {
name: "",

View File

@@ -1,7 +1,7 @@
import { Input, Textarea } from "@mantine/core"
import RichCodeEditor from "components/code/RichCodeEditor"
import { useMobile } from "hooks/useMobile"
import type { ReactNode } from "react"
import RichCodeEditor from "@/components/code/RichCodeEditor"
import { useMobile } from "@/hooks/useMobile"
interface CodeEditorProps {
label?: ReactNode
@@ -11,7 +11,7 @@ interface CodeEditorProps {
onChange: (value: string | undefined) => void
}
export function CodeEditor(props: CodeEditorProps) {
export function CodeEditor(props: Readonly<CodeEditorProps>) {
const mobile = useMobile()
return mobile ? (

View File

@@ -1,6 +1,6 @@
import { Loader } from "components/Loader"
import { useColorScheme } from "hooks/useColorScheme"
import { useAsync } from "react-async-hook"
import { Loader } from "@/components/Loader"
import { useColorScheme } from "@/hooks/useColorScheme"
const init = async () => {
window.MonacoEnvironment = {
@@ -30,7 +30,7 @@ interface RichCodeEditorProps {
onChange: (value: string | undefined) => void
}
function RichCodeEditor(props: RichCodeEditorProps) {
function RichCodeEditor(props: Readonly<RichCodeEditorProps>) {
const colorScheme = useColorScheme()
const editorTheme = colorScheme === "dark" ? "vs-dark" : "light"

View File

@@ -1,6 +1,6 @@
import { TypographyStylesProvider } from "@mantine/core"
import { Typography } from "@mantine/core"
import type { ReactNode } from "react"
import { tss } from "tss"
import { tss } from "@/tss"
/**
* This component is used to provide basic styles to html typography elements.
@@ -20,5 +20,5 @@ const useStyles = tss.create(() => ({
export const BasicHtmlStyles = (props: { children: ReactNode }) => {
const { classes } = useStyles()
return <TypographyStylesProvider className={classes.content}>{props.children}</TypographyStylesProvider>
return <Typography className={classes.content}>{props.children}</Typography>
}

View File

@@ -1,7 +1,7 @@
import { MantineProvider } from "@mantine/core"
import { render } from "@testing-library/react"
import { Content } from "components/content/Content"
import { describe, expect, it } from "vitest"
import { Content } from "@/components/content/Content"
describe("Content component", () => {
it("renders basic content", () => {

View File

@@ -1,13 +1,13 @@
import { Box, Mark } from "@mantine/core"
import { Constants } from "app/constants"
import { calculatePlaceholderSize } from "app/utils"
import { ImageWithPlaceholderWhileLoading } from "components/ImageWithPlaceholderWhileLoading"
import { BasicHtmlStyles } from "components/content/BasicHtmlStyles"
import escapeStringRegexp from "escape-string-regexp"
import { ALLOWED_TAG_LIST, type ChildrenNode, Interweave, type MatchResponse, Matcher, type Node, type TransformCallback } from "interweave"
import { ALLOWED_TAG_LIST, type ChildrenNode, Interweave, Matcher, type MatchResponse, type Node, type TransformCallback } from "interweave"
import React from "react"
import styleToObject from "style-to-object"
import { tss } from "tss"
import { Constants } from "@/app/constants"
import { calculatePlaceholderSize } from "@/app/utils"
import { BasicHtmlStyles } from "@/components/content/BasicHtmlStyles"
import { ImageWithPlaceholderWhileLoading } from "@/components/ImageWithPlaceholderWhileLoading"
import { tss } from "@/tss"
export interface ContentProps {
content: string

View File

@@ -1,10 +1,12 @@
import { ImageWithPlaceholderWhileLoading } from "components/ImageWithPlaceholderWhileLoading"
import { BasicHtmlStyles } from "components/content/BasicHtmlStyles"
import { BasicHtmlStyles } from "@/components/content/BasicHtmlStyles"
import { ImageWithPlaceholderWhileLoading } from "@/components/ImageWithPlaceholderWhileLoading"
export function Enclosure(props: {
enclosureType: string
enclosureUrl: string
}) {
export function Enclosure(
props: Readonly<{
enclosureType: string
enclosureUrl: string
}>
) {
const hasVideo = props.enclosureType.startsWith("video")
const hasAudio = props.enclosureType.startsWith("audio")
const hasImage = props.enclosureType.startsWith("image")

View File

@@ -1,8 +1,12 @@
import { Trans } from "@lingui/react/macro"
import { Box } from "@mantine/core"
import { openModal } from "@mantine/modals"
import { Constants } from "app/constants"
import type { ExpendableEntry } from "app/entries/slice"
import { useEffect } from "react"
import { useContextMenu } from "react-contexify"
import InfiniteScroll from "react-infinite-scroller"
import { throttle } from "throttle-debounce"
import { Constants } from "@/app/constants"
import type { ExpendableEntry } from "@/app/entries/slice"
import {
loadMoreEntries,
markAllAsReadWithConfirmationIfRequired,
@@ -12,19 +16,15 @@ import {
selectNextEntry,
selectPreviousEntry,
starEntry,
} from "app/entries/thunks"
import { redirectToRootCategory } from "app/redirect/thunks"
import { useAppDispatch, useAppSelector } from "app/store"
import { toggleSidebar } from "app/tree/slice"
import { selectNextUnreadTreeItem } from "app/tree/thunks"
import { KeyboardShortcutsHelp } from "components/KeyboardShortcutsHelp"
import { Loader } from "components/Loader"
import { useBrowserExtension } from "hooks/useBrowserExtension"
import { useMousetrap } from "hooks/useMousetrap"
import { useEffect } from "react"
import { useContextMenu } from "react-contexify"
import InfiniteScroll from "react-infinite-scroller"
import { throttle } from "throttle-debounce"
} from "@/app/entries/thunks"
import { redirectToRootCategory } from "@/app/redirect/thunks"
import { useAppDispatch, useAppSelector } from "@/app/store"
import { toggleSidebar } from "@/app/tree/slice"
import { selectNextUnreadTreeItem } from "@/app/tree/thunks"
import { KeyboardShortcutsHelp } from "@/components/KeyboardShortcutsHelp"
import { Loader } from "@/components/Loader"
import { useBrowserExtension } from "@/hooks/useBrowserExtension"
import { useMousetrap } from "@/hooks/useMousetrap"
import { FeedEntry } from "./FeedEntry"
export function FeedEntries() {
@@ -287,7 +287,6 @@ export function FeedEntries() {
return (
<InfiniteScroll
id="entries"
className={`cf-entries cf-view-mode-${viewMode}`}
initialLoad={false}
loadMore={async () => await (!loading && dispatch(loadMoreEntries()))}

View File

@@ -1,13 +1,13 @@
import { Box, Divider, type MantineRadius, type MantineSpacing, Paper } from "@mantine/core"
import { Constants } from "app/constants"
import { useAppSelector } from "app/store"
import type { Entry, ViewMode } from "app/types"
import { FeedEntryCompactHeader } from "components/content/header/FeedEntryCompactHeader"
import { FeedEntryHeader } from "components/content/header/FeedEntryHeader"
import { useMobile } from "hooks/useMobile"
import type React from "react"
import { useSwipeable } from "react-swipeable"
import { tss } from "tss"
import { Constants } from "@/app/constants"
import { useAppSelector } from "@/app/store"
import type { Entry, ViewMode } from "@/app/types"
import { FeedEntryCompactHeader } from "@/components/content/header/FeedEntryCompactHeader"
import { FeedEntryHeader } from "@/components/content/header/FeedEntryHeader"
import { useMobile } from "@/hooks/useMobile"
import { tss } from "@/tss"
import { FeedEntryBody } from "./FeedEntryBody"
import { FeedEntryContextMenu } from "./FeedEntryContextMenu"
import { FeedEntryFooter } from "./FeedEntryFooter"
@@ -96,7 +96,7 @@ const useStyles = tss
}
})
export function FeedEntry(props: FeedEntryProps) {
export function FeedEntry(props: Readonly<FeedEntryProps>) {
const viewMode = useAppSelector(state => state.user.localSettings.viewMode)
const fontSizePercentage = useAppSelector(state => state.user.localSettings.fontSizePercentage)
const { classes, cx } = useStyles({
@@ -145,6 +145,7 @@ export function FeedEntry(props: FeedEntryProps) {
component="article"
id={Constants.dom.entryId(props.entry)}
data-id={props.entry.id}
data-feed-id={props.entry.feedId}
withBorder
radius={borderRadius}
className={cx(classes.paper, {

View File

@@ -1,6 +1,6 @@
import { Box } from "@mantine/core"
import { useAppSelector } from "app/store"
import type { Entry } from "app/types"
import { useAppSelector } from "@/app/store"
import type { Entry } from "@/app/types"
import { Content } from "./Content"
import { Enclosure } from "./Enclosure"
import { Media } from "./Media"
@@ -9,7 +9,7 @@ export interface FeedEntryBodyProps {
entry: Entry
}
export function FeedEntryBody(props: FeedEntryBodyProps) {
export function FeedEntryBody(props: Readonly<FeedEntryBodyProps>) {
const search = useAppSelector(state => state.entries.search)
return (
<Box>

View File

@@ -1,16 +1,16 @@
import { Trans } from "@lingui/react/macro"
import { Group } from "@mantine/core"
import { Constants } from "app/constants"
import { markEntriesUpToEntry, markEntry, starEntry } from "app/entries/thunks"
import { redirectToFeed } from "app/redirect/thunks"
import { useAppDispatch, useAppSelector } from "app/store"
import type { Entry } from "app/types"
import { truncate } from "app/utils"
import { useBrowserExtension } from "hooks/useBrowserExtension"
import { useColorScheme } from "hooks/useColorScheme"
import { Item, Menu, Separator } from "react-contexify"
import { TbArrowBarToDown, TbExternalLink, TbMail, TbMailOpened, TbRss, TbStar, TbStarOff } from "react-icons/tb"
import { tss } from "tss"
import { Constants } from "@/app/constants"
import { markEntriesUpToEntry, markEntry, starEntry } from "@/app/entries/thunks"
import { redirectToFeed } from "@/app/redirect/thunks"
import { useAppDispatch, useAppSelector } from "@/app/store"
import type { Entry } from "@/app/types"
import { truncate } from "@/app/utils"
import { useBrowserExtension } from "@/hooks/useBrowserExtension"
import { useColorScheme } from "@/hooks/useColorScheme"
import { tss } from "@/tss"
interface FeedEntryContextMenuProps {
entry: Entry
@@ -27,7 +27,7 @@ const useStyles = tss.create(({ theme, colorScheme }) => ({
},
}))
export function FeedEntryContextMenu(props: FeedEntryContextMenuProps) {
export function FeedEntryContextMenu(props: Readonly<FeedEntryContextMenuProps>) {
const colorScheme = useColorScheme()
const { classes } = useStyles()
const sourceType = useAppSelector(state => state.entries.source.type)
@@ -61,19 +61,21 @@ export function FeedEntryContextMenu(props: FeedEntryContextMenuProps) {
<Separator />
<Item onClick={async () => await dispatch(starEntry({ entry: props.entry, starred: !props.entry.starred }))}>
<Group>
{props.entry.starred ? <TbStarOff size={iconSize} /> : <TbStar size={iconSize} />}
{props.entry.starred ? <Trans>Unstar</Trans> : <Trans>Star</Trans>}
</Group>
</Item>
{props.entry.markable && (
<Item onClick={async () => await dispatch(markEntry({ entry: props.entry, read: !props.entry.read }))}>
<Group>
{props.entry.read ? <TbMail size={iconSize} /> : <TbMailOpened size={iconSize} />}
{props.entry.read ? <Trans>Keep unread</Trans> : <Trans>Mark as read</Trans>}
</Group>
</Item>
<>
<Item onClick={async () => await dispatch(starEntry({ entry: props.entry, starred: !props.entry.starred }))}>
<Group>
{props.entry.starred ? <TbStarOff size={iconSize} /> : <TbStar size={iconSize} />}
{props.entry.starred ? <Trans>Unstar</Trans> : <Trans>Star</Trans>}
</Group>
</Item>
<Item onClick={async () => await dispatch(markEntry({ entry: props.entry, read: !props.entry.read }))}>
<Group>
{props.entry.read ? <TbMail size={iconSize} /> : <TbMailOpened size={iconSize} />}
{props.entry.read ? <Trans>Keep unread</Trans> : <Trans>Mark as read</Trans>}
</Group>
</Item>
</>
)}
<Item onClick={async () => await dispatch(markEntriesUpToEntry(props.entry))}>
<Group>

View File

@@ -1,20 +1,20 @@
import { msg } from "@lingui/core/macro"
import { useLingui } from "@lingui/react"
import { Group, Indicator, Popover, TagsInput } from "@mantine/core"
import { markEntriesUpToEntry, markEntry, starEntry, tagEntry } from "app/entries/thunks"
import { useAppDispatch, useAppSelector } from "app/store"
import type { Entry } from "app/types"
import { ActionButton } from "components/ActionButton"
import { useActionButton } from "hooks/useActionButton"
import { useMobile } from "hooks/useMobile"
import { TbArrowBarToDown, TbExternalLink, TbMail, TbMailOpened, TbShare, TbStar, TbStarOff, TbTag } from "react-icons/tb"
import { markEntriesUpToEntry, markEntry, starEntry, tagEntry } from "@/app/entries/thunks"
import { useAppDispatch, useAppSelector } from "@/app/store"
import type { Entry } from "@/app/types"
import { ActionButton } from "@/components/ActionButton"
import { useActionButton } from "@/hooks/useActionButton"
import { useMobile } from "@/hooks/useMobile"
import { ShareButtons } from "./ShareButtons"
interface FeedEntryFooterProps {
entry: Entry
}
export function FeedEntryFooter(props: FeedEntryFooterProps) {
export function FeedEntryFooter(props: Readonly<FeedEntryFooterProps>) {
const tags = useAppSelector(state => state.user.tags)
const mobile = useMobile()
const { spacing } = useActionButton()

View File

@@ -1,11 +1,11 @@
import { ImageWithPlaceholderWhileLoading } from "components/ImageWithPlaceholderWhileLoading"
import { ImageWithPlaceholderWhileLoading } from "@/components/ImageWithPlaceholderWhileLoading"
export interface FeedFaviconProps {
url: string
size?: number
}
export function FeedFavicon({ url, size = 18 }: FeedFaviconProps) {
export function FeedFavicon({ url, size = 18 }: Readonly<FeedFaviconProps>) {
return (
<ImageWithPlaceholderWhileLoading
src={url}

View File

@@ -1,8 +1,8 @@
import { Box } from "@mantine/core"
import { Constants } from "app/constants"
import { calculatePlaceholderSize } from "app/utils"
import { ImageWithPlaceholderWhileLoading } from "components/ImageWithPlaceholderWhileLoading"
import { BasicHtmlStyles } from "components/content/BasicHtmlStyles"
import { Constants } from "@/app/constants"
import { calculatePlaceholderSize } from "@/app/utils"
import { BasicHtmlStyles } from "@/components/content/BasicHtmlStyles"
import { ImageWithPlaceholderWhileLoading } from "@/components/ImageWithPlaceholderWhileLoading"
import { Content } from "./Content"
export interface MediaProps {
@@ -12,7 +12,7 @@ export interface MediaProps {
description?: string
}
export function Media(props: MediaProps) {
export function Media(props: Readonly<MediaProps>) {
const width = props.thumbnailWidth
const height = props.thumbnailHeight
const placeholderSize = calculatePlaceholderSize({

View File

@@ -1,13 +1,13 @@
import { Trans } from "@lingui/react/macro"
import { ActionIcon, Box, CopyButton, Divider, SimpleGrid } from "@mantine/core"
import { Constants } from "app/constants"
import { useAppSelector } from "app/store"
import type { SharingSettings } from "app/types"
import { useBrowserExtension } from "hooks/useBrowserExtension"
import { useMobile } from "hooks/useMobile"
import type { IconType } from "react-icons"
import { TbCheck, TbCopy, TbDeviceDesktopShare, TbDeviceMobileShare } from "react-icons/tb"
import { tss } from "tss"
import { Constants } from "@/app/constants"
import { useAppSelector } from "@/app/store"
import type { SharingSettings } from "@/app/types"
import { useBrowserExtension } from "@/hooks/useBrowserExtension"
import { useMobile } from "@/hooks/useMobile"
import { tss } from "@/tss"
type Color = `#${string}`
@@ -22,7 +22,15 @@ const useStyles = tss
},
}))
function ShareButton({ icon, color, onClick }: { icon: IconType; color: Color; onClick: () => void }) {
function ShareButton({
icon,
color,
onClick,
}: Readonly<{
icon: IconType
color: Color
onClick: () => void
}>) {
const { classes } = useStyles({
color,
})
@@ -36,7 +44,15 @@ function ShareButton({ icon, color, onClick }: { icon: IconType; color: Color; o
)
}
function SiteShareButton({ url, icon, color }: { icon: IconType; color: Color; url: string }) {
function SiteShareButton({
url,
icon,
color,
}: Readonly<{
icon: IconType
color: Color
url: string
}>) {
const onClick = () => {
window.open(url, "", "menubar=no,toolbar=no,resizable=yes,scrollbars=yes,width=800,height=600")
}
@@ -44,7 +60,11 @@ function SiteShareButton({ url, icon, color }: { icon: IconType; color: Color; u
return <ShareButton icon={icon} color={color} onClick={onClick} />
}
function CopyUrlButton({ url }: { url: string }) {
function CopyUrlButton({
url,
}: Readonly<{
url: string
}>) {
return (
<CopyButton value={url}>
{({ copied, copy }) => <ShareButton icon={copied ? TbCheck : TbCopy} color="#000" onClick={copy} />}
@@ -52,7 +72,13 @@ function CopyUrlButton({ url }: { url: string }) {
)
}
function BrowserNativeShareButton({ url, description }: { url: string; description: string }) {
function BrowserNativeShareButton({
url,
description,
}: Readonly<{
url: string
description: string
}>) {
const mobile = useMobile()
const { isBrowserExtensionPopup } = useBrowserExtension()
const onClick = () => {
@@ -71,7 +97,12 @@ function BrowserNativeShareButton({ url, description }: { url: string; descripti
)
}
export function ShareButtons(props: { url: string; description: string }) {
export function ShareButtons(
props: Readonly<{
url: string
description: string
}>
) {
const sharingSettings = useAppSelector(state => state.user.settings?.sharingSettings)
const enabledSharingSites = (Object.keys(Constants.sharing) as Array<keyof SharingSettings>).filter(site => sharingSettings?.[site])
const url = encodeURIComponent(props.url)

View File

@@ -3,14 +3,14 @@ import { useLingui } from "@lingui/react"
import { Trans } from "@lingui/react/macro"
import { Box, Button, Group, Stack, TextInput } from "@mantine/core"
import { useForm } from "@mantine/form"
import { client, errorToStrings } from "app/client"
import { redirectToSelectedSource } from "app/redirect/thunks"
import { useAppDispatch } from "app/store"
import { reloadTree } from "app/tree/thunks"
import type { AddCategoryRequest } from "app/types"
import { Alert } from "components/Alert"
import { useAsyncCallback } from "react-async-hook"
import { TbFolderPlus } from "react-icons/tb"
import { client, errorToStrings } from "@/app/client"
import { redirectToSelectedSource } from "@/app/redirect/thunks"
import { useAppDispatch } from "@/app/store"
import { reloadTree } from "@/app/tree/thunks"
import type { AddCategoryRequest } from "@/app/types"
import { Alert } from "@/components/Alert"
import { CategorySelect } from "./CategorySelect"
export function AddCategory() {

View File

@@ -2,10 +2,10 @@ import { msg } from "@lingui/core/macro"
import { useLingui } from "@lingui/react"
import { Select, type SelectProps } from "@mantine/core"
import type { ComboboxItem } from "@mantine/core/lib/components/Combobox/Combobox.types"
import { Constants } from "app/constants"
import { useAppSelector } from "app/store"
import type { Category } from "app/types"
import { flattenCategoryTree } from "app/utils"
import { Constants } from "@/app/constants"
import { useAppSelector } from "@/app/store"
import type { Category } from "@/app/types"
import { flattenCategoryTree } from "@/app/utils"
type CategorySelectProps = Partial<SelectProps> & {
withAll?: boolean

View File

@@ -3,13 +3,13 @@ import { useLingui } from "@lingui/react"
import { Trans } from "@lingui/react/macro"
import { Box, Button, FileInput, Group, Stack } from "@mantine/core"
import { isNotEmpty, useForm } from "@mantine/form"
import { client, errorToStrings } from "app/client"
import { redirectToSelectedSource } from "app/redirect/thunks"
import { useAppDispatch } from "app/store"
import { reloadTree } from "app/tree/thunks"
import { Alert } from "components/Alert"
import { useAsyncCallback } from "react-async-hook"
import { TbFileImport } from "react-icons/tb"
import { client, errorToStrings } from "@/app/client"
import { redirectToSelectedSource } from "@/app/redirect/thunks"
import { useAppDispatch } from "@/app/store"
import { reloadTree } from "@/app/tree/thunks"
import { Alert } from "@/components/Alert"
export function ImportOpml() {
const dispatch = useAppDispatch()

View File

@@ -1,16 +1,16 @@
import { Trans } from "@lingui/react/macro"
import { Box, Button, Group, Stack, Stepper, TextInput } from "@mantine/core"
import { useForm } from "@mantine/form"
import { client, errorToStrings } from "app/client"
import { Constants } from "app/constants"
import { redirectToFeed, redirectToSelectedSource } from "app/redirect/thunks"
import { useAppDispatch } from "app/store"
import { reloadTree } from "app/tree/thunks"
import type { FeedInfoRequest, SubscribeRequest } from "app/types"
import { Alert } from "components/Alert"
import { useState } from "react"
import { useAsyncCallback } from "react-async-hook"
import { TbRss } from "react-icons/tb"
import { client, errorToStrings } from "@/app/client"
import { Constants } from "@/app/constants"
import { redirectToFeed, redirectToSelectedSource } from "@/app/redirect/thunks"
import { useAppDispatch } from "@/app/store"
import { reloadTree } from "@/app/tree/thunks"
import type { FeedInfoRequest, SubscribeRequest } from "@/app/types"
import { Alert } from "@/components/Alert"
import { CategorySelect } from "./CategorySelect"
export function Subscribe() {
@@ -39,9 +39,8 @@ export function Subscribe() {
},
})
const subscribe = useAsyncCallback(client.feed.subscribe, {
onSuccess: async sub => {
await dispatch(reloadTree())
dispatch(redirectToFeed(sub.data))
onSuccess: sub => {
dispatch(reloadTree()).then(() => dispatch(redirectToFeed(sub.data)))
},
})

View File

@@ -0,0 +1,118 @@
import { Stack } from "@mantine/core"
import { MantineValueSelector, QueryBuilderMantine } from "@react-querybuilder/mantine"
import {
type CombinatorSelectorProps,
defaultOperators,
defaultRuleProcessorCEL,
type Field,
type FormatQueryOptions,
formatQuery,
QueryBuilder,
type RuleGroupType,
} from "react-querybuilder"
import { isCELIdentifier, isCELMember, isCELStringLiteral, parseCEL } from "react-querybuilder/parseCEL"
import "react-querybuilder/dist/query-builder.css"
const fields: Field[] = [
{ name: "title", label: "Title" },
{ name: "content", label: "Content" },
{ name: "url", label: "URL" },
{ name: "author", label: "Author" },
{ name: "categories", label: "Categories" },
{ name: "titleLower", label: "Title (lower case)" },
{ name: "contentLower", label: "Content (lower case)" },
{ name: "urlLower", label: "URL (lower case)" },
{ name: "authorLower", label: "Author (lower case)" },
{ name: "categoriesLower", label: "Categories (lower case)" },
]
const textOperators = new Set(["=", "!=", "contains", "beginsWith", "endsWith", "doesNotContain", "doesNotBeginWith", "doesNotEndWith"])
function toCelString(query: RuleGroupType): string {
if (query.rules.length === 0) {
return ""
}
const celFormatOptions: FormatQueryOptions = {
format: "cel",
ruleProcessor: (rule, options, meta) => {
if (rule.operator === "matches") {
const escapedValue = String(rule.value).replaceAll("\\", "\\\\").replaceAll('"', String.raw`\"`)
return `${rule.field}.matches("${escapedValue}")`
}
return defaultRuleProcessorCEL(rule, options, meta)
},
}
return formatQuery(query, celFormatOptions)
}
function fromCelString(celString: string): RuleGroupType {
return parseCEL(celString ?? "", {
customExpressionHandler: expr => {
if (
isCELMember(expr) &&
expr.right?.value === "matches" &&
expr.left &&
isCELIdentifier(expr.left) &&
expr.list &&
isCELStringLiteral(expr.list.value[0])
) {
return {
field: expr.left.value,
operator: "matches",
value: JSON.parse(expr.list.value[0].value),
}
}
return null
},
})
}
const getOperators = () => {
const filteredDefault = defaultOperators.filter(op => textOperators.has(op.name))
return [
...filteredDefault,
{
name: "matches",
label: "matches pattern",
},
]
}
function CombinatorSelector(props: Readonly<CombinatorSelectorProps>) {
if (props.rules.length === 0) {
return null
}
return <MantineValueSelector {...props} />
}
interface FilteringExpressionEditorProps {
initialValue: string | undefined
onChange: (value: string) => void
}
export function FilteringExpressionEditor({ initialValue, onChange }: Readonly<FilteringExpressionEditorProps>) {
const handleQueryChange = (newQuery: RuleGroupType) => {
onChange(toCelString(newQuery))
}
return (
<Stack gap="sm">
<QueryBuilderMantine>
<QueryBuilder
fields={fields}
defaultQuery={fromCelString(initialValue ?? "")}
onQueryChange={handleQueryChange}
getOperators={getOperators}
addRuleToNewGroups
resetOnFieldChange={false}
controlClassnames={{ queryBuilder: "queryBuilder-branches" }}
controlElements={{ combinatorSelector: CombinatorSelector }}
/>
</QueryBuilderMantine>
</Stack>
)
}

View File

@@ -1,11 +1,11 @@
import { Box } from "@mantine/core"
import type { Entry } from "app/types"
import { RelativeDate } from "components/RelativeDate"
import { FeedFavicon } from "components/content/FeedFavicon"
import { OpenExternalLink } from "components/content/header/OpenExternalLink"
import { Star } from "components/content/header/Star"
import { OnDesktop } from "components/responsive/OnDesktop"
import { tss } from "tss"
import type { Entry } from "@/app/types"
import { FeedFavicon } from "@/components/content/FeedFavicon"
import { OpenExternalLink } from "@/components/content/header/OpenExternalLink"
import { Star } from "@/components/content/header/Star"
import { RelativeDate } from "@/components/RelativeDate"
import { OnDesktop } from "@/components/responsive/OnDesktop"
import { tss } from "@/tss"
import { FeedEntryTitle } from "./FeedEntryTitle"
export interface FeedEntryHeaderProps {
@@ -43,7 +43,7 @@ const useStyles = tss
},
}))
export function FeedEntryCompactHeader(props: FeedEntryHeaderProps) {
export function FeedEntryCompactHeader(props: Readonly<FeedEntryHeaderProps>) {
const { classes } = useStyles({
read: props.entry.read,
})

View File

@@ -1,10 +1,10 @@
import { Box, Flex, Space } from "@mantine/core"
import type { Entry } from "app/types"
import { RelativeDate } from "components/RelativeDate"
import { FeedFavicon } from "components/content/FeedFavicon"
import { OpenExternalLink } from "components/content/header/OpenExternalLink"
import { Star } from "components/content/header/Star"
import { tss } from "tss"
import type { Entry } from "@/app/types"
import { FeedFavicon } from "@/components/content/FeedFavicon"
import { OpenExternalLink } from "@/components/content/header/OpenExternalLink"
import { Star } from "@/components/content/header/Star"
import { RelativeDate } from "@/components/RelativeDate"
import { tss } from "@/tss"
import { FeedEntryTitle } from "./FeedEntryTitle"
export interface FeedEntryHeaderProps {
@@ -24,7 +24,7 @@ const useStyles = tss
},
}))
export function FeedEntryHeader(props: FeedEntryHeaderProps) {
export function FeedEntryHeader(props: Readonly<FeedEntryHeaderProps>) {
const { classes } = useStyles({
read: props.entry.read,
})

View File

@@ -1,12 +1,12 @@
import { Highlight } from "@mantine/core"
import { useAppSelector } from "app/store"
import type { Entry } from "app/types"
import { useAppSelector } from "@/app/store"
import type { Entry } from "@/app/types"
export interface FeedEntryTitleProps {
entry: Entry
}
export function FeedEntryTitle(props: FeedEntryTitleProps) {
export function FeedEntryTitle(props: Readonly<FeedEntryTitleProps>) {
const search = useAppSelector(state => state.entries.search)
const keywords = search?.split(" ")
return (

View File

@@ -1,12 +1,16 @@
import { Trans } from "@lingui/react/macro"
import { ActionIcon, Anchor, Tooltip } from "@mantine/core"
import { Constants } from "app/constants"
import { markEntry } from "app/entries/thunks"
import { useAppDispatch } from "app/store"
import type { Entry } from "app/types"
import { TbExternalLink } from "react-icons/tb"
import { Constants } from "@/app/constants"
import { markEntry } from "@/app/entries/thunks"
import { useAppDispatch } from "@/app/store"
import type { Entry } from "@/app/types"
export function OpenExternalLink(props: { entry: Entry }) {
export function OpenExternalLink(
props: Readonly<{
entry: Entry
}>
) {
const dispatch = useAppDispatch()
const onClick = (e: React.MouseEvent) => {
e.stopPropagation()

View File

@@ -1,12 +1,16 @@
import { Trans } from "@lingui/react/macro"
import { ActionIcon, Tooltip } from "@mantine/core"
import { Constants } from "app/constants"
import { starEntry } from "app/entries/thunks"
import { useAppDispatch } from "app/store"
import type { Entry } from "app/types"
import { TbStar, TbStarFilled } from "react-icons/tb"
import { Constants } from "@/app/constants"
import { starEntry } from "@/app/entries/thunks"
import { useAppDispatch } from "@/app/store"
import type { Entry } from "@/app/types"
export function Star(props: { entry: Entry }) {
export function Star(
props: Readonly<{
entry: Entry
}>
) {
const dispatch = useAppDispatch()
const onClick = (e: React.MouseEvent) => {
e.stopPropagation()

View File

@@ -2,14 +2,6 @@ import { msg } from "@lingui/core/macro"
import { useLingui } from "@lingui/react"
import { Box, Center, CloseButton, Divider, Group, Indicator, Popover, TextInput } from "@mantine/core"
import { useForm } from "@mantine/form"
import { markAllAsReadWithConfirmationIfRequired, reloadEntries, search, selectNextEntry, selectPreviousEntry } from "app/entries/thunks"
import { useAppDispatch, useAppSelector } from "app/store"
import { changeReadingMode, changeReadingOrder } from "app/user/thunks"
import { ActionButton } from "components/ActionButton"
import { Loader } from "components/Loader"
import { useActionButton } from "hooks/useActionButton"
import { useBrowserExtension } from "hooks/useBrowserExtension"
import { useMobile } from "hooks/useMobile"
import { useEffect } from "react"
import {
TbArrowDown,
@@ -25,6 +17,14 @@ import {
TbSortDescending,
TbUser,
} from "react-icons/tb"
import { markAllAsReadWithConfirmationIfRequired, reloadEntries, search, selectNextEntry, selectPreviousEntry } from "@/app/entries/thunks"
import { useAppDispatch, useAppSelector } from "@/app/store"
import { changeReadingMode, changeReadingOrder } from "@/app/user/thunks"
import { ActionButton } from "@/components/ActionButton"
import { Loader } from "@/components/Loader"
import { useActionButton } from "@/hooks/useActionButton"
import { useBrowserExtension } from "@/hooks/useBrowserExtension"
import { useMobile } from "@/hooks/useMobile"
import { ProfileMenu } from "./ProfileMenu"
function HeaderDivider() {
@@ -63,11 +63,7 @@ export function Header() {
const dispatch = useAppDispatch()
const { _ } = useLingui()
const searchForm = useForm<{ search: string }>({
validate: {
search: value => (value.length > 0 && value.length < 3 ? _(msg`Search requires at least 3 characters`) : null),
},
})
const searchForm = useForm<{ search: string }>()
const { setValues } = searchForm
useEffect(() => {

View File

@@ -11,15 +11,8 @@ import {
useMantineColorScheme,
} from "@mantine/core"
import { showNotification } from "@mantine/notifications"
import { client } from "app/client"
import { redirectToAbout, redirectToAdminUsers, redirectToDonate, redirectToMetrics, redirectToSettings } from "app/redirect/thunks"
import { useAppDispatch, useAppSelector } from "app/store"
import type { ViewMode } from "app/types"
import { setFontSizePercentage, setViewMode } from "app/user/slice"
import { reloadProfile } from "app/user/thunks"
import dayjs from "dayjs"
import { useNow } from "hooks/useNow"
import { type ReactNode, useState } from "react"
import { type ReactNode, useEffect, useState } from "react"
import {
TbChartLine,
TbHeartFilled,
@@ -36,6 +29,14 @@ import {
TbUsers,
TbWorldDownload,
} from "react-icons/tb"
import { throttle } from "throttle-debounce"
import { client } from "@/app/client"
import { redirectToAbout, redirectToAdminUsers, redirectToDonate, redirectToMetrics, redirectToSettings } from "@/app/redirect/thunks"
import { useAppDispatch, useAppSelector } from "@/app/store"
import type { ViewMode } from "@/app/types"
import { setFontSizePercentage, setViewMode } from "@/app/user/slice"
import { reloadProfile } from "@/app/user/thunks"
import { useNow } from "@/hooks/useNow"
interface ProfileMenuProps {
control: React.ReactElement
@@ -94,8 +95,16 @@ const viewModeData: ViewModeControlItem[] = [
},
]
export function ProfileMenu(props: ProfileMenuProps) {
export function ProfileMenu(props: Readonly<ProfileMenuProps>) {
const [opened, setOpened] = useState(false)
// close profile menu on scroll
useEffect(() => {
const listener = throttle(100, () => setOpened(false))
window.addEventListener("scroll", listener)
return () => window.removeEventListener("scroll", listener)
}, [])
const now = useNow()
const profile = useAppSelector(state => state.user.profile)
const admin = useAppSelector(state => state.user.profile?.admin)
@@ -145,7 +154,7 @@ export function ProfileMenu(props: ProfileMenuProps) {
color: "green",
autoClose: 1000,
})
} catch (_) {
} catch {
showNotification({
message: <Trans>Force fetching feeds is not yet available.</Trans>,
color: "red",

View File

@@ -1,10 +1,10 @@
import { NumberFormatter } from "@mantine/core"
import type { MetricGauge } from "app/types"
import type { MetricGauge } from "@/app/types"
interface MeterProps {
interface GaugeProps {
gauge: MetricGauge
}
export function Gauge(props: MeterProps) {
export function Gauge(props: Readonly<GaugeProps>) {
return <NumberFormatter value={props.gauge.value} thousandSeparator />
}

View File

@@ -1,11 +1,11 @@
import { Box } from "@mantine/core"
import type { MetricMeter } from "app/types"
import type { MetricMeter } from "@/app/types"
interface MeterProps {
meter: MetricMeter
}
export function Meter(props: MeterProps) {
export function Meter(props: Readonly<MeterProps>) {
return (
<Box>
<Box>Mean: {props.meter.mean_rate.toFixed(2)}</Box>

View File

@@ -7,7 +7,7 @@ interface MetricAccordionItemProps {
children: React.ReactNode
}
export function MetricAccordionItem({ metricKey, name, headerValue, children }: MetricAccordionItemProps) {
export function MetricAccordionItem({ metricKey, name, headerValue, children }: Readonly<MetricAccordionItemProps>) {
return (
<Accordion.Item value={metricKey} key={metricKey}>
<Accordion.Control>

View File

@@ -1,11 +1,11 @@
import { Box } from "@mantine/core"
import type { MetricTimer } from "app/types"
import type { MetricTimer } from "@/app/types"
interface MetricTimerProps {
timer: MetricTimer
}
export function Timer(props: MetricTimerProps) {
export function Timer(props: Readonly<MetricTimerProps>) {
return (
<Box>
<Box>Mean: {props.timer.mean_rate.toFixed(2)}</Box>

View File

@@ -1,8 +1,12 @@
import { Box } from "@mantine/core"
import { useMobile } from "hooks/useMobile"
import type React from "react"
import { useMobile } from "@/hooks/useMobile"
export function OnDesktop(props: { children: React.ReactNode }) {
export function OnDesktop(
props: Readonly<{
children: React.ReactNode
}>
) {
const mobile = useMobile()
return <Box>{!mobile && props.children}</Box>
}

View File

@@ -1,8 +1,12 @@
import { Box } from "@mantine/core"
import { useMobile } from "hooks/useMobile"
import type React from "react"
import { useMobile } from "@/hooks/useMobile"
export function OnMobile(props: { children: React.ReactNode }) {
export function OnMobile(
props: Readonly<{
children: React.ReactNode
}>
) {
const mobile = useMobile()
return <Box>{mobile && props.children}</Box>
}

View File

@@ -1,15 +1,15 @@
import { Trans } from "@lingui/react/macro"
import { Anchor, Box, Button, Group, Stack } from "@mantine/core"
import { useForm } from "@mantine/form"
import { client, errorToStrings } from "app/client"
import { Constants } from "app/constants"
import { redirectToSelectedSource } from "app/redirect/thunks"
import { useAppDispatch, useAppSelector } from "app/store"
import { Alert } from "components/Alert"
import { CodeEditor } from "components/code/CodeEditor"
import { useEffect } from "react"
import { useAsyncCallback } from "react-async-hook"
import { TbDeviceFloppy } from "react-icons/tb"
import { client, errorToStrings } from "@/app/client"
import { Constants } from "@/app/constants"
import { redirectToSelectedSource } from "@/app/redirect/thunks"
import { useAppDispatch, useAppSelector } from "@/app/store"
import { Alert } from "@/components/Alert"
import { CodeEditor } from "@/components/code/CodeEditor"
interface FormData {
customCss: string
@@ -60,18 +60,14 @@ export function CustomCodeSettings() {
<CodeEditor
label={<Trans>Custom CSS rules that will be applied</Trans>}
description={
<Trans>
<span>See </span>
<Anchor
href={Constants.customCssDocumentationUrl}
target="_blank"
rel="noreferrer"
style={{ fontSize: "inherit" }}
>
here
</Anchor>
<span> for more information.</span>
</Trans>
<Anchor
href={Constants.customCssDocumentationUrl}
target="_blank"
rel="noreferrer"
style={{ fontSize: "inherit" }}
>
<Trans>Link to the documentation</Trans>
</Anchor>
}
language="css"
{...form.getInputProps("customCss")}

View File

@@ -3,15 +3,18 @@ import { useLingui } from "@lingui/react"
import { Trans } from "@lingui/react/macro"
import { Box, Divider, Group, NumberInput, Radio, Select, type SelectProps, SimpleGrid, Stack, Switch } from "@mantine/core"
import type { ComboboxData } from "@mantine/core/lib/components/Combobox/Combobox.types"
import { Constants } from "app/constants"
import { useAppDispatch, useAppSelector } from "app/store"
import type { IconDisplayMode, ScrollMode, SharingSettings } from "app/types"
import type { ReactNode } from "react"
import { Constants } from "@/app/constants"
import { useAppDispatch, useAppSelector } from "@/app/store"
import type { IconDisplayMode, ScrollMode, SharingSettings } from "@/app/types"
import {
changeCustomContextMenu,
changeDisablePullToRefresh,
changeEntriesToKeepOnTopWhenScrolling,
changeExternalLinkIconDisplayMode,
changeLanguage,
changeMarkAllAsReadConfirmation,
changeMarkAllAsReadNavigateToUnread,
changeMobileFooter,
changePrimaryColor,
changeScrollMarks,
@@ -22,9 +25,8 @@ import {
changeStarIconDisplayMode,
changeUnreadCountFavicon,
changeUnreadCountTitle,
} from "app/user/thunks"
import { locales } from "i18n"
import type { ReactNode } from "react"
} from "@/app/user/thunks"
import { locales } from "@/i18n"
export function DisplaySettings() {
const language = useAppSelector(state => state.user.settings?.language)
@@ -36,10 +38,12 @@ export function DisplaySettings() {
const starIconDisplayMode = useAppSelector(state => state.user.settings?.starIconDisplayMode)
const externalLinkIconDisplayMode = useAppSelector(state => state.user.settings?.externalLinkIconDisplayMode)
const markAllAsReadConfirmation = useAppSelector(state => state.user.settings?.markAllAsReadConfirmation)
const markAllAsReadNavigateToNextUnread = useAppSelector(state => state.user.settings?.markAllAsReadNavigateToNextUnread)
const customContextMenu = useAppSelector(state => state.user.settings?.customContextMenu)
const mobileFooter = useAppSelector(state => state.user.settings?.mobileFooter)
const unreadCountTitle = useAppSelector(state => state.user.settings?.unreadCountTitle)
const unreadCountFavicon = useAppSelector(state => state.user.settings?.unreadCountFavicon)
const disablePullToRefresh = useAppSelector(state => state.user.settings?.disablePullToRefresh)
const sharingSettings = useAppSelector(state => state.user.settings?.sharingSettings)
const primaryColor = useAppSelector(state => state.user.settings?.primaryColor) || Constants.theme.defaultPrimaryColor
const { _ } = useLingui()
@@ -127,12 +131,59 @@ export function DisplaySettings() {
onChange={async e => await dispatch(changeMarkAllAsReadConfirmation(e.currentTarget.checked))}
/>
<Switch
label={<Trans>Navigate to the next category/feed with unread entries when marking all entries as read</Trans>}
checked={markAllAsReadNavigateToNextUnread}
onChange={async e => await dispatch(changeMarkAllAsReadNavigateToUnread(e.currentTarget.checked))}
/>
<Switch
label={<Trans>On mobile, show action buttons at the bottom of the screen</Trans>}
checked={mobileFooter}
onChange={async e => await dispatch(changeMobileFooter(e.currentTarget.checked))}
/>
<Divider label={<Trans>Scrolling</Trans>} labelPosition="center" />
<Switch
label={<Trans>Disable "Pull to refresh" browser behavior</Trans>}
description={<Trans>This setting can cause scrolling issues on some browsers (e.g. Safari)</Trans>}
checked={disablePullToRefresh}
onChange={async e => await dispatch(changeDisablePullToRefresh(e.currentTarget.checked))}
/>
<Radio.Group
label={<Trans>Scroll selected entry to the top of the page</Trans>}
value={scrollMode}
onChange={async value => await dispatch(changeScrollMode(value as ScrollMode))}
>
<Group mt="xs">
{Object.entries(scrollModeOptions).map(e => (
<Radio key={e[0]} value={e[0]} label={e[1]} />
))}
</Group>
</Radio.Group>
<NumberInput
label={<Trans>Entries to keep above the selected entry when scrolling</Trans>}
description={<Trans>Only applies to compact, cozy and detailed modes</Trans>}
min={0}
value={entriesToKeepOnTop}
onChange={async value => await dispatch(changeEntriesToKeepOnTopWhenScrolling(+value))}
/>
<Switch
label={<Trans>Scroll smoothly when navigating between entries</Trans>}
checked={scrollSpeed ? scrollSpeed > 0 : false}
onChange={async e => await dispatch(changeScrollSpeed(e.currentTarget.checked))}
/>
<Switch
label={<Trans>In expanded view, scrolling through entries mark them as read</Trans>}
checked={scrollMarks}
onChange={async e => await dispatch(changeScrollMarks(e.currentTarget.checked))}
/>
<Divider label={<Trans>Browser tab</Trans>} labelPosition="center" />
<Switch
@@ -169,40 +220,6 @@ export function DisplaySettings() {
onChange={async e => await dispatch(changeCustomContextMenu(e.currentTarget.checked))}
/>
<Divider label={<Trans>Scrolling</Trans>} labelPosition="center" />
<Radio.Group
label={<Trans>Scroll selected entry to the top of the page</Trans>}
value={scrollMode}
onChange={async value => await dispatch(changeScrollMode(value as ScrollMode))}
>
<Group mt="xs">
{Object.entries(scrollModeOptions).map(e => (
<Radio key={e[0]} value={e[0]} label={e[1]} />
))}
</Group>
</Radio.Group>
<NumberInput
label={<Trans>Entries to keep above the selected entry when scrolling</Trans>}
description={<Trans>Only applies to compact, cozy and detailed modes</Trans>}
min={0}
value={entriesToKeepOnTop}
onChange={async value => await dispatch(changeEntriesToKeepOnTopWhenScrolling(+value))}
/>
<Switch
label={<Trans>Scroll smoothly when navigating between entries</Trans>}
checked={scrollSpeed ? scrollSpeed > 0 : false}
onChange={async e => await dispatch(changeScrollSpeed(e.currentTarget.checked))}
/>
<Switch
label={<Trans>In expanded view, scrolling through entries mark them as read</Trans>}
checked={scrollMarks}
onChange={async e => await dispatch(changeScrollMarks(e.currentTarget.checked))}
/>
<Divider label={<Trans>Sharing sites</Trans>} labelPosition="center" />
<SimpleGrid cols={2}>

View File

@@ -1,18 +1,18 @@
import { msg } from "@lingui/core/macro"
import { useLingui } from "@lingui/react"
import { Trans } from "@lingui/react/macro"
import { Anchor, Box, Button, Checkbox, Divider, Group, Input, PasswordInput, Stack, Text, TextInput } from "@mantine/core"
import { useForm } from "@mantine/form"
import { openConfirmModal } from "@mantine/modals"
import { client, errorToStrings } from "app/client"
import { redirectToLogin, redirectToSelectedSource } from "app/redirect/thunks"
import { useAppDispatch, useAppSelector } from "app/store"
import type { ProfileModificationRequest } from "app/types"
import { reloadProfile } from "app/user/thunks"
import { Alert } from "components/Alert"
import { useEffect } from "react"
import { useAsyncCallback } from "react-async-hook"
import { TbDeviceFloppy, TbTrash } from "react-icons/tb"
import { client, errorToStrings } from "@/app/client"
import { redirectToLogin, redirectToSelectedSource } from "@/app/redirect/thunks"
import { useAppDispatch, useAppSelector } from "@/app/store"
import type { ProfileModificationRequest } from "@/app/types"
import { reloadProfile } from "@/app/user/thunks"
import { Alert } from "@/components/Alert"
import { useValidationRules } from "@/hooks/useValidationRules"
interface FormData extends ProfileModificationRequest {
newPasswordConfirmation?: string
@@ -20,13 +20,17 @@ interface FormData extends ProfileModificationRequest {
export function ProfileSettings() {
const profile = useAppSelector(state => state.user.profile)
const serverInfos = useAppSelector(state => state.server.serverInfos)
const dispatch = useAppDispatch()
const { _ } = useLingui()
const validationRules = useValidationRules()
const form = useForm<FormData>({
validate: {
newPasswordConfirmation: (value, values) => (value !== values.newPassword ? _(msg`Passwords do not match`) : null),
newPassword: validationRules.password,
newPasswordConfirmation: (value, values) => validationRules.passwordConfirmation(value, values.newPassword),
},
validateInputOnChange: true,
})
const { setValues } = form
@@ -52,7 +56,9 @@ export function ProfileSettings() {
),
labels: { confirm: <Trans>Confirm</Trans>, cancel: <Trans>Cancel</Trans> },
confirmProps: { color: "red" },
onConfirm: async () => await deleteProfile.execute(),
onConfirm: () => {
deleteProfile.execute()
},
})
useEffect(() => {
@@ -132,7 +138,12 @@ export function ProfileSettings() {
required
{...form.getInputProps("currentPassword")}
/>
<TextInput type="email" label={<Trans>E-mail</Trans>} {...form.getInputProps("email")} required />
<TextInput
type="email"
label={<Trans>E-mail</Trans>}
{...form.getInputProps("email")}
required={serverInfos?.emailAddressRequired}
/>
<PasswordInput
label={<Trans>New password</Trans>}
description={<Trans>Changing password will generate a new API key</Trans>}

View File

@@ -0,0 +1,124 @@
import { msg } from "@lingui/core/macro"
import { useLingui } from "@lingui/react"
import { Trans } from "@lingui/react/macro"
import { Button, Divider, Group, Select, Stack, TextInput } from "@mantine/core"
import { useForm } from "@mantine/form"
import { useEffect } from "react"
import { useAsyncCallback } from "react-async-hook"
import { TbDeviceFloppy, TbSend } from "react-icons/tb"
import { client, errorToStrings } from "@/app/client"
import { redirectToSelectedSource } from "@/app/redirect/thunks"
import { useAppDispatch, useAppSelector } from "@/app/store"
import type { PushNotificationSettings as PushNotificationSettingsModel } from "@/app/types"
import { changePushNotificationSettings } from "@/app/user/thunks"
import { Alert } from "@/components/Alert"
export function PushNotificationSettings() {
const notificationSettings = useAppSelector(state => state.user.settings?.pushNotificationSettings)
const pushNotificationsEnabled = useAppSelector(state => state.server.serverInfos?.pushNotificationsEnabled)
const { _ } = useLingui()
const dispatch = useAppDispatch()
const form = useForm<PushNotificationSettingsModel>()
useEffect(() => {
if (notificationSettings) form.initialize(notificationSettings)
}, [form.initialize, notificationSettings])
const handleSubmit = (values: PushNotificationSettingsModel) => {
dispatch(changePushNotificationSettings(values))
}
const sendTestPushNotification = useAsyncCallback(client.user.sendTestPushNotification)
const typeInputProps = form.getInputProps("type")
if (!pushNotificationsEnabled) {
return <Trans>Push notifications are not enabled on this CommaFeed instance.</Trans>
}
return (
<form onSubmit={form.onSubmit(handleSubmit)}>
<Stack>
{sendTestPushNotification.status === "success" && (
<Alert level="success" messages={[_(msg`Test notification sent successfully.`)]} />
)}
{sendTestPushNotification.status === "error" && (
<Alert level="error" messages={errorToStrings(sendTestPushNotification.error)} />
)}
<Select
label={<Trans>Push notification service</Trans>}
description={
<Trans>
Receive push notifications when new feed entries are discovered. Enable "Receive push notifications" in the
settings of each feed for which you want to receive notifications.
</Trans>
}
data={[
{ value: "ntfy", label: "ntfy" },
{ value: "gotify", label: "Gotify" },
{ value: "pushover", label: "Pushover" },
]}
clearable
{...typeInputProps}
onChange={value => {
typeInputProps.onChange(value)
form.setFieldValue("serverUrl", "")
form.setFieldValue("topic", "")
form.setFieldValue("userSecret", "")
form.setFieldValue("userId", "")
}}
/>
{form.values.type === "ntfy" && (
<>
<TextInput
label={<Trans>Server URL</Trans>}
placeholder="https://ntfy.sh"
required
{...form.getInputProps("serverUrl")}
/>
<TextInput label={<Trans>Topic</Trans>} placeholder="commafeed" required {...form.getInputProps("topic")} />
<TextInput label={<Trans>Access token</Trans>} {...form.getInputProps("userSecret")} />
</>
)}
{form.values.type === "gotify" && (
<>
<TextInput
label={<Trans>Server URL</Trans>}
placeholder="https://gotify.example.com"
required
{...form.getInputProps("serverUrl")}
/>
<TextInput label={<Trans>App token</Trans>} required {...form.getInputProps("userSecret")} />
</>
)}
{form.values.type === "pushover" && (
<>
<TextInput label={<Trans>User key</Trans>} required {...form.getInputProps("userId")} />
<TextInput label={<Trans>API token</Trans>} required {...form.getInputProps("userSecret")} />
</>
)}
<Group>
<Button variant="default" onClick={async () => await dispatch(redirectToSelectedSource())}>
<Trans>Cancel</Trans>
</Button>
<Button type="submit" leftSection={<TbDeviceFloppy size={16} />}>
<Trans>Save</Trans>
</Button>
<Divider orientation="vertical" />
<Button
variant="outline"
leftSection={<TbSend size={16} />}
onClick={() => sendTestPushNotification.execute(form.values)}
loading={sendTestPushNotification.loading}
>
<Trans>Test</Trans>
</Button>
</Group>
</Stack>
</form>
)
}

View File

@@ -1,6 +1,8 @@
import { Trans } from "@lingui/react/macro"
import { Box, Stack } from "@mantine/core"
import { Constants } from "app/constants"
import React from "react"
import { TbChevronDown, TbChevronRight, TbInbox, TbStar, TbTag } from "react-icons/tb"
import { Constants } from "@/app/constants"
import {
redirectToCategory,
redirectToCategoryDetails,
@@ -8,16 +10,14 @@ import {
redirectToFeedDetails,
redirectToTag,
redirectToTagDetails,
} from "app/redirect/thunks"
import { useAppDispatch, useAppSelector } from "app/store"
import type { TreeSubscription } from "app/tree/slice"
import { collapseTreeCategory } from "app/tree/thunks"
import type { Category, Subscription } from "app/types"
import { categoryHasNewEntries, categoryUnreadCount, flattenCategoryTree } from "app/utils"
import { Loader } from "components/Loader"
import { OnDesktop } from "components/responsive/OnDesktop"
import React from "react"
import { TbChevronDown, TbChevronRight, TbInbox, TbStar, TbTag } from "react-icons/tb"
} from "@/app/redirect/thunks"
import { useAppDispatch, useAppSelector } from "@/app/store"
import type { TreeSubscription } from "@/app/tree/slice"
import { collapseTreeCategory } from "@/app/tree/thunks"
import type { Category, Subscription } from "@/app/types"
import { categoryHasNewEntries, categoryUnreadCount, flattenCategoryTree } from "@/app/utils"
import { Loader } from "@/components/Loader"
import { OnDesktop } from "@/components/responsive/OnDesktop"
import { TreeNode } from "./TreeNode"
import { TreeSearch } from "./TreeSearch"
@@ -95,6 +95,7 @@ export function Tree() {
expanded={false}
level={0}
hasError={false}
hasWarning={false}
onClick={categoryClicked}
/>
)
@@ -110,6 +111,7 @@ export function Tree() {
expanded={false}
level={0}
hasError={false}
hasWarning={false}
onClick={categoryClicked}
/>
)
@@ -118,6 +120,7 @@ export function Tree() {
if (!isCategoryDisplayed(category)) return null
const hasError = !category.expanded && flattenCategoryTree(category).some(c => c.feeds.some(f => f.errorCount > errorThreshold))
const hasWarning = !category.expanded && flattenCategoryTree(category).some(c => c.feeds.some(f => !!f.filterLegacy))
return (
<TreeNode
id={category.id}
@@ -130,6 +133,7 @@ export function Tree() {
expanded={category.expanded}
level={level}
hasError={hasError}
hasWarning={hasWarning}
onClick={categoryClicked}
onIconClick={e => categoryIconClicked(e, category)}
key={category.id}
@@ -151,6 +155,7 @@ export function Tree() {
selected={source.type === "feed" && source.id === String(feed.id)}
level={level}
hasError={feed.errorCount > errorThreshold}
hasWarning={!!feed.filterLegacy}
onClick={feedClicked}
key={feed.id}
/>
@@ -168,6 +173,7 @@ export function Tree() {
selected={source.type === "tag" && source.id === tag}
level={0}
hasError={false}
hasWarning={false}
onClick={tagClicked}
key={tag}
/>

View File

@@ -1,8 +1,8 @@
import { Box, Center } from "@mantine/core"
import type { EntrySourceType } from "app/entries/slice"
import { FeedFavicon } from "components/content/FeedFavicon"
import type React from "react"
import { tss } from "tss"
import type { EntrySourceType } from "@/app/entries/slice"
import { FeedFavicon } from "@/components/content/FeedFavicon"
import { tss } from "@/tss"
import { UnreadCount } from "./UnreadCount"
interface TreeNodeProps {
@@ -15,6 +15,7 @@ interface TreeNodeProps {
expanded?: boolean
level: number
hasError: boolean
hasWarning: boolean
hasNewEntries: boolean
onClick: (e: React.MouseEvent, id: string) => void
onIconClick?: (e: React.MouseEvent, id: string) => void
@@ -24,15 +25,18 @@ const useStyles = tss
.withParams<{
selected: boolean
hasError: boolean
hasWarning: boolean
hasUnread: boolean
}>()
.create(({ theme, colorScheme, selected, hasError, hasUnread }) => {
.create(({ theme, colorScheme, selected, hasError, hasWarning, hasUnread }) => {
let backgroundColor = "inherit"
if (selected) backgroundColor = colorScheme === "dark" ? theme.colors.dark[4] : theme.colors.gray[1]
let color: string
if (hasError) {
color = theme.colors.red[6]
} else if (hasWarning) {
color = theme.colors.yellow[6]
} else if (colorScheme === "dark") {
color = hasUnread ? theme.colors.dark[0] : theme.colors.dark[3]
} else {
@@ -59,10 +63,11 @@ const useStyles = tss
}
})
export function TreeNode(props: TreeNodeProps) {
export function TreeNode(props: Readonly<TreeNodeProps>) {
const { classes } = useStyles({
selected: props.selected,
hasError: props.hasError,
hasWarning: props.hasWarning,
hasUnread: props.unread > 0,
})
return (

View File

@@ -3,18 +3,18 @@ import { useLingui } from "@lingui/react"
import { Trans } from "@lingui/react/macro"
import { Box, TextInput } from "@mantine/core"
import { Spotlight, type SpotlightActionData, spotlight } from "@mantine/spotlight"
import { redirectToFeed } from "app/redirect/thunks"
import { useAppDispatch } from "app/store"
import type { Subscription } from "app/types"
import { FeedFavicon } from "components/content/FeedFavicon"
import { useMousetrap } from "hooks/useMousetrap"
import { TbSearch } from "react-icons/tb"
import { redirectToFeed } from "@/app/redirect/thunks"
import { useAppDispatch } from "@/app/store"
import type { Subscription } from "@/app/types"
import { FeedFavicon } from "@/components/content/FeedFavicon"
import { useMousetrap } from "@/hooks/useMousetrap"
export interface TreeSearchProps {
feeds: Subscription[]
}
export function TreeSearch(props: TreeSearchProps) {
export function TreeSearch(props: Readonly<TreeSearchProps>) {
const dispatch = useAppDispatch()
const { _ } = useLingui()

View File

@@ -1,6 +1,6 @@
import { Badge, Indicator, Tooltip } from "@mantine/core"
import { Constants } from "app/constants"
import { tss } from "tss"
import { Constants } from "@/app/constants"
import { tss } from "@/tss"
const useStyles = tss.create(() => ({
badge: {
@@ -10,7 +10,12 @@ const useStyles = tss.create(() => ({
},
}))
export function UnreadCount(props: { unreadCount: number; showIndicator: boolean }) {
export function UnreadCount(
props: Readonly<{
unreadCount: number
showIndicator: boolean
}>
) {
const { classes } = useStyles()
if (props.unreadCount <= 0) return null

View File

@@ -1,5 +1,5 @@
import { useMantineTheme } from "@mantine/core"
import { useMobile } from "hooks/useMobile"
import { useMobile } from "@/hooks/useMobile"
export const useActionButton = () => {
const theme = useMantineTheme()

View File

@@ -1,6 +1,6 @@
import { msg } from "@lingui/core/macro"
import { useLingui } from "@lingui/react"
import { useAppSelector } from "app/store"
import { useAppSelector } from "@/app/store"
interface Step {
label: string

View File

@@ -1,5 +1,5 @@
import { useMediaQuery } from "@mantine/hooks"
import { Constants } from "app/constants"
import { Constants } from "@/app/constants"
export const useMobile = (breakpoint: string | number = Constants.layout.mobileBreakpoint) => {
const bp = typeof breakpoint === "number" ? `${breakpoint}px` : breakpoint

View File

@@ -0,0 +1,17 @@
import { msg } from "@lingui/core/macro"
import { useLingui } from "@lingui/react"
import { useAppSelector } from "@/app/store"
export function useValidationRules() {
const minimumPasswordLength = useAppSelector(state => state.server.serverInfos?.minimumPasswordLength)
const { _ } = useLingui()
return {
password: (value: string | undefined) =>
value && minimumPasswordLength && value.length < minimumPasswordLength
? _(msg`Password must be at least ${minimumPasswordLength} characters`)
: null,
passwordConfirmation: (newPasswordConfirmation: string | undefined, newPassword: string | undefined) =>
newPasswordConfirmation && newPasswordConfirmation !== newPassword ? _(msg`Passwords do not match`) : null,
}
}

View File

@@ -1,8 +1,8 @@
import { setWebSocketConnected } from "app/server/slice"
import { type AppDispatch, useAppDispatch, useAppSelector } from "app/store"
import { newFeedEntriesDiscovered } from "app/tree/thunks"
import { useEffect } from "react"
import WebsocketHeartbeatJs from "websocket-heartbeat-js"
import { setWebSocketConnected } from "@/app/server/slice"
import { type AppDispatch, useAppDispatch, useAppSelector } from "@/app/store"
import { newFeedEntriesDiscovered } from "@/app/tree/thunks"
const handleMessage = (dispatch: AppDispatch, message: string) => {
const parts = message.split(":")

View File

@@ -1,7 +1,7 @@
import { type Messages, i18n } from "@lingui/core"
import { useAppSelector } from "app/store"
import { i18n, type Messages } from "@lingui/core"
import dayjs from "dayjs"
import { useEffect } from "react"
import { useAppSelector } from "@/app/store"
interface Locale {
key: string
@@ -12,34 +12,146 @@ interface Locale {
// add an object to the array to add a new locale
// don't forget to also add it to the 'locales' array in lingui.config.ts
export const locales: Locale[] = [
{ key: "ar", label: "العربية", dayjsImportFn: async () => await import("dayjs/locale/ar") },
{ key: "ca", label: "Català", dayjsImportFn: async () => await import("dayjs/locale/ca") },
{ key: "cs", label: "Čeština", dayjsImportFn: async () => await import("dayjs/locale/cs") },
{ key: "cy", label: "Cymraeg", dayjsImportFn: async () => await import("dayjs/locale/cy") },
{ key: "da", label: "Danish", dayjsImportFn: async () => await import("dayjs/locale/da") },
{ key: "de", label: "Deutsch", dayjsImportFn: async () => await import("dayjs/locale/de") },
{ key: "en", label: "English", dayjsImportFn: async () => await import("dayjs/locale/en") },
{ key: "es", label: "Español", dayjsImportFn: async () => await import("dayjs/locale/es") },
{ key: "fa", label: "فارسی", dayjsImportFn: async () => await import("dayjs/locale/fa") },
{ key: "fi", label: "Suomi", dayjsImportFn: async () => await import("dayjs/locale/fi") },
{ key: "fr", label: "Français", dayjsImportFn: async () => await import("dayjs/locale/fr") },
{ key: "gl", label: "Galician", dayjsImportFn: async () => await import("dayjs/locale/gl") },
{ key: "hu", label: "Magyar", dayjsImportFn: async () => await import("dayjs/locale/hu") },
{ key: "id", label: "Indonesian", dayjsImportFn: async () => await import("dayjs/locale/id") },
{ key: "it", label: "Italiano", dayjsImportFn: async () => await import("dayjs/locale/it") },
{ key: "ja", label: "日本語", dayjsImportFn: async () => await import("dayjs/locale/ja") },
{ key: "ko", label: "한국어", dayjsImportFn: async () => await import("dayjs/locale/ko") },
{ key: "ms", label: "Bahasa Malaysian", dayjsImportFn: async () => await import("dayjs/locale/ms") },
{ key: "nb", label: "Norsk (bokmål)", dayjsImportFn: async () => await import("dayjs/locale/nb") },
{ key: "nl", label: "Nederlands", dayjsImportFn: async () => await import("dayjs/locale/nl") },
{ key: "nn", label: "Norsk (nynorsk)", dayjsImportFn: async () => await import("dayjs/locale/nn") },
{ key: "pl", label: "Polski", dayjsImportFn: async () => await import("dayjs/locale/pl") },
{ key: "pt", label: "Português", dayjsImportFn: async () => await import("dayjs/locale/pt") },
{ key: "ru", label: "Русский", dayjsImportFn: async () => await import("dayjs/locale/ru") },
{ key: "sk", label: "Slovenčina", dayjsImportFn: async () => await import("dayjs/locale/sk") },
{ key: "sv", label: "Svenska", dayjsImportFn: async () => await import("dayjs/locale/sv") },
{ key: "tr", label: "Türkçe", dayjsImportFn: async () => await import("dayjs/locale/tr") },
{ key: "zh", label: "简体中文", dayjsImportFn: async () => await import("dayjs/locale/zh") },
{
key: "ar",
label: "العربية",
dayjsImportFn: async () => await import("dayjs/locale/ar"),
},
{
key: "ca",
label: "Català",
dayjsImportFn: async () => await import("dayjs/locale/ca"),
},
{
key: "cs",
label: "Čeština",
dayjsImportFn: async () => await import("dayjs/locale/cs"),
},
{
key: "cy",
label: "Cymraeg",
dayjsImportFn: async () => await import("dayjs/locale/cy"),
},
{
key: "da",
label: "Danish",
dayjsImportFn: async () => await import("dayjs/locale/da"),
},
{
key: "de",
label: "Deutsch",
dayjsImportFn: async () => await import("dayjs/locale/de"),
},
{
key: "en",
label: "English",
dayjsImportFn: async () => await import("dayjs/locale/en"),
},
{
key: "es",
label: "Español",
dayjsImportFn: async () => await import("dayjs/locale/es"),
},
{
key: "fa",
label: "فارسی",
dayjsImportFn: async () => await import("dayjs/locale/fa"),
},
{
key: "fi",
label: "Suomi",
dayjsImportFn: async () => await import("dayjs/locale/fi"),
},
{
key: "fr",
label: "Français",
dayjsImportFn: async () => await import("dayjs/locale/fr"),
},
{
key: "gl",
label: "Galician",
dayjsImportFn: async () => await import("dayjs/locale/gl"),
},
{
key: "hu",
label: "Magyar",
dayjsImportFn: async () => await import("dayjs/locale/hu"),
},
{
key: "id",
label: "Indonesian",
dayjsImportFn: async () => await import("dayjs/locale/id"),
},
{
key: "it",
label: "Italiano",
dayjsImportFn: async () => await import("dayjs/locale/it"),
},
{
key: "ja",
label: "日本語",
dayjsImportFn: async () => await import("dayjs/locale/ja"),
},
{
key: "ko",
label: "한국어",
dayjsImportFn: async () => await import("dayjs/locale/ko"),
},
{
key: "ms",
label: "Bahasa Malaysian",
dayjsImportFn: async () => await import("dayjs/locale/ms"),
},
{
key: "nb",
label: "Norsk (bokmål)",
dayjsImportFn: async () => await import("dayjs/locale/nb"),
},
{
key: "nl",
label: "Nederlands",
dayjsImportFn: async () => await import("dayjs/locale/nl"),
},
{
key: "nn",
label: "Norsk (nynorsk)",
dayjsImportFn: async () => await import("dayjs/locale/nn"),
},
{
key: "pl",
label: "Polski",
dayjsImportFn: async () => await import("dayjs/locale/pl"),
},
{
key: "pt",
label: "Português",
dayjsImportFn: async () => await import("dayjs/locale/pt"),
},
{
key: "ru",
label: "Русский",
dayjsImportFn: async () => await import("dayjs/locale/ru"),
},
{
key: "sk",
label: "Slovenčina",
dayjsImportFn: async () => await import("dayjs/locale/sk"),
},
{
key: "sv",
label: "Svenska",
dayjsImportFn: async () => await import("dayjs/locale/sv"),
},
{
key: "tr",
label: "Türkçe",
dayjsImportFn: async () => await import("dayjs/locale/tr"),
},
{
key: "zh",
label: "简体中文",
dayjsImportFn: async () => await import("dayjs/locale/zh"),
},
]
function activateLocale(locale: string) {

File diff suppressed because it is too large Load Diff

View File

@@ -17,10 +17,6 @@ msgstr ""
msgid "<0>CommaFeed is an open-source project. Sources are hosted on </0><1>GitHub</1>."
msgstr "<0>CommaFeed és un projecte de codi obert. El codi font està allotjat a </0><1>GitHub</1>."
#: src/pages/app/FeedDetailsPage.tsx
msgid "<0>Complete syntax is available </0><1>here</1>."
msgstr "<0>La sintaxi completa està disponible </0><1>aquí</1>."
#: src/pages/auth/RegistrationPage.tsx
msgid "<0>Have an account?</0><1>Log in!</1>"
msgstr "<0>Teniu un compte?</0><1>Inicieu la sessió!</1>"
@@ -33,22 +29,22 @@ msgstr "<0>Ei,</0><1> sóc la Jérémie de Bèlgica i fa més de 10 anys que tre
msgid "<0>Need an account?</0><1>Sign up!</1>"
msgstr "<0>Necessites un compte?</0><1>Registreu-vos!</1>"
#: src/components/settings/CustomCodeSettings.tsx
msgid "<0>See </0><1>here</1><2> for more information.</2>"
msgstr ""
#: src/pages/app/AboutPage.tsx
#: src/components/header/ProfileMenu.tsx
#: src/pages/app/AboutPage.tsx
msgid "About"
msgstr "Sobre"
#: src/components/settings/PushNotificationSettings.tsx
msgid "Access token"
msgstr "Token d'accés"
#: src/pages/admin/AdminUsersPage.tsx
msgid "Actions"
msgstr "Accions"
#: src/components/content/add/AddCategory.tsx
msgid "Add"
msgstr "Afegir"
msgstr "Afegeix"
#: src/pages/app/AddPage.tsx
msgid "Add category"
@@ -58,17 +54,22 @@ msgstr "Afegeix categoria"
msgid "Add user"
msgstr "Afegeix usuari"
#: src/pages/admin/AdminUsersPage.tsx
#: src/components/header/ProfileMenu.tsx
#: src/components/admin/UserEdit.tsx
#: src/components/header/ProfileMenu.tsx
#: src/pages/admin/AdminUsersPage.tsx
msgid "Admin"
msgstr "Administrador"
#: src/pages/app/FeedEntriesPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/components/sidebar/Tree.tsx
#: src/components/header/Header.tsx
#: src/pages/auth/InitialSetupPage.tsx
#: src/pages/auth/InitialSetupPage.tsx
msgid "Admin user name"
msgstr "Nom d'usuari de l'administrador"
#: src/components/content/add/CategorySelect.tsx
#: src/components/header/Header.tsx
#: src/components/sidebar/Tree.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/app/FeedEntriesPage.tsx
msgid "All"
msgstr "Tot"
@@ -87,7 +88,7 @@ msgstr "Un fitxer opml és un fitxer XML que conté URL i categories de canals.
#: src/components/content/add/Subscribe.tsx
msgid "Analyze feed"
msgstr "Analitzar el feed"
msgstr "Analitza el canal"
#: src/components/AnnouncementDialog.tsx
msgid "Announcement"
@@ -95,11 +96,19 @@ msgstr "Anunci"
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "clau API"
msgstr "Clau API"
#: src/components/settings/PushNotificationSettings.tsx
msgid "API token"
msgstr "Token d'API"
#: src/components/settings/PushNotificationSettings.tsx
msgid "App token"
msgstr "Token d'aplicació"
#: src/pages/app/CategoryDetailsPage.tsx
msgid "Are you sure you want to delete category <0>{categoryName}</0>?"
msgstr "Estàs segur que vols suprimir la categoria <0>{categoryName}</0>?"
msgstr "Esteu segur que voleu suprimir la categoria <0>{categoryName}</0>?"
#: src/pages/admin/AdminUsersPage.tsx
msgid "Are you sure you want to delete user <0>{userName}</0> ?"
@@ -119,61 +128,67 @@ msgstr "Esteu segur que voleu marcar les entrades més antigues de {threshold} d
#: src/pages/app/FeedDetailsPage.tsx
msgid "Are you sure you want to unsubscribe from <0>{feedName}</0>?"
msgstr "Estàs segur que vols cancel·lar la subscripció a <0>{feedName}</0>?"
msgstr "Esteu segur que voleu cancel·lar la subscripció a <0>{feedName}</0>?"
#: src/components/header/Header.tsx
msgid "Asc"
msgstr "Asc"
#: src/pages/app/FeedDetailsPage.tsx
msgid "Available variables are 'title', 'content', 'url' 'author' and 'categories' and their content is converted to lower case to ease string comparison."
msgstr "Les variables disponibles són \"títol\", \"contingut\", \"url\" \"autor\" i \"categories\" i el seu contingut es converteix en minúscules per facilitar la comparació de cadenes."
msgid "Auto-mark as read"
msgstr "Marcar com a llegit automàticament"
#: src/components/content/add/Subscribe.tsx
msgid "Back"
msgstr "Enrere"
#: src/pages/auth/PasswordRecoveryPage.tsx
#: src/pages/auth/PasswordResetPage.tsx
msgid "Back to log in"
msgstr "Tornar a iniciar sessió"
msgstr "Torna a iniciar sessió"
#: src/components/settings/DisplaySettings.tsx
msgid "Blue"
msgstr ""
msgstr "Blau"
#: src/pages/app/AboutPage.tsx
msgid "Browser extension"
msgstr "Extensió del navegador"
#: src/components/KeyboardShortcutsHelp.tsx
msgid "Browser extension required for Chrome"
msgstr "Extensió del navegador necessària per a Chrome"
#: src/pages/app/AboutPage.tsx
msgid "Browser extention"
msgstr "Extensió del navegador"
#: src/components/settings/DisplaySettings.tsx
msgid "Browser tab"
msgstr ""
msgstr "Pestanya del navegador"
#: src/pages/app/TagDetailsPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/admin/AdminUsersPage.tsx
#: src/components/MarkAllAsReadConfirmationDialog.tsx
#: src/components/settings/ProfileSettings.tsx
#: src/components/settings/ProfileSettings.tsx
#: src/components/settings/CustomCodeSettings.tsx
#: src/components/content/add/ImportOpml.tsx
#: src/components/content/add/AddCategory.tsx
msgid "Build a filter expression to indicate what you want to read. Entries that don't match will be marked as read automatically."
msgstr "Creeu una expressió de filtratge per indicar què voleu llegir. Les entrades que no coincideixin es marcaran com a llegides automàticament."
#: src/components/admin/UserEdit.tsx
#: src/components/content/add/AddCategory.tsx
#: src/components/content/add/ImportOpml.tsx
#: src/components/MarkAllAsReadConfirmationDialog.tsx
#: src/components/settings/CustomCodeSettings.tsx
#: src/components/settings/ProfileSettings.tsx
#: src/components/settings/ProfileSettings.tsx
#: src/components/settings/PushNotificationSettings.tsx
#: src/pages/admin/AdminUsersPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/TagDetailsPage.tsx
msgid "Cancel"
msgstr "Cancel·la"
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/AboutPage.tsx
#: src/components/content/add/AddCategory.tsx
#: src/components/content/add/AddCategory.tsx
#: src/components/content/add/Subscribe.tsx
#: src/components/content/add/AddCategory.tsx
#: src/components/content/add/AddCategory.tsx
#: src/pages/app/AboutPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
msgid "Category"
msgstr "Categoria"
@@ -191,7 +206,7 @@ msgstr "Tanca el menu"
#: src/components/KeyboardShortcutsHelp.tsx
msgid "Cmd"
msgstr ""
msgstr "Cmd"
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed browser extension version {browserExtensionVersion}."
@@ -213,11 +228,11 @@ msgstr "CommaFeed versió {version} ({version})."
msgid "Compact"
msgstr "Compacte"
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/admin/AdminUsersPage.tsx
#: src/components/MarkAllAsReadConfirmationDialog.tsx
#: src/components/settings/ProfileSettings.tsx
#: src/pages/admin/AdminUsersPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
msgid "Confirm"
msgstr "Confirma"
@@ -225,10 +240,19 @@ msgstr "Confirma"
msgid "Confirm password"
msgstr "Confirmeu la contrasenya"
#: src/pages/auth/PasswordResetPage.tsx
#: src/pages/auth/PasswordResetPage.tsx
msgid "Confirm Password"
msgstr "Confirma la contrasenya"
#: src/components/header/ProfileMenu.tsx
msgid "Cozy"
msgstr "Acollidor"
#: src/pages/auth/InitialSetupPage.tsx
msgid "Create Admin Account"
msgstr "Crea un compte d'administrador"
#: src/components/KeyboardShortcutsHelp.tsx
msgid "Ctrl"
msgstr "Ctrl"
@@ -251,10 +275,10 @@ msgstr "Codi JS personalitzat que s'executarà en carregar la pàgina"
#: src/components/settings/DisplaySettings.tsx
msgid "Cyan"
msgstr ""
msgstr "Cian"
#: src/components/settings/DisplaySettings.tsx
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Dark"
msgstr "Fosc"
@@ -262,6 +286,10 @@ msgstr "Fosc"
msgid "Date created"
msgstr "Data de creació"
#: src/pages/app/FeedDetailsPage.tsx
msgid "days"
msgstr "dies"
#: src/pages/app/CategoryDetailsPage.tsx
msgid "Delete"
msgstr "Eliminar"
@@ -287,14 +315,18 @@ msgstr "Desc"
msgid "Detailed"
msgstr "Detallat"
#: src/pages/app/SettingsPage.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr "Desactiva el comportament \"Arrossega per actualitzar\"\\ del navegador"
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx
msgid "Display"
msgstr "Mostra"
#: src/pages/app/DonatePage.tsx
#: src/components/header/ProfileMenu.tsx
#: src/pages/app/DonatePage.tsx
msgid "Donate"
msgstr "Donar"
@@ -306,11 +338,13 @@ msgstr "Descarrega"
msgid "Drag link to bookmark bar"
msgstr "Arrossegueu l'enllaç a la barra d'adreces d'interès"
#: src/pages/auth/PasswordRecoveryPage.tsx
#: src/pages/auth/PasswordRecoveryPage.tsx
#: src/pages/admin/AdminUsersPage.tsx
#: src/components/settings/ProfileSettings.tsx
#: src/components/admin/UserEdit.tsx
#: src/components/settings/ProfileSettings.tsx
#: src/pages/admin/AdminUsersPage.tsx
#: src/pages/auth/InitialSetupPage.tsx
#: src/pages/auth/InitialSetupPage.tsx
#: src/pages/auth/PasswordRecoveryPage.tsx
#: src/pages/auth/PasswordRecoveryPage.tsx
msgid "E-mail"
msgstr "Correu electrònic"
@@ -323,10 +357,10 @@ msgstr "Adreça de correu electrònic"
msgid "Edit user"
msgstr "Edita l'usuari"
#: src/pages/admin/AdminUsersPage.tsx
#: src/components/admin/UserEdit.tsx
#: src/pages/admin/AdminUsersPage.tsx
msgid "Enabled"
msgstr "activat"
msgstr "Activat"
#: src/components/KeyboardShortcutsHelp.tsx
msgid "Enter"
@@ -338,20 +372,16 @@ msgstr "introduïu la vostra contrasenya actual per canviar la configuració del
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
msgstr "Entrades que es mantindran a sobre de l'entrada seleccionada en desplaçar-se"
#: src/components/settings/DisplaySettings.tsx
msgid "Entry headers"
msgstr ""
msgstr "Encapçalaments d'entrada"
#: src/components/Alert.tsx
msgid "Error"
msgstr "Error"
#: src/pages/app/FeedDetailsPage.tsx
msgid "Example: {example}."
msgstr "Exemple: {exemple}."
#: src/components/header/ProfileMenu.tsx
msgid "Expanded"
msgstr "Ampliat"
@@ -360,8 +390,8 @@ msgstr "Ampliat"
msgid "Export your subscriptions and categories as an OPML file that can be imported in other feed reading services"
msgstr "exporteu les vostres subscripcions i categories com a fitxer OPML que es pot importar a altres serveis de lectura de feeds"
#: src/pages/WelcomePage.tsx
#: src/components/header/Header.tsx
#: src/pages/WelcomePage.tsx
msgid "Extension options"
msgstr "Opcions de l'extensió"
@@ -369,9 +399,9 @@ msgstr "Opcions de l'extensió"
msgid "Feed name"
msgstr "Nom del canal"
#: src/components/content/add/Subscribe.tsx
#: src/components/content/add/Subscribe.tsx
#: src/pages/app/FeedDetailsPage.tsx
#: src/components/content/add/Subscribe.tsx
#: src/components/content/add/Subscribe.tsx
msgid "Feed URL"
msgstr "URL del canal"
@@ -381,11 +411,11 @@ msgstr "Carrega tots els meus feeds ara"
#: src/components/settings/ProfileSettings.tsx
msgid "Fever API"
msgstr ""
msgstr "Fever API"
#: src/components/settings/ProfileSettings.tsx
msgid "Fever API URL"
msgstr ""
msgstr "URL de Fever API"
#: src/pages/app/FeedDetailsPage.tsx
msgid "Filtering expression"
@@ -393,19 +423,19 @@ msgstr "Expressió de filtratge"
#: src/components/header/ProfileMenu.tsx
msgid "Font size"
msgstr ""
msgstr "Mida de la lletra"
#: src/components/header/ProfileMenu.tsx
msgid "Force fetching feeds is not yet available."
msgstr ""
msgstr "La recuperació forçada de feeds encara no està disponible."
#: src/pages/auth/LoginPage.tsx
msgid "Forgot password?"
msgstr "Heu oblidat la contrasenya?"
#: src/pages/app/TagDetailsPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/TagDetailsPage.tsx
msgid "Generate an API key in your profile first."
msgstr "primer genereu una clau API al vostre perfil."
@@ -413,9 +443,9 @@ msgstr "primer genereu una clau API al vostre perfil."
msgid "Generate new API key"
msgstr "Genera una nova clau d'API"
#: src/pages/app/TagDetailsPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/TagDetailsPage.tsx
msgid "Generated feed url"
msgstr "URL del feed generat"
@@ -434,28 +464,24 @@ msgstr "Vés a la documentació de l'API."
#: src/pages/app/AboutPage.tsx
msgid "Goodies"
msgstr "Bones"
msgstr "Extres"
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr ""
msgstr "Raïm"
#: src/components/settings/DisplaySettings.tsx
msgid "Gray"
msgstr ""
msgstr "Gris"
#: src/components/settings/DisplaySettings.tsx
msgid "Green"
msgstr ""
msgstr "Verd"
#: src/pages/admin/AdminUsersPage.tsx
msgid "Id"
msgstr "Id"
#: src/pages/app/FeedDetailsPage.tsx
msgid "If not empty, an expression evaluating to 'true' or 'false'. If false, new entries for this feed will be marked as read automatically."
msgstr "Si no està buida, una expressió que s'avalua com a \"vertader\" o \"fals\". "
#: src/components/settings/DisplaySettings.tsx
msgid "If the entry doesn't entirely fit on the screen"
msgstr "Si l'entrada no encaixa del tot a la pantalla"
@@ -470,19 +496,27 @@ msgstr "Importació"
#: src/components/settings/DisplaySettings.tsx
msgid "In expanded view, scrolling through entries mark them as read"
msgstr "a la vista ampliada, desplaçant-se per les entrades les marqueu com a llegides"
msgstr "En la vista ampliada, en desplaçar-se per les entrades, es marquen com a llegides"
#: src/components/settings/DisplaySettings.tsx
msgid "Indigo"
msgstr ""
msgstr "Indi"
#: src/pages/auth/InitialSetupPage.tsx
msgid "Initial Setup"
msgstr "Configuració inicial"
#: src/pages/auth/PasswordResetPage.tsx
msgid "Invalid password reset link. Please request a new one."
msgstr "L'enllaç de restabliment de la contrasenya no és vàlid. Sol·liciteu-ne un de nou."
#: src/components/content/FeedEntryFooter.tsx
#: src/components/content/FeedEntryContextMenu.tsx
#: src/components/content/FeedEntryFooter.tsx
msgid "Keep unread"
msgstr "Mantenir sense llegir"
#: src/pages/app/AboutPage.tsx
#: src/components/content/FeedEntries.tsx
#: src/pages/app/AboutPage.tsx
msgid "Keyboard shortcuts"
msgstr "Dreceres de teclat"
@@ -508,14 +542,18 @@ msgstr "Clar"
#: src/components/settings/DisplaySettings.tsx
msgid "Lime"
msgstr ""
msgstr "Llima"
#: src/pages/app/TagDetailsPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/TagDetailsPage.tsx
msgid "Link"
msgstr "Enllaç"
#: src/components/settings/CustomCodeSettings.tsx
msgid "Link to the documentation"
msgstr "Enllaç a la documentació"
#: src/hooks/useAppLoading.ts
msgid "Loading profile..."
msgstr "Carregant el perfil..."
@@ -532,9 +570,9 @@ msgstr "S'estan carregant les subscripcions..."
msgid "Loading tags..."
msgstr "Carregant les etiquetes..."
#: src/pages/auth/LoginPage.tsx
#: src/pages/auth/LoginPage.tsx
#: src/pages/WelcomePage.tsx
#: src/pages/auth/LoginPage.tsx
#: src/pages/auth/LoginPage.tsx
msgid "Log in"
msgstr "Inicia sessió"
@@ -544,10 +582,10 @@ msgstr "Tanca sessió"
#: src/components/KeyboardShortcutsHelp.tsx
msgid "Long press"
msgstr ""
msgstr "Prem llargament la tecla"
#: src/pages/admin/AdminUsersPage.tsx
#: src/components/header/ProfileMenu.tsx
#: src/pages/admin/AdminUsersPage.tsx
msgid "Manage users"
msgstr "Gestionar usuaris"
@@ -555,21 +593,25 @@ msgstr "Gestionar usuaris"
msgid "Mark all as read"
msgstr "Marca-ho tot com a llegit"
#: src/components/MarkAllAsReadConfirmationDialog.tsx
#: src/components/KeyboardShortcutsHelp.tsx
#: src/components/MarkAllAsReadConfirmationDialog.tsx
msgid "Mark all entries as read"
msgstr "Marqueu totes les entrades com a llegides"
#: src/components/content/FeedEntryFooter.tsx
#: src/components/content/FeedEntryContextMenu.tsx
#: src/components/content/FeedEntryFooter.tsx
msgid "Mark as read"
msgstr "Marca com a llegit"
#: src/components/content/FeedEntryFooter.tsx
#: src/components/content/FeedEntryContextMenu.tsx
#: src/components/content/FeedEntryFooter.tsx
msgid "Mark as read up to here"
msgstr "Marca com a llegit fins aquí"
#: src/pages/app/FeedDetailsPage.tsx
msgid "Mark entries in this feed as read after this number of days. Leave empty to disable."
msgstr "Marca les entrades d'aquest feed com a llegides després d'aquest nombre de dies. Deixeu-ho buit per desactivar-lo."
#: src/components/header/ProfileMenu.tsx
msgid "Metrics"
msgstr "mètriques"
@@ -586,15 +628,15 @@ msgstr "Mou la pàgina cap avall"
msgid "Move the page up"
msgstr "Mou la pàgina cap amunt"
#: src/pages/app/FeedDetailsPage.tsx
#: src/components/RelativeDate.tsx
msgid "N/A"
msgstr ""
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/admin/AdminUsersPage.tsx
msgid "N/A"
msgstr "No es coneix"
#: src/components/admin/UserEdit.tsx
#: src/pages/admin/AdminUsersPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
msgid "Name"
msgstr "Nom"
@@ -602,6 +644,10 @@ msgstr "Nom"
msgid "Navigate to a subscription by entering its name"
msgstr "Navegueu a una subscripció introduint-ne el nom"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr "Navega a la següent categoria/canal amb entrades no llegides quan es marquen totes les entrades com a llegides"
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"
@@ -611,12 +657,17 @@ msgstr "Mai"
msgid "New password"
msgstr "Contrasenya nova"
#: src/pages/auth/PasswordResetPage.tsx
#: src/pages/auth/PasswordResetPage.tsx
msgid "New Password"
msgstr "Contrasenya nova"
#: src/pages/app/AboutPage.tsx
msgid "Newest first"
msgstr "El més nou primer"
#: src/components/header/Header.tsx
#: src/components/content/add/Subscribe.tsx
#: src/components/header/Header.tsx
msgid "Next"
msgstr "Següent"
@@ -634,7 +685,7 @@ msgstr "No hi ha més entrades"
#: src/components/content/ShareButtons.tsx
msgid "No sharing options available."
msgstr ""
msgstr "No hi ha opcions de compartició disponibles."
#: src/components/sidebar/TreeSearch.tsx
msgid "Nothing found"
@@ -646,11 +697,11 @@ msgstr "el més vell primer"
#: src/components/settings/DisplaySettings.tsx
msgid "On desktop"
msgstr ""
msgstr "A l'escriptori"
#: src/components/settings/DisplaySettings.tsx
msgid "On mobile"
msgstr ""
msgstr "Al mòbil"
#: src/components/settings/DisplaySettings.tsx
msgid "On mobile, show action buttons at the bottom of the screen"
@@ -658,7 +709,7 @@ msgstr "Al mòbil, mostra els botons d'acció a la part inferior de la pantalla"
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
msgstr "Només s'aplica als modes compacte, acollidor i detallat"
#: src/pages/ErrorPage.tsx
msgid "Oops!"
@@ -720,11 +771,11 @@ msgstr "Fitxer OPML"
#: src/components/content/add/ImportOpml.tsx
msgid "OPML file is required"
msgstr ""
msgstr "Cal un fitxer OPML"
#: src/components/settings/DisplaySettings.tsx
msgid "Orange"
msgstr ""
msgstr "Taronja"
#: src/pages/app/AboutPage.tsx
msgid "Order"
@@ -738,28 +789,34 @@ msgstr "pares"
msgid "Parent Category"
msgstr "Categoria pare"
#: src/pages/auth/RegistrationPage.tsx
#: src/pages/auth/RegistrationPage.tsx
#: src/pages/auth/LoginPage.tsx
#: src/pages/auth/LoginPage.tsx
#: src/components/admin/UserEdit.tsx
#: src/pages/auth/InitialSetupPage.tsx
#: src/pages/auth/InitialSetupPage.tsx
#: src/pages/auth/LoginPage.tsx
#: src/pages/auth/LoginPage.tsx
#: src/pages/auth/RegistrationPage.tsx
#: src/pages/auth/RegistrationPage.tsx
msgid "Password"
msgstr "Contrasenya"
#: src/hooks/useValidationRules.ts
msgid "Password must be at least {minimumPasswordLength} characters"
msgstr "La contrasenya ha de tenir almenys {minimumPasswordLength} caràcters"
#: src/pages/auth/PasswordRecoveryPage.tsx
msgid "Password Recovery"
msgstr "Recuperació de contrasenya"
#: src/components/settings/ProfileSettings.tsx
#: src/hooks/useValidationRules.ts
msgid "Passwords do not match"
msgstr "Les contrasenyes no coincideixen"
#: src/components/settings/DisplaySettings.tsx
msgid "Pink"
msgstr ""
msgstr "Rosa"
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
msgid "Position"
msgstr "Posició"
@@ -769,22 +826,47 @@ msgstr "Anterior"
#: src/components/settings/DisplaySettings.tsx
msgid "Primary color"
msgstr ""
msgstr "Color primari"
#: src/pages/app/SettingsPage.tsx
msgid "Profile"
msgstr "Perfil"
#: src/components/settings/PushNotificationSettings.tsx
msgid "Push notification service"
msgstr "Servei de notificacions push"
#: src/pages/app/SettingsPage.tsx
msgid "Push notifications"
msgstr "Notificacions push"
#: src/components/ReceivePushNotificationsChechbox.tsx
msgid "Push notifications are not configured in your user settings."
msgstr "Les notificacions push no estan configurades a la vostra configuració d'usuari."
#: src/components/ReceivePushNotificationsChechbox.tsx
#: src/components/settings/PushNotificationSettings.tsx
msgid "Push notifications are not enabled on this CommaFeed instance."
msgstr "Les notificacions push no estan activades en aquesta instància de CommaFeed."
#: src/components/ReceivePushNotificationsChechbox.tsx
msgid "Receive push notifications"
msgstr "Rep notificacions push"
#: src/components/settings/PushNotificationSettings.tsx
msgid "Receive push notifications when new feed entries are discovered. Enable \"Receive push notifications\" in the settings of each feed for which you want to receive notifications."
msgstr "Rebre notificacions push quan es descobreixin noves entrades de feed. Activeu \"Rep notificacions push\" a la configuració de cada feed per al qual vulgueu rebre notificacions."
#: src/pages/auth/PasswordRecoveryPage.tsx
msgid "Recover password"
msgstr "Recuperar la contrasenya"
#: src/components/settings/DisplaySettings.tsx
msgid "Red"
msgstr ""
msgstr "Vermell"
#: src/components/KeyboardShortcutsHelp.tsx
#: src/components/header/Header.tsx
#: src/components/KeyboardShortcutsHelp.tsx
msgid "Refresh"
msgstr "Actualitzar"
@@ -792,6 +874,11 @@ msgstr "Actualitzar"
msgid "Registrations are closed on this CommaFeed instance"
msgstr "Els registres estan tancats en aquesta instància de CommaFeed"
#: src/pages/auth/PasswordResetPage.tsx
#: src/pages/auth/PasswordResetPage.tsx
msgid "Reset Password"
msgstr "Restableix la contrasenya"
#: src/pages/app/AboutPage.tsx
msgid "REST API"
msgstr "API REST"
@@ -801,11 +888,12 @@ msgstr "API REST"
msgid "Right click"
msgstr "Clic dret"
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/components/settings/ProfileSettings.tsx
#: src/components/settings/CustomCodeSettings.tsx
#: src/components/admin/UserEdit.tsx
#: src/components/settings/CustomCodeSettings.tsx
#: src/components/settings/ProfileSettings.tsx
#: src/components/settings/PushNotificationSettings.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
msgid "Save"
msgstr "Desa"
@@ -821,28 +909,29 @@ msgstr "Desplaceu-vos suaument quan navegueu entre entrades"
msgid "Scrolling"
msgstr "Desplaçament"
#: src/components/sidebar/TreeSearch.tsx
#: src/components/sidebar/TreeSearch.tsx
#: src/components/header/Header.tsx
#: src/components/header/Header.tsx
#: src/components/sidebar/TreeSearch.tsx
#: src/components/sidebar/TreeSearch.tsx
msgid "Search"
msgstr "Cerca"
#: src/components/header/Header.tsx
msgid "Search requires at least 3 characters"
msgstr "la cerca requereix almenys 3 caràcters"
#: src/components/KeyboardShortcutsHelp.tsx
msgid "Select next unread feed/category"
msgstr ""
msgstr "Selecciona el següent canal/categoria no llegit"
#: src/components/KeyboardShortcutsHelp.tsx
msgid "Select previous unread feed/category"
msgstr ""
msgstr "Selecciona el canal/categoria anterior sense llegir"
#: src/components/settings/PushNotificationSettings.tsx
#: src/components/settings/PushNotificationSettings.tsx
msgid "Server URL"
msgstr "URL del servidor"
#: src/components/KeyboardShortcutsHelp.tsx
msgid "Set focus on next entry without opening it"
msgstr "posa el focus a la següent entrada sense obrir-la"
msgstr "Posa el focus a la següent entrada sense obrir-la"
#: src/components/KeyboardShortcutsHelp.tsx
msgid "Set focus on previous entry without opening it"
@@ -862,7 +951,7 @@ msgstr "Comparteix"
#: src/components/settings/DisplaySettings.tsx
msgid "Sharing sites"
msgstr "Compartir llocs"
msgstr "Compartir a altres llocs web"
#: src/components/KeyboardShortcutsHelp.tsx
#: src/components/KeyboardShortcutsHelp.tsx
@@ -888,7 +977,7 @@ msgstr "Mostra el menú d'entrada (mòbil)"
#: src/components/settings/DisplaySettings.tsx
msgid "Show external link icon"
msgstr ""
msgstr "Mostra la icona d'enllaç extern"
#: src/components/settings/DisplaySettings.tsx
msgid "Show feeds and categories with no unread entries"
@@ -904,19 +993,19 @@ msgstr "Mostra el menú natiu (escriptori)"
#: src/components/settings/DisplaySettings.tsx
msgid "Show star icon"
msgstr ""
msgstr "Mostra la icona d'estrella"
#: src/components/settings/DisplaySettings.tsx
msgid "Show unread count in tab favicon"
msgstr ""
msgstr "Mostra el recompte de no llegits a la icona de favorits de la pestanya"
#: src/components/settings/DisplaySettings.tsx
msgid "Show unread count in tab title"
msgstr ""
msgstr "Mostra el recompte de no llegits al títol de la pestanya"
#: src/pages/auth/RegistrationPage.tsx
#: src/pages/auth/RegistrationPage.tsx
#: src/pages/WelcomePage.tsx
#: src/pages/auth/RegistrationPage.tsx
#: src/pages/auth/RegistrationPage.tsx
msgid "Sign up"
msgstr "Registra't"
@@ -929,21 +1018,21 @@ msgstr "Acaba de passar una cosa dolenta..."
msgid "Space"
msgstr "Espai"
#: src/components/content/FeedEntryFooter.tsx
#: src/components/content/FeedEntryContextMenu.tsx
#: src/components/content/FeedEntryFooter.tsx
#: src/components/content/header/Star.tsx
msgid "Star"
msgstr "Estrella"
#: src/pages/app/FeedEntriesPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/components/sidebar/Tree.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/app/FeedEntriesPage.tsx
msgid "Starred"
msgstr "Estrellat"
#: src/components/content/add/Subscribe.tsx
#: src/components/content/add/Subscribe.tsx
#: src/pages/app/AddPage.tsx
#: src/components/content/add/Subscribe.tsx
#: src/components/content/add/Subscribe.tsx
msgid "Subscribe"
msgstr "Subscriu-te"
@@ -982,7 +1071,15 @@ msgstr "Etiquetes"
#: src/components/settings/DisplaySettings.tsx
msgid "Teal"
msgstr ""
msgstr "Blau verdós"
#: src/components/settings/PushNotificationSettings.tsx
msgid "Test"
msgstr "Prova"
#: src/components/settings/PushNotificationSettings.tsx
msgid "Test notification sent successfully."
msgstr "La notificació de prova s'ha enviat correctament."
#: src/components/content/add/Subscribe.tsx
msgid "The URL for the feed you want to subscribe to. You can also use the website's url directly and CommaFeed will try to find the feed in the page."
@@ -992,10 +1089,19 @@ msgstr "l'URL del canal al qual us voleu subscriure. "
msgid "Theme"
msgstr "Tema"
#. placeholder {0}: feed.filterLegacy
#: src/pages/app/FeedDetailsPage.tsx
msgid "This feed has a legacy filter that cannot be edited and is not applied. Please recreate the filter using the new expression editor. The legacy filter expression was: <0>{0}</0>"
msgstr "Aquest feed té un filtre heretat que no es pot editar i no s'aplica. Torneu a crear el filtre amb el nou editor d'expressions. L'expressió del filtre heretat era: <0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "Aquesta és la vostra clau de l'API. Es pot utilitzar per a algunes operacions de l'API de només lectura i permet accedir a l'API Fever. Utilitzeu el formulari de la part inferior de la pàgina per generar una nova clau d'API."
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
msgstr "Aquesta configuració pot causar problemes de desplaçament en alguns navegadors (per exemple, Safari)"
#: src/components/KeyboardShortcutsHelp.tsx
msgid "Toggle read status of current entry"
msgstr "Canvia l'estat de lectura de l'entrada actual"
@@ -1008,6 +1114,10 @@ msgstr "Canvia la barra lateral"
msgid "Toggle starred status of current entry"
msgstr "Commuta l'estat destacat de l'entrada actual"
#: src/components/settings/PushNotificationSettings.tsx
msgid "Topic"
msgstr "Tema"
#: src/pages/auth/LoginPage.tsx
msgid "Try out CommaFeed with the demo account: demo/demo"
msgstr "Proveu CommaFeed amb el compte de demostració: demo/demo"
@@ -1020,8 +1130,8 @@ msgstr "Prova la demostració!"
msgid "Unread"
msgstr "Sense llegir"
#: src/components/content/FeedEntryFooter.tsx
#: src/components/content/FeedEntryContextMenu.tsx
#: src/components/content/FeedEntryFooter.tsx
#: src/components/content/header/Star.tsx
msgid "Unstar"
msgstr "Desestrellar"
@@ -1031,6 +1141,10 @@ msgstr "Desestrellar"
msgid "Unsubscribe"
msgstr "Donar-se de baixa"
#: src/components/settings/PushNotificationSettings.tsx
msgid "User key"
msgstr "Clau d'usuari"
#: src/components/settings/ProfileSettings.tsx
msgid "User name"
msgstr "Nom d'usuari"
@@ -1042,7 +1156,7 @@ msgstr "Nom d'usuari o correu electrònic"
#: src/components/settings/DisplaySettings.tsx
msgid "Violet"
msgstr ""
msgstr "Violeta"
#: src/components/Alert.tsx
msgid "Warning"
@@ -1052,9 +1166,13 @@ msgstr "Avís"
msgid "Website"
msgstr "Lloc web"
#: src/pages/auth/InitialSetupPage.tsx
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "Benvingut! Sembla que aquesta és la primera vegada que executeu CommaFeed. Creeu un compte d'administrador per començar."
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr ""
msgstr "Groc"
#: src/pages/app/FeedEntriesPage.tsx
msgid "You don't have any subscriptions yet. Why not try adding one by clicking on the + sign at the top of the page?"
@@ -1063,3 +1181,7 @@ msgstr "Encara no teniu cap subscripció. "
#: src/components/header/ProfileMenu.tsx
msgid "Your feeds have been queued for refresh."
msgstr "Els vostres feeds s'han posat a la cua per actualitzar-los."
#: src/pages/auth/PasswordResetPage.tsx
msgid "Your password has been changed. You can now log in with your new password."
msgstr "La vostra contrasenya s'ha canviat. Ara podeu iniciar la sessió amb la vostra nova contrasenya."

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -17,10 +17,6 @@ msgstr ""
msgid "<0>CommaFeed is an open-source project. Sources are hosted on </0><1>GitHub</1>."
msgstr "<0>CommaFeed ist ein Open Source Projekt. Der Quellcode wird auf auf </0><1>GitHub</1> gehostet."
#: src/pages/app/FeedDetailsPage.tsx
msgid "<0>Complete syntax is available </0><1>here</1>."
msgstr "<0>Die vollständige Syntax ist </0><1>hier</1> verfügbar."
#: src/pages/auth/RegistrationPage.tsx
msgid "<0>Have an account?</0><1>Log in!</1>"
msgstr "<0>Haben Sie ein Konto?</0><1>Melden Sie sich an!</1>"
@@ -33,15 +29,15 @@ msgstr "<0>Hey,</0><1>Ich bin Jérémie aus Belgien und arbeite seit über 10 Ja
msgid "<0>Need an account?</0><1>Sign up!</1>"
msgstr "<0>Benötigen Sie ein Konto?</0><1>Hier geht's zur Registrierung!</1>"
#: src/components/settings/CustomCodeSettings.tsx
msgid "<0>See </0><1>here</1><2> for more information.</2>"
msgstr ""
#: src/pages/app/AboutPage.tsx
#: src/components/header/ProfileMenu.tsx
#: src/pages/app/AboutPage.tsx
msgid "About"
msgstr "Über"
#: src/components/settings/PushNotificationSettings.tsx
msgid "Access token"
msgstr "Zugriffstoken"
#: src/pages/admin/AdminUsersPage.tsx
msgid "Actions"
msgstr "Aktionen"
@@ -58,17 +54,22 @@ msgstr "Kategorie hinzufügen"
msgid "Add user"
msgstr "Benutzer hinzufügen"
#: src/pages/admin/AdminUsersPage.tsx
#: src/components/header/ProfileMenu.tsx
#: src/components/admin/UserEdit.tsx
#: src/components/header/ProfileMenu.tsx
#: src/pages/admin/AdminUsersPage.tsx
msgid "Admin"
msgstr "Verwaltung"
#: src/pages/app/FeedEntriesPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/components/sidebar/Tree.tsx
#: src/components/header/Header.tsx
#: src/pages/auth/InitialSetupPage.tsx
#: src/pages/auth/InitialSetupPage.tsx
msgid "Admin user name"
msgstr "Administrator-Benutzername"
#: src/components/content/add/CategorySelect.tsx
#: src/components/header/Header.tsx
#: src/components/sidebar/Tree.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/app/FeedEntriesPage.tsx
msgid "All"
msgstr "Alle"
@@ -97,6 +98,14 @@ msgstr "Ankündigung"
msgid "API key"
msgstr "API-Schlüssel"
#: src/components/settings/PushNotificationSettings.tsx
msgid "API token"
msgstr "API-Token"
#: src/components/settings/PushNotificationSettings.tsx
msgid "App token"
msgstr "App-Token"
#: src/pages/app/CategoryDetailsPage.tsx
msgid "Are you sure you want to delete category <0>{categoryName}</0>?"
msgstr "Sind Sie sicher, dass Sie die Kategorie <0>{categoryName}</0> löschen möchten?"
@@ -126,54 +135,60 @@ msgid "Asc"
msgstr "Aufsteigend"
#: src/pages/app/FeedDetailsPage.tsx
msgid "Available variables are 'title', 'content', 'url' 'author' and 'categories' and their content is converted to lower case to ease string comparison."
msgstr "Verfügbare Variablen sind „Titel“, „Inhalt“, „URL“, „Autor“ und „Kategorien“, und ihr Inhalt wird in Kleinbuchstaben umgewandelt, um den String-Vergleich zu erleichtern."
msgid "Auto-mark as read"
msgstr "Automatisch als gelesen markieren"
#: src/components/content/add/Subscribe.tsx
msgid "Back"
msgstr "Zurück"
#: src/pages/auth/PasswordRecoveryPage.tsx
#: src/pages/auth/PasswordResetPage.tsx
msgid "Back to log in"
msgstr "Zurück zum Login"
#: src/components/settings/DisplaySettings.tsx
msgid "Blue"
msgstr ""
msgstr "Blau"
#: src/pages/app/AboutPage.tsx
msgid "Browser extension"
msgstr "Browser-Erweiterung"
#: src/components/KeyboardShortcutsHelp.tsx
msgid "Browser extension required for Chrome"
msgstr "Browser-Erweiterung für Chrome benötigt"
#: src/pages/app/AboutPage.tsx
msgid "Browser extention"
msgstr "Browser-Erweiterung"
#: src/components/settings/DisplaySettings.tsx
msgid "Browser tab"
msgstr ""
msgstr "Browsertab"
#: src/pages/app/TagDetailsPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/admin/AdminUsersPage.tsx
#: src/components/MarkAllAsReadConfirmationDialog.tsx
#: src/components/settings/ProfileSettings.tsx
#: src/components/settings/ProfileSettings.tsx
#: src/components/settings/CustomCodeSettings.tsx
#: src/components/content/add/ImportOpml.tsx
#: src/components/content/add/AddCategory.tsx
msgid "Build a filter expression to indicate what you want to read. Entries that don't match will be marked as read automatically."
msgstr "Erstellen Sie einen Filterausdruck, um anzugeben, was Sie lesen möchten. Einträge, die nicht übereinstimmen, werden automatisch als gelesen markiert."
#: src/components/admin/UserEdit.tsx
#: src/components/content/add/AddCategory.tsx
#: src/components/content/add/ImportOpml.tsx
#: src/components/MarkAllAsReadConfirmationDialog.tsx
#: src/components/settings/CustomCodeSettings.tsx
#: src/components/settings/ProfileSettings.tsx
#: src/components/settings/ProfileSettings.tsx
#: src/components/settings/PushNotificationSettings.tsx
#: src/pages/admin/AdminUsersPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/TagDetailsPage.tsx
msgid "Cancel"
msgstr "Abbrechen"
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/AboutPage.tsx
#: src/components/content/add/AddCategory.tsx
#: src/components/content/add/AddCategory.tsx
#: src/components/content/add/Subscribe.tsx
#: src/components/content/add/AddCategory.tsx
#: src/components/content/add/AddCategory.tsx
#: src/pages/app/AboutPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
msgid "Category"
msgstr "Kategorie"
@@ -191,7 +206,7 @@ msgstr "Menü schließen"
#: src/components/KeyboardShortcutsHelp.tsx
msgid "Cmd"
msgstr ""
msgstr "Befehl"
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed browser extension version {browserExtensionVersion}."
@@ -213,11 +228,11 @@ msgstr "CommaFeed version {version} ({revision})."
msgid "Compact"
msgstr "Kompakt"
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/admin/AdminUsersPage.tsx
#: src/components/MarkAllAsReadConfirmationDialog.tsx
#: src/components/settings/ProfileSettings.tsx
#: src/pages/admin/AdminUsersPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
msgid "Confirm"
msgstr "Bestätigen"
@@ -225,10 +240,19 @@ msgstr "Bestätigen"
msgid "Confirm password"
msgstr "Passwort bestätigen"
#: src/pages/auth/PasswordResetPage.tsx
#: src/pages/auth/PasswordResetPage.tsx
msgid "Confirm Password"
msgstr "Passwort bestätigen"
#: src/components/header/ProfileMenu.tsx
msgid "Cozy"
msgstr "Gemütlich"
#: src/pages/auth/InitialSetupPage.tsx
msgid "Create Admin Account"
msgstr "Administrator-Konto erstellen"
#: src/components/KeyboardShortcutsHelp.tsx
msgid "Ctrl"
msgstr "Strg"
@@ -251,10 +275,10 @@ msgstr "Einer JS Code der beim Laden der Seite ausgeführt wird"
#: src/components/settings/DisplaySettings.tsx
msgid "Cyan"
msgstr ""
msgstr "Cyan"
#: src/components/settings/DisplaySettings.tsx
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Dark"
msgstr "Dunkel"
@@ -262,6 +286,10 @@ msgstr "Dunkel"
msgid "Date created"
msgstr "Erstellungsdatum"
#: src/pages/app/FeedDetailsPage.tsx
msgid "days"
msgstr "Tage"
#: src/pages/app/CategoryDetailsPage.tsx
msgid "Delete"
msgstr "Löschen"
@@ -287,14 +315,18 @@ msgstr "Beschr"
msgid "Detailed"
msgstr "Detailliert"
#: src/pages/app/SettingsPage.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Disable \"Pull to refresh\" browser behavior"
msgstr "Browser-Verhalten \"Zum Aktualisieren ziehen\" deaktivieren"
#: src/components/header/ProfileMenu.tsx
#: src/components/settings/DisplaySettings.tsx
#: src/pages/app/SettingsPage.tsx
msgid "Display"
msgstr "Anzeige"
#: src/pages/app/DonatePage.tsx
#: src/components/header/ProfileMenu.tsx
#: src/pages/app/DonatePage.tsx
msgid "Donate"
msgstr "Spenden"
@@ -306,11 +338,13 @@ msgstr "Herunterladen"
msgid "Drag link to bookmark bar"
msgstr "Link in Lesezeichenleiste ziehen"
#: src/pages/auth/PasswordRecoveryPage.tsx
#: src/pages/auth/PasswordRecoveryPage.tsx
#: src/pages/admin/AdminUsersPage.tsx
#: src/components/settings/ProfileSettings.tsx
#: src/components/admin/UserEdit.tsx
#: src/components/settings/ProfileSettings.tsx
#: src/pages/admin/AdminUsersPage.tsx
#: src/pages/auth/InitialSetupPage.tsx
#: src/pages/auth/InitialSetupPage.tsx
#: src/pages/auth/PasswordRecoveryPage.tsx
#: src/pages/auth/PasswordRecoveryPage.tsx
msgid "E-mail"
msgstr "E-Mail"
@@ -323,8 +357,8 @@ msgstr "E-Mail-Adresse"
msgid "Edit user"
msgstr "Benutzer bearbeiten"
#: src/pages/admin/AdminUsersPage.tsx
#: src/components/admin/UserEdit.tsx
#: src/pages/admin/AdminUsersPage.tsx
msgid "Enabled"
msgstr "Aktiviert"
@@ -338,20 +372,16 @@ msgstr "Geben Sie Ihr aktuelles Passwort ein, um die Profileinstellungen zu änd
#: src/components/settings/DisplaySettings.tsx
msgid "Entries to keep above the selected entry when scrolling"
msgstr ""
msgstr "Anzahl der Einträge, die beim Scrollen über dem ausgewählten Eintrag bleiben sollen"
#: src/components/settings/DisplaySettings.tsx
msgid "Entry headers"
msgstr ""
msgstr "Eintragsüberschriften"
#: src/components/Alert.tsx
msgid "Error"
msgstr "Fehler"
#: src/pages/app/FeedDetailsPage.tsx
msgid "Example: {example}."
msgstr "Beispiel: {example}."
#: src/components/header/ProfileMenu.tsx
msgid "Expanded"
msgstr "Erweitert"
@@ -360,8 +390,8 @@ msgstr "Erweitert"
msgid "Export your subscriptions and categories as an OPML file that can be imported in other feed reading services"
msgstr "Exportieren Sie Ihre Abonnements und Kategorien als OPML-Datei, die in andere Feed-Lesedienste importiert werden kann"
#: src/pages/WelcomePage.tsx
#: src/components/header/Header.tsx
#: src/pages/WelcomePage.tsx
msgid "Extension options"
msgstr "Erweiterungsoptionen"
@@ -369,9 +399,9 @@ msgstr "Erweiterungsoptionen"
msgid "Feed name"
msgstr "Feedname"
#: src/components/content/add/Subscribe.tsx
#: src/components/content/add/Subscribe.tsx
#: src/pages/app/FeedDetailsPage.tsx
#: src/components/content/add/Subscribe.tsx
#: src/components/content/add/Subscribe.tsx
msgid "Feed URL"
msgstr "Feed-URL"
@@ -381,11 +411,11 @@ msgstr "Alle Feeds jetzt abrufen"
#: src/components/settings/ProfileSettings.tsx
msgid "Fever API"
msgstr ""
msgstr "Fever-API"
#: src/components/settings/ProfileSettings.tsx
msgid "Fever API URL"
msgstr ""
msgstr "Fever-API-URL"
#: src/pages/app/FeedDetailsPage.tsx
msgid "Filtering expression"
@@ -393,19 +423,19 @@ msgstr "Filterausdruck"
#: src/components/header/ProfileMenu.tsx
msgid "Font size"
msgstr ""
msgstr "Schriftgröße"
#: src/components/header/ProfileMenu.tsx
msgid "Force fetching feeds is not yet available."
msgstr ""
msgstr "Das Erzwingen des Feed-Abrufs ist noch nicht verfügbar."
#: src/pages/auth/LoginPage.tsx
msgid "Forgot password?"
msgstr "Passwort vergessen?"
#: src/pages/app/TagDetailsPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/TagDetailsPage.tsx
msgid "Generate an API key in your profile first."
msgstr "Generieren Sie zuerst einen API-Schlüssel in Ihrem Profil."
@@ -413,9 +443,9 @@ msgstr "Generieren Sie zuerst einen API-Schlüssel in Ihrem Profil."
msgid "Generate new API key"
msgstr "Neuen API-Schlüssel generieren"
#: src/pages/app/TagDetailsPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/TagDetailsPage.tsx
msgid "Generated feed url"
msgstr "Generierte Feed-URL"
@@ -438,23 +468,19 @@ msgstr "Goodies"
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr ""
msgstr "Traube"
#: src/components/settings/DisplaySettings.tsx
msgid "Gray"
msgstr ""
msgstr "Grau"
#: src/components/settings/DisplaySettings.tsx
msgid "Green"
msgstr ""
msgstr "Grün"
#: src/pages/admin/AdminUsersPage.tsx
msgid "Id"
msgstr ""
#: src/pages/app/FeedDetailsPage.tsx
msgid "If not empty, an expression evaluating to 'true' or 'false'. If false, new entries for this feed will be marked as read automatically."
msgstr "Wenn nicht leer, ein Ausdruck, der als „wahr“ oder „falsch“ ausgewertet wird."
msgstr "ID"
#: src/components/settings/DisplaySettings.tsx
msgid "If the entry doesn't entirely fit on the screen"
@@ -474,15 +500,23 @@ msgstr "In der erweiterten Ansicht werden Einträge beim Scrollen als gelesen ma
#: src/components/settings/DisplaySettings.tsx
msgid "Indigo"
msgstr ""
msgstr "Indigo"
#: src/pages/auth/InitialSetupPage.tsx
msgid "Initial Setup"
msgstr "Ersteinrichtung"
#: src/pages/auth/PasswordResetPage.tsx
msgid "Invalid password reset link. Please request a new one."
msgstr "Ungültiger Link zum Zurücksetzen des Passworts. Bitte fordern Sie einen neuen an."
#: src/components/content/FeedEntryFooter.tsx
#: src/components/content/FeedEntryContextMenu.tsx
#: src/components/content/FeedEntryFooter.tsx
msgid "Keep unread"
msgstr "Ungelesen lassen"
#: src/pages/app/AboutPage.tsx
#: src/components/content/FeedEntries.tsx
#: src/pages/app/AboutPage.tsx
msgid "Keyboard shortcuts"
msgstr "Tastaturkürzel"
@@ -508,14 +542,18 @@ msgstr "Hell"
#: src/components/settings/DisplaySettings.tsx
msgid "Lime"
msgstr ""
msgstr "Limette"
#: src/pages/app/TagDetailsPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/TagDetailsPage.tsx
msgid "Link"
msgstr "Verbindung"
#: src/components/settings/CustomCodeSettings.tsx
msgid "Link to the documentation"
msgstr "Link zur Dokumentation"
#: src/hooks/useAppLoading.ts
msgid "Loading profile..."
msgstr "Lade Profil..."
@@ -532,9 +570,9 @@ msgstr "Abonnements werden geladen..."
msgid "Loading tags..."
msgstr "Tags werden geladen..."
#: src/pages/auth/LoginPage.tsx
#: src/pages/auth/LoginPage.tsx
#: src/pages/WelcomePage.tsx
#: src/pages/auth/LoginPage.tsx
#: src/pages/auth/LoginPage.tsx
msgid "Log in"
msgstr "Einloggen"
@@ -546,8 +584,8 @@ msgstr "Abmelden"
msgid "Long press"
msgstr "Langer Tastendruck"
#: src/pages/admin/AdminUsersPage.tsx
#: src/components/header/ProfileMenu.tsx
#: src/pages/admin/AdminUsersPage.tsx
msgid "Manage users"
msgstr "Benutzer verwalten"
@@ -555,21 +593,25 @@ msgstr "Benutzer verwalten"
msgid "Mark all as read"
msgstr "Alle als gelesen markieren"
#: src/components/MarkAllAsReadConfirmationDialog.tsx
#: src/components/KeyboardShortcutsHelp.tsx
#: src/components/MarkAllAsReadConfirmationDialog.tsx
msgid "Mark all entries as read"
msgstr "Alle Einträge als gelesen markieren"
#: src/components/content/FeedEntryFooter.tsx
#: src/components/content/FeedEntryContextMenu.tsx
#: src/components/content/FeedEntryFooter.tsx
msgid "Mark as read"
msgstr "Als gelesen markieren"
#: src/components/content/FeedEntryFooter.tsx
#: src/components/content/FeedEntryContextMenu.tsx
#: src/components/content/FeedEntryFooter.tsx
msgid "Mark as read up to here"
msgstr "Bis hierhin als gelesen markieren"
#: src/pages/app/FeedDetailsPage.tsx
msgid "Mark entries in this feed as read after this number of days. Leave empty to disable."
msgstr "Markieren Sie Einträge in diesem Feed nach dieser Anzahl von Tagen als gelesen. Leer lassen zum Deaktivieren."
#: src/components/header/ProfileMenu.tsx
msgid "Metrics"
msgstr "Metriken"
@@ -586,22 +628,26 @@ msgstr "Seite nach unten verschieben"
msgid "Move the page up"
msgstr "Bewege die Seite nach oben"
#: src/pages/app/FeedDetailsPage.tsx
#: src/components/RelativeDate.tsx
#: src/pages/app/FeedDetailsPage.tsx
msgid "N/A"
msgstr "n.v."
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/admin/AdminUsersPage.tsx
#: src/components/admin/UserEdit.tsx
#: src/pages/admin/AdminUsersPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
msgid "Name"
msgstr ""
msgstr "Name"
#: src/components/KeyboardShortcutsHelp.tsx
msgid "Navigate to a subscription by entering its name"
msgstr "Navigieren Sie zu einem Abonnement, indem Sie seinen Namen eingeben"
#: src/components/settings/DisplaySettings.tsx
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
msgstr "Navigieren Sie zum nächsten Feed/Kategorie mit ungelesenen Einträgen, wenn Sie alle Einträge als gelesen markieren"
#: src/components/settings/DisplaySettings.tsx
#: src/components/settings/DisplaySettings.tsx
msgid "Never"
@@ -611,12 +657,17 @@ msgstr "Niemals"
msgid "New password"
msgstr "Neues Passwort"
#: src/pages/auth/PasswordResetPage.tsx
#: src/pages/auth/PasswordResetPage.tsx
msgid "New Password"
msgstr "Neues Passwort"
#: src/pages/app/AboutPage.tsx
msgid "Newest first"
msgstr "Neueste zuerst"
#: src/components/header/Header.tsx
#: src/components/content/add/Subscribe.tsx
#: src/components/header/Header.tsx
msgid "Next"
msgstr "Weiter"
@@ -634,7 +685,7 @@ msgstr "Keine weiteren Einträge"
#: src/components/content/ShareButtons.tsx
msgid "No sharing options available."
msgstr ""
msgstr "Keine Optionen zum Teilen verfügbar."
#: src/components/sidebar/TreeSearch.tsx
msgid "Nothing found"
@@ -646,11 +697,11 @@ msgstr "Älteste zuerst"
#: src/components/settings/DisplaySettings.tsx
msgid "On desktop"
msgstr ""
msgstr "Auf dem Desktop"
#: src/components/settings/DisplaySettings.tsx
msgid "On mobile"
msgstr ""
msgstr "Auf dem Handy"
#: src/components/settings/DisplaySettings.tsx
msgid "On mobile, show action buttons at the bottom of the screen"
@@ -658,7 +709,7 @@ msgstr "Auf mobilen Geräten die Aktion-Buttons am unteren Ende des Bildschirms
#: src/components/settings/DisplaySettings.tsx
msgid "Only applies to compact, cozy and detailed modes"
msgstr ""
msgstr "Gilt nur für die Modi Kompakt, Gemütlich und Detailliert"
#: src/pages/ErrorPage.tsx
msgid "Oops!"
@@ -707,7 +758,7 @@ msgstr "Aktuellen Eintrag öffnen/schließen"
#: src/pages/app/AddPage.tsx
msgid "OPML"
msgstr ""
msgstr "OPML"
#: src/components/settings/ProfileSettings.tsx
msgid "OPML export"
@@ -720,11 +771,11 @@ msgstr "OPML-Datei"
#: src/components/content/add/ImportOpml.tsx
msgid "OPML file is required"
msgstr ""
msgstr "OPML-Datei ist erforderlich"
#: src/components/settings/DisplaySettings.tsx
msgid "Orange"
msgstr ""
msgstr "Orange"
#: src/pages/app/AboutPage.tsx
msgid "Order"
@@ -738,28 +789,34 @@ msgstr "Übergeordnet"
msgid "Parent Category"
msgstr "Übergeordnete Kategorie"
#: src/pages/auth/RegistrationPage.tsx
#: src/pages/auth/RegistrationPage.tsx
#: src/pages/auth/LoginPage.tsx
#: src/pages/auth/LoginPage.tsx
#: src/components/admin/UserEdit.tsx
#: src/pages/auth/InitialSetupPage.tsx
#: src/pages/auth/InitialSetupPage.tsx
#: src/pages/auth/LoginPage.tsx
#: src/pages/auth/LoginPage.tsx
#: src/pages/auth/RegistrationPage.tsx
#: src/pages/auth/RegistrationPage.tsx
msgid "Password"
msgstr "Passwort"
#: src/hooks/useValidationRules.ts
msgid "Password must be at least {minimumPasswordLength} characters"
msgstr "Passwort muss mindestens {minimumPasswordLength} Zeichen lang sein"
#: src/pages/auth/PasswordRecoveryPage.tsx
msgid "Password Recovery"
msgstr "Passwortwiederherstellung"
#: src/components/settings/ProfileSettings.tsx
#: src/hooks/useValidationRules.ts
msgid "Passwords do not match"
msgstr "Passwörter stimmen nicht überein"
#: src/components/settings/DisplaySettings.tsx
msgid "Pink"
msgstr ""
msgstr "Rosa"
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
msgid "Position"
msgstr "Position"
@@ -769,22 +826,47 @@ msgstr "Vorheriges"
#: src/components/settings/DisplaySettings.tsx
msgid "Primary color"
msgstr ""
msgstr "Primärfarbe"
#: src/pages/app/SettingsPage.tsx
msgid "Profile"
msgstr "Profil"
#: src/components/settings/PushNotificationSettings.tsx
msgid "Push notification service"
msgstr "Push-Benachrichtigungsdienst"
#: src/pages/app/SettingsPage.tsx
msgid "Push notifications"
msgstr "Push-Benachrichtigungen"
#: src/components/ReceivePushNotificationsChechbox.tsx
msgid "Push notifications are not configured in your user settings."
msgstr "Push-Benachrichtigungen sind in Ihren Benutzereinstellungen nicht konfiguriert."
#: src/components/ReceivePushNotificationsChechbox.tsx
#: src/components/settings/PushNotificationSettings.tsx
msgid "Push notifications are not enabled on this CommaFeed instance."
msgstr "Push-Benachrichtigungen sind auf dieser CommaFeed-Instanz nicht aktiviert."
#: src/components/ReceivePushNotificationsChechbox.tsx
msgid "Receive push notifications"
msgstr "Push-Benachrichtigungen erhalten"
#: src/components/settings/PushNotificationSettings.tsx
msgid "Receive push notifications when new feed entries are discovered. Enable \"Receive push notifications\" in the settings of each feed for which you want to receive notifications."
msgstr "Erhalten Sie Push-Benachrichtigungen, wenn neue Feed-Einträge entdeckt werden. Aktivieren Sie \"Push-Benachrichtigungen erhalten\" in den Einstellungen jedes Feeds, für den Sie Benachrichtigungen erhalten möchten."
#: src/pages/auth/PasswordRecoveryPage.tsx
msgid "Recover password"
msgstr "Kennwort wiederherstellen"
#: src/components/settings/DisplaySettings.tsx
msgid "Red"
msgstr ""
msgstr "Rot"
#: src/components/KeyboardShortcutsHelp.tsx
#: src/components/header/Header.tsx
#: src/components/KeyboardShortcutsHelp.tsx
msgid "Refresh"
msgstr "Aktualisieren"
@@ -792,6 +874,11 @@ msgstr "Aktualisieren"
msgid "Registrations are closed on this CommaFeed instance"
msgstr "Registrierungen sind für diese CommaFeed-Instanz geschlossen"
#: src/pages/auth/PasswordResetPage.tsx
#: src/pages/auth/PasswordResetPage.tsx
msgid "Reset Password"
msgstr "Passwort zurücksetzen"
#: src/pages/app/AboutPage.tsx
msgid "REST API"
msgstr "REST-API"
@@ -801,11 +888,12 @@ msgstr "REST-API"
msgid "Right click"
msgstr "Rechtsklick"
#: src/pages/app/FeedDetailsPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/components/settings/ProfileSettings.tsx
#: src/components/settings/CustomCodeSettings.tsx
#: src/components/admin/UserEdit.tsx
#: src/components/settings/CustomCodeSettings.tsx
#: src/components/settings/ProfileSettings.tsx
#: src/components/settings/PushNotificationSettings.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/app/FeedDetailsPage.tsx
msgid "Save"
msgstr "Speichern"
@@ -821,24 +909,25 @@ msgstr "Schnelles Scrollen beim Navigieren zwischen Einträgen"
msgid "Scrolling"
msgstr "Scrollen"
#: src/components/sidebar/TreeSearch.tsx
#: src/components/sidebar/TreeSearch.tsx
#: src/components/header/Header.tsx
#: src/components/header/Header.tsx
#: src/components/sidebar/TreeSearch.tsx
#: src/components/sidebar/TreeSearch.tsx
msgid "Search"
msgstr "Suche"
#: src/components/header/Header.tsx
msgid "Search requires at least 3 characters"
msgstr "Suche erfordert mindestens 3 Zeichen"
#: src/components/KeyboardShortcutsHelp.tsx
msgid "Select next unread feed/category"
msgstr ""
msgstr "Nächsten ungelesenen Feed/Kategorie auswählen"
#: src/components/KeyboardShortcutsHelp.tsx
msgid "Select previous unread feed/category"
msgstr ""
msgstr "Vorherigen ungelesenen Feed/Kategorie auswählen"
#: src/components/settings/PushNotificationSettings.tsx
#: src/components/settings/PushNotificationSettings.tsx
msgid "Server URL"
msgstr "Server-URL"
#: src/components/KeyboardShortcutsHelp.tsx
msgid "Set focus on next entry without opening it"
@@ -888,7 +977,7 @@ msgstr "Eintragsmenü anzeigen (Handy)"
#: src/components/settings/DisplaySettings.tsx
msgid "Show external link icon"
msgstr ""
msgstr "Symbol für externen Link anzeigen"
#: src/components/settings/DisplaySettings.tsx
msgid "Show feeds and categories with no unread entries"
@@ -904,19 +993,19 @@ msgstr "Natives Menü anzeigen (Desktop)"
#: src/components/settings/DisplaySettings.tsx
msgid "Show star icon"
msgstr ""
msgstr "Stern-Symbol anzeigen"
#: src/components/settings/DisplaySettings.tsx
msgid "Show unread count in tab favicon"
msgstr ""
msgstr "Anzahl ungelesener Nachrichten im Tab-Favicon anzeigen"
#: src/components/settings/DisplaySettings.tsx
msgid "Show unread count in tab title"
msgstr ""
msgstr "Anzahl ungelesener Nachrichten im Tab-Titel anzeigen"
#: src/pages/auth/RegistrationPage.tsx
#: src/pages/auth/RegistrationPage.tsx
#: src/pages/WelcomePage.tsx
#: src/pages/auth/RegistrationPage.tsx
#: src/pages/auth/RegistrationPage.tsx
msgid "Sign up"
msgstr "Melden Sie sich an"
@@ -929,21 +1018,21 @@ msgstr "Etwas Schlimmes ist gerade passiert..."
msgid "Space"
msgstr "Raum"
#: src/components/content/FeedEntryFooter.tsx
#: src/components/content/FeedEntryContextMenu.tsx
#: src/components/content/FeedEntryFooter.tsx
#: src/components/content/header/Star.tsx
msgid "Star"
msgstr "Stern"
#: src/pages/app/FeedEntriesPage.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/components/sidebar/Tree.tsx
#: src/pages/app/CategoryDetailsPage.tsx
#: src/pages/app/FeedEntriesPage.tsx
msgid "Starred"
msgstr "Markiert"
#: src/components/content/add/Subscribe.tsx
#: src/components/content/add/Subscribe.tsx
#: src/pages/app/AddPage.tsx
#: src/components/content/add/Subscribe.tsx
#: src/components/content/add/Subscribe.tsx
msgid "Subscribe"
msgstr "Abonnieren"
@@ -973,16 +1062,24 @@ msgstr "Zum Lightmode wechseln"
#: src/components/header/ProfileMenu.tsx
msgid "System"
msgstr ""
msgstr "System"
#: src/components/content/FeedEntryFooter.tsx
#: src/components/content/FeedEntryFooter.tsx
msgid "Tags"
msgstr ""
msgstr "Tags"
#: src/components/settings/DisplaySettings.tsx
msgid "Teal"
msgstr ""
msgstr "Blaugrün"
#: src/components/settings/PushNotificationSettings.tsx
msgid "Test"
msgstr "Test"
#: src/components/settings/PushNotificationSettings.tsx
msgid "Test notification sent successfully."
msgstr "Testbenachrichtigung erfolgreich gesendet."
#: src/components/content/add/Subscribe.tsx
msgid "The URL for the feed you want to subscribe to. You can also use the website's url directly and CommaFeed will try to find the feed in the page."
@@ -992,10 +1089,19 @@ msgstr "Die URL für den Feed, den Sie abonnieren möchten. "
msgid "Theme"
msgstr "Thema"
#. placeholder {0}: feed.filterLegacy
#: src/pages/app/FeedDetailsPage.tsx
msgid "This feed has a legacy filter that cannot be edited and is not applied. Please recreate the filter using the new expression editor. The legacy filter expression was: <0>{0}</0>"
msgstr "Dieser Feed verfügt über einen veralteten Filter, der nicht bearbeitet werden kann und nicht angewendet wird. Bitte erstellen Sie den Filter mit dem neuen Ausdruckseditor neu. Der veraltete Filterausdruck war: <0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "Dies ist Ihr API-Schlüssel. Er kann für einige schreibgeschützte API-Vorgänge verwendet werden und ermöglicht den Zugriff auf die Fever-API. Verwenden Sie das Formular unten auf der Seite, um einen neuen API-Schlüssel zu generieren"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
msgstr "Diese Einstellung kann auf einigen Browsern (z. B. Safari) zu Scrollproblemen führen"
#: src/components/KeyboardShortcutsHelp.tsx
msgid "Toggle read status of current entry"
msgstr "Lesestatus des aktuellen Eintrags umschalten"
@@ -1008,6 +1114,10 @@ msgstr "Sidebar an- und ausschalten"
msgid "Toggle starred status of current entry"
msgstr "Markierungsstatus des aktuellen Eintrags ändern"
#: src/components/settings/PushNotificationSettings.tsx
msgid "Topic"
msgstr "Thema"
#: src/pages/auth/LoginPage.tsx
msgid "Try out CommaFeed with the demo account: demo/demo"
msgstr "Testen Sie CommaFeed mit dem Demokonto: demo/demo"
@@ -1020,8 +1130,8 @@ msgstr "Testen Sie die Demo!"
msgid "Unread"
msgstr "Ungelesen"
#: src/components/content/FeedEntryFooter.tsx
#: src/components/content/FeedEntryContextMenu.tsx
#: src/components/content/FeedEntryFooter.tsx
#: src/components/content/header/Star.tsx
msgid "Unstar"
msgstr "Stern entfernen"
@@ -1031,6 +1141,10 @@ msgstr "Stern entfernen"
msgid "Unsubscribe"
msgstr "Abbestellen"
#: src/components/settings/PushNotificationSettings.tsx
msgid "User key"
msgstr "Benutzerschlüssel"
#: src/components/settings/ProfileSettings.tsx
msgid "User name"
msgstr "Benutzername"
@@ -1042,7 +1156,7 @@ msgstr "Benutzername oder E-Mail"
#: src/components/settings/DisplaySettings.tsx
msgid "Violet"
msgstr ""
msgstr "Violett"
#: src/components/Alert.tsx
msgid "Warning"
@@ -1052,9 +1166,13 @@ msgstr "Warnung"
msgid "Website"
msgstr "Webseite"
#: src/pages/auth/InitialSetupPage.tsx
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "Willkommen! Dies scheint das erste Mal zu sein, dass Sie CommaFeed ausführen. Bitte erstellen Sie ein Administrator-Konto, um zu beginnen."
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr ""
msgstr "Gelb"
#: src/pages/app/FeedEntriesPage.tsx
msgid "You don't have any subscriptions yet. Why not try adding one by clicking on the + sign at the top of the page?"
@@ -1063,3 +1181,7 @@ msgstr "Sie haben noch keine Abonnements."
#: src/components/header/ProfileMenu.tsx
msgid "Your feeds have been queued for refresh."
msgstr "Ihr Feed wurde für die Aktualisierung eingereiht."
#: src/pages/auth/PasswordResetPage.tsx
msgid "Your password has been changed. You can now log in with your new password."
msgstr "Ihr Passwort wurde geändert. Sie können sich nun mit Ihrem neuen Passwort anmelden."

Some files were not shown because too many files have changed in this diff Show More