Compare commits

...

1821 Commits

Author SHA1 Message Date
3cefc0f176 Update docker script to build pgsql variant 2026-03-21 17:32:21 -05:00
1cb346866a Add script to build Docker image from forked code 2026-03-21 17:11:32 -05:00
5cc8c736e7 Add user preference to disable sidebar swipe-to-open on mobile; cleanup migrations + README in prep for long-term fork maintenance 2026-03-21 17:04:05 -05:00
eb5614a03b Merge branch 'master' of code.garrettmills.dev:garrettmills/commafeed 2026-03-21 16:39:28 -05:00
renovate[bot]
fc76d7e609 fix(deps): update dependency @rolldown/plugin-babel to ^0.2.2 2026-03-21 08:51:10 +00:00
renovate[bot]
1b24bf33ed fix(deps): update dependency com.google.protobuf:protobuf-java to v4.34.1 2026-03-20 18:02:04 +00:00
renovate[bot]
58ff378735 fix(deps): update dependency io.github.hakky54:ayza-for-apache5 to v10.0.4 2026-03-19 13:44:43 +00:00
Jérémie Panzer
1cee04a233 Merge pull request #2088 from Athou/renovate/com.diffplug.spotless-spotless-maven-plugin-3.x
chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v3.4.0
2026-03-19 00:03:44 +01:00
renovate[bot]
ac11a0efb8 chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v3.4.0 2026-03-18 21:29:01 +00:00
renovate[bot]
f2ea1e3f7a fix(deps): update dependency io.quarkus.platform:quarkus-bom to v3.32.4 2026-03-18 18:07:29 +00:00
Jérémie Panzer
153970c146 Merge pull request #2087 from Athou/renovate/jsdom-29.x
chore(deps): update dependency jsdom to v29
2026-03-18 13:46:24 +01:00
renovate[bot]
c21287e642 chore(deps): update dependency jsdom to v29 2026-03-18 12:13:28 +00:00
Athou
284942a82e add feature-request to the list of exempted labels 2026-03-18 13:00:44 +01:00
Jérémie Panzer
e796916e73 Merge pull request #2085 from Athou/renovate/com.ibm.icu-icu4j-78.x
fix(deps): update dependency com.ibm.icu:icu4j to v78.3
2026-03-18 12:42:41 +01:00
e2a1630adc Add Infrequent tab and corresponding user setting 2026-03-17 21:38:17 -05:00
renovate[bot]
004db1762c fix(deps): update dependency com.ibm.icu:icu4j to v78.3 2026-03-17 22:35:16 +00:00
renovate[bot]
8e05ba8820 chore(deps): update dependency lint-staged to ^16.4.0 (#2083)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-17 20:33:50 +00:00
renovate[bot]
f4f386b5e5 chore(deps): update dependency lint-staged to ^16.3.4 2026-03-17 09:01:31 +00:00
Jérémie Panzer
ecbf8bec23 Merge pull request #2082 from Athou/renovate/debian-13.x
chore(deps): update debian docker tag to v13.4
2026-03-17 07:29:17 +01:00
renovate[bot]
5d8c09ccda chore(deps): update debian docker tag to v13.4 2026-03-17 00:35:37 +00:00
renovate[bot]
47c5c3d8a0 chore(deps): update dependency io.quarkiverse.playwright:quarkus-playwright to v2.3.3 2026-03-16 21:27:52 +00:00
renovate[bot]
3ddce16d5b chore(deps): update graalvm/setup-graalvm digest to 03e8abf 2026-03-16 18:35:24 +00:00
renovate[bot]
acefdc44d9 chore(deps): lock file maintenance 2026-03-16 01:07:15 +00:00
renovate[bot]
d05c5b9d7f chore(deps): update dependency npm to v11.11.1 2026-03-15 04:53:39 +00:00
renovate[bot]
5d1237d1f4 chore(deps): update ncipollo/release-action digest to 339a818 2026-03-15 01:34:06 +00:00
Athou
6bac8631ac output mantine as its own chunk because it is quite large 2026-03-14 20:20:51 +01:00
Athou
2c803327ad upgrade to vite 8 2026-03-13 22:35:20 +01:00
renovate[bot]
451ae5bc51 chore(deps): update dependency lint-staged to ^16.3.3 2026-03-13 05:46:24 +00:00
renovate[bot]
f41ce8c878 chore(deps): update graalvm/setup-graalvm digest to 6e327d2 2026-03-12 19:12:27 +00:00
renovate[bot]
177c54c813 chore(deps): update dependency maven to v3.9.14 2026-03-12 14:46:09 +00:00
Jérémie Panzer
3765e32fd4 Merge pull request #2079 from Athou/renovate/protobuf-monorepo
fix(deps): update dependency com.google.protobuf:protobuf-java to v4.34.0
2026-03-12 08:19:25 +01:00
renovate[bot]
aab7a16d18 fix(deps): update dependency com.google.protobuf:protobuf-java to v4.34.0 2026-03-12 06:26:40 +00:00
Athou
f2463af63c cel update 2026-03-12 07:25:36 +01:00
renovate[bot]
212c2c3b56 fix(deps): update quarkus.version to v3.32.3 2026-03-11 22:48:05 +00:00
renovate[bot]
3ab00b0cdd chore(deps): update actions/download-artifact digest to 3e5f45b 2026-03-11 17:53:34 +00:00
renovate[bot]
fad85e9299 fix(deps): update dependency org.projectlombok:lombok to v1.18.44 2026-03-11 02:48:12 +00:00
renovate[bot]
3cd5e203e2 fix(deps): update mantine monorepo to ^8.3.16 (#2076)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-09 08:40:30 +00:00
Jérémie Panzer
7b081fa870 Merge pull request #2077 from Athou/renovate/biomejs-biome-2.4.x
chore(deps): update dependency @biomejs/biome to v2.4.6
2026-03-09 09:08:37 +01:00
renovate[bot]
5ce22051d4 chore(deps): update dependency @biomejs/biome to v2.4.6 2026-03-09 07:19:20 +00:00
Jérémie Panzer
1e59489fa5 Merge pull request #2078 from Athou/renovate/lock-file-maintenance
chore(deps): lock file maintenance
2026-03-09 08:18:42 +01:00
renovate[bot]
1e691b1255 chore(deps): lock file maintenance 2026-03-09 01:10:36 +00:00
Jérémie Panzer
61e1bef63f Merge pull request #2074 from Athou/renovate/maven-3.9.x
chore(deps): update dependency maven to v3.9.13
2026-03-07 03:45:01 +01:00
renovate[bot]
46dbb78fbf chore(deps): update dependency maven to v3.9.13 2026-03-07 01:16:46 +00:00
renovate[bot]
99890707b3 chore(deps): update dependency lint-staged to ^16.3.2 2026-03-06 21:20:05 +00:00
Jérémie Panzer
f54c841fdc Merge pull request #2073 from Athou/renovate/react-icons-5.x
fix(deps): update dependency react-icons to ^5.6.0
2026-03-06 17:37:19 +01:00
renovate[bot]
e2a6009ee9 fix(deps): update dependency react-icons to ^5.6.0 2026-03-06 10:39:30 +00:00
Jérémie Panzer
a34dd15040 Merge pull request #2072 from Athou/renovate/docker-build-push-action-7.x
chore(deps): update docker/build-push-action action to v7
2026-03-06 07:20:22 +01:00
renovate[bot]
24c934003d chore(deps): update docker/build-push-action action to v7 2026-03-05 21:51:18 +00:00
renovate[bot]
5300e1a245 chore(deps): update dependency @biomejs/biome to v2.4.5 2026-03-05 18:43:33 +00:00
Jérémie Panzer
90381c670b Merge pull request #2071 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.5.0
2026-03-05 14:08:00 +01:00
renovate[bot]
23edea93db chore(deps): update dependency org.apache.maven.plugins:maven-resources-plugin to v3.5.0 2026-03-05 12:25:30 +00:00
Jérémie Panzer
a51712e363 Merge pull request #2070 from Athou/renovate/docker-setup-buildx-action-4.x
chore(deps): update docker/setup-buildx-action action to v4
2026-03-05 13:25:03 +01:00
renovate[bot]
4310e979e1 chore(deps): update docker/setup-buildx-action action to v4 2026-03-05 09:47:18 +00:00
renovate[bot]
f690b76d87 fix(deps): update quarkus.version to v3.32.2 2026-03-05 01:25:51 +00:00
Jérémie Panzer
ac29594b67 Merge pull request #2069 from Athou/renovate/docker-setup-qemu-action-4.x
chore(deps): update docker/setup-qemu-action action to v4
2026-03-04 15:29:50 +01:00
renovate[bot]
93f535bb87 chore(deps): update docker/setup-qemu-action action to v4 2026-03-04 13:38:20 +00:00
Jérémie Panzer
076eb3cf42 Merge pull request #2068 from Athou/renovate/docker-login-action-4.x
chore(deps): update docker/login-action action to v4
2026-03-04 14:35:47 +01:00
Athou
7b2e0fffbd reduce timeout for tests to speed up shutdown 2026-03-04 14:19:56 +01:00
renovate[bot]
8eaab0dbc3 chore(deps): update docker/login-action action to v4 2026-03-04 12:59:09 +00:00
Athou
eaa5bc896e stop the application between tests to make sure that there are no active transactions when we truncate the tables 2026-03-04 13:58:06 +01:00
renovate[bot]
42d1db5fc3 chore(deps): update dependency lint-staged to ^16.3.1 2026-03-04 12:09:08 +00:00
Athou
78c017ddaf wait for tasks to complete when shutting down 2026-03-04 12:49:06 +01:00
renovate[bot]
231551d743 chore(deps): update dependency lint-staged to ^16.3.0 (#2067)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-03 21:56:21 +00:00
Jérémie Panzer
d0984eaba7 Merge pull request #2066 from Athou/renovate/com.diffplug.spotless-spotless-maven-plugin-3.x
chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v3.3.0
2026-03-03 06:05:51 +01:00
renovate[bot]
15854a72d1 chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v3.3.0 2026-03-03 01:56:14 +00:00
renovate[bot]
7fd2bf0eda fix(deps): update dependency axios to ^1.13.6 2026-03-02 18:15:22 +00:00
renovate[bot]
6a10a2167e chore(deps): lock file maintenance 2026-03-02 01:25:14 +00:00
Jérémie Panzer
1ba99d255c Merge pull request #2063 from Athou/renovate/npm-11.x
chore(deps): update dependency npm to v11.11.0
2026-03-01 00:43:13 +01:00
renovate[bot]
ff1c2947b6 chore(deps): update dependency npm to v11.11.0 2026-02-28 23:17:20 +00:00
Jérémie Panzer
a690d2e0db Merge pull request #2062 from Athou/renovate/com.puppycrawl.tools-checkstyle-13.x
chore(deps): update dependency com.puppycrawl.tools:checkstyle to v13.3.0
2026-03-01 00:16:55 +01:00
renovate[bot]
a3df327396 chore(deps): update dependency com.puppycrawl.tools:checkstyle to v13.3.0 2026-02-28 20:52:06 +00:00
Jérémie Panzer
ede0016d8e Merge pull request #2060 from Athou/renovate/major-github-artifact-actions
chore(deps): update github artifact actions (major)
2026-02-26 22:57:55 +01:00
renovate[bot]
c19b091795 chore(deps): update github artifact actions 2026-02-26 20:39:27 +00:00
renovate[bot]
9e62c8b9f3 fix(deps): update linguijs monorepo to ^5.9.2 2026-02-26 20:39:23 +00:00
renovate[bot]
9f30dc181c fix(deps): update dependency react-router-dom to ^7.13.1 2026-02-26 18:02:38 +00:00
Jérémie Panzer
37fe44f860 Merge pull request #2059 from Athou/renovate/quarkus.version
fix(deps): update quarkus.version to v3.32.1 (minor)
2026-02-25 20:23:16 +01:00
renovate[bot]
68aaab8467 fix(deps): update quarkus.version to v3.32.1 2026-02-25 16:48:25 +00:00
renovate[bot]
b951ed1fcd chore(deps): update debian:13.3 docker digest to 3615a74 2026-02-24 21:53:17 +00:00
Jérémie Panzer
9bd9dc568a Merge pull request #2058 from Athou/renovate/node-24.x
chore(deps): update node.js to v24.14.0
2026-02-24 21:18:33 +01:00
renovate[bot]
29e4356fee chore(deps): update node.js to v24.14.0 2026-02-24 17:22:57 +00:00
renovate[bot]
0ed31eaa99 chore(deps): update dependency @biomejs/biome to v2.4.4 2026-02-23 21:56:45 +00:00
Jérémie Panzer
1e9869b217 Merge pull request #2057 from Athou/renovate/npm-11.10.x
chore(deps): update dependency npm to v11.10.1
2026-02-23 07:21:35 +01:00
renovate[bot]
78cfc2c827 chore(deps): update dependency npm to v11.10.1 2026-02-23 05:33:44 +00:00
renovate[bot]
a6e5a0d125 chore(deps): lock file maintenance 2026-02-23 00:55:55 +00:00
renovate[bot]
ea13aecd27 chore(deps): update dependency @biomejs/biome to v2.4.3 2026-02-22 21:47:30 +00:00
Athou
d838e8f28f fix occasional flicker 2026-02-22 14:36:25 +01:00
Athou
c9a7b9e17c ensure the indicator is not shown above the app header 2026-02-22 11:47:13 +01:00
Athou
8fe2d0bc0e fix typo 2026-02-21 23:58:49 +01:00
Athou
71e2f1e1e6 kill biome on build to prevent unlink errors on Windows 2026-02-21 23:55:08 +01:00
Athou
1ce9d1b9b2 prevent title line wrapping 2026-02-21 23:39:38 +01:00
Athou
b3d6ae467f reduce code duplication 2026-02-21 23:24:03 +01:00
Athou
da8d720dc4 don't show a pointer on hover 2026-02-21 22:58:49 +01:00
Athou
824c38f8ce show unread count on mobile only 2026-02-21 22:52:32 +01:00
Athou
b0579a70d8 Merge branch 'master' of https://github.com/lpoirothattermann/commafeed into lpoirothattermann-master 2026-02-21 22:28:03 +01:00
Athou
f195eb6d0d release 7.0.0 2026-02-21 22:26:40 +01:00
Louis POIROT--HATTERMANN
f9fe2d0976 feat: add unread count badge next to title 2026-02-21 18:54:23 +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
Athou
f361be0c72 release 5.10.0 2025-05-28 07:08:11 +02:00
renovate[bot]
1611dc5703 chore(deps): update docker/build-push-action digest to 2634353 2025-05-27 20:52:00 +00:00
renovate[bot]
04faad84a4 fix(deps): update mantine monorepo to ^8.0.2 2025-05-27 14:24:50 +00:00
renovate[bot]
19c42e5838 chore(deps): update dependency @types/react to ^19.1.6 2025-05-27 11:59:22 +00:00
Athou
4918b69d0a improve performance by enabling the react compiler (#1087) 2025-05-26 21:06:53 +02:00
Athou
c7cec464aa improve performance by avoiding some big re-renders (#1087) 2025-05-26 20:55:27 +02:00
renovate[bot]
91857c4d73 chore(deps): lock file maintenance 2025-05-26 01:42:10 +00:00
Jérémie Panzer
fc6f9f4258 Merge pull request #1799 from Athou/renovate/patch-react-router-monorepo
fix(deps): update dependency react-router-dom to ^7.6.1
2025-05-25 20:54:27 +02:00
renovate[bot]
34f9f9374a fix(deps): update dependency react-router-dom to ^7.6.1 2025-05-25 15:16:31 +00:00
renovate[bot]
0ae4c1621f fix(deps): update dependency io.dropwizard.metrics:metrics-json to v4.2.32 2025-05-25 01:30:25 +00:00
Athou
c393f5c045 improve aarch64 compatibility 2025-05-24 18:21:50 +02:00
Jérémie Panzer
1624290dc1 Merge pull request #1798 from Athou/renovate/rollup-plugin-visualizer-6.x
chore(deps): update dependency rollup-plugin-visualizer to v6
2025-05-24 16:31:45 +02:00
renovate[bot]
c6491990ac chore(deps): update dependency rollup-plugin-visualizer to v6 2025-05-24 13:46:34 +00:00
renovate[bot]
15dea17923 chore(deps): update dependency io.github.git-commit-id:git-commit-id-maven-plugin to v9.0.2 2025-05-23 21:45:42 +00:00
Athou
689d5ac7b2 clear indicator when entries are loaded 2025-05-23 22:37:28 +02:00
Athou
2142e20e7d cleanup 2025-05-23 16:03:16 +02:00
Jérémie Panzer
dc23126570 Merge pull request #1780 from Eshwar1212-maker/clean-red-dot
feat: red dot indicator for new unread articles
2025-05-23 15:54:22 +02:00
Jérémie Panzer
55856f9060 Merge pull request #1794 from Athou/renovate/vitejs-plugin-react-4.x
chore(deps): update dependency @vitejs/plugin-react to ^4.5.0
2025-05-23 09:20:28 +02:00
renovate[bot]
c756ce5fc8 chore(deps): update dependency @vitejs/plugin-react to ^4.5.0 2025-05-23 02:55:39 +00:00
Eshwar Tangirala
0546f25d55 Removed console.log 2025-05-22 20:13:16 -04:00
Eshwar Tangirala
7b33717333 Readjusted code to not use localstorage, and just used redux for indicator 2025-05-22 20:10:52 -04:00
Jérémie Panzer
6ea6d16e58 Merge pull request #1793 from Athou/renovate/org.apache.httpcomponents.client5-httpclient5-5.x
fix(deps): update dependency org.apache.httpcomponents.client5:httpclient5 to v5.5
2025-05-22 22:13:31 +02:00
renovate[bot]
a9b65c83aa fix(deps): update dependency org.apache.httpcomponents.client5:httpclient5 to v5.5 2025-05-22 17:14:03 +00:00
renovate[bot]
a497802b50 chore(deps): update dependency npm to v11.4.1 2025-05-22 05:05:19 +00:00
Jérémie Panzer
42b0428b9a Merge pull request #1792 from Athou/renovate/com.puppycrawl.tools-checkstyle-10.x
chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.24.0
2025-05-22 07:04:34 +02:00
Jérémie Panzer
931c553e1d Merge pull request #1791 from Athou/renovate/debian-12.x
chore(deps): update debian docker tag to v12.11
2025-05-22 07:03:52 +02:00
renovate[bot]
f3c0b92a3c chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.24.0 2025-05-22 03:10:15 +00:00
renovate[bot]
970cabf241 chore(deps): update debian docker tag to v12.11 2025-05-22 03:10:12 +00:00
renovate[bot]
e321ecde5d chore(deps): update dependency @types/react to ^19.1.5 2025-05-21 17:09:30 +00:00
Jérémie Panzer
32ac326a77 Merge pull request #1790 from Athou/renovate/node-22.x
chore(deps): update node.js to v22.16.0
2025-05-21 19:08:34 +02:00
renovate[bot]
134dcd4466 chore(deps): update node.js to v22.16.0 2025-05-21 16:41:07 +00:00
renovate[bot]
26a44353d4 chore(deps): update dependency vitest to ^3.1.4 2025-05-19 18:09:09 +00:00
renovate[bot]
55acb3ef28 chore(deps): lock file maintenance 2025-05-19 03:45:55 +00:00
Athou
0e96307726 ignore scheme case 2025-05-18 17:40:06 +02:00
Eshwar Tangirala
0199a36238 Working on indicator feature for new unread feeds 2025-05-18 00:03:28 -04:00
Eshwar Tangirala
3f2f6e83fa Adding red dot indicator feature, got main components done 2025-05-15 20:19:05 -04:00
renovate[bot]
4fa780cac2 chore(deps): update docker/build-push-action digest to 1dc7386 2025-05-15 21:12:24 +00:00
Jérémie Panzer
edb0f655b0 Merge pull request #1786 from Athou/renovate/patch-quarkus.version
fix(deps): update quarkus.version to v3.22.3 (patch)
2025-05-15 23:11:52 +02:00
Jérémie Panzer
651ada7073 Merge pull request #1787 from Athou/renovate/npm-11.x
chore(deps): update dependency npm to v11.4.0
2025-05-15 23:11:36 +02:00
renovate[bot]
efb5d49d04 chore(deps): update dependency npm to v11.4.0 2025-05-15 20:08:41 +00:00
renovate[bot]
f78cc18b06 fix(deps): update quarkus.version to v3.22.3 2025-05-15 12:39:28 +00:00
renovate[bot]
8acffa11e5 fix(deps): update swagger.version to v2.2.32 2025-05-15 03:27:38 +00:00
renovate[bot]
f4246807ff chore(deps): update node.js to v22.15.1 2025-05-14 22:48:58 +00:00
renovate[bot]
abf6e7131b fix(deps): update dependency @reduxjs/toolkit to ^2.8.2 2025-05-14 19:06:20 +00:00
renovate[bot]
b2688520cc fix(deps): update mantine monorepo to ^8.0.1 2025-05-14 14:57:49 +00:00
Athou
fad0aea108 release 5.9.0 2025-05-14 16:56:01 +02:00
renovate[bot]
0b63773c83 fix(deps): update swagger.version to v2.2.31 2025-05-13 19:10:00 +00:00
renovate[bot]
3ef28009ac chore(deps): update dependency @types/react-dom to ^19.1.5 2025-05-13 14:35:24 +00:00
renovate[bot]
8979e2b191 chore(deps): update dependency @types/react to ^19.1.4 2025-05-12 23:34:04 +00:00
Eshwar Tangirala
d6910aa1e8 Cleaned up UI for Indicator 2025-05-12 16:30:06 -04:00
Eshwar Tangirala
afc56c6053 feat: red dot indicator for new unread articles 2025-05-12 16:22:40 -04:00
Eshwar Tangirala
1bd504cbfb feat: red dot indicator for new unread articles 2025-05-12 16:22:40 -04:00
renovate[bot]
2c089ddb5e chore(deps): update dependency @types/react-dom to ^19.1.4 2025-05-12 15:39:00 +00:00
Athou
0b5245643a increase cache duration of static resources even more (#1782) 2025-05-12 15:11:05 +02:00
Athou
ae35d43f7f revert back to deploy documentation on release only 2025-05-12 09:57:01 +02:00
Athou
fe55682c9f force update pages this time only 2025-05-12 09:56:22 +02:00
Jérémie Panzer
0d3e6f17e2 Merge pull request #1783 from Athou/renovate/pin-dependencies
chore(deps): pin jaywcjlove/markdown-to-html-cli action to d2c8ffd
2025-05-12 09:54:23 +02:00
renovate[bot]
d5659c4278 chore(deps): lock file maintenance 2025-05-12 06:49:59 +00:00
renovate[bot]
69b87b9026 chore(deps): pin jaywcjlove/markdown-to-html-cli action to d2c8ffd 2025-05-12 06:49:09 +00:00
Athou
168bcd3a37 add reference to the custom css documentation 2025-05-12 08:48:16 +02:00
Athou
e3b6be0cd0 add documentation for custom CSS (#1757) 2025-05-12 07:51:38 +02:00
Athou
eeceda0ca8 increase static resources cache duration (#1782) 2025-05-11 18:12:15 +02:00
renovate[bot]
aa903039c8 chore(deps): update ibm-semeru-runtimes docker tag to open-21.0.7_6-jre 2025-05-09 20:05:00 +00:00
Jérémie Panzer
73d81d0cdb Merge pull request #1778 from Athou/renovate/react-router-monorepo
fix(deps): update dependency react-router-dom to ^7.6.0
2025-05-08 20:11:28 +02:00
renovate[bot]
01fe539af6 fix(deps): update dependency react-router-dom to ^7.6.0 2025-05-08 17:13:56 +00:00
renovate[bot]
c08063ca57 fix(deps): update dependency @reduxjs/toolkit to ^2.8.1 2025-05-08 03:51:29 +00:00
renovate[bot]
60d4af2890 fix(deps): update quarkus.version to v3.22.2 2025-05-07 22:33:33 +00:00
renovate[bot]
6378f074a8 fix(deps): update dependency tss-react to ^4.9.18 2025-05-07 19:57:06 +00:00
Athou
5082ec86fd Merge branch 'custom-css' 2025-05-07 19:44:24 +02:00
Jérémie Panzer
6cff5bb099 Merge pull request #1777 from WangLei1993/master
add Chinese translation for new entry
2025-05-07 07:32:45 +02:00
WangLei1993
d54562d56f add Chinese translation for new entry 2025-05-07 12:06:56 +08:00
Jérémie Panzer
2b45a8fae5 Merge pull request #1776 from Athou/renovate/reduxjs-toolkit-2.x
fix(deps): update dependency @reduxjs/toolkit to ^2.8.0
2025-05-07 05:37:18 +02:00
renovate[bot]
8654df8994 fix(deps): update dependency @reduxjs/toolkit to ^2.8.0 2025-05-06 23:47:34 +00:00
renovate[bot]
4d5145c17e chore(deps): update dependency vite-plugin-checker to ^0.9.3 2025-05-06 18:09:24 +00:00
Athou
850921bca9 release 5.8.0 2025-05-06 20:07:54 +02:00
Athou
1dc6470419 move github sponsors up to match the order on the github page 2025-05-06 20:05:33 +02:00
Athou
b5c197f499 add more css classes based on feedback 2025-05-06 19:26:03 +02:00
Athou
d417655a86 add css classes to elements to ease css customization 2025-05-06 19:04:39 +02:00
renovate[bot]
ebca9f8290 fix(deps): update dependency tss-react to ^4.9.17 2025-05-06 07:51:25 +00:00
renovate[bot]
53b1f89b30 chore(deps): update dependency @types/react to ^19.1.3 2025-05-06 03:41:03 +00:00
renovate[bot]
6885191877 chore(deps): update ibm-semeru-runtimes:open-21.0.6_7-jre docker digest to bb59a7e 2025-05-05 22:59:50 +00:00
renovate[bot]
e69d9fe8b8 chore(deps): update dependency vitest to ^3.1.3 2025-05-05 17:13:14 +00:00
Jérémie Panzer
d6a1f1ae15 Merge pull request #1773 from canoine/patch-4
Update fr/messages.po
2025-05-05 19:12:16 +02:00
canoine
a7813f4442 Update fr/messages.po
Translation of the new message
2025-05-05 19:03:00 +02:00
Athou
1e4664987a add missing i18n label 2025-05-05 17:28:52 +02:00
Jérémie Panzer
7a819f5d58 Merge pull request #1772 from Athou/renovate/major-mantine-monorepo
fix(deps): update mantine monorepo to v8 (major)
2025-05-05 14:00:14 +02:00
Athou
45ef56e9da reduce vertical room occupied by slider 2025-05-05 13:59:23 +02:00
Athou
f43c7aa5d0 change default value of entriesToKeepOnTopWhenScrolling to match what other feed readers are doing 2025-05-05 13:51:32 +02:00
renovate[bot]
8d88711e59 fix(deps): update mantine monorepo to v8 2025-05-05 11:49:11 +00:00
renovate[bot]
280c0b60e9 chore(deps): update dependency vite to ^6.3.5 2025-05-05 10:01:35 +00:00
renovate[bot]
605f8f6615 chore(deps): lock file maintenance 2025-05-05 01:29:24 +00:00
renovate[bot]
0e88b4de1b chore(deps): update dependency vite-plugin-checker to ^0.9.2 2025-05-04 13:26:48 +00:00
Athou
b02aa923d7 customizable font size (#1462) 2025-05-04 13:26:33 +02:00
Athou
680c927e1d font size reduction was not actually working, and looks bad now that it does 2025-05-04 01:21:07 +02:00
Athou
4b2e65abdc use Box instead of Text because Text resets font size 2025-05-04 01:16:11 +02:00
Athou
e501bf6b05 fix initial value not loaded correctly for newly added settings 2025-05-03 21:50:53 +02:00
Jérémie Panzer
80bf2582bd Merge pull request #1771 from Athou/renovate/com.microsoft.playwright-playwright-1.x
chore(deps): update dependency com.microsoft.playwright:playwright to v1.52.0
2025-05-02 22:14:41 +02:00
renovate[bot]
586da4424d chore(deps): update dependency com.microsoft.playwright:playwright to v1.52.0 2025-05-02 18:59:58 +00:00
renovate[bot]
8e0e8c2407 fix(deps): update mantine monorepo to ^7.17.7 2025-05-02 10:10:57 +00:00
Athou
40461ac883 fix wrong category mapping 2025-05-01 13:01:28 +02:00
renovate[bot]
9288a7e66e chore(deps): update dependency vite to ^6.3.4 2025-04-30 19:48:04 +00:00
Jérémie Panzer
275db4ec72 Merge pull request #1770 from Athou/renovate/quarkus.version
fix(deps): update quarkus.version to v3.22.1 (minor)
2025-04-30 21:47:10 +02:00
renovate[bot]
67b2f8968d fix(deps): update quarkus.version to v3.22.1 2025-04-30 19:04:04 +00:00
renovate[bot]
45ce35dfdb chore(deps): update dependency @types/react-dom to ^19.1.3 2025-04-30 13:32:29 +00:00
renovate[bot]
52aa9ab2fe chore(deps): update debian:12.10 docker digest to 264982f 2025-04-29 11:18:53 +00:00
Jérémie Panzer
d24725bd55 Merge pull request #1769 from Athou/renovate/org.jsoup-jsoup-1.x
fix(deps): update dependency org.jsoup:jsoup to v1.20.1
2025-04-29 13:18:04 +02:00
renovate[bot]
f368a67dec fix(deps): update dependency org.jsoup:jsoup to v1.20.1 2025-04-29 08:40:01 +00:00
Jérémie Panzer
564d1744e1 Merge pull request #1768 from canoine/patch-2
Update fr/messages.po
2025-04-29 10:39:05 +02:00
canoine
d091ecfa5f Update fr/messages.po
Translation of new messages
2025-04-29 09:22:39 +02:00
Jérémie Panzer
7d23165e14 Merge pull request #1764 from WangLei1993/master
add Chinese translation for new entry
2025-04-29 06:33:39 +02:00
WangLei1993
a9ca3278c6 add Chinese translation for color 2025-04-29 11:55:32 +08:00
WangLei1993
e8734710ca Merge branch 'Athou:master' into master 2025-04-29 10:42:39 +08:00
renovate[bot]
f8a0e20df9 fix(deps): update dependency react-router-dom to ^7.5.3 2025-04-28 22:47:15 +00:00
Athou
de90e4de54 try to find a suitable language for the user before defaulting to english (#1767) 2025-04-28 22:59:41 +02:00
Athou
03cb27f69a add new translation placeholders 2025-04-28 22:49:57 +02:00
Athou
f86f1dd770 'All' and 'Starred' labels are now translatable (#1765) 2025-04-28 22:48:02 +02:00
Athou
ec21ffc571 color names are now translatable (#1766) 2025-04-28 22:39:15 +02:00
WangLei1993
c73c9c74ba Merge branch 'Athou:master' into master 2025-04-29 03:25:58 +08:00
WangLei1993
fd3c264d0c add Chinese translation for new entry 2025-04-29 03:25:16 +08:00
renovate[bot]
3983ba6cd0 chore(deps): lock file maintenance 2025-04-28 08:49:58 +00:00
renovate[bot]
dc0b5bdd11 chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.23.1 2025-04-28 03:08:48 +00:00
renovate[bot]
5b3728186e fix(deps): update dependency react-router-dom to ^7.5.2 2025-04-25 06:22:05 +00:00
renovate[bot]
8b0936b678 fix(deps): update dependency org.apache.httpcomponents.client5:httpclient5 to v5.4.4 2025-04-25 05:11:21 +00:00
Jérémie Panzer
b99e81a389 Merge pull request #1763 from Athou/renovate/axios-1.x
fix(deps): update dependency axios to ^1.9.0
2025-04-25 07:10:40 +02:00
renovate[bot]
0b8fb0f9a7 fix(deps): update dependency axios to ^1.9.0 2025-04-24 23:53:43 +00:00
renovate[bot]
7d5bbe0130 chore(deps): update docker/build-push-action digest to 14487ce 2025-04-24 23:53:15 +00:00
renovate[bot]
c6637c6814 chore(deps): update actions/download-artifact digest to d3f86a1 2025-04-24 20:09:51 +00:00
renovate[bot]
e302a011bb fix(deps): update mantine monorepo to ^7.17.5 2025-04-24 12:41:34 +00:00
renovate[bot]
25f8bdaa28 chore(deps): update dependency vite to ^6.3.3 2025-04-24 09:42:45 +00:00
renovate[bot]
e7d1018cbc chore(deps): update dependency io.quarkus.platform:quarkus-maven-plugin to v3.21.4 2025-04-23 22:14:40 +00:00
Jérémie Panzer
e81fa69a03 Merge pull request #1761 from Athou/renovate/node-22.x
chore(deps): update node.js to v22.15.0
2025-04-23 15:22:37 +02:00
renovate[bot]
176e76ad2d chore(deps): update node.js to v22.15.0 2025-04-23 12:58:46 +00:00
Jérémie Panzer
0925a91089 Merge pull request #1759 from Athou/renovate/org.apache.commons-commons-collections4-4.x
fix(deps): update dependency org.apache.commons:commons-collections4 to v4.5.0
2025-04-23 07:24:00 +02:00
renovate[bot]
c04d0b147c fix(deps): update dependency org.apache.commons:commons-collections4 to v4.5.0 2025-04-22 20:08:59 +00:00
renovate[bot]
a349eff1a3 chore(deps): update dependency vitest to ^3.1.2 2025-04-21 10:23:42 +00:00
renovate[bot]
2ddeda9a27 chore(deps): lock file maintenance 2025-04-21 02:01:50 +00:00
renovate[bot]
00b0fe921f chore(deps): update dependency @vitejs/plugin-react to ^4.4.1 2025-04-19 15:03:29 +00:00
renovate[bot]
bcc6cdf4b1 chore(deps): update dependency vite to ^6.3.2 2025-04-18 07:33:49 +00:00
renovate[bot]
ba46cc3cd6 fix(deps): update dependency react-router-dom to ^7.5.1 2025-04-17 15:41:39 +00:00
renovate[bot]
ed1bf609b8 chore(deps): update dependency vite to ^6.3.1 2025-04-17 02:11:49 +00:00
Jérémie Panzer
13262b678d Merge pull request #1756 from Athou/renovate/reduxjs-toolkit-2.x
fix(deps): update dependency @reduxjs/toolkit to ^2.7.0
2025-04-16 21:53:25 +02:00
renovate[bot]
cf9321de23 fix(deps): update dependency @reduxjs/toolkit to ^2.7.0 2025-04-16 18:48:12 +00:00
renovate[bot]
ac7a78bdc0 fix(deps): update quarkus.version to v3.21.3 2025-04-16 15:27:22 +00:00
Jérémie Panzer
640d3f1f6e Merge pull request #1754 from Athou/renovate/vite-6.x
chore(deps): update dependency vite to ^6.3.0
2025-04-16 11:45:25 +02:00
renovate[bot]
d716a8081c chore(deps): update dependency vite to ^6.3.0 2025-04-16 09:03:14 +00:00
Athou
1cec4e68b1 remove unused variables 2025-04-16 01:16:34 +02:00
Jérémie Panzer
9d16299c5b Merge pull request #1753 from Athou/renovate/vitejs-plugin-react-4.x
chore(deps): update dependency @vitejs/plugin-react to ^4.4.0
2025-04-15 14:22:10 +02:00
renovate[bot]
cb92b1969c chore(deps): update dependency @vitejs/plugin-react to ^4.4.0 2025-04-15 10:50:23 +00:00
renovate[bot]
55a62d393d chore(deps): update dependency @types/react to ^19.1.2 2025-04-14 23:14:48 +00:00
renovate[bot]
027b2252db fix(deps): update linguijs monorepo to ^5.3.1 2025-04-14 17:27:06 +00:00
Jérémie Panzer
ccfb88ddcc Merge pull request #1752 from Athou/renovate/redoc-2.x
fix(deps): update dependency redoc to ^2.5.0
2025-04-14 19:26:10 +02:00
renovate[bot]
dde0736fcf fix(deps): update dependency redoc to ^2.5.0 2025-04-14 16:24:14 +00:00
renovate[bot]
6498bb5ee6 chore(deps): lock file maintenance 2025-04-14 01:54:18 +00:00
Jérémie Panzer
d7ca2db330 Merge pull request #1751 from Athou/renovate/jsdom-26.x
chore(deps): update dependency jsdom to ^26.1.0
2025-04-13 18:11:54 +02:00
renovate[bot]
99b32795a5 chore(deps): update dependency jsdom to ^26.1.0 2025-04-13 14:35:09 +00:00
renovate[bot]
840f670d5d chore(deps): update dependency @types/react to ^19.1.1 2025-04-11 15:51:04 +00:00
renovate[bot]
e3c0a4c665 chore(deps): update dependency vite to ^6.2.6 2025-04-10 13:00:03 +00:00
Athou
915506527a add theme color picker (#1598) 2025-04-10 14:17:44 +02:00
renovate[bot]
7541251344 fix(deps): update quarkus.version to v3.21.2 2025-04-09 22:01:45 +00:00
Athou
40c9b42b24 mark all as read confirmation now also applies to the "shift+a" keyboard shortcut (#1744) 2025-04-09 20:28:40 +02:00
Athou
dfab678070 remove unused imports 2025-04-09 20:28:40 +02:00
renovate[bot]
3d371d5942 chore(deps): update dependency @types/react-dom to ^19.1.2 2025-04-09 17:25:25 +00:00
renovate[bot]
9bfbaa8ded chore(deps): update ibm-semeru-runtimes:open-21.0.6_7-jre docker digest to 475c325 2025-04-09 16:47:23 +00:00
Athou
be0fc95c45 dialog can now by confirmed with the enter key 2025-04-09 14:40:53 +02:00
Athou
dcb6113eb7 set focus to slider when the dialog opens to ease keyboard navigation 2025-04-09 14:40:53 +02:00
renovate[bot]
55491651f6 chore(deps): update ibm-semeru-runtimes:open-21.0.6_7-jre docker digest to 1515f0d 2025-04-09 07:58:05 +00:00
Jérémie Panzer
c1d471ebdc Merge pull request #1750 from Athou/renovate/npm-11.x
chore(deps): update dependency npm to v11.3.0
2025-04-09 07:19:10 +02:00
renovate[bot]
069e675f19 chore(deps): update dependency npm to v11.3.0 2025-04-08 22:06:01 +00:00
renovate[bot]
d34f719a4f fix(deps): update mantine monorepo to ^7.17.4 2025-04-08 16:57:23 +00:00
renovate[bot]
4eb932a3f0 chore(deps): update debian:12.10 docker digest to 00cd074 2025-04-08 06:24:19 +00:00
renovate[bot]
1ab27f2626 chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v2.44.4 2025-04-08 03:28:41 +00:00
renovate[bot]
7d3ce7e602 fix(deps): update swagger.version to v2.2.30 2025-04-07 16:46:41 +00:00
renovate[bot]
cf530b2c60 chore(deps): lock file maintenance 2025-04-07 01:34:57 +00:00
Athou
d9bcd7f592 remove warning about Non-Serializable Data passed to redux action 2025-04-05 17:19:04 +02:00
Athou
8b854b5cda remove intermediate element by rendering the mantine Paper as <article> 2025-04-05 17:19:04 +02:00
renovate[bot]
f7b6677bb1 chore(deps): update dependency typescript to ^5.8.3 2025-04-05 04:17:26 +00:00
Jérémie Panzer
0cc5e8f5b8 Merge pull request #1748 from Athou/renovate/react-router-monorepo
fix(deps): update dependency react-router-dom to ^7.5.0
2025-04-05 06:16:57 +02:00
Jérémie Panzer
8d153e3b2b Merge pull request #1749 from Athou/renovate/querydsl.version
fix(deps): update querydsl.version to v6.11 (minor)
2025-04-05 06:16:45 +02:00
renovate[bot]
d15428971c fix(deps): update querydsl.version to v6.11 2025-04-05 02:02:22 +00:00
renovate[bot]
f34c2aa437 fix(deps): update dependency react-router-dom to ^7.5.0 2025-04-04 23:12:23 +00:00
Athou
9b3ff5f81f fix wrong issue numbers in changelog 2025-04-04 22:15:37 +02:00
Athou
e1f6937802 release 5.7.0 2025-04-04 19:39:29 +02:00
Athou
0c0834b30f fix bookmarklet, React 19 no longer allows 'javascript:' urls 2025-04-04 14:25:21 +02:00
Jérémie Panzer
5ad4b97205 Merge pull request #1747 from flisk/patch-1
don't throw NotModifiedException on etag/lm changes
2025-04-04 11:18:57 +02:00
flisk
c4ec249bc4 don't throw NotModifiedException on etag/lm changes
A well-behaved server should return 304 if our If-Modified-Since and If-None-Match indicate that we don't have the latest version of a resource cached. Having these extra conditions where we consider our local version fresh is not necessary, and may in fact lead to resource updates being missed when only one header changes.

We should instead trust the server to know whether it needs to send us a new resource or not based on the cache headers we provide.
2025-04-04 11:00:47 +02:00
renovate[bot]
cf8d3965d5 chore(deps): update dependency vite to ^6.2.5 2025-04-03 14:51:19 +00:00
renovate[bot]
3903fd9374 chore(deps): update peter-evans/dockerhub-description digest to 432a30c 2025-04-03 09:42:24 +00:00
Jérémie Panzer
77d59dabe8 Merge pull request #1742 from Athou/renovate/testing-library-monorepo
chore(deps): update dependency @testing-library/react to ^16.3.0
2025-04-03 00:37:51 +02:00
Jérémie Panzer
56ca737297 Merge pull request #1743 from Athou/renovate/com.puppycrawl.tools-checkstyle-10.x
chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.23.0
2025-04-03 00:37:34 +02:00
renovate[bot]
9edb539be3 chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.23.0 2025-04-02 19:13:17 +00:00
renovate[bot]
31a773d200 chore(deps): update dependency @testing-library/react to ^16.3.0 2025-04-02 19:13:13 +00:00
renovate[bot]
61355eabf7 chore(deps): update dependency io.quarkus.platform:quarkus-maven-plugin to v3.21.1 2025-04-02 19:12:53 +00:00
Jérémie Panzer
569874e51f Merge pull request #1741 from Athou/renovate/react-monorepo
chore(deps): update react monorepo (minor)
2025-04-02 21:53:31 +09:00
renovate[bot]
00d47901fc chore(deps): update react monorepo 2025-04-02 10:49:12 +00:00
renovate[bot]
d8b4ef55ce chore(deps): lock file maintenance 2025-03-31 22:26:46 +00:00
renovate[bot]
da41a4cab9 fix(deps): update dependency org.projectlombok:lombok to v1.18.38 2025-03-31 19:13:21 +00:00
Jérémie Panzer
8a90ef0471 Merge pull request #1740 from Athou/renovate/vitest-monorepo
chore(deps): update dependency vitest to ^3.1.1
2025-04-01 04:12:48 +09:00
renovate[bot]
b4ab32a578 chore(deps): update dependency vite to ^6.2.4 2025-03-31 16:02:10 +00:00
renovate[bot]
03aa53abc8 chore(deps): update dependency vitest to ^3.1.1 2025-03-31 11:06:04 +00:00
renovate[bot]
2ae5c0cd8e chore(deps): update peter-evans/dockerhub-description digest to 0505d8b 2025-03-31 11:05:32 +00:00
renovate[bot]
cacc632443 chore(deps): update dependency org.apache.maven.plugins:maven-surefire-plugin to v3.5.3 2025-03-31 07:27:09 +00:00
renovate[bot]
28f865ccfa chore(deps): update dependency org.apache.maven.plugins:maven-failsafe-plugin to v3.5.3 2025-03-31 03:07:34 +00:00
Jérémie Panzer
a4c949e8b3 Merge pull request #1739 from Athou/renovate/com.puppycrawl.tools-checkstyle-10.x
chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.22.0
2025-03-31 04:49:23 +09:00
renovate[bot]
6098994397 chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.22.0 2025-03-30 17:50:39 +00:00
renovate[bot]
5763ca30d6 fix(deps): update dependency react-router-dom to ^7.4.1 2025-03-29 00:17:28 +00:00
Jérémie Panzer
7d039d1001 Merge pull request #1738 from Athou/renovate/react-monorepo
fix(deps): update react monorepo to ^19.1.0 (minor)
2025-03-29 09:16:31 +09:00
renovate[bot]
7fe74af906 fix(deps): update react monorepo to ^19.1.0 2025-03-28 23:25:45 +00:00
renovate[bot]
80b72aa30b fix(deps): update dependency tss-react to ^4.9.16 2025-03-28 10:05:38 +00:00
renovate[bot]
3ba0d241f9 fix(deps): update mantine monorepo to ^7.17.3 2025-03-27 12:04:33 +00:00
renovate[bot]
67428aa0c7 fix(deps): update dependency org.apache.httpcomponents.client5:httpclient5 to v5.4.3 2025-03-26 23:20:17 +00:00
Jérémie Panzer
b9a0256031 Merge pull request #1737 from Athou/renovate/quarkus.version
fix(deps): update quarkus.version to v3.21.0 (minor)
2025-03-27 08:19:41 +09:00
renovate[bot]
f3c2296636 fix(deps): update quarkus.version to v3.21.0 2025-03-26 12:33:20 +00:00
renovate[bot]
b6e8f21975 chore(deps): update ibm-semeru-runtimes:open-21.0.6_7-jre docker digest to fc0d0c8 2025-03-25 01:44:57 +00:00
renovate[bot]
284f80045f chore(deps): update dependency vite to ^6.2.3 2025-03-24 12:07:42 +00:00
renovate[bot]
f589477aa8 chore(deps): lock file maintenance 2025-03-24 02:45:32 +00:00
Jérémie Panzer
29cb296d09 Merge pull request #1733 from Athou/renovate/linguijs-monorepo
fix(deps): update linguijs monorepo to ^5.3.0 (minor)
2025-03-21 21:07:34 +09:00
renovate[bot]
86caa1450a fix(deps): update linguijs monorepo to ^5.3.0 2025-03-21 11:26:04 +00:00
Jérémie Panzer
9dd4b9e67f Merge pull request #1732 from Athou/renovate/patch-react-monorepo
chore(deps): update dependency @types/react to ^19.0.12
2025-03-21 07:09:17 +09:00
renovate[bot]
e2e654f05b chore(deps): update dependency @types/react to ^19.0.12 2025-03-20 16:27:41 +00:00
renovate[bot]
72dbc62b41 fix(deps): update quarkus.version to v3.19.4 2025-03-20 10:58:22 +00:00
renovate[bot]
0a21014668 fix(deps): update dependency axios to ^1.8.4 2025-03-20 06:35:53 +00:00
renovate[bot]
b6d9d2a26c chore(deps): update actions/upload-artifact digest to ea165f8 2025-03-20 01:47:55 +00:00
renovate[bot]
25c3a7748c chore(deps): update actions/download-artifact digest to 95815c3 2025-03-19 20:49:20 +00:00
Jérémie Panzer
b2bcfdd6eb Merge pull request #1731 from Athou/renovate/react-router-monorepo
fix(deps): update dependency react-router-dom to ^7.4.0
2025-03-19 21:48:46 +01:00
renovate[bot]
2a978db406 fix(deps): update dependency react-router-dom to ^7.4.0 2025-03-19 17:04:09 +00:00
renovate[bot]
9e40d0d066 chore(deps): update actions/download-artifact digest to cc20338 2025-03-19 02:40:14 +00:00
renovate[bot]
c912650d59 chore(deps): update actions/download-artifact digest to b14cf4c 2025-03-18 19:01:24 +00:00
renovate[bot]
464ebcb471 chore(deps): lock file maintenance 2025-03-18 12:30:06 +00:00
renovate[bot]
463e0e59d7 chore(deps): update debian:12.10 docker digest to 18023f1 2025-03-18 07:34:16 +00:00
Jérémie Panzer
b4e5d8ef20 Merge pull request #1729 from Athou/renovate/patch-react-monorepo
chore(deps): update dependency @types/react to ^19.0.11
2025-03-18 08:33:48 +01:00
renovate[bot]
126905aeb3 chore(deps): update dependency @types/react to ^19.0.11 2025-03-18 04:22:16 +00:00
Jérémie Panzer
1af10d3364 Merge pull request #1727 from Athou/renovate/lock-file-maintenance
chore(deps): lock file maintenance
2025-03-18 05:20:59 +01:00
Jérémie Panzer
6ad854c019 Merge pull request #1728 from Athou/renovate/com.microsoft.playwright-playwright-1.x
chore(deps): update dependency com.microsoft.playwright:playwright to v1.51.0
2025-03-18 05:20:37 +01:00
Jérémie Panzer
b30117aa4d Merge pull request #1730 from Athou/renovate/debian-12.x
chore(deps): update debian docker tag to v12.10
2025-03-18 05:19:56 +01:00
renovate[bot]
5a66482d1e chore(deps): lock file maintenance 2025-03-18 02:30:37 +00:00
renovate[bot]
2628ec49bb chore(deps): update debian docker tag to v12.10 2025-03-18 02:29:44 +00:00
renovate[bot]
f3d15cf173 chore(deps): update dependency com.microsoft.playwright:playwright to v1.51.0 2025-03-17 23:39:46 +00:00
renovate[bot]
bbcf55ce57 chore(deps): update dependency vitest to ^3.0.9 2025-03-17 23:39:43 +00:00
renovate[bot]
72fc3716e7 chore(deps): update dependency vite-plugin-checker to ^0.9.1 2025-03-17 17:30:58 +00:00
Jérémie Panzer
81a6cfaa88 Merge pull request #1725 from Athou/renovate/com.ibm.icu-icu4j-77.x
fix(deps): update dependency com.ibm.icu:icu4j to v77
2025-03-15 01:14:58 +01:00
renovate[bot]
aed5165ef3 chore(deps): update dependency vite to ^6.2.2 (#1726)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-14 23:14:20 +00:00
renovate[bot]
eaf2933726 fix(deps): update mantine monorepo to ^7.17.2 2025-03-14 15:16:11 +00:00
renovate[bot]
39da4d9d36 chore(deps): update docker/login-action digest to 74a5d14 2025-03-14 11:05:08 +00:00
renovate[bot]
e5ebd7ff39 fix(deps): update dependency com.ibm.icu:icu4j to v77 2025-03-14 04:29:10 +00:00
renovate[bot]
b6ae3e4e1e fix(deps): update dependency io.quarkus.platform:quarkus-bom to v3.19.3 2025-03-12 16:05:37 +00:00
renovate[bot]
32d1488352 fix(deps): update dependency axios to ^1.8.3 2025-03-12 10:40:24 +00:00
Athou
b08d0a388f no need to re-render the custom js handler on route change 2025-03-12 10:36:17 +01:00
Athou
7fe004a696 load js when the app is done loading (#1724) 2025-03-12 07:33:44 +01:00
Athou
f620d033b0 DisablePullToRefresh doesn't need to be in HashRouter 2025-03-12 07:21:31 +01:00
Athou
ba071ba71f add the referrer meta (#1724) 2025-03-12 06:37:12 +01:00
Athou
6f3197302d make biome format root files too (package.json, vite config, ...) 2025-03-11 15:50:04 +01:00
Athou
131a8ebf68 remove warning about vite not finding custom code at build time 2025-03-11 15:48:52 +01:00
Athou
8b24c125c2 also skip js tests when skipping tests 2025-03-11 15:36:32 +01:00
Jérémie Panzer
52293376ec Merge pull request #1723 from Athou/renovate/patch-swagger.version
fix(deps): update swagger.version to v2.2.29 (patch)
2025-03-11 07:23:52 +01:00
renovate[bot]
f8ac59af6a fix(deps): update swagger.version to v2.2.29 2025-03-10 23:04:46 +00:00
Athou
5c791e2305 revert corrupted png files 2025-03-10 11:03:43 +01:00
Athou
6641bc0631 don't expose exception message 2025-03-10 10:54:40 +01:00
Jérémie Panzer
da690aa750 Merge pull request #1722 from Athou/line-endings
normalize line endings
2025-03-10 10:50:11 +01:00
Athou
fb7f041454 normalize line endings 2025-03-10 08:48:26 +01:00
renovate[bot]
ec4554c76e chore(deps): lock file maintenance 2025-03-10 03:01:10 +00:00
Athou
068e85fe6e add tests for selectNextUnreadTreeItem 2025-03-08 08:32:46 +01:00
renovate[bot]
ba926c674e fix(deps): update dependency @reduxjs/toolkit to ^2.6.1 2025-03-07 22:23:31 +00:00
renovate[bot]
836f8f14c0 fix(deps): update dependency axios to ^1.8.2 2025-03-07 10:56:42 +00:00
renovate[bot]
eeecac96e1 chore(deps): update dependency vite to ^6.2.1 2025-03-07 05:02:32 +00:00
Jérémie Panzer
ecc62f222a Merge pull request #1721 from Athou/renovate/react-router-monorepo
fix(deps): update dependency react-router-dom to ^7.3.0
2025-03-07 06:01:39 +01:00
renovate[bot]
9022f93811 fix(deps): update dependency react-router-dom to ^7.3.0 2025-03-06 22:53:13 +00:00
renovate[bot]
e7225d35b2 chore(deps): update dependency vitest to ^3.0.8 2025-03-06 20:01:28 +00:00
Athou
454fc03038 automerge digest changes 2025-03-06 21:00:28 +01:00
Jérémie Panzer
9c0674fd83 Merge pull request #1720 from Athou/renovate/migrate-config
chore(config): migrate renovate config
2025-03-06 20:57:05 +01:00
Jérémie Panzer
7a20482ddf Merge pull request #1719 from Athou/renovate/pin-dependencies
chore(deps): pin dependencies
2025-03-06 20:55:28 +01:00
renovate[bot]
32ad47ba16 chore(config): migrate config renovate.json 2025-03-06 16:52:01 +00:00
renovate[bot]
fc562cce0f chore(deps): pin dependencies 2025-03-06 16:51:34 +00:00
Athou
b029b251db use renovate best practices 2025-03-06 17:50:54 +01:00
Jérémie Panzer
e3e28e727f Merge pull request #1718 from Athou/renovate/io.github.hakky54-sslcontext-kickstart-for-apache5-9.x
fix(deps): update dependency io.github.hakky54:sslcontext-kickstart-for-apache5 to v9.1.0
2025-03-06 07:08:24 +01:00
Jérémie Panzer
50cb728db7 Merge pull request #1717 from Athou/renovate/npm-11.x
chore(deps): update dependency npm to v11.2.0
2025-03-06 07:08:12 +01:00
renovate[bot]
c654ba4d1b fix(deps): update dependency io.github.hakky54:sslcontext-kickstart-for-apache5 to v9.1.0 2025-03-05 21:32:08 +00:00
renovate[bot]
846e29b15e chore(deps): update dependency npm to v11.2.0 2025-03-05 21:32:05 +00:00
renovate[bot]
f2b4062d73 fix(deps): update quarkus.version to v3.19.2 2025-03-05 19:37:47 +00:00
Athou
9051e6a6db add test to make sure documentation is available 2025-03-05 17:22:53 +01:00
Athou
b733129043 remove the need for selectPreviousUnreadTreeItem by reversing the array if we're going backwards 2025-03-05 07:33:36 +01:00
Athou
d46b571444 select next/previous unread feed/category when marking all as read (#1558) 2025-03-04 21:18:45 +01:00
renovate[bot]
7d744b4ce0 chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.21.4 2025-03-04 13:07:31 +00:00
Jérémie Panzer
801dda912c Merge pull request #1714 from Athou/renovate/org.jsoup-jsoup-1.x
fix(deps): update dependency org.jsoup:jsoup to v1.19.1
2025-03-04 14:06:58 +01:00
renovate[bot]
a20005409a fix(deps): update dependency org.jsoup:jsoup to v1.19.1 2025-03-04 06:23:04 +00:00
renovate[bot]
6f1411d075 fix(deps): update mantine monorepo to ^7.17.1 (#1712)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-03-04 06:22:47 +00:00
Athou
1aa263a6c0 simplify UnitOfWork code 2025-03-03 22:29:21 +01:00
Jérémie Panzer
9d511ac7dd Merge pull request #1710 from Athou/renovate/graalvm-setup-graalvm-digest
chore(deps): update graalvm/setup-graalvm digest to 01ed653
2025-03-03 21:24:20 +01:00
Athou
122e98cc76 revert to mantine 7.17.0 (#1711) 2025-03-03 21:21:44 +01:00
Athou
e445e5ea39 clarify in the README that if -Pnative is used, database should be specified (#1708) 2025-03-03 16:23:29 +01:00
renovate[bot]
5b9212015b chore(deps): update graalvm/setup-graalvm digest to 01ed653 2025-03-03 15:18:50 +00:00
Jérémie Panzer
293292f341 Merge pull request #1709 from Athou/renovate/graalvm-setup-graalvm-digest
chore(deps): update graalvm/setup-graalvm digest to 271a696
2025-03-03 16:18:21 +01:00
renovate[bot]
57d8a4dbb1 chore(deps): update graalvm/setup-graalvm digest to 271a696 2025-03-03 11:35:48 +00:00
renovate[bot]
e104f531f9 chore(deps): lock file maintenance 2025-03-03 02:42:48 +00:00
Athou
bf1361926f don't host by default 2025-03-02 19:21:07 +01:00
Athou
cc4f4d9eb4 remove dev:typescript, we don't need it anymore with the vite checker plugin 2025-03-02 19:20:24 +01:00
Athou
706bad26f1 use typesafe mocks 2025-03-02 19:18:51 +01:00
Athou
4ecefe6491 reduce tooltip delay for all tests 2025-03-02 19:18:27 +01:00
Athou
937e7353ce build regexp only once 2025-03-02 15:49:02 +01:00
Athou
1dcf76fc0a remove warning about missing index during tests 2025-03-02 15:49:02 +01:00
renovate[bot]
9d794dcad7 fix(deps): update dependency @fontsource/open-sans to ^5.2.5 2025-03-02 15:49:02 +01:00
Athou
d11b666755 remove vitest-mock-extended as vitest now exposes a vi.mocked() function 2025-03-02 15:49:02 +01:00
Athou
7a444e4861 add tests for ActionButton 2025-03-02 15:49:02 +01:00
Athou
5992795579 fix tooltips not showing up in mobile view 2025-03-02 15:49:02 +01:00
Athou
4441d76a7f Merge remote-tracking branch 'origin/renovate/patch-fontsource-monorepo' 2025-03-02 11:39:21 +01:00
Athou
c1305b56e3 insert jakarta imports where javax import were positioned 2025-03-02 11:37:06 +01:00
Athou
cc0440c029 enable quarkus compression (compression in dropwizard was enabled by default) 2025-03-02 09:45:10 +01:00
renovate[bot]
f65591c170 fix(deps): update dependency @fontsource/open-sans to ^5.2.1 2025-03-02 06:57:09 +00:00
Jérémie Panzer
9a32dce9d1 Merge pull request #1707 from Athou/renovate/fontsource-monorepo
fix(deps): update dependency @fontsource/open-sans to ^5.2.0
2025-03-01 19:59:07 +01:00
renovate[bot]
789bd3edae fix(deps): update dependency @fontsource/open-sans to ^5.2.0 2025-03-01 18:15:36 +00:00
renovate[bot]
256cd426d9 fix(deps): update mantine monorepo to ^7.17.1 2025-03-01 10:40:20 +00:00
Jérémie Panzer
58af2da105 Merge pull request #1706 from Athou/renovate/typescript-5.x
chore(deps): update dependency typescript to ^5.8.2
2025-02-28 21:02:58 +01:00
renovate[bot]
e0de397273 chore(deps): update dependency typescript to ^5.8.2 2025-02-28 19:33:23 +00:00
Jérémie Panzer
75cc3cf29c Merge pull request #1705 from Athou/renovate/docker-setup-qemu-action-digest
chore(deps): update docker/setup-qemu-action digest to 2910929
2025-02-28 17:11:02 +01:00
renovate[bot]
af60758e2a chore(deps): update docker/setup-qemu-action digest to 2910929 2025-02-28 14:32:17 +00:00
Jérémie Panzer
01180e95a2 Merge pull request #1704 from Athou/renovate/docker-setup-qemu-action-digest
chore(deps): update docker/setup-qemu-action digest to 5964de0
2025-02-26 21:15:41 +01:00
renovate[bot]
fa683ef7e1 chore(deps): update docker/setup-qemu-action digest to 5964de0 2025-02-26 19:20:27 +00:00
Jérémie Panzer
462d17a429 Merge pull request #1703 from Athou/renovate/docker-setup-buildx-action-digest
chore(deps): update docker/setup-buildx-action digest to b5ca514
2025-02-26 20:20:04 +01:00
Jérémie Panzer
17f71a40d4 Merge pull request #1702 from Athou/renovate/docker-build-push-action-digest
chore(deps): update docker/build-push-action digest to 471d1dc
2025-02-26 20:19:54 +01:00
renovate[bot]
de91a3a05a chore(deps): update docker/setup-buildx-action digest to b5ca514 2025-02-26 16:46:20 +00:00
renovate[bot]
ead587ee88 chore(deps): update docker/build-push-action digest to 471d1dc 2025-02-26 16:46:16 +00:00
Jérémie Panzer
62b3e6fb3a Merge pull request #1700 from Athou/renovate/actions-download-artifact-digest
chore(deps): update actions/download-artifact digest to cc20338
2025-02-26 17:46:01 +01:00
Jérémie Panzer
037ff15045 Merge pull request #1701 from Athou/renovate/quarkus.version
fix(deps): update quarkus.version to v3.19.1 (minor)
2025-02-26 17:45:45 +01:00
renovate[bot]
ed35b06934 fix(deps): update quarkus.version to v3.19.1 2025-02-26 15:39:08 +00:00
renovate[bot]
3cfb1a13a7 chore(deps): update actions/download-artifact digest to cc20338 2025-02-26 15:38:48 +00:00
renovate[bot]
d04745d859 fix(deps): update dependency axios to ^1.8.1 2025-02-26 10:29:47 +00:00
Jérémie Panzer
58b18f36c5 Merge pull request #1699 from Athou/renovate/axios-1.x
fix(deps): update dependency axios to ^1.8.0
2025-02-26 08:10:25 +01:00
renovate[bot]
7282d18d8f fix(deps): update dependency axios to ^1.8.0 2025-02-26 06:46:03 +00:00
Jérémie Panzer
8e58fa22b4 Merge pull request #1698 from Athou/renovate/vite-6.x
chore(deps): update dependency vite to ^6.2.0
2025-02-25 05:09:34 +01:00
renovate[bot]
58d6eb2c5a chore(deps): update dependency vite to ^6.2.0 2025-02-25 03:36:32 +00:00
renovate[bot]
2f7c7498e2 chore(deps): update dependency vitest to ^3.0.7 2025-02-24 18:16:11 +00:00
renovate[bot]
bcf8dcd551 chore(deps): lock file maintenance 2025-02-24 05:39:25 +00:00
Jérémie Panzer
511f0a60bb Merge pull request #1697 from Athou/renovate/reduxjs-toolkit-2.x
fix(deps): update dependency @reduxjs/toolkit to ^2.6.0
2025-02-24 06:37:30 +01:00
renovate[bot]
72db0d815f fix(deps): update dependency @reduxjs/toolkit to ^2.6.0 2025-02-24 01:36:04 +00:00
renovate[bot]
280d0b7fdd chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.21.3 2025-02-23 19:49:59 +00:00
Athou
42e4575cb7 release 5.6.1 2025-02-23 20:49:01 +01:00
Jérémie Panzer
28a4bb403a Merge pull request #1691 from dcelasun/arch-package
Mention Arch package
2025-02-23 20:47:57 +01:00
Athou
cca3c907db documentation is now hosted on github pages 2025-02-23 20:23:02 +01:00
Athou
1a5b932742 upload generated documentation to github pages 2025-02-23 20:05:04 +01:00
Jérémie Panzer
a1d3f3008a Merge pull request #1693 from Athou/renovate/ncipollo-release-action-digest
chore(deps): update ncipollo/release-action digest to 440c8c1
2025-02-23 08:22:14 +01:00
Jérémie Panzer
902f2efbd2 Merge pull request #1694 from Athou/renovate/vitest-mock-extended-3.x
chore(deps): update dependency vitest-mock-extended to v3
2025-02-23 08:21:47 +01:00
renovate[bot]
2e534af146 chore(deps): update dependency vitest-mock-extended to v3 2025-02-22 17:50:06 +00:00
renovate[bot]
23ca30c3c2 chore(deps): update ncipollo/release-action digest to 440c8c1 2025-02-22 17:49:45 +00:00
Athou
517eedad00 Merge branch 'generated-properties' 2025-02-22 11:12:16 +01:00
Jérémie Panzer
216ea1fb42 Merge pull request #1692 from Athou/renovate/actions-upload-artifact-digest
chore(deps): update actions/upload-artifact digest to 4cec3d8
2025-02-22 11:11:34 +01:00
Athou
640d1a0ce3 add a tool to generate a properties file from configuration (#1691) 2025-02-22 08:03:01 +01:00
renovate[bot]
bba7425b5f chore(deps): update actions/upload-artifact digest to 4cec3d8 2025-02-21 22:15:42 +00:00
D. Can Celasun
7a1a49bfb4 Mention Arch package 2025-02-21 13:02:59 +00:00
Jérémie Panzer
e451e6698c Merge pull request #1690 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.14.0
2025-02-21 13:52:18 +01:00
renovate[bot]
9af3f21404 chore(deps): update dependency org.apache.maven.plugins:maven-compiler-plugin to v3.14.0 2025-02-21 09:32:56 +00:00
renovate[bot]
7b14a9c0c2 chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v2.44.3 2025-02-21 02:12:51 +00:00
Jérémie Panzer
0b65cc9510 Merge pull request #1689 from Athou/renovate/vite-plugin-checker-0.x
chore(deps): update dependency vite-plugin-checker to ^0.9.0
2025-02-20 18:29:10 +01:00
renovate[bot]
7879ab9b61 chore(deps): update dependency vite-plugin-checker to ^0.9.0 2025-02-20 15:11:34 +00:00
Athou
e6bebcafb3 allow iframes in feed entries (#1688) 2025-02-20 10:07:45 +01:00
renovate[bot]
3b465cebb7 fix(deps): update quarkus.version to v3.18.4 2025-02-19 20:28:09 +00:00
renovate[bot]
aeb211be06 chore(deps): update dependency vite to ^6.1.1 2025-02-19 18:26:04 +00:00
Jérémie Panzer
ad992aea7b Merge pull request #1687 from Athou/renovate/docker-build-push-action-digest
chore(deps): update docker/build-push-action digest to 0adf995
2025-02-19 19:25:11 +01:00
renovate[bot]
d848f72a0b chore(deps): update docker/build-push-action digest to 0adf995 2025-02-19 17:00:18 +00:00
Athou
0db087908d remove "jakarta.ws.rs.WebApplicationException" from the errors displayed in the client 2025-02-19 13:08:43 +01:00
Jérémie Panzer
42138d04d6 Merge pull request #1685 from Athou/renovate/react-router-monorepo
fix(deps): update dependency react-router-dom to ^7.2.0
2025-02-19 10:16:26 +01:00
renovate[bot]
4522a9d0d5 fix(deps): update dependency react-router-dom to ^7.2.0 2025-02-19 06:32:35 +00:00
Jérémie Panzer
7440fcad0e Merge pull request #1686 from Athou/renovate/react-icons-5.x
fix(deps): update dependency react-icons to ^5.5.0
2025-02-19 07:31:05 +01:00
renovate[bot]
fc51c1882f fix(deps): update dependency react-icons to ^5.5.0 2025-02-19 05:47:14 +00:00
renovate[bot]
e24498b31f chore(deps): update dependency vitest to ^3.0.6 2025-02-18 14:27:16 +00:00
Athou
60fdc79563 don't expose rome's FeedException 2025-02-18 08:57:24 +01:00
Athou
6729ebc6ea throw a specific exception if we can't parse the url's content (#1684) 2025-02-18 07:41:02 +01:00
Athou
c8ff216ce5 README update 2025-02-17 21:23:38 +01:00
Jérémie Panzer
98c4150cfe Merge pull request #1683 from Athou/renovate/mantine-monorepo
fix(deps): update mantine monorepo to ^7.17.0 (minor)
2025-02-17 21:11:53 +01:00
renovate[bot]
128332d710 fix(deps): update mantine monorepo to ^7.17.0 2025-02-17 19:31:07 +00:00
renovate[bot]
eabcb519a4 chore(deps): update react monorepo 2025-02-17 11:01:27 +00:00
renovate[bot]
5e14cead3d chore(deps): lock file maintenance 2025-02-17 01:44:54 +00:00
renovate[bot]
b601f938ff chore(deps): update ibm-semeru-runtimes docker tag to open-21.0.6_7-jre (#1682)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-02-16 21:26:14 +00:00
renovate[bot]
4acfda32d0 chore(deps): update dependency @types/react to ^19.0.9 2025-02-16 13:16:31 +00:00
Athou
54da4e6839 release 5.6.0 2025-02-16 14:14:30 +01:00
Athou
3a6b4c588c PRs and renovate now build the docker images regardless of the branch/tag 2025-02-15 10:20:39 +01:00
Athou
48071b9fd1 PRs now build the docker images but don't push them 2025-02-15 10:18:16 +01:00
Athou
f519aa039f block local addresses to prevent SSRF attacks 2025-02-14 16:20:04 +01:00
Athou
dc3e5476a1 reload the tree when we receive a websocket notification about an unknown feed 2025-02-14 16:16:07 +01:00
Athou
903035ecfc formatting 2025-02-14 16:16:07 +01:00
Athou
13ad57da10 make sure the tree has been reloaded before navigating to the new feed subscription 2025-02-14 16:16:06 +01:00
Athou
44bc24c22a ubuntu-22.04-arm is supposed to be more stable 2025-02-14 16:16:06 +01:00
Athou
97f90405fc try to fix flaky IT test 2025-02-14 16:16:06 +01:00
renovate[bot]
0fc2a0b022 fix(deps): update dependency @monaco-editor/react to ^4.7.0 2025-02-13 19:39:46 +00:00
Jérémie Panzer
89eb641704 Merge pull request #1679 from Athou/renovate/graalvm-setup-graalvm-digest
chore(deps): update graalvm/setup-graalvm digest to b0cb26a
2025-02-13 06:22:29 +01:00
renovate[bot]
c53da9f631 chore(deps): update graalvm/setup-graalvm digest to b0cb26a 2025-02-12 22:32:09 +00:00
renovate[bot]
998868e63a fix(deps): update quarkus.version to v3.18.3 2025-02-12 18:26:21 +00:00
Athou
93f22d2351 reduce max interval to 4h 2025-02-12 18:17:39 +01:00
Athou
c3782bd7d2 also constrain to lower bound 2025-02-12 18:04:56 +01:00
Athou
f330349397 update documentation 2025-02-12 17:31:46 +01:00
Athou
99c973c8c2 change the default value of empirical interval calculation (#1677) 2025-02-12 17:26:38 +01:00
Athou
469420b5bf feed refresh engine previously hardcoded values are now configurable (#1677) 2025-02-12 17:08:20 +01:00
Athou
bde556d41f start to back off when we repeatedly receive a 429 2025-02-12 08:00:27 +01:00
Jérémie Panzer
bf6c2d7beb Merge pull request #1678 from Athou/renovate/node-22.x
chore(deps): update node.js to v22.14.0
2025-02-11 16:03:32 +01:00
renovate[bot]
fa62ca21e0 chore(deps): update node.js to v22.14.0 2025-02-11 11:47:44 +00:00
renovate[bot]
7dcf76da84 fix(deps): update dependency interweave to ^13.1.1 2025-02-10 21:40:32 +01:00
renovate[bot]
3dc80fa762 chore(deps): lock file maintenance 2025-02-10 01:47:04 +00:00
Athou
dbce12492b release 5.5.0 2025-02-09 16:31:06 +01:00
renovate[bot]
85f5eaffec fix(deps): update mantine monorepo to ^7.16.3 2025-02-09 06:12:54 +00:00
Athou
106276351e use React 19 features to be able to remove unmaintained React Helmet 2025-02-07 20:13:13 +01:00
Athou
961fb6a464 redoc upgrade 2025-02-07 19:42:39 +01:00
Jérémie Panzer
ac3d9ef57f Merge pull request #1675 from Athou/renovate/docker-setup-qemu-action-digest
chore(deps): update docker/setup-qemu-action digest to 4574d27
2025-02-06 19:55:54 +01:00
Jérémie Panzer
3478ee4815 Merge pull request #1674 from Athou/renovate/docker-setup-buildx-action-digest
chore(deps): update docker/setup-buildx-action digest to f7ce87c
2025-02-06 19:55:49 +01:00
renovate[bot]
3dc02d7ba1 chore(deps): update docker/setup-qemu-action digest to 4574d27 2025-02-06 16:38:04 +00:00
renovate[bot]
c886f8b83c chore(deps): update docker/setup-buildx-action digest to f7ce87c 2025-02-06 16:38:00 +00:00
renovate[bot]
4a2154d0b3 fix(deps): update quarkus.version to v3.18.2 2025-02-05 19:35:32 +00:00
Jérémie Panzer
ba530d5019 Merge pull request #1673 from Athou/renovate/vite-6.x
chore(deps): update dependency vite to ^6.1.0
2025-02-05 20:34:57 +01:00
renovate[bot]
85b6209c52 chore(deps): update dependency vite to ^6.1.0 2025-02-05 16:58:47 +00:00
Athou
7ff86a5e31 make audio enclosures fill available width 2025-02-05 16:51:23 +01:00
Athou
8edd6a1e2d correctly handle 0 as a Retry-Header value (#1671) 2025-02-05 07:50:10 +01:00
Jérémie Panzer
6e65ed49e9 Merge pull request #1670 from Athou/renovate/com.microsoft.playwright-playwright-1.x
chore(deps): update dependency com.microsoft.playwright:playwright to v1.50.0
2025-02-04 23:29:26 +01:00
renovate[bot]
711b01abfa chore(deps): update dependency com.microsoft.playwright:playwright to v1.50.0 2025-02-04 22:01:19 +00:00
renovate[bot]
c7014ca2a1 chore(deps): update dependency vitest to ^3.0.5 2025-02-03 16:31:55 +00:00
renovate[bot]
a3984cd959 chore(deps): lock file maintenance 2025-02-03 08:00:36 +00:00
Athou
8d85b1bcba tweak tests to be more resilient 2025-02-03 08:55:26 +01:00
Athou
c451eee406 fix(deps): update dependency org.apache.httpcomponents.client5:httpclient5 to v5.4.2
remove workaround that is no longer needed
2025-02-02 15:58:59 +01:00
Jérémie Panzer
8f42135996 Merge pull request #1669 from Athou/renovate/linguijs-monorepo
fix(deps): update linguijs monorepo to ^5.2.0 (minor)
2025-02-01 16:28:59 +01:00
renovate[bot]
2c26aeed17 fix(deps): update linguijs monorepo to ^5.2.0 2025-02-01 14:12:40 +00:00
renovate[bot]
e2c4aa998b fix(deps): update dependency react-router-dom to ^7.1.5 2025-02-01 13:20:46 +00:00
Athou
c9e3b7f349 renovate already builds on push, don't trigger twice when it opens a PR 2025-02-01 14:19:50 +01:00
Athou
ebb4e52ba7 don't use lingui before it's initialized 2025-02-01 12:32:44 +01:00
Jérémie Panzer
1ddfdfb12e Merge pull request #1666 from Athou/renovate/quarkus.version
fix(deps): update quarkus.version to v3.18.1 (minor)
2025-01-31 07:47:00 +01:00
Jérémie Panzer
81f16aea62 Merge pull request #1667 from Athou/renovate/npm-11.x
chore(deps): update dependency npm to v11.1.0
2025-01-31 07:25:16 +01:00
renovate[bot]
429ec193c8 fix(deps): update dependency react-router-dom to ^7.1.4 2025-01-30 18:19:26 +00:00
renovate[bot]
732b714448 chore(deps): update dependency npm to v11.1.0 2025-01-30 01:05:55 +00:00
renovate[bot]
82e0405ad9 fix(deps): update quarkus.version to v3.18.1 2025-01-29 20:55:23 +00:00
Athou
9ef002fcd1 swagger-ui-react is no longer used 2025-01-29 15:06:00 +01:00
Athou
ec938e416c README clarification 2025-01-28 10:32:04 +01:00
Athou
37cf711cbc add support for the Retry-After header sent by OpenRSS 2025-01-27 07:48:19 +01:00
renovate[bot]
de441e4ff7 chore(deps): lock file maintenance 2025-01-27 01:07:29 +00:00
renovate[bot]
46251526b6 fix(deps): update dependency @reduxjs/toolkit to ^2.5.1 2025-01-26 22:09:50 +00:00
Jérémie Panzer
67eeea0b06 Merge pull request #1664 from Athou/renovate/com.puppycrawl.tools-checkstyle-10.21.x
chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.21.2
2025-01-26 23:09:03 +01:00
renovate[bot]
b49ccc4cd9 chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.21.2 2025-01-26 16:48:25 +00:00
renovate[bot]
8586a8b57b fix(deps): update mantine monorepo to ^7.16.2 2025-01-26 13:53:50 +00:00
Jérémie Panzer
d9f63786a8 Merge pull request #1663 from Athou/renovate/swagger-ui-react-4.x
chore(deps): update dependency @types/swagger-ui-react to ^4.19.0
2025-01-26 14:53:04 +01:00
renovate[bot]
8f0c8b68b9 chore(deps): update dependency @types/swagger-ui-react to ^4.19.0 2025-01-26 12:40:20 +00:00
Jérémie Panzer
15e574c5c4 Merge pull request #1662 from Athou/renovate/docker-build-push-action-digest
chore(deps): update docker/build-push-action digest to ca877d9
2025-01-24 11:21:15 +01:00
renovate[bot]
fe532242b4 chore(deps): update docker/build-push-action digest to ca877d9 2025-01-24 09:35:09 +00:00
renovate[bot]
fb48ff0858 chore(deps): update dependency vitest to ^3.0.4 2025-01-23 21:13:02 +00:00
Athou
8d850639d7 remove branches-ignore because it applies to target branch 2025-01-23 22:11:53 +01:00
Athou
ee73195915 add github actions permissions 2025-01-23 21:50:27 +01:00
Athou
72d9dad61b fix "an artifact with this name already exists on the workflow run" 2025-01-23 21:50:12 +01:00
Athou
fde8dab8cd simplify youtube channels url detection 2025-01-23 21:49:52 +01:00
Athou
dae5efa787 allow next Java LTS version 2025-01-23 21:49:28 +01:00
Jérémie Panzer
3c067140fd Merge pull request #1661 from Athou/renovate/patch-react-monorepo
chore(deps): update dependency @types/react to ^19.0.8
2025-01-23 18:39:30 +01:00
renovate[bot]
4ccbe81e87 chore(deps): update dependency @types/react to ^19.0.8 2025-01-23 13:31:56 +00:00
Jérémie Panzer
3d5d93bb72 Merge pull request #1660 from Athou/renovate/patch-quarkus.version
fix(deps): update quarkus.version to v3.17.8 (patch)
2025-01-22 21:55:17 +01:00
renovate[bot]
4138b6eb9b fix(deps): update quarkus.version to v3.17.8 2025-01-22 18:33:36 +00:00
Jérémie Panzer
9c39c95a9b Merge pull request #1659 from Athou/renovate/pin-dependencies
chore(deps): pin dependencies
2025-01-22 10:53:56 +01:00
Jérémie Panzer
32b2bf99a4 Merge pull request #1658 from Athou/renovate/node-22.13.x
chore(deps): update node.js to v22.13.1
2025-01-22 08:19:38 +01:00
renovate[bot]
cf459876af chore(deps): update node.js to v22.13.1 2025-01-22 06:53:04 +00:00
renovate[bot]
6698bd74b5 chore(deps): pin dependencies 2025-01-22 06:52:59 +00:00
Athou
c81d06e5f3 pin github actions 2025-01-22 07:52:09 +01:00
renovate[bot]
b12a78dc84 fix(deps): update dependency tss-react to ^4.9.15 2025-01-21 21:34:41 +00:00
renovate[bot]
b076587e44 chore(deps): update dependency vitest to ^3.0.3 2025-01-21 17:42:28 +00:00
renovate[bot]
bb12f16bea chore(deps): update dependency vite to ^6.0.11 2025-01-21 12:35:00 +00:00
renovate[bot]
e80caadd12 chore(deps): update dependency vite to ^6.0.10 2025-01-20 21:35:21 +00:00
renovate[bot]
846d93f2b2 chore(deps): lock file maintenance 2025-01-20 19:18:35 +00:00
Steven Conaway
0ed6f6ef9c chore(deps): move to react@^19 (#1657)
* chore(deps): move to react@^19

* chore(deps): manually override old peer dependencies

* chore(deps): upgrade rollup-plugin-visualizer

* chore(deps): remove `package-lock.json` and `node_modules/` and regen lockfile

* chore(deps): remove randomly added dependencies

* chore(deps): change override for react@^19 peer dep
2025-01-20 19:59:42 +01:00
renovate[bot]
15992dcb80 chore(deps): update dependency vite to ^6.0.9 2025-01-20 14:11:24 +00:00
renovate[bot]
1a5c399b54 chore(deps): lock file maintenance 2025-01-20 01:15:47 +00:00
Athou
5e92f9ffb8 we can skip the docker step altogether for PRs 2025-01-19 21:40:30 +01:00
renovate[bot]
71164d1b69 fix(deps): update mantine monorepo to ^7.16.1 2025-01-19 13:51:46 +00:00
renovate[bot]
6947670fe6 fix(deps): update dependency react-router-dom to ^7.1.3 2025-01-17 22:16:53 +00:00
renovate[bot]
30810e37b9 chore(deps): update dependency vitest to ^3.0.2 2025-01-17 21:52:28 +00:00
Athou
b17b2767b0 run CI on pull requests 2025-01-17 22:40:47 +01:00
Athou
d37cf5bbcf release 5.4.0 2025-01-17 17:15:09 +01:00
Athou
045baba705 use github actions to build a native arm64 docker image 2025-01-17 16:12:05 +01:00
renovate[bot]
3623dc8e1d chore(deps): update dependency vitest to ^3.0.1 2025-01-16 20:17:53 +00:00
renovate[bot]
2610c37067 fix(deps): update swagger.version to v2.2.28 2025-01-16 18:17:44 +00:00
renovate[bot]
286b69a646 fix(deps): update dependency react-router-dom to ^7.1.2 2025-01-16 15:56:44 +00:00
Jérémie Panzer
9673f27090 Merge pull request #1656 from Athou/renovate/major-vitest-monorepo
chore(deps): update dependency vitest to v3
2025-01-16 16:55:55 +01:00
renovate[bot]
0722599f6d chore(deps): update dependency vitest to v3 2025-01-16 14:17:05 +00:00
Jérémie Panzer
1df40d8370 Merge pull request #1655 from Athou/renovate/redoc-2.x
fix(deps): update dependency redoc to ^2.3.0
2025-01-16 15:15:28 +01:00
renovate[bot]
457e4ec69e fix(deps): update dependency redoc to ^2.3.0 2025-01-16 13:56:26 +00:00
renovate[bot]
647310a45f fix(deps): update quarkus.version to v3.17.7 2025-01-15 17:22:28 +00:00
renovate[bot]
e85c92f216 chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v2.44.2 2025-01-15 02:04:18 +00:00
renovate[bot]
d93b0dbfd4 fix(deps): update dependency io.dropwizard.metrics:metrics-json to v4.2.30 2025-01-14 20:40:37 +00:00
Jérémie Panzer
b4e61ef547 Merge pull request #1654 from Athou/renovate/mantine-monorepo
fix(deps): update mantine monorepo to ^7.16.0 (minor)
2025-01-14 14:14:01 +01:00
Jérémie Panzer
71dffbba46 Merge pull request #1653 from Athou/renovate/debian-12.x
chore(deps): update debian docker tag to v12.9
2025-01-14 14:13:51 +01:00
renovate[bot]
2c0b0c4e3b fix(deps): update mantine monorepo to ^7.16.0 2025-01-14 12:49:52 +00:00
renovate[bot]
d868e58e1e chore(deps): update debian docker tag to v12.9 2025-01-14 12:49:31 +00:00
renovate[bot]
90eb2095bf chore(deps): lock file maintenance 2025-01-13 01:27:25 +00:00
Athou
62d3ed16e6 remove DOCTYPE declarations (#1260) 2025-01-10 16:18:49 +01:00
Jérémie Panzer
74f7c48818 Merge pull request #1652 from Athou/renovate/jsdom-26.x
chore(deps): update dependency jsdom to v26
2025-01-10 15:43:55 +01:00
renovate[bot]
23fe9c29ed chore(deps): update dependency jsdom to v26 2025-01-09 10:23:05 +00:00
renovate[bot]
8f7be8278a chore(deps): update dependency typescript to ^5.7.3 (#1651)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-09 05:40:40 +00:00
renovate[bot]
49118b6ea0 fix(deps): update quarkus.version to v3.17.6 2025-01-08 17:50:38 +00:00
Jérémie Panzer
d97bd04ae2 Merge pull request #1649 from Athou/renovate/com.diffplug.spotless-spotless-maven-plugin-2.x
chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v2.44.1
2025-01-08 18:50:20 +01:00
Jérémie Panzer
8d11309b64 Merge pull request #1650 from Athou/renovate/node-22.x
chore(deps): update node.js to v22.13.0
2025-01-08 18:50:07 +01:00
renovate[bot]
68c24e4cb8 chore(deps): update node.js to v22.13.0 2025-01-08 17:21:57 +00:00
renovate[bot]
4e43e0235f chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v2.44.1 2025-01-08 15:35:52 +00:00
renovate[bot]
62b79a9625 fix(deps): update mantine monorepo to ^7.15.3 2025-01-08 15:35:49 +00:00
renovate[bot]
cb0706808c chore(deps): lock file maintenance 2025-01-06 02:01:57 +00:00
renovate[bot]
ffd5704b1e chore(deps): update dependency vite to ^6.0.7 2025-01-02 23:21:46 +00:00
Jérémie Panzer
3987077e5a Merge pull request #1647 from Athou/renovate/io.github.hakky54-sslcontext-kickstart-for-apache5-9.x
fix(deps): update dependency io.github.hakky54:sslcontext-kickstart-for-apache5 to v9
2025-01-01 16:02:38 +01:00
renovate[bot]
2e01a76784 fix(deps): update dependency io.github.hakky54:sslcontext-kickstart-for-apache5 to v9 2025-01-01 13:58:06 +00:00
Athou
8254093f5f fix tests failing because pubDate is older than a year 2024-12-30 08:07:03 +01:00
Jérémie Panzer
0b06526756 Merge pull request #1646 from Athou/renovate/lock-file-maintenance
chore(deps): lock file maintenance
2024-12-30 07:20:00 +01:00
renovate[bot]
06731ae76d chore(deps): lock file maintenance 2024-12-30 00:18:52 +00:00
Jérémie Panzer
9a59453792 Merge pull request #1645 from Athou/renovate/patch-fontsource-monorepo
fix(deps): update dependency @fontsource/open-sans to ^5.1.1
2024-12-29 19:01:50 +01:00
renovate[bot]
c195a52c89 fix(deps): update dependency @fontsource/open-sans to ^5.1.1 2024-12-29 14:30:46 +00:00
Jérémie Panzer
3d7924f953 Merge pull request #1644 from Athou/renovate/com.puppycrawl.tools-checkstyle-10.21.x
chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.21.1
2024-12-29 10:20:33 +01:00
renovate[bot]
f29efd7fae chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.21.1 2024-12-28 15:55:17 +00:00
Jérémie Panzer
157bff3c83 Merge pull request #1643 from Athou/renovate/rollup-plugin-visualizer-5.13.x
chore(deps): update dependency rollup-plugin-visualizer to ^5.13.1
2024-12-28 13:41:58 +01:00
renovate[bot]
5c17bbc36d chore(deps): update dependency rollup-plugin-visualizer to ^5.13.1 2024-12-27 11:16:46 +00:00
Jérémie Panzer
c85e72e70c Merge pull request #1642 from Athou/renovate/rollup-plugin-visualizer-5.x
chore(deps): update dependency rollup-plugin-visualizer to ^5.13.0
2024-12-27 12:16:03 +01:00
renovate[bot]
01150f67e1 chore(deps): update dependency rollup-plugin-visualizer to ^5.13.0 2024-12-27 10:55:17 +00:00
Jérémie Panzer
75aca7aa6f Merge pull request #1638 from bestZwei/patch-1
Update zh/messages.po
2024-12-27 05:05:22 +01:00
zwei
affde7e43c Update messages.po
add a few Chinese Translations
2024-12-26 22:49:36 +08:00
renovate[bot]
b9b1b53235 chore(deps): update dependency vite to ^6.0.6 2024-12-26 05:23:50 +00:00
renovate[bot]
708ebb8abc fix(deps): update dependency react-router-dom to ^7.1.1 2024-12-23 18:42:33 +00:00
renovate[bot]
83e763df0a fix(deps): update mantine monorepo to ^7.15.2 2024-12-23 11:22:09 +00:00
Jérémie Panzer
0ff812c1ea Merge pull request #1637 from Athou/renovate/lock-file-maintenance
chore(deps): lock file maintenance
2024-12-23 12:21:17 +01:00
renovate[bot]
3e9dd6d8e2 chore(deps): lock file maintenance 2024-12-23 10:39:01 +00:00
Jérémie Panzer
23af73e847 Merge pull request #1626 from Athou/renovate/mantine-monorepo
fix(deps): update mantine monorepo (minor)
2024-12-23 11:37:18 +01:00
renovate[bot]
e79e4719fd fix(deps): update mantine monorepo 2024-12-23 10:17:49 +00:00
Jérémie Panzer
23fef98432 Merge pull request #1636 from Athou/renovate/react-router-monorepo
fix(deps): update dependency react-router-dom to ^7.1.0
2024-12-21 10:50:32 +01:00
renovate[bot]
22478252e7 fix(deps): update dependency react-router-dom to ^7.1.0 2024-12-21 02:23:37 +00:00
Jérémie Panzer
76b1f3cd35 Merge pull request #1635 from Athou/renovate/vite-6.0.x
chore(deps): update dependency vite to ^6.0.5
2024-12-20 22:47:21 +01:00
renovate[bot]
420d73ec6a chore(deps): update dependency vite to ^6.0.5 2024-12-20 11:53:07 +00:00
renovate[bot]
e0211cfa0c chore(deps): update dependency @types/react to ^18.3.18 2024-12-20 02:18:48 +00:00
renovate[bot]
25a92c651c fix(deps): update quarkus.version to v3.17.5 2024-12-19 20:26:08 +00:00
renovate[bot]
0781205c69 chore(deps): update dependency vite to ^6.0.4 2024-12-19 11:15:48 +00:00
Jérémie Panzer
5102dd5e30 Merge pull request #1613 from Athou/renovate/vite-6.x
chore(deps): update dependency vite to v6
2024-12-16 21:30:14 +01:00
renovate[bot]
6ccfc3fd67 chore(deps): update dependency vite to v6 2024-12-16 20:14:47 +00:00
Athou
2791ed91ab lingui update 2024-12-16 21:11:54 +01:00
Jérémie Panzer
f40c198233 Merge pull request #1634 from Athou/renovate/npm-11.x
chore(deps): update dependency npm to v11
2024-12-16 20:57:57 +01:00
renovate[bot]
003dc63121 chore(deps): update dependency npm to v11 2024-12-16 19:36:39 +00:00
renovate[bot]
f8ef1e2a99 chore(deps): update dependency @types/react to ^18.3.17 2024-12-16 15:42:17 +00:00
renovate[bot]
14c7078940 fix(deps): update querydsl.version to v6.10.1 2024-12-16 00:30:43 +00:00
Jérémie Panzer
074836d3e8 Merge pull request #1632 from Athou/renovate/querydsl.version
fix(deps): update querydsl.version to v6.10 (minor)
2024-12-14 06:59:55 +01:00
renovate[bot]
0cdbc144b3 fix(deps): update querydsl.version to v6.10 2024-12-13 20:09:27 +00:00
Jérémie Panzer
dc63ec24c0 Merge pull request #1630 from Athou/renovate/com.puppycrawl.tools-checkstyle-10.x
chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.21.0
2024-12-12 22:42:41 +01:00
renovate[bot]
6d4c6c36a5 chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.21.0 2024-12-12 20:31:27 +00:00
renovate[bot]
464af5f4d9 fix(deps): update swagger.version to v2.2.27 2024-12-11 18:13:04 +00:00
renovate[bot]
aa94a46a3d fix(deps): update quarkus.version to v3.17.4 2024-12-11 16:27:30 +00:00
renovate[bot]
8542197dc3 chore(deps): update react monorepo 2024-12-11 06:15:47 +00:00
Jérémie Panzer
64d77eaef4 Merge pull request #1628 from Athou/renovate/reduxjs-toolkit-2.x
fix(deps): update dependency @reduxjs/toolkit to ^2.5.0
2024-12-11 07:14:49 +01:00
Jérémie Panzer
675ef8794c Merge pull request #1627 from Athou/renovate/react-redux-9.x
fix(deps): update dependency react-redux to ^9.2.0
2024-12-11 07:14:17 +01:00
renovate[bot]
4bcdbeb516 fix(deps): update dependency @reduxjs/toolkit to ^2.5.0 2024-12-11 04:59:19 +00:00
renovate[bot]
a9f37739fb fix(deps): update dependency react-redux to ^9.2.0 2024-12-11 02:11:18 +00:00
renovate[bot]
5ab0fc19da chore(deps): update dependency @types/react-dom to ^18.3.3 2024-12-09 22:54:32 +00:00
renovate[bot]
7b232425f3 fix(deps): update dependency monaco-editor to ^0.52.2 2024-12-09 19:06:36 +00:00
Jérémie Panzer
c0e7668140 Merge pull request #1625 from Athou/renovate/emotion-monorepo
fix(deps): update dependency @emotion/react to ^11.14.0
2024-12-09 16:02:32 +01:00
renovate[bot]
ae3f059257 fix(deps): update dependency @emotion/react to ^11.14.0 2024-12-09 12:04:31 +00:00
renovate[bot]
d44c7c1e95 fix(deps): update dependency tss-react to ^4.9.14 2024-12-09 07:48:44 +00:00
renovate[bot]
6cd9d134cf chore(deps): update dependency vite-tsconfig-paths to ^5.1.4 2024-12-07 05:53:17 +00:00
renovate[bot]
6f21ba8afc chore(deps): update react monorepo 2024-12-05 19:55:23 +00:00
renovate[bot]
b2fe13c117 chore(deps): update dependency npm to v10.9.2 2024-12-05 01:06:03 +00:00
renovate[bot]
03ece7a262 chore(deps): update dependency @types/react to ^18.3.13 (#1622)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-05 01:05:43 +00:00
renovate[bot]
697fde2d0e chore(deps): update quarkus.version to v3.17.3 2024-12-04 20:09:33 +00:00
renovate[bot]
7f0f85b356 fix(deps): update dependency axios to ^1.7.9 2024-12-04 09:43:27 +00:00
Jérémie Panzer
a7d41debfe Merge pull request #1621 from Athou/renovate/node-22.x
chore(deps): update node.js to v22.12.0
2024-12-04 07:21:31 +01:00
renovate[bot]
57bf758108 chore(deps): update node.js to v22.12.0 2024-12-03 21:03:12 +00:00
Jérémie Panzer
b37d933047 Merge pull request #1620 from Athou/renovate/react-icons-5.x
fix(deps): update dependency react-icons to ^5.4.0
2024-12-03 13:08:38 +01:00
renovate[bot]
80ffef4555 fix(deps): update dependency react-icons to ^5.4.0 2024-12-03 11:31:44 +00:00
renovate[bot]
af5a0002aa fix(deps): update dependency react-router-dom to ^7.0.2 2024-12-03 04:09:43 +00:00
Athou
cd24e412e3 release 5.3.6 2024-12-02 18:50:14 +01:00
Athou
a073d843ab ignore invalid cache control values (#1619) 2024-12-02 18:43:46 +01:00
renovate[bot]
8ccb59ed18 chore(deps): update dependency vitest to ^2.1.8 2024-12-02 14:56:45 +00:00
renovate[bot]
e6dc7d2d0d chore(deps): lock file maintenance 2024-12-02 03:59:25 +00:00
Athou
f7b21ca3f6 release 5.3.5 2024-12-02 04:57:26 +01:00
Athou
df3a1bcdb6 update changelog 2024-12-02 04:54:58 +01:00
renovate[bot]
5bec494a7c fix(deps): update dependency org.jsoup:jsoup to v1.18.3 2024-12-02 03:18:47 +00:00
renovate[bot]
d8eef4dd9f chore(deps): lock file maintenance 2024-12-02 02:00:17 +00:00
renovate[bot]
d80138caf3 chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.20.2 2024-12-01 06:04:51 +00:00
Athou
d26c103aa5 migrate to markdown documentation 2024-12-01 06:04:08 +01:00
Athou
249231f57e add support for JDK 23 compilation (#1618) 2024-12-01 05:43:35 +01:00
Athou
7a838cddad honor Cache-Control response header (#1615) 2024-11-29 17:06:57 +01:00
renovate[bot]
477f2cd6db fix(deps): update dependency io.quarkus.platform:quarkus-bom to v3.17.2 2024-11-29 13:10:54 +00:00
Athou
9915f05f73 remove lingui warnings 2024-11-29 14:08:25 +01:00
Athou
0a16bb2fba if width is specified, keep images aspect ratio (#1595) 2024-11-29 13:30:48 +01:00
Jérémie Panzer
3d4faf2406 Merge pull request #1616 from Athou/renovate/major-linguijs-monorepo
chore(deps): update linguijs monorepo to v5 (major)
2024-11-29 07:42:28 +01:00
Jérémie Panzer
63de6fe833 Merge pull request #1617 from Athou/renovate/reduxjs-toolkit-2.x
fix(deps): update dependency @reduxjs/toolkit to ^2.4.0
2024-11-29 07:42:17 +01:00
renovate[bot]
9c6219a58a fix(deps): update dependency @reduxjs/toolkit to ^2.4.0 2024-11-28 22:00:49 +00:00
renovate[bot]
3e664d4287 chore(deps): update linguijs monorepo to v5 2024-11-28 19:15:26 +00:00
renovate[bot]
4c4ffd84f3 chore(deps): update linguijs monorepo to ^4.14.1 2024-11-28 15:13:09 +00:00
renovate[bot]
f555f0e392 fix(deps): update mantine monorepo to ^7.14.3 2024-11-28 14:43:41 +00:00
renovate[bot]
124166738b fix(deps): update dependency io.dropwizard.metrics:metrics-json to v4.2.29 2024-11-28 09:55:36 +00:00
Jérémie Panzer
8b32dcc576 Merge pull request #1614 from Athou/renovate/quarkus.version
fix(deps): update dependency io.quarkus.platform:quarkus-bom to v3.17.0
2024-11-27 16:13:19 +01:00
renovate[bot]
105651215a fix(deps): update dependency io.quarkus.platform:quarkus-bom to v3.17.0 2024-11-27 14:52:32 +00:00
renovate[bot]
d9c6cbd072 fix(deps): update dependency org.jsoup:jsoup to v1.18.2 2024-11-27 13:00:42 +00:00
renovate[bot]
b4c52e06fe chore(deps): update dependency vitest to ^2.1.6 2024-11-27 11:35:05 +00:00
Athou
2565dfe528 remove workaround because quarkus.http.auth.form.cookie-max-age is now available 2024-11-27 10:05:26 +01:00
Athou
b5036c9148 Merge branch 'renovate/quarkus.version' 2024-11-27 10:00:53 +01:00
renovate[bot]
e2c8ddb8f7 chore(deps): update quarkus.version to v3.16.4 2024-11-27 10:00:32 +01:00
renovate[bot]
85fbd284fa chore(deps): update dependency @vitejs/plugin-react to ^4.3.4 2024-11-26 11:15:33 +00:00
renovate[bot]
559fb69a64 fix(deps): update dependency axios to ^1.7.8 2024-11-25 23:25:26 +00:00
renovate[bot]
054c76716a chore(deps): lock file maintenance 2024-11-25 00:49:27 +00:00
renovate[bot]
ba17c9350f fix(deps): update mantine monorepo to ^7.14.2 2024-11-24 14:33:06 +00:00
Jérémie Panzer
781015eea4 Merge pull request #1608 from Athou/renovate/major-react-router-monorepo
fix(deps): update dependency react-router-dom to v7
2024-11-23 15:40:57 +01:00
Jérémie Panzer
13e5c0e8d2 Merge pull request #1607 from Athou/renovate/com.microsoft.playwright-playwright-1.x
chore(deps): update dependency com.microsoft.playwright:playwright to v1.49.0
2024-11-23 15:40:41 +01:00
Jérémie Panzer
4d88a30848 Merge pull request #1597 from Athou/renovate/com.puppycrawl.tools-checkstyle-10.x
chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.20.1
2024-11-23 15:40:05 +01:00
Jérémie Panzer
19c03de9e4 Merge pull request #1604 from Athou/renovate/debian-12.x
chore(deps): update debian docker tag to v12.8
2024-11-23 15:39:57 +01:00
Jérémie Panzer
e3169c9f2d Merge pull request #1609 from Athou/renovate/querydsl.version
fix(deps): update querydsl.version to v6.9 (minor)
2024-11-23 15:39:46 +01:00
Jérémie Panzer
e90fb0b56f Merge pull request #1611 from Athou/renovate/typescript-5.x
chore(deps): update dependency typescript to ^5.7.2
2024-11-23 15:39:31 +01:00
renovate[bot]
69607a5122 chore(deps): update dependency typescript to ^5.7.2 2024-11-22 19:13:41 +00:00
renovate[bot]
21eb8e6d9f fix(deps): update dependency react-router-dom to v7 2024-11-22 16:56:53 +00:00
renovate[bot]
a28a6b9dc4 fix(deps): update dependency io.github.openfeign.querydsl:querydsl-jpa to v6.9 2024-11-22 14:10:54 +00:00
renovate[bot]
a9cadbafeb chore(deps): update dependency com.microsoft.playwright:playwright to v1.49.0 2024-11-22 03:47:15 +00:00
renovate[bot]
d491af5a8d chore(deps): update dependency npm to v10.9.1 2024-11-22 00:38:41 +00:00
renovate[bot]
39c7934fb8 fix(deps): update dependency @emotion/react to ^11.13.5 2024-11-20 10:41:11 +00:00
renovate[bot]
76eba8cc63 chore(deps): update dependency vite-tsconfig-paths to ^5.1.3 2024-11-19 23:22:57 +00:00
renovate[bot]
7549ff2491 chore(deps): update dependency @types/tinycon to ^0.6.7 2024-11-19 18:55:08 +00:00
renovate[bot]
66cd18bc4b chore(deps): update dependency io.swagger.core.v3:swagger-maven-plugin-jakarta to v2.2.26 2024-11-19 06:34:58 +00:00
renovate[bot]
44d7a2c340 chore(deps): update dependency io.quarkus.platform:quarkus-maven-plugin to v3.15.2 2024-11-19 02:12:42 +00:00
renovate[bot]
d6ee63a01f chore(deps): update ibm-semeru-runtimes docker tag to open-21.0.5_11-jre 2024-11-18 22:02:31 +00:00
renovate[bot]
a495c9cacd fix(deps): update mantine monorepo to ^7.14.1 2024-11-18 04:24:54 +00:00
renovate[bot]
530185d15c chore(deps): lock file maintenance 2024-11-18 01:29:43 +00:00
renovate[bot]
8dd28c25a7 fix(deps): update dependency org.projectlombok:lombok to v1.18.36 2024-11-15 22:09:25 +00:00
renovate[bot]
50884b236c chore(deps): update dependency vitest to ^2.1.5 2024-11-13 16:06:06 +00:00
renovate[bot]
da9fe09e58 chore(deps): update dependency @types/tinycon to ^0.6.6 2024-11-12 09:54:28 +00:00
renovate[bot]
3c24c9aa7a chore(deps): update debian docker tag to v12.8 2024-11-12 02:04:08 +00:00
renovate[bot]
9d10a4b46f fix(deps): update dependency react-router-dom to ^6.28.0 2024-11-12 02:04:06 +00:00
renovate[bot]
d56ed3bd06 chore(deps): update linguijs monorepo to ^4.14.0 2024-11-11 21:19:20 +00:00
renovate[bot]
41c1c429d0 chore(deps): update dependency vite-tsconfig-paths to ^5.1.2 2024-11-11 19:43:20 +00:00
renovate[bot]
1a3d890b40 chore(deps): lock file maintenance (#1603)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-11 19:42:44 +00:00
renovate[bot]
e3ec9b2ccd chore(deps): update dependency vite to ^5.4.11 2024-11-11 13:43:13 +00:00
renovate[bot]
f69878a242 fix(deps): update mantine monorepo to ^7.13.5 2024-11-09 02:31:03 +00:00
renovate[bot]
ea766706fb chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.20.1 2024-11-07 19:31:05 +00:00
renovate[bot]
306507af80 fix(deps): update dependency react-swipeable to ^7.0.2 2024-11-04 17:47:41 +00:00
renovate[bot]
67084783b2 chore(deps): lock file maintenance 2024-11-04 00:09:27 +00:00
renovate[bot]
7cbb75f717 chore(deps): update dependency org.apache.maven.plugins:maven-surefire-plugin to v3.5.2 2024-11-02 21:48:13 +00:00
renovate[bot]
1c335492d5 chore(deps): update dependency org.apache.maven.plugins:maven-failsafe-plugin to v3.5.2 2024-11-02 20:25:15 +00:00
Jérémie Panzer
de92e74c8e Merge pull request #1594 from Athou/renovate/node-22.x
chore(deps): update dependency node to v22
2024-10-29 18:07:01 +01:00
renovate[bot]
9cbbd30618 chore(deps): update dependency node to v22 2024-10-29 16:43:49 +00:00
Jérémie Panzer
f14f1493c4 Merge pull request #1593 from Athou/renovate/patch-vitest-monorepo
chore(deps): update dependency vitest to ^2.1.4
2024-10-29 00:09:00 +01:00
renovate[bot]
e68c8fdbe1 chore(deps): update dependency vitest to ^2.1.4 2024-10-28 22:13:08 +00:00
renovate[bot]
e094972aa2 fix(deps): update dependency org.apache.httpcomponents.client5:httpclient5 to v5.4.1 2024-10-28 19:56:15 +00:00
renovate[bot]
ff831c6d2b chore(deps): lock file maintenance 2024-10-28 01:19:01 +00:00
Jérémie Panzer
9957cda11a Merge pull request #1592 from Athou/renovate/com.puppycrawl.tools-checkstyle-10.x
chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.19.0
2024-10-26 16:33:49 +02:00
renovate[bot]
6809822000 chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.19.0 2024-10-26 13:58:03 +00:00
Jérémie Panzer
8048b1a9aa Merge pull request #1591 from Athou/renovate/org.apache.maven.plugins-maven-checkstyle-plugin-3.x
chore(deps): update dependency org.apache.maven.plugins:maven-checkstyle-plugin to v3.6.0
2024-10-26 05:57:45 +02:00
renovate[bot]
8557bd018a chore(deps): update dependency org.apache.maven.plugins:maven-checkstyle-plugin to v3.6.0 2024-10-25 18:25:58 +00:00
Jérémie Panzer
183d5fd162 Merge pull request #1590 from Athou/renovate/com.ibm.icu-icu4j-76.x
fix(deps): update dependency com.ibm.icu:icu4j to v76
2024-10-25 17:22:54 +02:00
renovate[bot]
411f86fbeb fix(deps): update dependency com.ibm.icu:icu4j to v76 2024-10-25 06:17:19 +00:00
renovate[bot]
5493046f25 fix(deps): update mantine monorepo to ^7.13.4 2024-10-23 18:02:39 +00:00
Athou
42015015a5 release 5.3.4 2024-10-23 20:01:40 +02:00
Athou
f3d2808f7d add support for Internationalized Domain Names (#1588) 2024-10-23 19:58:47 +02:00
renovate[bot]
906c353a7f chore(deps): update dependency @types/react to ^18.3.12 2024-10-23 06:05:51 +00:00
renovate[bot]
93dea83cd3 chore(deps): update dependency vite to ^5.4.10 2024-10-23 03:47:21 +00:00
renovate[bot]
1fc76ce1ad chore(deps): update dependency org.apache.maven.plugins:maven-help-plugin to v3.5.1 2024-10-21 19:53:59 +00:00
Athou
a337b01bc7 release 5.3.3 2024-10-21 21:53:28 +02:00
Athou
689e5c0004 remove image bottom margins (#1587) 2024-10-21 21:51:46 +02:00
Athou
d5a3c81c85 release 5.3.2 2024-10-21 21:20:27 +02:00
Athou
8230fde5d2 preserve style attribute from images (#1587) 2024-10-21 21:15:57 +02:00
renovate[bot]
b35513ea84 chore(deps): lock file maintenance 2024-10-21 01:29:16 +00:00
renovate[bot]
42a7785ca1 chore(deps): update dependency @vitejs/plugin-react to ^4.3.3 2024-10-19 18:29:57 +00:00
Jérémie Panzer
ea5ee4f04f Merge pull request #1586 from Athou/renovate/com.microsoft.playwright-playwright-1.x
chore(deps): update dependency com.microsoft.playwright:playwright to v1.48.0
2024-10-18 05:53:42 +02:00
renovate[bot]
3e14b12d4f chore(deps): update dependency com.microsoft.playwright:playwright to v1.48.0 2024-10-17 21:46:18 +00:00
renovate[bot]
78cc30f828 chore(deps): update dependency @biomejs/biome to v1.9.4 2024-10-17 21:46:15 +00:00
renovate[bot]
6091c84e60 fix(deps): update mantine monorepo to ^7.13.3 2024-10-17 09:14:54 +00:00
Jérémie Panzer
6ea95ad254 Merge pull request #1585 from Athou/renovate/redoc-2.x
fix(deps): update dependency redoc to ^2.2.0
2024-10-16 14:24:28 +02:00
renovate[bot]
7f888d926e fix(deps): update dependency redoc to ^2.2.0 2024-10-16 11:00:17 +00:00
Jérémie Panzer
5e4e02474f Merge pull request #1583 from Athou/renovate/linguijs-monorepo
chore(deps): update linguijs monorepo to ^4.13.0 (minor)
2024-10-15 16:07:30 +02:00
renovate[bot]
bff8611b42 chore(deps): update linguijs monorepo to ^4.13.0 2024-10-15 10:56:26 +00:00
renovate[bot]
f674048af3 fix(deps): update dependency org.passay:passay to v1.6.6 2024-10-15 02:21:46 +00:00
Jérémie Panzer
0265c24cf9 Merge pull request #1582 from Athou/renovate/reduxjs-toolkit-2.x
fix(deps): update dependency @reduxjs/toolkit to ^2.3.0
2024-10-15 04:21:26 +02:00
renovate[bot]
f8c3a229ec fix(deps): update dependency @reduxjs/toolkit to ^2.3.0 2024-10-14 21:53:07 +00:00
renovate[bot]
c424f40420 chore(deps): update dependency vitest to ^2.1.3 2024-10-14 21:52:47 +00:00
renovate[bot]
b77666cfe5 chore(deps): update dependency vite to ^5.4.9 2024-10-14 19:06:28 +00:00
renovate[bot]
193d1604d9 chore(deps): lock file maintenance 2024-10-14 03:20:28 +00:00
renovate[bot]
4efc6296b5 chore(deps): lock file maintenance 2024-10-14 01:22:19 +00:00
Jérémie Panzer
f753a4bdda Merge pull request #1578 from Athou/renovate/react-router-monorepo
fix(deps): update dependency react-router-dom to ^6.27.0
2024-10-12 07:25:02 +02:00
Jérémie Panzer
afaaaf9657 Merge pull request #1577 from Athou/renovate/linguijs-monorepo
chore(deps): update linguijs monorepo to ^4.12.0 (minor)
2024-10-12 07:24:54 +02:00
renovate[bot]
4d46896bf0 fix(deps): update dependency react-router-dom to ^6.27.0 2024-10-11 20:09:41 +00:00
renovate[bot]
2ad28c927f chore(deps): update linguijs monorepo to ^4.12.0 2024-10-11 15:36:55 +00:00
renovate[bot]
b9680a66ef chore(deps): update dependency @types/react-dom to ^18.3.1 2024-10-11 15:36:38 +00:00
Athou
4f687d5857 indicate that -Xmx also works for the native package (#1539) 2024-10-10 15:29:18 +02:00
renovate[bot]
9cca026834 chore(deps): update dependency typescript to ^5.6.3 2024-10-09 01:04:51 +00:00
renovate[bot]
058a9cd192 fix(deps): update dependency @reduxjs/toolkit to ^2.2.8 2024-10-08 07:21:11 +00:00
renovate[bot]
57d2ede86e chore(deps): update dependency org.apache.maven.plugins:maven-failsafe-plugin to v3.5.1 2024-10-07 13:07:50 +00:00
renovate[bot]
e3abea4ec5 chore(deps): lock file maintenance 2024-10-07 00:38:09 +00:00
renovate[bot]
b831f1f35c chore(deps): update dependency org.apache.maven.plugins:maven-surefire-plugin to v3.5.1 2024-10-06 12:53:45 +00:00
Athou
74bce1308c release 5.3.1 2024-10-04 20:33:56 +02:00
Athou
98cfa6d2c8 add regression test 2024-10-04 20:24:43 +02:00
Athou
99a02a2186 fix issue with some HTTP feeds (#1572) 2024-10-04 20:20:02 +02:00
Jérémie Panzer
3431a813b1 Merge pull request #1574 from Athou/renovate/npm-10.x
chore(deps): update dependency npm to v10.9.0
2024-10-04 07:51:15 +02:00
renovate[bot]
e9e0e8d32b chore(deps): update dependency npm to v10.9.0 2024-10-03 19:31:06 +00:00
renovate[bot]
2d14409d35 fix(deps): update dependency io.dropwizard.metrics:metrics-json to v4.2.28 2024-10-03 19:31:04 +00:00
Jérémie Panzer
a8200e5c58 Merge pull request #1573 from Athou/renovate/node-20.x
chore(deps): update dependency node to v20.18.0
2024-10-03 21:30:44 +02:00
renovate[bot]
79a8df8b06 chore(deps): update dependency node to v20.18.0 2024-10-03 19:00:34 +00:00
renovate[bot]
061a5f0262 fix(deps): update mantine monorepo to ^7.13.2 2024-10-03 13:32:54 +00:00
renovate[bot]
821bdb3b0f chore(deps): update dependency vitest to ^2.1.2 2024-10-02 21:46:25 +00:00
renovate[bot]
606dfa9299 chore(deps): update dependency @types/react to ^18.3.11 2024-10-02 18:42:46 +00:00
renovate[bot]
131357c616 fix(deps): update swagger.version to v2.2.25 2024-10-02 13:17:53 +00:00
renovate[bot]
f6d3493bad chore(deps): update dependency @biomejs/biome to v1.9.3 2024-10-01 14:28:45 +00:00
renovate[bot]
0c6104e25b fix(deps): update mantine monorepo to ^7.13.1 2024-09-30 09:40:08 +00:00
Jérémie Panzer
d73735a35d Merge pull request #1571 from Athou/renovate/vitejs-plugin-react-4.3.x
chore(deps): update dependency @vitejs/plugin-react to ^4.3.2
2024-09-30 06:31:07 +02:00
renovate[bot]
e725d2d6b6 chore(deps): update dependency @vitejs/plugin-react to ^4.3.2 2024-09-30 04:02:46 +00:00
renovate[bot]
f0e1279d68 chore(deps): lock file maintenance 2024-09-30 00:36:34 +00:00
renovate[bot]
c74c74d2c4 chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.18.2 2024-09-29 19:11:52 +00:00
renovate[bot]
aa70cf5dcd chore(deps): update dependency @types/react to ^18.3.10 2024-09-27 16:41:55 +00:00
Jérémie Panzer
1055259627 Merge pull request #1569 from canoine/patch-1
Update fr/messages.po
2024-09-26 22:35:33 +02:00
canoine
302d37b6ef Update fr/messages.po
French translation update
2024-09-26 21:41:37 +02:00
Jérémie Panzer
8532a73d94 Merge pull request #1565 from Athou/renovate/quarkus.version
chore(deps): update quarkus.version to v3.15.1 (minor)
2024-09-26 10:25:09 +02:00
Athou
ffafb272cb update docs 2024-09-26 10:08:52 +02:00
Jérémie Panzer
22e0171a34 Merge pull request #1566 from dai/master
chore(ja): translated some strings
2024-09-26 10:03:32 +02:00
renovate[bot]
2b410f040c Update quarkus.version to v3.15.1 2024-09-26 08:02:28 +00:00
dai
259e8ad4e5 chore: translated some strings
Chore: Translated some new strings and reworked some wording.
2024-09-26 14:25:19 +09:00
Jérémie Panzer
21244dd9f5 Merge pull request #1564 from Athou/renovate/mantine-monorepo
Update mantine monorepo to ^7.13.0 (minor)
2024-09-25 12:52:53 +02:00
renovate[bot]
bc6206180d Update mantine monorepo to ^7.13.0 2024-09-25 09:53:00 +00:00
renovate[bot]
6e22d21358 Update dependency vite to ^5.4.8 2024-09-25 05:04:17 +00:00
renovate[bot]
95bdb4e700 Update dependency @types/react to ^18.3.9 2024-09-24 15:24:13 +00:00
Athou
9b7dbc68ab release 5.3.0 2024-09-24 07:58:43 +02:00
Athou
dc86c9b0db also manually load more entries if needed when pressing the next entry button in the header (#1557) 2024-09-24 07:54:50 +02:00
renovate[bot]
cb92ed753f Update swagger.version to v2.2.24 2024-09-23 16:36:50 +00:00
renovate[bot]
10a085e24e Lock file maintenance 2024-09-23 00:08:26 +00:00
renovate[bot]
3400a39edf Update dependency jsdom to ^25.0.1 2024-09-22 07:08:58 +00:00
Athou
21efffa345 Update dependency io.github.hakky54:sslcontext-kickstart-for-apache5 to v8.3.7
Update dependency org.apache.httpcomponents.client5:httpclient5 to v5.4
2024-09-22 09:07:20 +02:00
renovate[bot]
e2e80ba7e5 Update dependency com.github.eirslett:frontend-maven-plugin to v1.15.1 2024-09-21 18:11:14 +00:00
Jérémie Panzer
d988dba66e Merge pull request #1563 from Athou/renovate/querydsl.version
Update querydsl.version to v6.8 (minor)
2024-09-21 15:42:21 +02:00
renovate[bot]
403201fbff Update querydsl.version to v6.8 2024-09-21 13:25:28 +00:00
Athou
3cc93b51bb set default cooldown duration to 0 so it's not a breaking change 2024-09-21 10:57:16 +02:00
Athou
6a7d83bb45 show an error if force fetching feeds is not yet available 2024-09-21 10:31:17 +02:00
Athou
19c8db8b31 add a cooldown on the force refresh action (#1556) 2024-09-21 08:24:14 +02:00
renovate[bot]
0d75688ec8 Update dependency vite to ^5.4.7 2024-09-20 16:39:11 +00:00
renovate[bot]
e01dcb2f5b Update dependency @types/react to ^18.3.8 2024-09-19 22:25:45 +00:00
Jérémie Panzer
57757e2c14 Merge pull request #1561 from Athou/renovate/monaco-editor-0.x
Update dependency monaco-editor to ^0.52.0
2024-09-19 17:59:58 +02:00
renovate[bot]
779cd2fcfe Update dependency monaco-editor to ^0.52.0 2024-09-19 13:51:05 +00:00
renovate[bot]
94919f22e4 Update dependency @biomejs/biome to v1.9.2 2024-09-19 13:51:00 +00:00
Athou
d5cf690703 release 5.2.0 2024-09-18 17:21:10 +02:00
Athou
191574dace manually load more entries if needed when pressing a keyboard shortcut to go to the next entry (#1557) 2024-09-18 16:23:53 +02:00
renovate[bot]
ee7c6792c9 Update dependency @types/react to ^18.3.7 2024-09-17 11:39:38 +00:00
renovate[bot]
e2962dc2eb Update dependency vite to ^5.4.6 2024-09-16 23:19:58 +00:00
Jérémie Panzer
8c335cb8fd Merge pull request #1555 from victorhck/master
Update messages.po
2024-09-16 18:40:24 +02:00
Victorhck
461c18a591 Update messages.po
Keep in spanish the same name for Shift Key
2024-09-16 16:59:56 +02:00
Jérémie Panzer
363837ab26 we no longer need this file thanks to quarkus dev services 2024-09-16 15:55:06 +02:00
renovate[bot]
a184485421 Update dependency @types/react to ^18.3.6 2024-09-16 11:44:00 +00:00
renovate[bot]
f992c3f1a6 Lock file maintenance 2024-09-16 01:01:23 +00:00
Jérémie Panzer
3219a9e313 Merge pull request #1554 from Athou/renovate/biomejs-biome-1.9.x
Update dependency @biomejs/biome to v1.9.1
2024-09-15 21:39:44 +02:00
renovate[bot]
4717c31058 Update dependency @biomejs/biome to v1.9.1 2024-09-15 18:33:30 +00:00
Athou
693844828b comment tweak 2024-09-15 12:18:56 +02:00
renovate[bot]
ef4b479638 Update quarkus.version to v3.14.4 2024-09-14 16:38:57 +00:00
Athou
8eefb1bcfb add http cache to avoid fetching feeds too often (#1431) 2024-09-14 14:00:15 +02:00
Athou
ada9a5039b add support for all charsets in native mode 2024-09-14 07:56:36 +02:00
Athou
cca2d49cc3 Revert "reduce artifact size by using a smaller library for charset detection" because juniversalchardet doesn't support as many charsets as icu4j 2024-09-13 23:40:13 +02:00
Athou
f4a43e9950 only compute rtl once by storing it in the database on fetch 2024-09-13 22:25:02 +02:00
Athou
9a89b39b62 fix formatting 2024-09-13 21:57:21 +02:00
Jérémie Panzer
2dba844b6c Merge pull request #1552 from victorhck/master
uptade and improve Spanish translation
2024-09-13 21:56:49 +02:00
renovate[bot]
3101dc91de Update dependency vitest to ^2.1.1 2024-09-13 15:51:45 +00:00
Victorhck
83cacd97f3 fix typo Spanish messages.po 2024-09-13 17:19:44 +02:00
Victorhck
aa179c21f8 uptade and improve Spanish translation 2024-09-13 17:17:35 +02:00
Athou
31cf4d8bb2 use our own bidi detector to drop 10Mb from gwt 2024-09-13 16:05:21 +02:00
Athou
19bcc2c0da reduce artifact size by using a smaller library for charset detection 2024-09-13 14:48:24 +02:00
renovate[bot]
ca803ff7ce Update dependency vite to ^5.4.5 2024-09-13 09:42:41 +00:00
Athou
0e26d975aa we don't need quarkus-extension-processor at runtime 2024-09-13 10:55:02 +02:00
Athou
86a3cb67f2 exclude unused database dependencies from final artifact 2024-09-13 10:20:19 +02:00
Jérémie Panzer
6297463445 Merge pull request #1551 from Athou/renovate/com.microsoft.playwright-playwright-1.x
Update dependency com.microsoft.playwright:playwright to v1.47.0
2024-09-13 03:56:06 +02:00
renovate[bot]
1a3a3076b1 Update dependency com.microsoft.playwright:playwright to v1.47.0 2024-09-13 00:06:46 +00:00
Jérémie Panzer
7fb9cfeaf1 Merge pull request #1550 from Athou/renovate/vitest-monorepo
Update dependency vitest to ^2.1.0
2024-09-12 20:46:39 +02:00
renovate[bot]
5c7dbe6304 Update dependency vitest to ^2.1.0 2024-09-12 16:01:52 +00:00
Jérémie Panzer
c41fd9216a Merge pull request #1549 from Athou/renovate/fontsource-monorepo
Update dependency @fontsource/open-sans to ^5.1.0
2024-09-12 16:42:21 +02:00
Jérémie Panzer
91a9ad79f0 Merge pull request #1548 from Athou/renovate/biomejs-biome-1.x
Update dependency @biomejs/biome to v1.9.0
2024-09-12 16:42:10 +02:00
renovate[bot]
906458dc96 Update dependency @fontsource/open-sans to ^5.1.0 2024-09-12 14:21:15 +00:00
renovate[bot]
2f4fddf539 Update dependency @biomejs/biome to v1.9.0 2024-09-12 14:21:09 +00:00
renovate[bot]
a8157143b9 Update dependency io.quarkus.platform:quarkus-bom to v3.14.3 2024-09-11 14:55:31 +00:00
Athou
92576e28e9 fix tests incorrectly always running with h2 2024-09-11 16:49:02 +02:00
Athou
a6e34a2960 no need to repeat the plugin, we can just use the variable 2024-09-11 16:35:08 +02:00
renovate[bot]
306cf7aab7 Update dependency vite to ^5.4.4 2024-09-11 12:55:32 +00:00
Athou
f3b806686d help during development by showing typescript errors for the whole project 2024-09-11 14:54:01 +02:00
Athou
6634cfb991 load from old settings if new settings are not found to smooth transition 2024-09-11 07:52:41 +02:00
Athou
9930bb68b2 rename variable because it now contains a duration 2024-09-10 20:47:08 +02:00
Athou
37722131e5 remove warning about deprecated findDOMNode 2024-09-10 20:16:24 +02:00
Athou
5f2d213419 move other settings to localSettings too 2024-09-10 20:16:24 +02:00
Athou
e119941762 add option to keep some entries above the selected entry when scrolling 2024-09-10 20:16:24 +02:00
Athou
ba496c1395 no longer fetch feeds without subscriptions 2024-09-10 11:16:25 +02:00
renovate[bot]
9c3fc84542 Update dependency react-router-dom to ^6.26.2 2024-09-09 17:31:13 +00:00
Jérémie Panzer
b017ce936a Merge pull request #1546 from Athou/renovate/typescript-5.x
Update dependency typescript to ^5.6.2
2024-09-09 19:30:40 +02:00
renovate[bot]
d696b0581b Update dependency typescript to ^5.6.2 2024-09-09 17:03:23 +00:00
Athou
e4b2880f2b funding links tweaks 2024-09-09 18:56:04 +02:00
renovate[bot]
e071049969 Lock file maintenance 2024-09-09 03:25:09 +00:00
renovate[bot]
5e1f592951 Lock file maintenance 2024-09-09 00:21:56 +00:00
renovate[bot]
231f82da28 Update dependency @fontsource/open-sans to ^5.0.30 2024-09-08 04:53:38 +00:00
Athou
9a28bc7334 release 5.1.1 2024-09-06 11:44:37 +02:00
Athou
00907e92ff indicate that we actually set a boolean value (#1544) 2024-09-06 10:12:05 +02:00
Athou
5669798881 tweak bug report template 2024-09-06 09:09:14 +02:00
Athou
f3a62a5f75 always show current feed/category (#1543) 2024-09-06 09:09:14 +02:00
Jérémie Panzer
3b20ed222c Merge pull request #1542 from Athou/renovate/debian-12.x
Update debian Docker tag to v12.7
2024-09-05 04:42:59 +02:00
renovate[bot]
1f40f3f59c Update debian Docker tag to v12.7 2024-09-05 02:04:26 +00:00
Athou
a8d890524f fix doc 2024-09-04 20:22:24 +02:00
renovate[bot]
b635799e80 Update quarkus.version to v3.14.2 2024-09-04 17:32:46 +00:00
renovate[bot]
50ea66620d Update dependency tss-react to ^4.9.13 2024-09-04 07:10:20 +00:00
Athou
46581d0e22 quarkus has an extension that pulls both junit and mockito 2024-09-04 09:09:28 +02:00
renovate[bot]
a3562867a6 Update dependency vite to ^5.4.3 2024-09-03 19:41:15 +00:00
Athou
c0117ada93 add a link to the feed of the GitHub release page in the README 2024-09-03 19:38:55 +02:00
Jérémie Panzer
a3dcb2c03e Merge pull request #1540 from dai/master
Update messages.po
2024-09-03 10:45:13 +02:00
dai
8f8aaa5a1d Update messages.po
Updated and added Japanese language file.
2024-09-03 16:31:15 +09:00
renovate[bot]
85482422fd Lock file maintenance 2024-09-02 15:50:13 +00:00
Athou
643c969faf release 5.1.0 2024-09-02 17:47:08 +02:00
renovate[bot]
85f9469d6d Update linguijs monorepo to ^4.11.4 2024-09-02 14:07:26 +00:00
renovate[bot]
0df0d50695 Lock file maintenance 2024-09-02 01:33:37 +00:00
Athou
5e9256c197 reduce intermediate database cleanup logging level to reduce logging volume 2024-09-01 21:51:07 +02:00
Athou
b67e1a92f5 fix hibernate warnings about wrong types 2024-09-01 18:21:26 +02:00
Athou
d250e4bc26 add missing foreign key on feedentrystatuses.user_id 2024-09-01 18:02:38 +02:00
Athou
dcf1f41f2d add config doc sections 2024-09-01 13:47:09 +02:00
renovate[bot]
3df6ba1457 Update dependency axios to ^1.7.7 2024-08-31 22:33:06 +00:00
renovate[bot]
b89928f6c6 Update dependency axios to ^1.7.6 2024-08-30 21:06:14 +00:00
renovate[bot]
2e014484e3 Update mantine monorepo to ^7.12.2 2024-08-30 18:47:41 +00:00
renovate[bot]
3b2b18fd2e Update dependency com.puppycrawl.tools:checkstyle to v10.18.1 2024-08-30 15:35:27 +00:00
renovate[bot]
ebf1e592ff Update dependency @types/react to ^18.3.5 2024-08-30 10:40:03 +00:00
renovate[bot]
88404b91d8 Update dependency npm to v10.8.3 2024-08-28 20:30:31 +00:00
Athou
9cbb60313c there are only native implementations of brotli encoders, don't use them because it doesn't work on all platforms 2024-08-28 20:53:48 +02:00
Jérémie Panzer
b95d417f5e Merge pull request #1526 from Athou/renovate/quarkus.version
Update quarkus.version to v3.14.1 (minor)
2024-08-28 19:27:02 +02:00
Athou
994f1fb121 quarkus-config-doc-maven-plugin is now required to generate the documentation 2024-08-28 19:08:34 +02:00
renovate[bot]
e533c1fa4b Update quarkus.version to v3.14.1 2024-08-28 16:31:58 +00:00
renovate[bot]
d0d946ffe9 Update dependency vitest-mock-extended to ^2.0.2 2024-08-28 15:39:32 +00:00
Athou
e3bcc824c7 use a property to sync swagger versions 2024-08-28 17:36:15 +02:00
Athou
357e4e207f add a test to make sure brotli compression is supported 2024-08-28 17:34:24 +02:00
Athou
2aee961600 specify what version of checkstyle we want to use 2024-08-28 09:20:18 +02:00
Athou
3aa1987319 make renovate ignore all "io.quarkus" versions 2024-08-28 09:10:03 +02:00
Jérémie Panzer
ae15f61fc2 Merge pull request #1535 from Athou/renovate/org.apache.maven.plugins-maven-failsafe-plugin-3.x
Update dependency org.apache.maven.plugins:maven-failsafe-plugin to v3.5.0
2024-08-27 16:55:50 +02:00
Jérémie Panzer
e58f92a812 Merge pull request #1536 from Athou/renovate/org.apache.maven.plugins-maven-surefire-plugin-3.x
Update dependency org.apache.maven.plugins:maven-surefire-plugin to v3.5.0
2024-08-27 16:55:38 +02:00
renovate[bot]
46383924b1 Update dependency org.apache.maven.plugins:maven-surefire-plugin to v3.5.0 2024-08-27 14:39:46 +00:00
renovate[bot]
071920e864 Update dependency org.apache.maven.plugins:maven-failsafe-plugin to v3.5.0 2024-08-27 14:39:42 +00:00
Athou
012238e6a9 Docker README tweak 2024-08-27 13:40:18 +02:00
Athou
a565566c50 remove deprecation warning 2024-08-27 09:02:42 +02:00
Athou
550804c666 use @Transactional where possible 2024-08-27 08:47:39 +02:00
Athou
f7a4a33f5e fix wrong path in documentation 2024-08-27 08:41:53 +02:00
Athou
f1b19ebae3 after reading the spec, what we want is actually "no-cache" that actually means "cache but revalidate immediately" using If-Modified-Since request headers and 304 response codes 2024-08-26 11:41:56 +02:00
Jérémie Panzer
4049fa2e17 Merge pull request #1534 from canoine/master
Update fr/messages.po
2024-08-26 09:43:21 +02:00
canoine
28808cf4f5 Merge pull request #2 from canoine/canoine-patch-1
Update fr/messages.po
2024-08-26 09:07:18 +02:00
canoine
870b46cf9d Update fr/messages.po
Blind update, as I didn't find where some of the new fields are shown.
2024-08-26 08:58:03 +02:00
renovate[bot]
9c20dea99c Lock file maintenance 2024-08-26 02:13:39 +00:00
Athou
63c7679067 make sure the webapp and openapi documentation are always up to date by preventing caching 2024-08-26 00:28:44 +02:00
Athou
764c1a6430 add setting for showing unread count in tab/favicon (#1518) 2024-08-25 20:24:57 +02:00
renovate[bot]
bb6578bdd0 Update dependency org.passay:passay to v1.6.5 2024-08-25 03:23:37 +00:00
renovate[bot]
748c8531ad Lock file maintenance 2024-08-23 19:32:29 +00:00
Athou
a734fe68d2 fix link README 2024-08-23 21:21:15 +02:00
renovate[bot]
cc5ebc55a4 Update dependency axios to ^1.7.5 2024-08-23 14:17:51 +00:00
Jérémie Panzer
aa396c1e1c Merge pull request #1531 from Athou/renovate/monaco-editor-0.x
Update dependency monaco-editor to ^0.51.0
2024-08-23 11:51:22 +02:00
Athou
fbf87ff291 make renovate ignore quarkus-extension-processor 2024-08-23 11:44:24 +02:00
renovate[bot]
e9f3ffddf4 Update dependency monaco-editor to ^0.51.0 2024-08-23 09:33:00 +00:00
Jérémie Panzer
695518d68b Merge pull request #1530 from Athou/renovate/querydsl.version
Update querydsl.version to v6.7 (minor)
2024-08-23 05:34:54 +02:00
renovate[bot]
5d96c1e12b Update querydsl.version to v6.7 2024-08-22 22:39:22 +00:00
Jérémie Panzer
3a72a1cc04 Merge pull request #1529 from Athou/renovate/org.apache.maven.plugins-maven-checkstyle-plugin-3.x
Update dependency org.apache.maven.plugins:maven-checkstyle-plugin to v3.5.0
2024-08-22 21:15:42 +02:00
renovate[bot]
54f5714108 Update dependency org.apache.maven.plugins:maven-checkstyle-plugin to v3.5.0 2024-08-22 18:58:15 +00:00
Jérémie Panzer
04811c7eca Merge pull request #1528 from Athou/renovate/org.apache.maven.plugins-maven-help-plugin-3.x
Update dependency org.apache.maven.plugins:maven-help-plugin to v3.5.0
2024-08-22 07:10:46 +02:00
renovate[bot]
6856736ddb Update dependency org.apache.maven.plugins:maven-help-plugin to v3.5.0 2024-08-21 21:04:31 +00:00
Athou
db6c43993a simpler workaround for cookie max-age 2024-08-21 21:56:57 +02:00
Jérémie Panzer
508a22576a Merge pull request #1527 from Athou/renovate/node-20.x
Update dependency node to v20.17.0
2024-08-21 21:35:26 +02:00
renovate[bot]
8fb012b3a1 Update dependency node to v20.17.0 2024-08-21 18:25:57 +00:00
renovate[bot]
133781d314 Update dependency @emotion/react to ^11.13.3 2024-08-21 11:41:31 +00:00
renovate[bot]
50cb12896e Update dependency vite to ^5.4.2 2024-08-21 02:14:50 +00:00
renovate[bot]
79a4315941 Update dependency @types/react to ^18.3.4 2024-08-20 22:13:31 +00:00
renovate[bot]
33a2f76521 Update dependency dayjs to ^1.11.13 2024-08-20 19:25:48 +00:00
Jérémie Panzer
d4041a1d88 Merge pull request #1525 from Athou/renovate/patch-quarkus.version
Update quarkus.version to v3.13.3 (patch)
2024-08-20 21:24:48 +02:00
renovate[bot]
09f2f56446 Update quarkus.version to v3.13.3 2024-08-20 17:16:54 +00:00
Athou
a0c3eda506 remove warning 2024-08-20 10:03:15 +02:00
Athou
84de3199cc guava version is managed by quarkus 2024-08-20 10:01:13 +02:00
Athou
a7e8309d63 fix docker readme missing word 2024-08-20 08:36:31 +02:00
Athou
7e74d2f6f4 release 5.0.2 2024-08-20 07:27:46 +02:00
Athou
dc25d53dc0 github actions is sometimes slow, increase timeout for tests 2024-08-20 00:03:45 +02:00
Athou
ac1a927836 remove google-api-services-youtube because it doesn't play nicely with native-image 2024-08-19 23:55:38 +02:00
Athou
b50b69adb2 Revert "better workaround for cookie max-age" because it causes issues with favicon fetching 2024-08-19 18:27:50 +02:00
Athou
b112e912af release 5.0.1 2024-08-19 15:55:13 +02:00
Athou
ece55727d3 better workaround for cookie max-age 2024-08-19 14:31:12 +02:00
Athou
181dd24b57 format both Dockerfiles the same way 2024-08-19 10:29:35 +02:00
Athou
10008ca0e8 add link to all quarkus settings 2024-08-19 09:38:26 +02:00
Athou
134c4621a8 docker README tweaks 2024-08-19 08:47:23 +02:00
Athou
51f15bf487 github actions is sometimes very slow, increase default timeouts for tests 2024-08-19 08:26:06 +02:00
renovate[bot]
49ae2c88ad Lock file maintenance 2024-08-19 05:53:45 +00:00
Jérémie Panzer
43a628fc55 Merge pull request #1523 from Athou/renovate/org.apache.maven.plugins-maven-surefire-plugin-3.x
Update dependency org.apache.maven.plugins:maven-surefire-plugin to v3.4.0
2024-08-19 07:51:49 +02:00
Jérémie Panzer
7f71f95f7c Merge pull request #1522 from Athou/renovate/org.apache.maven.plugins-maven-failsafe-plugin-3.x
Update dependency org.apache.maven.plugins:maven-failsafe-plugin to v3.4.0
2024-08-19 07:51:41 +02:00
Athou
e8d5eab419 compile to native image with support for older CPUs 2024-08-19 07:08:18 +02:00
renovate[bot]
de3a6b1f20 Update dependency io.dropwizard.metrics:metrics-json to v4.2.27 2024-08-19 00:25:33 +00:00
renovate[bot]
849742e19a Update dependency org.apache.maven.plugins:maven-surefire-plugin to v3.4.0 2024-08-18 21:04:13 +00:00
renovate[bot]
b6392b114c Update dependency org.apache.maven.plugins:maven-failsafe-plugin to v3.4.0 2024-08-18 21:04:10 +00:00
Athou
4db0c775ff add settings documentation 2024-08-18 21:23:42 +02:00
Athou
ff9374f1ed README tweak 2024-08-18 19:20:34 +02:00
Athou
ea86c9bb1f README tweak 2024-08-18 17:07:31 +02:00
Athou
e6dd088abe fix typo 2024-08-18 17:00:59 +02:00
Jérémie Panzer
c039d8f3a4 Merge pull request #1521 from Athou/renovate/com.google.apis-google-api-services-youtube-3.0.x
Update dependency com.google.apis:google-api-services-youtube to v3-rev20240814-2.0.0
2024-08-18 14:51:39 +02:00
renovate[bot]
bffa6329fd Update dependency com.google.apis:google-api-services-youtube to v3-rev20240814-2.0.0 2024-08-18 10:58:38 +00:00
Athou
b88e5d2847 increase ssl handshake timeout during tests to fix build on slower machines 2024-08-18 12:25:52 +02:00
Jérémie Panzer
0fc4fcd406 Merge pull request #1516 from Athou/renovate/react-icons-5.x
Update dependency react-icons to ^5.3.0
2024-08-18 10:39:10 +02:00
Athou
f04ca21394 Twitter has been renamed X 2024-08-18 10:15:17 +02:00
renovate[bot]
a82fca130f Update dependency react-icons to ^5.3.0 2024-08-18 07:58:41 +00:00
Athou
70d494798c Docker readme tweaks 2024-08-18 09:45:44 +02:00
408 changed files with 37856 additions and 25998 deletions

3
.gitattributes vendored Normal file
View File

@@ -0,0 +1,3 @@
* text eol=lf
*.cmd text eol=crlf
*.png binary

7
.github/FUNDING.yml vendored
View File

@@ -1,2 +1,5 @@
github: [athou]
custom: ['https://www.paypal.com/donate/?business=9CNQHMJG2ZJVY&no_recurring=0&item_name=CommaFeed&currency_code=EUR']
github: [ athou ]
custom: [
'https://github.com/sponsors/Athou',
'https://www.paypal.com/donate/?business=9CNQHMJG2ZJVY&no_recurring=0&item_name=CommaFeed&currency_code=EUR'
]

View File

@@ -25,7 +25,8 @@ If applicable, add screenshots to help explain your problem.
**Environment (please complete the following information):**
- CommaFeed version (or "commafeed.com"): 3.2.1
- commafeed.com or self-hosted:
- If self-hosted, CommaFeed version [e.g. 5.1.0 (a3dcb2c)]:
- Browser [e.g. chrome, firefox]:
- Device [e.g. desktop, mobile]:

37
.github/stale.yml vendored
View File

@@ -1,19 +1,20 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 60
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- pinned
- security
- enhancement
- bug
# Label to use when marking an issue as stale
staleLabel: wontfix
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 60
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- pinned
- security
- enhancement
- feature-request
- bug
# Label to use when marking an issue as stale
staleLabel: wontfix
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

View File

@@ -1,183 +1,278 @@
name: ci
on: [ push ]
env:
JAVA_VERSION: 21
DOCKER_BUILD_SUMMARY: false
jobs:
build-linux:
runs-on: ubuntu-latest
strategy:
matrix:
database: [ "h2", "postgresql", "mysql", "mariadb" ]
steps:
# Checkout
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
# Setup
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Set up GraalVM
uses: graalvm/setup-graalvm@v1
with:
java-version: ${{ env.JAVA_VERSION }}
distribution: "graalvm"
cache: "maven"
# Build & Test
- name: Build with Maven
run: mvn --batch-mode --no-transfer-progress install -Pnative -P${{ matrix.database }}
# Upload artifacts
- name: Upload cross-platform app
uses: actions/upload-artifact@v4
with:
name: commafeed-${{ matrix.database }}-jvm
path: commafeed-server/target/commafeed-*.zip
- name: Upload native executable
uses: actions/upload-artifact@v4
with:
name: commafeed-${{ matrix.database }}-${{ runner.os }}-${{ runner.arch }}
path: commafeed-server/target/commafeed-*-runner
# Docker
- name: Login to Container Registry
uses: docker/login-action@v3
if: ${{ github.ref_type == 'tag' || github.ref_name == 'master' }}
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
## tags
- name: Docker build and push tag - native
uses: docker/build-push-action@v6
if: ${{ github.ref_type == 'tag' }}
with:
context: .
file: commafeed-server/src/main/docker/Dockerfile.native
push: true
platforms: linux/amd64
tags: |
athou/commafeed:latest-${{ matrix.database }}
athou/commafeed:${{ github.ref_name }}-${{ matrix.database }}
- name: Docker build and push tag - jvm
uses: docker/build-push-action@v6
if: ${{ github.ref_type == 'tag' }}
with:
context: .
file: commafeed-server/src/main/docker/Dockerfile.jvm
push: true
platforms: linux/amd64,linux/arm64/v8
tags: |
athou/commafeed:latest-${{ matrix.database }}-jvm
athou/commafeed:${{ github.ref_name }}-${{ matrix.database }}-jvm
## master
- name: Docker build and push master - native
uses: docker/build-push-action@v6
if: ${{ github.ref_name == 'master' }}
with:
context: .
file: commafeed-server/src/main/docker/Dockerfile.native
push: true
platforms: linux/amd64
tags: athou/commafeed:master-${{ matrix.database }}
- name: Docker build and push master - jvm
uses: docker/build-push-action@v6
if: ${{ github.ref_name == 'master' }}
with:
context: .
file: commafeed-server/src/main/docker/Dockerfile.jvm
push: true
platforms: linux/amd64,linux/arm64/v8
tags: athou/commafeed:master-${{ matrix.database }}-jvm
build-windows:
runs-on: windows-latest
strategy:
matrix:
database: [ "h2", "postgresql", "mysql", "mariadb" ]
steps:
# Checkout
- name: Configure git to checkout as-is
run: git config --global core.autocrlf false
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
# Setup
- name: Set up GraalVM
uses: graalvm/setup-graalvm@v1
with:
java-version: ${{ env.JAVA_VERSION }}
distribution: "graalvm"
cache: "maven"
# Build & Test
- name: Build with Maven
run: mvn --batch-mode --no-transfer-progress install -Pnative -P${{ matrix.database }} -DskipTests=${{ matrix.database != 'h2' }}
# Upload artifacts
- name: Upload native executable
uses: actions/upload-artifact@v4
with:
name: commafeed-${{ matrix.database }}-${{ runner.os }}-${{ runner.arch }}
path: commafeed-server/target/commafeed-*-runner.exe
release:
runs-on: ubuntu-latest
needs:
- build-linux
- build-windows
if: github.ref_type == 'tag'
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download artifacts
uses: actions/download-artifact@v4
with:
pattern: commafeed-*
path: ./artifacts
merge-multiple: true
- name: Extract Changelog Entry
uses: mindsers/changelog-reader-action@v2
id: changelog_reader
with:
version: ${{ github.ref_name }}
- name: Create GitHub release
uses: ncipollo/release-action@v1
with:
name: CommaFeed ${{ github.ref_name }}
body: ${{ steps.changelog_reader.outputs.changes }}
artifacts: ./artifacts/*
- name: Update Docker Hub Description
uses: peter-evans/dockerhub-description@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
repository: athou/commafeed
short-description: ${{ github.event.repository.description }}
readme-filepath: commafeed-server/src/main/docker/README.md
name: ci
permissions:
contents: read
on:
push:
pull_request:
env:
JAVA_VERSION: 25
DOCKER_BUILD_SUMMARY: false
jobs:
build:
if: github.event_name != 'pull_request' || github.actor != 'renovate[bot]' # renovate already triggers the build on pushes
strategy:
matrix:
os: [ "ubuntu-latest", "ubuntu-22.04-arm", "windows-latest" ]
database: [ "h2", "postgresql", "mysql", "mariadb" ]
runs-on: ${{ matrix.os }}
steps:
# Checkout
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 0
# Setup
- name: Set up GraalVM
uses: graalvm/setup-graalvm@03e8abf916fd0e281b2efe7b2da3378bb0a1d085 # v1
with:
java-version: ${{ env.JAVA_VERSION }}
distribution: "graalvm"
cache: "maven"
- name: Install Playwright dependencies
run: sudo apt-get install -y libgbm1
if: matrix.os != 'windows-latest'
# Build & Test
- name: Build with Maven
run: mvn --batch-mode --no-transfer-progress install -Pnative -P${{ matrix.database }} -DskipTests=${{ matrix.os == 'windows-latest' && matrix.database != 'h2' }}
# Build pages
- name: Create pages directory structure
run: mkdir -p target/pages/documentation/custom-css
- name: Convert readme file to html
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@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@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@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
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@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: commafeed-${{ matrix.database }}-${{ runner.os }}-${{ runner.arch }}
path: commafeed-server/target/commafeed-*-runner*
- name: Upload pages
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
docker:
runs-on: ubuntu-latest
needs: build
env:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
strategy:
matrix:
database: [ "h2", "postgresql", "mysql", "mariadb" ]
steps:
# Checkout
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 0
# Setup
- name: Set up QEMU
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4
- name: Install required packages
run: sudo apt-get install -y rename unzip
# Prepare artifacts
- name: Download artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
pattern: commafeed-${{ matrix.database }}-*
path: ./artifacts
merge-multiple: true
- name: Set the exec flag on the native executables
run: chmod +x artifacts/*-runner
- name: Rename native executables to match buildx TARGETARCH
run: |
rename 's/x86_64/amd64/g' artifacts/*
rename 's/aarch_64/arm64/g' artifacts/*
- name: Unzip jvm package
run: |
unzip artifacts/*-jvm.zip -d artifacts/extracted-jvm-package
rename 's/commafeed-.*/quarkus-app/g' artifacts/extracted-jvm-package/*
# Docker
- name: Login to Container Registry
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4
if: ${{ env.DOCKERHUB_USERNAME != '' }}
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
## build but don't push for PRs and renovate
- name: Docker build - native
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7
with:
context: .
file: commafeed-server/src/main/docker/Dockerfile.native
push: false
platforms: linux/amd64,linux/arm64/v8
- name: Docker build - jvm
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7
with:
context: .
file: commafeed-server/src/main/docker/Dockerfile.jvm
push: false
platforms: linux/amd64,linux/arm64/v8
## build and push tag
- name: Docker build and push tag - native
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7
if: ${{ github.ref_type == 'tag' }}
with:
context: .
file: commafeed-server/src/main/docker/Dockerfile.native
push: ${{ env.DOCKERHUB_USERNAME != '' }}
platforms: linux/amd64,linux/arm64/v8
tags: |
athou/commafeed:latest-${{ matrix.database }}
athou/commafeed:${{ github.ref_name }}-${{ matrix.database }}
- name: Docker build and push tag - jvm
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7
if: ${{ github.ref_type == 'tag' }}
with:
context: .
file: commafeed-server/src/main/docker/Dockerfile.jvm
push: ${{ env.DOCKERHUB_USERNAME != '' }}
platforms: linux/amd64,linux/arm64/v8
tags: |
athou/commafeed:latest-${{ matrix.database }}-jvm
athou/commafeed:${{ github.ref_name }}-${{ matrix.database }}-jvm
## build and push master
- name: Docker build and push master - native
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7
if: ${{ github.ref_name == 'master' }}
with:
context: .
file: commafeed-server/src/main/docker/Dockerfile.native
push: ${{ env.DOCKERHUB_USERNAME != '' }}
platforms: linux/amd64,linux/arm64/v8
tags: athou/commafeed:master-${{ matrix.database }}
- name: Docker build and push master - jvm
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7
if: ${{ github.ref_name == 'master' }}
with:
context: .
file: commafeed-server/src/main/docker/Dockerfile.jvm
push: ${{ env.DOCKERHUB_USERNAME != '' }}
platforms: linux/amd64,linux/arm64/v8
tags: athou/commafeed:master-${{ matrix.database }}-jvm
release:
runs-on: ubuntu-latest
needs:
- build
- docker
permissions:
contents: write
if: github.ref_type == 'tag'
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 0
- name: Download artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
pattern: commafeed-*
path: ./artifacts
merge-multiple: true
- name: Set the exec flag on the native executables
run: chmod +x artifacts/*-runner
- name: Extract Changelog Entry
uses: mindsers/changelog-reader-action@32aa5b4c155d76c94e4ec883a223c947b2f02656 # v2
id: changelog_reader
with:
version: ${{ github.ref_name }}
- name: Create GitHub release
uses: ncipollo/release-action@339a81892b84b4eeb0f6e744e4574d79d0d9b8dd # v1
with:
name: CommaFeed ${{ github.ref_name }}
body: ${{ steps.changelog_reader.outputs.changes }}
artifacts: ./artifacts/*
update-dockerhub-description:
runs-on: ubuntu-latest
needs: release
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 0
- name: Update Docker Hub Description
uses: peter-evans/dockerhub-description@1b9a80c056b620d92cedb9d9b5a223409c68ddfa # v5
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
repository: athou/commafeed
short-description: ${{ github.event.repository.description }}
readme-filepath: commafeed-server/src/main/docker/README.md
deploy-pages:
runs-on: ubuntu-latest
needs: release
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4
id: deployment

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.
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
wrapperVersion=3.3.4
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.14/apache-maven-3.9.14-bin.zip

View File

@@ -1,383 +1,552 @@
# Changelog
## [5.0.0]
CommaFeed is now powered by Quarkus instead of Dropwizard. Read the rationale behind this change in
the [announcement](https://github.com/Athou/commafeed/discussions/1517).
The gist of it is that CommaFeed can now be compiled to a native binary, resulting in blazing fast startup times (around
0.3s) and very low memory footprint (< 50M).
- CommaFeed now has a different package for each supported database.
- If you are deploying CommaFeed with a precompiled package, please
read [this section of the README](https://github.com/Athou/commafeed/tree/master?tab=readme-ov-file#download-a-precompiled-package).
- If you are building CommaFeed from sources, please
read [this section of the README](https://github.com/Athou/commafeed/tree/master?tab=readme-ov-file#build-from-sources).
- If you are using the Docker image, please read the instructions on
the [Docker Hub page](https://hub.docker.com/r/athou/commafeed).
- Due to the switch to Quarkus, the way CommaFeed is configured is very different (the `config.yml` file is gone).
Please
read [this section of the README](https://github.com/Athou/commafeed/tree/master?tab=readme-ov-file#configuration).
Note that a lot of configuration elements have been removed or renamed and are now nested/grouped by feature.
- Added a setting to prevent parsing large feeds to avoid out of memory errors. The default is 5MB.
- Use a different icon for filtering unread entries and marking an entry as read (#1506)
- Added various HTML attributes to ease custom JS/CSS customization (#1507)
- The Redis cache has been removed. There have been multiple enhancements to the feed refresh engine and it is no longer
needed, even for instances with a large number of feeds.
- The H2 migration tool that automatically upgrades H2 databases from format 2 to 3 has been removed. If you're using
the H2 embedded database, please upgrade to at least version 4.3.0 before upgrading to CommaFeed 5.0.0.
## [4.6.0]
- switched from Temurin to OpenJ9 as the JVM used in the Docker image, resulting in memory usage reduction by up to 50%
- fix an issue that could cause old entries to reappear if they were updated by their author (#1486)
- show all entries regardless of their read status when searching with keywords, even if the ui is configured to show
unread entries only
## [4.5.0]
- significantly reduce the time needed to retrieve entries or mark them as read, especially when there are a lot of
entries (#1452)
- fix a race condition where a feed could be refreshed before it was created in the database
- fix an issue that could cause the websocket notification to contain the wrong number of unread entries when using
mysql/mariadb
- fix an error when trying to mark all starred entries as read
- remove the `onlyIds` parameter from REST endpoints since retrieving all the entries is now just as fast
- remove support for microsoft sqlserver because it's not covered with integration tests (please open an issue if you'd
like it back)
## [4.4.1]
- fix vertical scrolling issues with Safari (#1168)
- the default value for new users for the "star entry" button and the "open in new tab" button in the entry headers is
now "on desktop" instead of "always"
- the "keyboard shortcuts" help page now shows "Cmd" instead of "Ctrl" on macOS (#1389)
- remove a superfluous feed fetch when subscribing to a feed (#1431)
- the Docker image now uses Java 21
## [4.4.0]
- add support for sharing using the browser native capabilities if available (#1255)
- add a button in the entry headers to star an entry (#1025)
- add a button in the entry headers to open links in a new tab (#1333)
- add two options in the settings to toggle those buttons
- accept .opml file extension when importing and export with the .opml extension
- the "mark as read" option is no longer shown in the context menu for entries that are too old to be marked as read (
older than `keepStatusDays`) (#1303)
## [4.3.3]
- fix OPML import (#1279)
## [4.3.2]
- added support for unix sockets (#1278)
## [4.3.1]
- fix an issue that prevents new feeds from being added when mysql/mariadb is used as the database and the database
timezone is not UTC (#1239)
- videos in enclosures can no longer have a width larger than the page (#1240)
## [4.3.0]
- h2 (the embedded database) has been upgraded to 2.2.224
- this version uses a different file format than 2.1.x, the first time you start CommaFeed with this version, the
database will be automatically converted to the new format
- add a setting to completely disable scrolling to selected entry (#1157)
- add a css class reflecting the current view mode to ease custom css rules (#1232)
- fix an issue that prevents new feeds from being added when mysql/mariadb is used as the database (#1239)
## [4.2.1]
- fix an issue that caused the tree to show an incorrect unread count after a websocket notification because entries
that were already marked as read by a filtering expression were not ignored (#1191)
## [4.2.0]
- add a setting to display the action buttons in the footer instead of in the header on mobile (#1121)
- the websocket notification now contains everything needed to update the UI, the client no longer needs to make an API
call to get the latest data when receiving the notification
- add a workaround to the Fever API for the Unread iOS app (#1188)
- fix an issue that caused dates to be saved incorrectly if the database server and the application server were in
different timezones (#1187)
## [4.1.0]
- it is now possible to open the sidebar on mobile by swiping to the right (#1098)
- swiping to mark entries as read/unread changed from swiping right to left because swiping right now opens the sidebar
- the full hierarchy of categories are now displayed in the category dropdown (#1045)
- added a setting `maxEntriesAgeDays` to delete old entries based on their age during database cleanup.
The setting is disabled by default for existing installations, except for the docker image where it is enabled and set
to 365 days
- if user registrations are disabled on your instance which is the default behavior, users are redirected on the login
page instead of the welcome page when not logged in (#1185)
- the sidebar resizer is no longer shown in the middle of the screen on mobile
- when using the system color scheme and the system is using a dark theme, feed entries no longer flicker on load
- the demo account (if enabled) cannot register custom javascript code anymore
- removed the usage of `toSorted` in the client because older browsers do not support it (#1183)
- the openapi documentation is no longer cached by the browser so you always have access to the latest version
- added a memory management section to the readme, reading it is recommended if you are running CommaFeed on a server
with limited memory
- fixed an issue that caused users without an email address set to be unable to edit their profile (#1184)
## [4.0.0]
- migrated from dropwizard 2 to dropwizard 4, Java 17+ is now required
- entries that were fetched and inserted in the database but not yet shown in the UI are no longer marked as read when
marking all entries as read
- your custom sidebar width is now persisted in the local storage of your browser
- there is now a third color scheme option in addition to light and dark: system (follows the system color scheme)
- added support for youtube playlist favicons
- custom JS code is now executed when the app is done loading instead of when the page is loaded
- the favicon is now correctly returned for feeds that return an invalid content type
- the feed refresh engine now uses httpclient5 with connection pooling and no longer creates a new client for each
request, reducing CPU usage
- updated UI library Mantine to 7.0, improving performance
- the h2 embedded database is now compacted on shutdown to reclaim unused space
- the admin connector on port 8084 is now disabled in config.yml.example. Disabling it in your config.yml is
recommended (see https://github.com/Athou/commafeed/commit/929df60f09cce56020b0962ab111cd8349b271b0)
- migrated documentation from swagger 2 to openapi 3
- added a GET method to the fever api to indicate that the endpoint is working correctly when accessed from a browser
- the websocket connection can now be disabled, the websocket ping interval and the tree reload interval can now be
configured (see config.yml.example)
- the websocket connection now works correctly when the context root of the application is not "/"
- unstable pubsubhubbub support was removed
## [3.10.1]
- swap next and previous buttons (#1159)
- unread count for subscriptions will now be shortened starting at 10k instead of 1k
- increased websocket ping interval to just under a minute to reduce data and battery usage on mobile
- only refresh subscription tree on a timer if websocket connection is unavailable
- the Docker image now uses less memory by returning unused memory to the OS
- add support for Java 21
## [3.10.0]
- added a Fever-compatible API that is usable with mobile clients that support the Fever API (see instructions in
Settings -> Profile)
- long entry titles are no longer shortened in the detailed view
- added the "s" keyboard shortcut to star/unstar entries
- http sessions are now stored in the database (they were stored on disk before)
- fixed an issue that made it impossible to override the database url in a config.yml mounted in the Docker image
## [3.9.0]
- improve performance by disabling the loader when nothing is loading (most noticeable on mobile)
- added a setting to disable the 'mark all as read' confirmation
- added a setting to disable the custom context menu
- if the custom context is enabled, it can still be disabled by pressing the shift key
- the announcement feature is now working again and supports html ('announcement' configuration element in config.yml)
- add support for MariaDB 11+
- fix entry header shortly rendered as mobile on desktop, causing a small visual glitch
- fix an issue that could cause a feed to not refresh correctly if the url was very long
- database cleanup batch size is now configurable
- css parsing errors are no longer logged to the standard output
- fix small errors in the api documentation
## [3.8.1]
- in expanded mode, don't scroll when clicking on the body of the current entry
- improve content cleanup task performance for instances with a very large number of feeds
## [3.8.0]
- add previous and next buttons in the toolbar
- add a setting to always scroll selected entry to the top of the page, even if it fits entirely on screen
- clicking on the body of an entry in expanded mode selects it and marks it as read
- add rich text editor with autocomplete for custom css and js code in settings (desktop only)
- dramatically improve performance while scrolling
- fix broken welcome page mobile layout
- format dates in user locale instead of GMT in relative date popups
## [3.7.0]
- the sidebar is now resizable
- added the "f" keyboard shortcut to hide the sidebar
- added tooltips to relative dates with the exact date
- add a setting to hide commafeed from search engines (exposes a robots.txt file, enabled by default)
- the browser extension unread count now updates when articles are marked as read/unread in the app
- The "b" keyboard shortcut now works as expected on Chrome but requires the browser extension to be installed
- dark mode has been disabled on the api documentation page as it was unreadable
- improvement to the feed refresh queuing logic when "heavy load" mode is enabled
- fix a bug that could prevent feeds and categories from being edited
## [3.6.0]
- add a button to open CommaFeed in a new tab and a button to open options when using the browser extension
- clicking on the entry title in expanded mode now opens the link instead of doing nothing
- add tooltips to buttons when the mobile layout is used on desktop
- redirect the user to the welcome page if the user was deleted from the database
- add link to api documentation on welcome page
- the unread count is now correctly updated when using the "/next" bookmarklet while redis cache is enabled
## [3.5.0]
- add compatibility with the new version of the CommaFeed browser extension
- disable pull-to-refresh on mobile as it messes with vertical scrolling
- add css classes to feed entries to help with custom css rules
- api documentation page no longer requires users to be authenticated
- add a setting to limit the number of feeds a user can subscribe to
- add a setting to disable strict password policy
- add feed refresh engine metrics
- fix redis timeouts
## [3.4.0]
- add support for arm64 docker images
- add divider to visually separate read-only information from form on the profile settings page
- reduce javascript bundle size by 30% by loading only the necessary translations
- add a standalone donate page with all ways to support CommaFeed
- fix an issue introduced in 3.1.0 that could make CommaFeed not refresh feeds as fast as before on instances with lots
of feeds
- fix alignment of icon with text for category tree nodes
- fix alignment of burger button with the rest of the header on mobile
## [3.3.2]
- restore entry selection indicator (left orange border) that was lost with the mantine 6.x upgrade (3.3.0)
- add dividers to visually separate read-only information from forms on feed and category details pages
- reduced javascript bundle size by 10%
## [3.3.1]
- fix long feed names not being shortened to respect tree max width
## [3.3.0]
- there are now database changes, rolling back to 2.x will no longer be possible
- restore support for user custom CSS rules
- add support for user custom JS code that will be executed on page load
## [3.2.0]
- restore the welcome page
- only apply hover effect for unread entries (same as commafeed v2)
- move notifications at the bottom of the screen
- always use https for sharing urls
- add support for redis ACLs
- transition to google analytics v4
## [3.1.0]
- add an even more compact layout
- restore hover effect from commafeed 2.x
- view mode (compact, expanded, ...) is now stored on the device so you can have a different view mode on desktop and
mobile
- fix for the "Illegal attempt to associate a collection with two open sessions." error
- feed fetching workflow is now orchestrated with rxjava, removing a lot of code
## [3.0.1]
- allow env variable substitution in config.yml
- e.g. having a custom config.yml file with `app.session.path=${SOME_ENV_VAR}` will substitute `SOME_ENV_VAR` with its
value
- allow env variable prefixed with `CF_` to override config.yml properties
- e.g. setting `CF_APP_ALLOWREGISTRATIONS=true` will set `app.allowRegistrations` to `true`
## [3.0.0]
- complete overhaul of the UI
- backend and frontend are now in separate maven modules
- no changes to the api or the database
- Docker images are now automatically built and available at https://hub.docker.com/r/athou/commafeed
## [2.6.0]
- add support for media content as a backup for missing content (useful for youtube feeds)
- correctly follow http error code 308 redirects
- fixed a bug that prevented users from deleting their account
- fixed a bug that made commafeed store entry contents multiple times
- fixed a bug that prevented the app to be used as an installed app on mobile devices if the context path of commafeed
was not "/"
- fixed a bug that prevented entries from being "marked as read older than xxx" for a feed that was just added
- removed support for google+ and readability as those services no longer exist
- removed support for deploying on openshift
- removed alphabetical sorting of entries because of really poor performance (title cannot be indexed)
- improve performance for instances with the heavy load setting enabled by preventing CommaFeed from fetching feeds from
users that did not log in for a long time
- various dependencies upgrades (notably dropwizard from 1.3 to 2.1)
- add support for mariadb
- add support for java17+ runtime
- various security improvements
## [2.5.0]
- unread count is now displayed in a favicon badge when supported
- the user agent string for the bot fetching feeds is now configurable
- feed parsing performance improvements
- support for java9+ runtime
- can now properly start from an empty postgresql database
## [2.4.0]
- users were not able to change password or delete account
- fix api key generation
- feed entries can now be sorted alphabetically
- fix facebook sharing
- fix layout on iOS
- postgresql driver update (fix for postgres 9.6)
- various internationalization fixes
- security fixes
## [2.3.0]
- dropwizard upgrade 0.9.1
- feed enclosures are hidden if they already displayed in the content
- fix youtube favicons
- various internationalization fixes
## [2.2.0]
- fix youtube and instagram favicon fetching
- mark as read filter was lost when a feed was rearranged with drag&drop
- feed entry categories are now displayed if available
- various performance and dependencies upgrades
- java8 is now required
## [2.1.0]
- dropwizard upgrade to 0.8.0
- you have to remove the "app.contextPath" setting from your yml file, you can optionally use
server.applicationContextPath instead
- new setting app.maxFeedCapacity for deleting old entries
- ability to set filtering expressions for subscriptions to automatically mark new entries as read based on title,
content, author or url.
- ability to use !keyword or -keyword to exclude a keyword from a search query
- facebook feeds now show user favicon instead of facebook favicon
- new dark theme 'nightsky'
## [2.0.3]
- internet explorer ajax cache workaround
- categories are now deletable again
- openshift support is back
- youtube feeds now show user favicon instead of youtube favicon
## [2.0.2]
- api using the api key is now working again
- context path is now configurable in config.yml (see app.contextPath in config.yml.example)
- fix login on firefox when fields are autofilled by the browser
- fix scrolling of subscriptions list on mobile
- user is now logged in after registration
- fix link to documentation on home page and about page
- fields autocomplete is disabled on the profile page
- users are able to delete their account again
- chinese and malaysian translation files are now correctly loaded
- software version in user-agent when fetching feeds is no longer hardcoded
- admin settings page is now read only, settings are configured in config.yml
- added link to metrics on the admin settings page
- Rome (rss library) upgrade to 1.5.0
## [2.0.1]
- the redis pool no longer throws an exception when it is unable to aquire a new connection
## [2.0.0]
- The backend has been completely rewritten using Dropwizard instead of TomEE, resulting in a lot less memory
consumption and better overall performances.
See the README on how to build CommaFeed from now on.
- CommaFeed should no longer fetch the same feed multiple times in a row
- Users can use their username or email to log in
# 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)
- Feeds with uppercase HTTP:// or HTTPS:// URLs are now correctly handled again
- The aarch64 native executable now also works on the Raspberry Pi 5 (#1795)
- Improve general performance of the UI by reducing the number of re-renders, especially when a lot of entries are displayed (#1087)
## [5.9.0]
- A lot of CSS classes have been added to the elements of the application to ease custom CSS rules (#1757)
- Added a link in the README to the [documentation](https://athou.github.io/commafeed/documentation/custom-css/) of the new CSS classes
- Static resources are now cached for much longer (#1782)
## [5.8.0]
- A color picker is now available on the settings page to change the orange accent of the application (#1598)
- A font size slider is now available to change the size of the text of feed entries (#1462)
- The "mark all as read" confirmation setting now also applies to the "shift+a" keyboard shortcut (#1744)
- CommaFeed wil try to match the language of the browser before defaulting to english (#1767)
- The default value for the number of entries to keep above the selected entry when scrolling is now 1 instead of 0 to match what other feed readers do
## [5.7.0]
- Add Shift+J/Shift+K keyboard shortcuts to navigate to the next/previous feed or category with unread entries (#1558)
- Add the referrer "no-referrer" meta to index.html (#1724)
- Load custom JS code when the app is done loading (#1724)
- Correctly handle feeds that return an unmodified Last-Modified header but a different ETag header (#1746)
- Restore gzip compression of responses that was accidentaly disabled since 5.0.0
- Fix tooltips not showing up in mobile view
- Fix the bookmarklet generator on the About page
## [5.6.1]
- Restore support for iframes in feed entries (#1688)
- There is now a package available for Arch Linux thanks to @dcelasun (#1691)
## [5.6.0]
- To better respect the bandwidth of feed owners, the default value of `commafeed.feed-refresh.interval-empirical` is now true. This means feeds no longer refresh exactly every 5 minutes (the default value of `commafeed.feed-refresh.interval`) but between 5 minutes and 4 hours (the default value of the new `commafeed.feed-refresh.max-interval` setting). The interval is calculated based on feed activity, so highly active feeds refresh more often (#1677)
- Many previously hardcoded values used in feed refresh interval calculation are now exposed as settings (#1677)
- Access to local addresses is now blocked to mitigate server-side request forgery (SSRF) attacks, which could potentially expose internal resources. You might want to disable the new `commafeed.http-client.block-local-addresses` setting if you subscribe to feeds only available on your local network and you trust all your users
- If a feed responds with a "429 - Too many requests" response, a backoff mechanism is triggered when the response does not contain a "Retry-After" header
## [5.5.0]
- CommaFeed now honors the Retry-After response header and will not try to refresh a feed sooner than the value of this header
- Audio enclosures (e.g. podcasts) now fill available entry width
- Fix an issue with some labels not correctly internationalized
## [5.4.0]
- An arm64 native executable is now available for download on the releases page
- The native executable Docker image now supports arm64
- Fixed an issue with feeds that declared an invalid DOCTYPE (#1260)
## [5.3.6]
- Ignore invalid Cache-Control header values (#1619)
## [5.3.5]
- Fixed an issue with the aspect ratio of images of some feeds (#1595)
- CommaFeed now honors the Cache-Control response header and will not try to refresh a feed sooner than its max-age property (#1615)
- Added support for compilation with JDK 23+. If you're building CommaFeed from sources with a JDK 17 or 21, you may need to update it to the most recent patch version to support `-proc:full` (#1618)
## [5.3.4]
- Added support for Internationalized Domain Names (#1588)
## [5.3.3]
- Removed image bottom margins (#1587)
## [5.3.2]
- Fixed an issue that could cause some images from not being rendered correctly (#1587)
## [5.3.1]
- Fixed an issue that could cause some HTTP feeds to return a 400 error (#1572)
## [5.3.0]
- Added a setting to set a cooldown on the "fetch all my feeds" action, disabled by default (#1556)
- Fixed an issue that could cause entries to not correctly load when using the "next" header button (#1557)
## [5.2.0]
- Added an option to keep a number of entries above the selected entry when scrolling
- Added a cache to the HTTP client to reduce the number of requests made to feeds when subscribing (#1431)
- Feeds are no longer refreshed between the moment its last user unsubscribes and the moment the feed is cleaned up (every hour)
- Fixed an issue that could cause entries to not correctly load when using keyboard navigation (#1557)
## [5.1.1]
- Fixed database migration issue when upgrading from 5.0.0 to 5.1.0 on MariaDB (#1544)
- When feeds without unread entries are hidden from the tree, the feed is displayed in the tree until another one is selected (#1543)
## [5.1.0]
- Added a setting for showing/hiding unread count in the browser's tab title/favicon (#1518)
- Fixed an issue that could prevent the app from starting on some systems (#1532)
- Added a cache busting filter for the webapp index.html and openapi documentation to make sure they are always up to date
- Reduced database cleanup log verbosity
## [5.0.2]
- Fix favicon fetching for Youtube channels in native mode when Google auth key is set
- Fix an error that appears in the logs when fetching some favicons
## [5.0.1]
- Configure native compilation to support older CPU architectures (#1524)
## [5.0.0]
CommaFeed is now powered by Quarkus instead of Dropwizard. Read the rationale behind this change in
the [announcement](https://github.com/Athou/commafeed/discussions/1517).
The gist of it is that CommaFeed can now be compiled to a native binary, resulting in blazing fast startup times (around
0.3s) and very low memory footprint (< 50M).
- CommaFeed now has a different package for each supported database.
- If you are deploying CommaFeed with a precompiled package, please
read [this section of the README](https://github.com/Athou/commafeed/tree/master?tab=readme-ov-file#download-a-precompiled-package).
- If you are building CommaFeed from sources, please
read [this section of the README](https://github.com/Athou/commafeed/tree/master?tab=readme-ov-file#build-from-sources).
- If you are using the Docker image, please read the instructions on
the [Docker Hub page](https://hub.docker.com/r/athou/commafeed).
- Due to the switch to Quarkus, the way CommaFeed is configured is very different (the `config.yml` file is gone).
Please
read [this section of the README](https://github.com/Athou/commafeed/tree/master?tab=readme-ov-file#configuration).
Note that a lot of configuration elements have been removed or renamed and are now nested/grouped by feature.
- Added a setting to prevent parsing large feeds to avoid out of memory errors. The default is 5MB.
- Use a different icon for filtering unread entries and marking an entry as read (#1506)
- Added various HTML attributes to ease custom JS/CSS customization (#1507)
- The Redis cache has been removed. There have been multiple enhancements to the feed refresh engine and it is no longer
needed, even for instances with a large number of feeds.
- The H2 migration tool that automatically upgrades H2 databases from format 2 to 3 has been removed. If you're using
the H2 embedded database, please upgrade to at least version 4.3.0 before upgrading to CommaFeed 5.0.0.
## [4.6.0]
- switched from Temurin to OpenJ9 as the JVM used in the Docker image, resulting in memory usage reduction by up to 50%
- fix an issue that could cause old entries to reappear if they were updated by their author (#1486)
- show all entries regardless of their read status when searching with keywords, even if the ui is configured to show
unread entries only
## [4.5.0]
- significantly reduce the time needed to retrieve entries or mark them as read, especially when there are a lot of
entries (#1452)
- fix a race condition where a feed could be refreshed before it was created in the database
- fix an issue that could cause the websocket notification to contain the wrong number of unread entries when using
mysql/mariadb
- fix an error when trying to mark all starred entries as read
- remove the `onlyIds` parameter from REST endpoints since retrieving all the entries is now just as fast
- remove support for microsoft sqlserver because it's not covered with integration tests (please open an issue if you'd
like it back)
## [4.4.1]
- fix vertical scrolling issues with Safari (#1168)
- the default value for new users for the "star entry" button and the "open in new tab" button in the entry headers is
now "on desktop" instead of "always"
- the "keyboard shortcuts" help page now shows "Cmd" instead of "Ctrl" on macOS (#1389)
- remove a superfluous feed fetch when subscribing to a feed (#1431)
- the Docker image now uses Java 21
## [4.4.0]
- add support for sharing using the browser native capabilities if available (#1255)
- add a button in the entry headers to star an entry (#1025)
- add a button in the entry headers to open links in a new tab (#1333)
- add two options in the settings to toggle those buttons
- accept .opml file extension when importing and export with the .opml extension
- the "mark as read" option is no longer shown in the context menu for entries that are too old to be marked as read (
older than `keepStatusDays`) (#1303)
## [4.3.3]
- fix OPML import (#1279)
## [4.3.2]
- added support for unix sockets (#1278)
## [4.3.1]
- fix an issue that prevents new feeds from being added when mysql/mariadb is used as the database and the database
timezone is not UTC (#1239)
- videos in enclosures can no longer have a width larger than the page (#1240)
## [4.3.0]
- h2 (the embedded database) has been upgraded to 2.2.224
- this version uses a different file format than 2.1.x, the first time you start CommaFeed with this version, the
database will be automatically converted to the new format
- add a setting to completely disable scrolling to selected entry (#1157)
- add a css class reflecting the current view mode to ease custom css rules (#1232)
- fix an issue that prevents new feeds from being added when mysql/mariadb is used as the database (#1239)
## [4.2.1]
- fix an issue that caused the tree to show an incorrect unread count after a websocket notification because entries
that were already marked as read by a filtering expression were not ignored (#1191)
## [4.2.0]
- add a setting to display the action buttons in the footer instead of in the header on mobile (#1121)
- the websocket notification now contains everything needed to update the UI, the client no longer needs to make an API
call to get the latest data when receiving the notification
- add a workaround to the Fever API for the Unread iOS app (#1188)
- fix an issue that caused dates to be saved incorrectly if the database server and the application server were in
different timezones (#1187)
## [4.1.0]
- it is now possible to open the sidebar on mobile by swiping to the right (#1098)
- swiping to mark entries as read/unread changed from swiping right to left because swiping right now opens the sidebar
- the full hierarchy of categories are now displayed in the category dropdown (#1045)
- added a setting `maxEntriesAgeDays` to delete old entries based on their age during database cleanup.
The setting is disabled by default for existing installations, except for the docker image where it is enabled and set
to 365 days
- if user registrations are disabled on your instance which is the default behavior, users are redirected on the login
page instead of the welcome page when not logged in (#1185)
- the sidebar resizer is no longer shown in the middle of the screen on mobile
- when using the system color scheme and the system is using a dark theme, feed entries no longer flicker on load
- the demo account (if enabled) cannot register custom javascript code anymore
- removed the usage of `toSorted` in the client because older browsers do not support it (#1183)
- the openapi documentation is no longer cached by the browser so you always have access to the latest version
- added a memory management section to the readme, reading it is recommended if you are running CommaFeed on a server
with limited memory
- fixed an issue that caused users without an email address set to be unable to edit their profile (#1184)
## [4.0.0]
- migrated from dropwizard 2 to dropwizard 4, Java 17+ is now required
- entries that were fetched and inserted in the database but not yet shown in the UI are no longer marked as read when
marking all entries as read
- your custom sidebar width is now persisted in the local storage of your browser
- there is now a third color scheme option in addition to light and dark: system (follows the system color scheme)
- added support for youtube playlist favicons
- custom JS code is now executed when the app is done loading instead of when the page is loaded
- the favicon is now correctly returned for feeds that return an invalid content type
- the feed refresh engine now uses httpclient5 with connection pooling and no longer creates a new client for each
request, reducing CPU usage
- updated UI library Mantine to 7.0, improving performance
- the h2 embedded database is now compacted on shutdown to reclaim unused space
- the admin connector on port 8084 is now disabled in config.yml.example. Disabling it in your config.yml is
recommended (see https://github.com/Athou/commafeed/commit/929df60f09cce56020b0962ab111cd8349b271b0)
- migrated documentation from swagger 2 to openapi 3
- added a GET method to the fever api to indicate that the endpoint is working correctly when accessed from a browser
- the websocket connection can now be disabled, the websocket ping interval and the tree reload interval can now be
configured (see config.yml.example)
- the websocket connection now works correctly when the context root of the application is not "/"
- unstable pubsubhubbub support was removed
## [3.10.1]
- swap next and previous buttons (#1159)
- unread count for subscriptions will now be shortened starting at 10k instead of 1k
- increased websocket ping interval to just under a minute to reduce data and battery usage on mobile
- only refresh subscription tree on a timer if websocket connection is unavailable
- the Docker image now uses less memory by returning unused memory to the OS
- add support for Java 21
## [3.10.0]
- added a Fever-compatible API that is usable with mobile clients that support the Fever API (see instructions in
Settings -> Profile)
- long entry titles are no longer shortened in the detailed view
- added the "s" keyboard shortcut to star/unstar entries
- http sessions are now stored in the database (they were stored on disk before)
- fixed an issue that made it impossible to override the database url in a config.yml mounted in the Docker image
## [3.9.0]
- improve performance by disabling the loader when nothing is loading (most noticeable on mobile)
- added a setting to disable the 'mark all as read' confirmation
- added a setting to disable the custom context menu
- if the custom context is enabled, it can still be disabled by pressing the shift key
- the announcement feature is now working again and supports html ('announcement' configuration element in config.yml)
- add support for MariaDB 11+
- fix entry header shortly rendered as mobile on desktop, causing a small visual glitch
- fix an issue that could cause a feed to not refresh correctly if the url was very long
- database cleanup batch size is now configurable
- css parsing errors are no longer logged to the standard output
- fix small errors in the api documentation
## [3.8.1]
- in expanded mode, don't scroll when clicking on the body of the current entry
- improve content cleanup task performance for instances with a very large number of feeds
## [3.8.0]
- add previous and next buttons in the toolbar
- add a setting to always scroll selected entry to the top of the page, even if it fits entirely on screen
- clicking on the body of an entry in expanded mode selects it and marks it as read
- add rich text editor with autocomplete for custom css and js code in settings (desktop only)
- dramatically improve performance while scrolling
- fix broken welcome page mobile layout
- format dates in user locale instead of GMT in relative date popups
## [3.7.0]
- the sidebar is now resizable
- added the "f" keyboard shortcut to hide the sidebar
- added tooltips to relative dates with the exact date
- add a setting to hide commafeed from search engines (exposes a robots.txt file, enabled by default)
- the browser extension unread count now updates when articles are marked as read/unread in the app
- The "b" keyboard shortcut now works as expected on Chrome but requires the browser extension to be installed
- dark mode has been disabled on the api documentation page as it was unreadable
- improvement to the feed refresh queuing logic when "heavy load" mode is enabled
- fix a bug that could prevent feeds and categories from being edited
## [3.6.0]
- add a button to open CommaFeed in a new tab and a button to open options when using the browser extension
- clicking on the entry title in expanded mode now opens the link instead of doing nothing
- add tooltips to buttons when the mobile layout is used on desktop
- redirect the user to the welcome page if the user was deleted from the database
- add link to api documentation on welcome page
- the unread count is now correctly updated when using the "/next" bookmarklet while redis cache is enabled
## [3.5.0]
- add compatibility with the new version of the CommaFeed browser extension
- disable pull-to-refresh on mobile as it messes with vertical scrolling
- add css classes to feed entries to help with custom css rules
- api documentation page no longer requires users to be authenticated
- add a setting to limit the number of feeds a user can subscribe to
- add a setting to disable strict password policy
- add feed refresh engine metrics
- fix redis timeouts
## [3.4.0]
- add support for arm64 docker images
- add divider to visually separate read-only information from form on the profile settings page
- reduce javascript bundle size by 30% by loading only the necessary translations
- add a standalone donate page with all ways to support CommaFeed
- fix an issue introduced in 3.1.0 that could make CommaFeed not refresh feeds as fast as before on instances with lots
of feeds
- fix alignment of icon with text for category tree nodes
- fix alignment of burger button with the rest of the header on mobile
## [3.3.2]
- restore entry selection indicator (left orange border) that was lost with the mantine 6.x upgrade (3.3.0)
- add dividers to visually separate read-only information from forms on feed and category details pages
- reduced javascript bundle size by 10%
## [3.3.1]
- fix long feed names not being shortened to respect tree max width
## [3.3.0]
- there are now database changes, rolling back to 2.x will no longer be possible
- restore support for user custom CSS rules
- add support for user custom JS code that will be executed on page load
## [3.2.0]
- restore the welcome page
- only apply hover effect for unread entries (same as commafeed v2)
- move notifications at the bottom of the screen
- always use https for sharing urls
- add support for redis ACLs
- transition to google analytics v4
## [3.1.0]
- add an even more compact layout
- restore hover effect from commafeed 2.x
- view mode (compact, expanded, ...) is now stored on the device so you can have a different view mode on desktop and
mobile
- fix for the "Illegal attempt to associate a collection with two open sessions." error
- feed fetching workflow is now orchestrated with rxjava, removing a lot of code
## [3.0.1]
- allow env variable substitution in config.yml
- e.g. having a custom config.yml file with `app.session.path=${SOME_ENV_VAR}` will substitute `SOME_ENV_VAR` with its
value
- allow env variable prefixed with `CF_` to override config.yml properties
- e.g. setting `CF_APP_ALLOWREGISTRATIONS=true` will set `app.allowRegistrations` to `true`
## [3.0.0]
- complete overhaul of the UI
- backend and frontend are now in separate maven modules
- no changes to the api or the database
- Docker images are now automatically built and available at https://hub.docker.com/r/athou/commafeed
## [2.6.0]
- add support for media content as a backup for missing content (useful for youtube feeds)
- correctly follow http error code 308 redirects
- fixed a bug that prevented users from deleting their account
- fixed a bug that made commafeed store entry contents multiple times
- fixed a bug that prevented the app to be used as an installed app on mobile devices if the context path of commafeed
was not "/"
- fixed a bug that prevented entries from being "marked as read older than xxx" for a feed that was just added
- removed support for google+ and readability as those services no longer exist
- removed support for deploying on openshift
- removed alphabetical sorting of entries because of really poor performance (title cannot be indexed)
- improve performance for instances with the heavy load setting enabled by preventing CommaFeed from fetching feeds from
users that did not log in for a long time
- various dependencies upgrades (notably dropwizard from 1.3 to 2.1)
- add support for mariadb
- add support for java17+ runtime
- various security improvements
## [2.5.0]
- unread count is now displayed in a favicon badge when supported
- the user agent string for the bot fetching feeds is now configurable
- feed parsing performance improvements
- support for java9+ runtime
- can now properly start from an empty postgresql database
## [2.4.0]
- users were not able to change password or delete account
- fix api key generation
- feed entries can now be sorted alphabetically
- fix facebook sharing
- fix layout on iOS
- postgresql driver update (fix for postgres 9.6)
- various internationalization fixes
- security fixes
## [2.3.0]
- dropwizard upgrade 0.9.1
- feed enclosures are hidden if they already displayed in the content
- fix youtube favicons
- various internationalization fixes
## [2.2.0]
- fix youtube and instagram favicon fetching
- mark as read filter was lost when a feed was rearranged with drag&drop
- feed entry categories are now displayed if available
- various performance and dependencies upgrades
- java8 is now required
## [2.1.0]
- dropwizard upgrade to 0.8.0
- you have to remove the "app.contextPath" setting from your yml file, you can optionally use
server.applicationContextPath instead
- new setting app.maxFeedCapacity for deleting old entries
- ability to set filtering expressions for subscriptions to automatically mark new entries as read based on title,
content, author or url.
- ability to use !keyword or -keyword to exclude a keyword from a search query
- facebook feeds now show user favicon instead of facebook favicon
- new dark theme 'nightsky'
## [2.0.3]
- internet explorer ajax cache workaround
- categories are now deletable again
- openshift support is back
- youtube feeds now show user favicon instead of youtube favicon
## [2.0.2]
- api using the api key is now working again
- context path is now configurable in config.yml (see app.contextPath in config.yml.example)
- fix login on firefox when fields are autofilled by the browser
- fix scrolling of subscriptions list on mobile
- user is now logged in after registration
- fix link to documentation on home page and about page
- fields autocomplete is disabled on the profile page
- users are able to delete their account again
- chinese and malaysian translation files are now correctly loaded
- software version in user-agent when fetching feeds is no longer hardcoded
- admin settings page is now read only, settings are configured in config.yml
- added link to metrics on the admin settings page
- Rome (rss library) upgrade to 1.5.0
## [2.0.1]
- the redis pool no longer throws an exception when it is unable to aquire a new connection
## [2.0.0]
- The backend has been completely rewritten using Dropwizard instead of TomEE, resulting in a lot less memory
consumption and better overall performances.
See the README on how to build CommaFeed from now on.
- CommaFeed should no longer fetch the same feed multiple times in a row
- Users can use their username or email to log in

60
LICENSE
View File

@@ -1,31 +1,31 @@
Apache License, Version 2.0 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
2. Grant of Copyright License.
Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License.
Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
4. Redistribution.
You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of this License; and You must cause any modified files to carry prominent notices stating that You changed the files; and You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
5. Submission of Contributions.
Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
6. Trademarks.
This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty.
Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
8. Limitation of Liability.
In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability.
While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
Apache License, Version 2.0 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
2. Grant of Copyright License.
Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License.
Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
4. Redistribution.
You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of this License; and You must cause any modified files to carry prominent notices stating that You changed the files; and You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
5. Submission of Contributions.
Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
6. Trademarks.
This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty.
Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
8. Limitation of Liability.
In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability.
While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

22
README-fork.md Normal file
View File

@@ -0,0 +1,22 @@
# `garrettmills/commafeed`
This is my personal fork of `Athou/commafeed` with some tweaks:
- "Infrequent" tab - like "All" but limits to blogs w/ an average post interval greater than a user-configurable number of days
- User preference to disable the swipe-to-open-menu gesture on mobile
## Building
Use `gmfork-build-docker.sh` to build the JVM Docker image for `linux/amd64`:
You can use the `DB_VARIANT` env var to change which DB the image builds with. By default, it builds the `postgresql` variant.
```sh
DOCKER_REGISTRY=myregistry.example.com DB_VARIANT=h2 ./gmfork-build-docker.sh
```
To run locally:
```sh
docker run -p 8082:8082 $DOCKER_REGISTRY/commafeed-fork:latest
```

View File

@@ -17,6 +17,8 @@ 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
- Supports 4 databases
@@ -25,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
@@ -48,17 +57,17 @@ system and database of choice.
There are two types of packages:
- The `linux-x86_64` and `windows-x86_64` packages are compiled natively and contain an executable that can be run
- The `linux-x86_64`, `linux-aarch_64` and `windows-x86_64` packages are compiled natively and contain an executable that can be run
directly.
- The `jvm` package is a zip file containing all `.jar` files required to run the application. This package works on all
platforms and is started with `java -jar quarkus-run.jar`.
platforms but requires a JRE and is started with `java -jar quarkus-run.jar`.
If available for your operating system, the native package is recommended because it has a faster startup time and lower
memory usage.
### Build from sources
./mvnw clean package [-P<database>] [-Pnative] [-DskipTests]
./mvnw clean package [-P<database> [-Pnative]] [-DskipTests]
- `<database>` can be one of `h2`, `postgresql`, `mysql` or `mariadb`. The default is `h2`.
- `-Pnative` compiles the application to native code. This requires GraalVM to be installed (`GRAALVM_HOME` environment
@@ -73,6 +82,10 @@ When the build is complete:
- if you used the native profile, the executable is located at
`commafeed-server/target/commafeed-<version>-<database>-<platform>-<arch>-runner[.exe]`
### Distribution packages
- Arch Linux users can use [the CommaFeed package on AUR](https://aur.archlinux.org/pkgbase/commafeed), which builds native binaries with GraalVM for all supported databases.
## Configuration
CommaFeed doesn't require any configuration to run with its embedded database (H2). The database file will be stored in
@@ -80,7 +93,7 @@ the `data` directory of the current directory.
To use a different database, you will need to configure the following properties:
- `quarkus.datasource.jdbc-url`
- `quarkus.datasource.jdbc.url`
- e.g. for H2: `jdbc:h2:./data/db;DEFRAG_ALWAYS=TRUE`
- e.g. for PostgreSQL: `jdbc:postgresql://localhost:5432/commafeed`
- e.g. for MySQL:
@@ -92,35 +105,39 @@ To use a different database, you will need to configure the following properties
There are multiple ways to configure CommaFeed:
- a [properties](https://en.wikipedia.org/wiki/.properties) file in `config/application.properties` (keys in kebab-case)
- Command line arguments prefixed with `-D` (keys in kebab-case)
- a `config/application.properties` [properties](https://en.wikipedia.org/wiki/.properties) file relative to the working
directory (keys in kebab-case)
- Command line arguments each prefixed with `-D` (keys in kebab-case)
- Environment variables (keys in UPPER_CASE)
- an .env file in the working directory (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.
When logging in, credentials are stored in an encrypted cookie. The encryption key is randomly generated at startup,
meaning that you will have to log back in after each restart of the application. To prevent this, you can set the
`quarkus.http.auth.session.encryption-key` property to a fixed value (min. 16 characters).
All [CommaFeed settings](commafeed-server/src/main/java/com/commafeed/CommaFeedConfiguration.java)
are optional and have sensible default values.
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`.
### Memory management (`jvm` package only)
### Updates
When CommaFeed is up and running, you can subscribe to [this feed](https://github.com/Athou/commafeed/releases.atom) to be notified of new releases.
### Memory management
The Java Virtual Machine (JVM) is rather greedy by default and will not release unused memory to the
operating system. This is because acquiring memory from the operating system is a relatively expensive operation.
This can be problematic on systems with limited memory.
#### Hard limit
#### Hard limit (`native` and `jvm` packages)
The JVM can be configured to use a maximum amount of memory with the `-Xmx` parameter.
For example, to limit the JVM to 256MB of memory, use `-Xmx256m`.
#### Dynamic sizing
#### Dynamic sizing (`jvm` package)
In addition to the previous setting, the JVM can be configured to release unused memory to the operating system with the
following parameters:
@@ -132,14 +149,15 @@ and [here](https://docs.oracle.com/en/java/javase/17/gctuning/factors-affecting-
more
information.
#### OpenJ9
#### OpenJ9 (`jvm` package)
The [OpenJ9](https://eclipse.dev/openj9/) JVM is a more memory-efficient alternative to the HotSpot JVM, at the cost of
slightly slower throughput.
IBM provides precompiled binaries for OpenJ9
named [Semeru](https://developer.ibm.com/languages/java/semeru-runtimes/downloads/).
This is the JVM used in the [Docker image](https://github.com/Athou/commafeed/blob/master/Dockerfile).
This is the JVM used in
the [Docker image](https://github.com/Athou/commafeed/blob/master/commafeed-server/src/main/docker/Dockerfile.jvm).
## Translation

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.8.3/schema.json",
"$schema": "https://biomejs.dev/schemas/2.4.7/schema.json",
"formatter": {
"indentStyle": "space",
"indentWidth": 4,
@@ -14,6 +14,6 @@
}
},
"files": {
"ignore": ["dist", "node_modules", "target", "target-ide"]
"includes": ["**", "!**/dist", "!**/node_modules", "!**/target", "!**/target-ide"]
}
}

View File

@@ -1,11 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<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" />
<title>CommaFeed</title>
<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" />
<meta name="referrer" content="no-referrer" />
<title>CommaFeed</title>
</head>
<body>
<div id="root"></div>

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

@@ -4,76 +4,83 @@
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite --host",
"dev:typescript": "tsc --watch",
"dev": "vite",
"dev:host": "vite --host",
"build": "tsc && vite build",
"preview": "vite preview",
"test": "vitest",
"test:ci": "vitest run",
"lint": "biome check ./src",
"lint:fix": "biome check --write ./src",
"i18n:extract": "lingui extract --clean"
"lint": "biome check",
"lint:fix": "biome check --write",
"i18n:extract": "lingui extract --clean",
"prepare": "cd .. && husky ./commafeed-client/.husky"
},
"dependencies": {
"@emotion/react": "^11.13.0",
"@fontsource/open-sans": "^5.0.29",
"@lingui/core": "^4.11.3",
"@lingui/macro": "^4.11.3",
"@lingui/react": "^4.11.3",
"@mantine/core": "^7.12.1",
"@mantine/form": "^7.12.1",
"@mantine/hooks": "^7.12.1",
"@mantine/modals": "^7.12.1",
"@mantine/notifications": "^7.12.1",
"@mantine/spotlight": "^7.12.1",
"@monaco-editor/react": "^4.6.0",
"@reduxjs/toolkit": "^2.2.7",
"axios": "^1.7.4",
"dayjs": "^1.11.12",
"@emotion/react": "^11.14.0",
"@fontsource/open-sans": "^5.2.7",
"@lingui/core": "^5.9.3",
"@lingui/react": "^5.9.3",
"@mantine/core": "^8.3.16",
"@mantine/form": "^8.3.16",
"@mantine/hooks": "^8.3.16",
"@mantine/modals": "^8.3.16",
"@mantine/notifications": "^8.3.16",
"@mantine/spotlight": "^8.3.16",
"@monaco-editor/react": "^4.7.0",
"@react-querybuilder/mantine": "^8.14.0",
"@reduxjs/toolkit": "^2.11.2",
"@rolldown/plugin-babel": "^0.2.2",
"axios": "^1.13.6",
"dayjs": "^1.11.20",
"escape-string-regexp": "^5.0.0",
"interweave": "^13.1.0",
"monaco-editor": "^0.50.0",
"interweave": "^13.1.1",
"monaco-editor": "^0.55.1",
"mousetrap": "^1.6.5",
"react": "^18.3.1",
"react": "^19.2.4",
"react-async-hook": "^4.0.0",
"react-contexify": "^6.0.0",
"react-device-detect": "^2.2.3",
"react-dom": "^18.3.1",
"react-draggable": "^4.4.6",
"react-ga4": "^2.1.0",
"react-helmet": "^6.1.0",
"react-icons": "^5.2.1",
"react-dom": "^19.2.4",
"react-draggable": "^4.5.0",
"react-icons": "^5.6.0",
"react-infinite-scroller": "^1.2.6",
"react-redux": "^9.1.2",
"react-router-dom": "^6.26.1",
"react-swipeable": "^7.0.1",
"redoc": "^2.1.5",
"react-querybuilder": "^8.14.0",
"react-redux": "^9.2.0",
"react-router-dom": "^7.13.1",
"react-swipeable": "^7.0.2",
"style-to-object": "^1.0.14",
"throttle-debounce": "^5.0.2",
"tinycon": "^0.6.8",
"tss-react": "^4.9.12",
"use-local-storage": "^3.0.0",
"vite-plugin-biome": "^1.0.12",
"tss-react": "^4.9.20",
"websocket-heartbeat-js": "^1.1.3"
},
"devDependencies": {
"@biomejs/biome": "^1.8.3",
"@lingui/cli": "^4.11.3",
"@lingui/vite-plugin": "^4.11.3",
"@biomejs/biome": "^2.4.7",
"@lingui/babel-plugin-lingui-macro": "^5.9.3",
"@lingui/cli": "^5.9.3",
"@lingui/vite-plugin": "^5.9.3",
"@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": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@types/react-helmet": "^6.1.11",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@types/react-infinite-scroller": "^1.2.5",
"@types/swagger-ui-react": "^4.18.3",
"@types/throttle-debounce": "^5.0.2",
"@types/tinycon": "^0.6.5",
"@vitejs/plugin-react": "^4.3.1",
"babel-plugin-macros": "^3.1.0",
"rollup-plugin-visualizer": "^5.12.0",
"typescript": "^5.5.4",
"vite": "^5.4.1",
"vite-tsconfig-paths": "^5.0.1",
"vitest": "^2.0.5",
"vitest-mock-extended": "^2.0.0"
"@types/tinycon": "^0.6.7",
"@vitejs/plugin-react": "^6.0.1",
"babel-plugin-react-compiler": "1.0.0",
"husky": "^9.1.7",
"jsdom": "^29.0.0",
"lint-staged": "^16.4.0",
"typescript": "^5.9.3",
"vite": "^8.0.0",
"vite-plugin-checker": "^0.12.0",
"vitest": "^4.1.0",
"yaml": "^2.8.2"
},
"overrides": {
"react-infinite-scroller": {
"react": "^19.2.4"
}
}
}

View File

@@ -1,96 +1,142 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.commafeed</groupId>
<artifactId>commafeed</artifactId>
<version>5.0.0</version>
</parent>
<artifactId>commafeed-client</artifactId>
<name>CommaFeed Client</name>
<properties>
<!-- renovate: datasource=node-version depName=node -->
<node.version>v20.16.0</node.version>
<!-- renovate: datasource=npm depName=npm -->
<npm.version>10.8.2</npm.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.15.0</version>
<?m2e ignore?>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<phase>compile</phase>
<configuration>
<nodeVersion>${node.version}</nodeVersion>
<npmVersion>${npm.version}</npmVersion>
</configuration>
</execution>
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
<phase>compile</phase>
<configuration>
<arguments>ci</arguments>
</configuration>
</execution>
<execution>
<id>npm run test</id>
<goals>
<goal>npm</goal>
</goals>
<phase>compile</phase>
<configuration>
<arguments>run test:ci</arguments>
</configuration>
</execution>
<execution>
<id>npm run build</id>
<goals>
<goal>npm</goal>
</goals>
<phase>compile</phase>
<configuration>
<arguments>run build</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.3.1</version>
<executions>
<execution>
<id>copy web interface to resources</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/classes/META-INF/resources</outputDirectory>
<resources>
<resource>
<directory>dist</directory>
<filtering>false</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.commafeed</groupId>
<artifactId>commafeed</artifactId>
<version>7.0.0</version>
</parent>
<artifactId>commafeed-client</artifactId>
<name>CommaFeed Client</name>
<properties>
<!-- renovate: datasource=node-version depName=node -->
<node.version>v24.14.0</node.version>
<!-- renovate: datasource=npm depName=npm -->
<npm.version>11.11.1</npm.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>2.0.0</version>
<?m2e ignore?>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<phase>compile</phase>
<configuration>
<nodeVersion>${node.version}</nodeVersion>
<npmVersion>${npm.version}</npmVersion>
</configuration>
</execution>
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
<phase>compile</phase>
<configuration>
<arguments>ci</arguments>
</configuration>
</execution>
<execution>
<id>npm run test</id>
<goals>
<goal>npm</goal>
</goals>
<phase>compile</phase>
<configuration>
<arguments>run test:ci</arguments>
<skip>${skipTests}</skip>
</configuration>
</execution>
<execution>
<id>npm run build</id>
<goals>
<goal>npm</goal>
</goals>
<phase>compile</phase>
<configuration>
<arguments>run build</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<id>copy web interface to resources</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/classes/META-INF/resources</outputDirectory>
<resources>
<resource>
<directory>dist</directory>
<filtering>false</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<!-- This profile is used to kill the Biome process on Windows -->
<!-- npm ci can fail if Biome is running (e.g., in the IDE) because it locks some files -->
<profile>
<id>kill-biome</id>
<activation>
<os>
<family>Windows</family>
</os>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.6.3</version>
<executions>
<execution>
<id>kill-biome</id>
<phase>initialize</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>taskkill</executable>
<arguments>
<argument>/F</argument>
<argument>/IM</argument>
<argument>biome.exe</argument>
</arguments>
<successCodes>
<successCode>0</successCode>
<!-- taskkill returns 128 if the process is not found, which is fine in this case -->
<successCode>128</successCode>
</successCodes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

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,46 +3,53 @@ 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 { 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 } from "react"
import { isSafari } from "react-device-detect"
import ReactGA from "react-ga4"
import { Helmet } from "react-helmet"
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}>
<MantineProvider
defaultColorScheme="auto"
theme={{
primaryColor: "orange",
primaryColor: primaryColor,
fontFamily: "Open Sans",
colors: {
// keep using dark colors from mantine v6
@@ -71,9 +78,6 @@ function Providers(props: { children: React.ReactNode }) {
)
}
// swagger-ui 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)
@@ -81,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" />} />
@@ -112,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()
@@ -127,31 +144,26 @@ 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,
}: Readonly<{
enabled?: boolean
}>) {
const root = useAppSelector(state => state.tree.rootCategory)
const unreadCount = categoryUnreadCount(root)
return <title>{enabled && unreadCount > 0 ? `(${unreadCount}) CommaFeed` : "CommaFeed"}</title>
}
function FaviconHandler() {
function UnreadCountFaviconHandler({ enabled }: { enabled?: boolean }) {
const root = useAppSelector(state => state.tree.rootCategory)
const unreadCount = categoryUnreadCount(root)
useEffect(() => {
const unreadCount = categoryUnreadCount(root)
if (unreadCount === 0) {
Tinycon.reset()
} else {
if (enabled && unreadCount > 0) {
Tinycon.setBubble(unreadCount)
} else {
Tinycon.reset()
}
}, [root])
}, [unreadCount, enabled])
return null
}
@@ -168,17 +180,47 @@ function BrowserExtensionBadgeUnreadCountHandler() {
return null
}
function CustomCode() {
return (
<Helmet>
<link rel="stylesheet" type="text/css" href="custom_css.css" />
<script type="text/javascript" src="custom_js.js" />
</Helmet>
)
function CustomJsHandler() {
const [scriptLoaded, setScriptLoaded] = useState(false)
const { loading } = useAppLoading()
useEffect(() => {
if (scriptLoaded || loading) {
return
}
const script = document.createElement("script")
script.src = "custom_js.js"
script.async = true
document.body.appendChild(script)
setScriptLoaded(true)
return () => script.remove()
}, [scriptLoaded, loading])
return null
}
function CustomCssHandler() {
useEffect(() => {
const link = document.createElement("link")
link.rel = "stylesheet"
link.type = "text/css"
link.href = "custom_css.css"
document.head.appendChild(link)
return () => link.remove()
}, [])
return null
}
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(() => {
@@ -187,21 +229,18 @@ export function App() {
return (
<Providers>
<>
<FaviconHandler />
<BrowserExtensionBadgeUnreadCountHandler />
<HashRouter>
<GoogleAnalyticsHandler />
<RedirectHandler />
<AppRoutes />
<CustomCode />
{/* 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>
</>
<UnreadCountTitleHandler enabled={unreadCountTitle} />
<UnreadCountFaviconHandler enabled={unreadCountFavicon} />
<BrowserExtensionBadgeUnreadCountHandler />
<CustomJsHandler />
<CustomCssHandler />
<DisablePullToRefresh enabled={disablePullToRefresh} />
<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

@@ -1,13 +1,11 @@
import { t } from "@lingui/macro"
import type { IconType } from "react-icons"
import { FaAt } from "react-icons/fa"
import { SiBuffer, SiFacebook, SiGmail, SiInstapaper, SiPocket, SiTumblr, SiTwitter } from "react-icons/si"
import { SiBuffer, SiFacebook, SiGmail, SiInstapaper, SiPocket, SiTumblr, SiX } from "react-icons/si"
import type { Category, Entry, SharingSettings } from "./types"
const categories: Record<string, Category> = {
const categories: Record<string, Omit<Category, "name">> = {
all: {
id: "all",
name: t`All`,
expanded: false,
children: [],
feeds: [],
@@ -15,12 +13,18 @@ const categories: Record<string, Category> = {
},
starred: {
id: "starred",
name: t`Starred`,
expanded: false,
children: [],
feeds: [],
position: 1,
},
infrequent: {
id: "infrequent",
expanded: false,
children: [],
feeds: [],
position: 2,
},
}
const sharing: {
@@ -50,10 +54,10 @@ const sharing: {
url: url => `https://www.facebook.com/sharer/sharer.php?u=${url}`,
},
twitter: {
label: "Twitter",
icon: SiTwitter,
color: "#1D9BF0",
url: (url, desc) => `https://twitter.com/share?text=${desc}&url=${url}`,
label: "X",
icon: SiX,
color: "#000000",
url: (url, desc) => `https://x.com/share?text=${desc}&url=${url}`,
},
tumblr: {
label: "Tumblr",
@@ -90,23 +94,26 @@ 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,
},
theme: {
defaultPrimaryColor: "orange",
},
tooltip: {
delay: 500,
},
infrequentThresholdDaysDefault: 7,
browserExtensionUrl: "https://github.com/Athou/commafeed-browser-extension",
customCssDocumentationUrl: "https://athou.github.io/commafeed/documentation/custom-css",
bitcoinWalletAddress: "1dymfUxqCWpyD7a6rQSqNy4rLVDBsAr5e",
}

View File

@@ -1,25 +1,20 @@
import { configureStore } from "@reduxjs/toolkit"
import type { 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 { any, mockReset } from "vitest-mock-extended"
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"
const mockClient = await vi.hoisted(async () => {
const mockModule = await import("vitest-mock-extended")
return mockModule.mockDeep<typeof client>()
})
vi.mock("app/client", () => ({ client: mockClient }))
vi.mock(import("@/app/client"))
describe("entries", () => {
beforeEach(() => {
mockReset(mockClient)
vi.resetAllMocks()
})
it("loads entries", async () => {
mockClient.feed.getEntries.calledWith(any()).mockResolvedValue({
vi.mocked(client.feed.getEntries).mockResolvedValue({
data: {
entries: [{ id: "3" } as Entry],
hasMore: false,
@@ -32,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")
@@ -53,7 +53,7 @@ describe("entries", () => {
})
it("loads more entries", async () => {
mockClient.category.getEntries.calledWith(any()).mockResolvedValue({
vi.mocked(client.category.getEntries).mockResolvedValue({
data: {
entries: [{ id: "4" } as Entry],
hasMore: false,
@@ -113,7 +113,7 @@ describe("entries", () => {
{ id: "3", read: true },
{ id: "4", read: false },
])
expect(mockClient.entry.mark).toHaveBeenCalledWith({ id: "3", read: true })
expect(client.entry.mark).toHaveBeenCalledWith({ id: "3", read: true })
})
it("marks all entries as read", () => {
@@ -135,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(mockClient.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"
@@ -28,6 +28,7 @@ interface EntriesState {
loading: boolean
search?: string
scrollingToEntry: boolean
markAllAsReadConfirmationDialogOpen: boolean
}
const initialState: EntriesState = {
@@ -41,6 +42,7 @@ const initialState: EntriesState = {
hasMore: true,
loading: false,
scrollingToEntry: false,
markAllAsReadConfirmationDialogOpen: false,
}
export const entriesSlice = createSlice({
@@ -61,6 +63,9 @@ export const entriesSlice = createSlice({
setSearch: (state, action: PayloadAction<string>) => {
state.search = action.payload
},
setMarkAllAsReadConfirmationDialogOpen: (state, action: PayloadAction<boolean>) => {
state.markAllAsReadConfirmationDialogOpen = action.payload
},
},
extraReducers: builder => {
builder.addCase(markEntry.pending, (state, action) => {
@@ -119,4 +124,4 @@ export const entriesSlice = createSlice({
},
})
export const { setSearch } = entriesSlice.actions
export const { setSearch, setMarkAllAsReadConfirmationDialogOpen } = entriesSlice.actions

View File

@@ -1,16 +1,23 @@
import { createAppAsyncThunk } from "app/async-thunk"
import { client } from "app/client"
import { Constants } from "app/constants"
import { type EntrySource, type EntrySourceType, entriesSlice, 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
export const loadEntries = createAppAsyncThunk(
"entries/load",
async (
@@ -28,15 +35,19 @@ export const loadEntries = createAppAsyncThunk(
return result.data
}
)
export const loadMoreEntries = createAppAsyncThunk("entries/loadMore", async (_, thunkApi) => {
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
})
const buildGetEntriesPaginatedRequest = (state: RootState, source: EntrySource, offset: number) => ({
id: source.type === "tag" ? Constants.categories.all.id : source.id,
order: state.user.settings?.readingOrder,
@@ -46,15 +57,18 @@ const buildGetEntriesPaginatedRequest = (state: RootState, source: EntrySource,
tag: source.type === "tag" ? source.id : undefined,
keywords: state.entries.search,
})
export const reloadEntries = createAppAsyncThunk("entries/reload", (arg, thunkApi) => {
export const reloadEntries = createAppAsyncThunk("entries/reload", (_, thunkApi) => {
const state = thunkApi.getState()
thunkApi.dispatch(loadEntries({ source: state.entries.source, clearSearch: false }))
})
export const search = createAppAsyncThunk("entries/search", (arg: string, thunkApi) => {
const state = thunkApi.getState()
thunkApi.dispatch(setSearch(arg))
thunkApi.dispatch(loadEntries({ source: state.entries.source, clearSearch: false }))
})
export const markEntry = createAppAsyncThunk(
"entries/entry/mark",
(arg: { entry: Entry; read: boolean }) => {
@@ -67,6 +81,7 @@ export const markEntry = createAppAsyncThunk(
condition: arg => arg.entry.markable && arg.entry.read !== arg.read,
}
)
export const markMultipleEntries = createAppAsyncThunk(
"entries/entry/markMultiple",
async (
@@ -84,6 +99,7 @@ export const markMultipleEntries = createAppAsyncThunk(
thunkApi.dispatch(reloadTree())
}
)
export const markEntriesUpToEntry = createAppAsyncThunk("entries/entry/upToEntry", (arg: Entry, thunkApi) => {
const state = thunkApi.getState()
const { entries } = state.entries
@@ -98,6 +114,7 @@ export const markEntriesUpToEntry = createAppAsyncThunk("entries/entry/upToEntry
})
)
})
export const markAllEntries = createAppAsyncThunk(
"entries/entry/markAll",
async (
@@ -113,6 +130,37 @@ export const markAllEntries = createAppAsyncThunk(
thunkApi.dispatch(reloadTree())
}
)
export const markAllAsReadWithConfirmationIfRequired = createAppAsyncThunk(
"entries/entry/markAllAsReadWithConfirmationIfRequired",
async (_, thunkApi) => {
const state = thunkApi.getState()
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 {
await thunkApi.dispatch(
markAllEntries({
sourceType: source.type,
req: {
id: source.id,
read: true,
olderThan: Date.now(),
insertedBefore: entriesTimestamp,
},
})
)
const isAllCategorySelected = source.type === "category" && source.id === Constants.categories.all.id
if (markAllAsReadNavigateToNextUnread && !isAllCategorySelected)
await thunkApi.dispatch(selectNextUnreadTreeItem({ direction: "forward" }))
}
}
)
export const starEntry = createAppAsyncThunk(
"entries/entry/star",
(arg: { entry: Entry; starred: boolean }) => {
@@ -126,6 +174,7 @@ export const starEntry = createAppAsyncThunk(
condition: arg => arg.entry.markable && arg.entry.starred !== arg.starred,
}
)
export const selectEntry = createAppAsyncThunk(
"entries/entry/select",
(
@@ -166,22 +215,35 @@ export const selectEntry = createAppAsyncThunk(
})
if (arg.scrollToEntry) {
const viewMode = state.user.localSettings.viewMode
const entryIndex = state.entries.entries.indexOf(entry)
const entriesToKeepOnTopWhenScrolling =
viewMode === "expanded" ? 0 : Math.min(state.user.settings?.entriesToKeepOnTopWhenScrolling ?? 0, entryIndex)
const entryToScrollTo = state.entries.entries[entryIndex - entriesToKeepOnTopWhenScrolling]
const entryElement = document.getElementById(Constants.dom.entryId(entry))
if (entryElement) {
const entryElementToScrollTo = document.getElementById(Constants.dom.entryId(entryToScrollTo))
if (entryElement && entryElementToScrollTo) {
const scrollMode = state.user.settings?.scrollMode
const entryEntirelyVisible = Constants.layout.isTopVisible(entryElement) && Constants.layout.isBottomVisible(entryElement)
const entryEntirelyVisible =
Constants.layout.isTopVisible(entryElementToScrollTo) && Constants.layout.isBottomVisible(entryElement)
if (scrollMode === "always" || (scrollMode === "if_needed" && !entryEntirelyVisible)) {
const scrollSpeed = state.user.settings?.scrollSpeed
const margin = viewMode === "detailed" ? 8 : 3
thunkApi.dispatch(entriesSlice.actions.setScrollingToEntry(true))
scrollToEntry(entryElement, scrollSpeed, () => thunkApi.dispatch(entriesSlice.actions.setScrollingToEntry(false)))
scrollToEntry(entryElementToScrollTo, margin, scrollSpeed, () =>
thunkApi.dispatch(entriesSlice.actions.setScrollingToEntry(false))
)
}
}
}
}
)
const scrollToEntry = (entryElement: HTMLElement, scrollSpeed: number | undefined, onScrollEnded: () => void) => {
const header = document.getElementById(Constants.dom.headerId)?.getBoundingClientRect()
const offset = (header?.bottom ?? 0) + 3
const scrollToEntry = (entryElement: HTMLElement, margin: number, scrollSpeed: number | undefined, onScrollEnded: () => void) => {
const header = document.getElementsByTagName("header").item(0)?.getBoundingClientRect()
const offset = (header?.bottom ?? 0) + margin
scrollToWithCallback({
options: {
top: entryElement.offsetTop - offset,
@@ -216,9 +278,10 @@ export const selectPreviousEntry = createAppAsyncThunk(
}
}
)
export const selectNextEntry = createAppAsyncThunk(
"entries/entry/selectNext",
(
async (
arg: {
expand: boolean
markAsRead: boolean
@@ -227,12 +290,20 @@ export const selectNextEntry = createAppAsyncThunk(
thunkApi
) => {
const state = thunkApi.getState()
const { entries } = state.entries
const { entries, hasMore, loading } = state.entries
const nextIndex = entries.findIndex(e => e.id === state.entries.selectedEntryId) + 1
if (nextIndex < entries.length) {
// load more entries if needed
// this can happen if the last entry is too large to fit on the screen and the infinite loader doesn't trigger
if (nextIndex >= entries.length && hasMore && !loading) {
await thunkApi.dispatch(loadMoreEntries())
}
const entriesAfterLoading = thunkApi.getState().entries.entries
if (nextIndex < entriesAfterLoading.length) {
thunkApi.dispatch(
selectEntry({
entry: entries[nextIndex],
entry: entriesAfterLoading[nextIndex],
expand: arg.expand,
markAsRead: arg.markAsRead,
scrollToEntry: arg.scrollToEntry,
@@ -241,6 +312,7 @@ export const selectNextEntry = createAppAsyncThunk(
}
}
)
export const tagEntry = createAppAsyncThunk("entries/entry/tag", async (arg: TagRequest, thunkApi) => {
await client.entry.tag(arg)
thunkApi.dispatch(reloadTags())

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,45 +1,61 @@
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 redirectToPasswordRecovery = createAppAsyncThunk("redirect/passwordRecovery", (_, thunkApi) =>
thunkApi.dispatch(redirectTo("/passwordRecovery"))
)
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
thunkApi.dispatch(redirectTo(`/app/${source.type}/${source.id}`))
})
export const redirectToCategory = createAppAsyncThunk("redirect/category", (id: string, thunkApi) =>
thunkApi.dispatch(redirectTo(`/app/category/${id}`))
)
export const redirectToRootCategory = createAppAsyncThunk(
"redirect/category/root",
async (_, thunkApi) => await thunkApi.dispatch(redirectToCategory(Constants.categories.all.id))
)
export const redirectToCategoryDetails = createAppAsyncThunk("redirect/category/details", (id: string, thunkApi) =>
thunkApi.dispatch(redirectTo(`/app/category/${id}/details`))
)
export const redirectToFeed = createAppAsyncThunk("redirect/feed", (id: string | number, thunkApi) =>
thunkApi.dispatch(redirectTo(`/app/feed/${id}`))
)
export const redirectToFeedDetails = createAppAsyncThunk("redirect/feed/details", (id: string, thunkApi) =>
thunkApi.dispatch(redirectTo(`/app/feed/${id}/details`))
)
export const redirectToTag = createAppAsyncThunk("redirect/tag", (id: string, thunkApi) => thunkApi.dispatch(redirectTo(`/app/tag/${id}`)))
export const redirectToTagDetails = createAppAsyncThunk("redirect/tag/details", (id: string, thunkApi) =>
thunkApi.dispatch(redirectTo(`/app/tag/${id}/details`))
)
export const redirectToAdd = createAppAsyncThunk("redirect/add", (_, thunkApi) => thunkApi.dispatch(redirectTo("/app/add")))
export const redirectToSettings = createAppAsyncThunk("redirect/settings", (_, thunkApi) => thunkApi.dispatch(redirectTo("/app/settings")))
export const redirectToAdminUsers = createAppAsyncThunk("redirect/admin/users", (_, thunkApi) =>
thunkApi.dispatch(redirectTo("/app/admin/users"))
)
export const redirectToMetrics = createAppAsyncThunk("redirect/admin/metrics", (_, thunkApi) =>
thunkApi.dispatch(redirectTo("/app/admin/metrics"))
)
export const redirectToDonate = createAppAsyncThunk("redirect/donate", (_, thunkApi) => thunkApi.dispatch(redirectTo("/app/donate")))
export const redirectToAbout = createAppAsyncThunk("redirect/about", (_, thunkApi) => thunkApi.dispatch(redirectTo("/app/about")))

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,10 +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 { userSlice } from "app/user/slice"
import { type TypedUseSelectorHook, useDispatch, useSelector } from "react-redux"
import { shallowEqual, 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,
@@ -14,10 +15,30 @@ export const reducers = {
user: userSlice.reducer,
}
export const store = configureStore({ reducer: reducers })
const loadLocalSettings = (): LocalSettings => {
const json = localStorage.getItem("commafeed-local-settings")
return {
...initialLocalSettings,
...(json ? JSON.parse(json) : {}),
}
}
export const store = configureStore({
reducer: reducers,
preloadedState: {
user: {
localSettings: loadLocalSettings(),
},
},
})
store.subscribe(() => {
const localSettings = store.getState().user.localSettings
localStorage.setItem("commafeed-local-settings", JSON.stringify(localSettings))
})
export type RootState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch
export const useAppDispatch: () => AppDispatch = useDispatch
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector
export const useShallowEqualAppSelector: TypedUseSelectorHook<RootState> = selector => useSelector(selector, shallowEqual)

View File

@@ -1,12 +1,22 @@
import { type PayloadAction, createSlice } from "@reduxjs/toolkit"
import { markEntry } from "app/entries/thunks"
import { redirectTo } from "app/redirect/slice"
import { collapseTreeCategory, reloadTree } from "app/tree/thunks"
import type { Category } from "app/types"
import { 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
hasNewEntries?: boolean
}
export interface TreeCategory extends Category {
feeds: TreeSubscription[]
children: TreeCategory[]
}
interface TreeState {
rootCategory?: Category
rootCategory?: TreeCategory
mobileMenuOpen: boolean
sidebarVisible: boolean
}
@@ -37,12 +47,27 @@ export const treeSlice = createSlice({
visitCategoryTree(state.rootCategory, c => {
for (const f of c.feeds.filter(f => f.id === action.payload.feedId)) {
f.unread += action.payload.amount
f.hasNewEntries = true
}
})
},
},
extraReducers: builder => {
builder.addCase(reloadTree.fulfilled, (state, action) => {
// set hasNewEntries to true if new unread > previous unread
if (state.rootCategory) {
const oldFeeds = flattenCategoryTree(state.rootCategory).flatMap(c => c.feeds)
const oldFeedsById = new Map(oldFeeds.map(f => [f.id, f]))
const newFeeds = flattenCategoryTree(action.payload).flatMap(c => c.feeds)
for (const newFeed of newFeeds) {
const oldFeed = oldFeedsById.get(newFeed.id)
if (oldFeed && newFeed.unread > oldFeed.unread) {
newFeed.hasNewEntries = true
}
}
}
state.rootCategory = action.payload
})
builder.addCase(collapseTreeCategory.pending, (state, action) => {
@@ -59,6 +84,25 @@ export const treeSlice = createSlice({
}
})
})
builder.addCase(loadEntries.fulfilled, (state, action) => {
if (!state.rootCategory) return
const { source } = action.meta.arg
if (source.type === "category") {
visitCategoryTree(state.rootCategory, c => {
if (c.id === source.id) {
for (const f of flattenCategoryTree(c).flatMap(c => c.feeds)) {
f.hasNewEntries = false
}
}
})
} else if (source.type === "feed") {
const feeds = flattenCategoryTree(state.rootCategory).flatMap(c => c.feeds)
for (const f of feeds.filter(f => f.id === +source.id)) {
f.hasNewEntries = false
}
}
})
builder.addCase(redirectTo, state => {
state.mobileMenuOpen = false
})

View File

@@ -1,9 +1,84 @@
import { createAppAsyncThunk } from "app/async-thunk"
import { client } from "app/client"
import type { CollapseRequest } from "app/types"
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))
export const collapseTreeCategory = createAppAsyncThunk(
"tree/category/collapse",
async (req: CollapseRequest) => await client.category.collapse(req)
async (req: CollapseRequest) => await client.category.collapse(req).then(r => r.data)
)
export const selectNextUnreadTreeItem = createAppAsyncThunk(
"tree/selectNextUnreadItem",
(
arg: {
direction: "forward" | "backward"
},
thunkApi
) => {
const state = thunkApi.getState()
const root = state.tree.rootCategory
if (!root) return
const { source } = state.entries
if (source.type === "category") {
const categories = flattenCategoryTree(root)
if (arg.direction === "backward") categories.reverse()
const index = categories.findIndex(c => c.id === source.id)
if (index === -1) return
for (let i = index + 1; i < categories.length; i++) {
const c = categories[i]
if (c.feeds.some(f => f.unread > 0)) {
return thunkApi.dispatch(redirectToCategory(String(c.id)))
}
}
} else if (source.type === "feed") {
const feeds: Subscription[] = []
visitCategoryTree(root, c => feeds.push(...c.feeds), { childrenFirst: true })
if (arg.direction === "backward") feeds.reverse()
const index = feeds.findIndex(f => f.id === +source.id)
if (index === -1) return
for (let i = index + 1; i < feeds.length; i++) {
const f = feeds[i]
if (f.unread > 0) {
return thunkApi.dispatch(redirectToFeed(String(f.id)))
}
}
}
// 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))
}
)
export const newFeedEntriesDiscovered = createAppAsyncThunk(
"tree/new-feed-entries-discovered",
async ({ feedId, amount }: { feedId: number; amount: number }, thunkApi) => {
const root = thunkApi.getState().tree.rootCategory
if (!root) return
const feed = flattenCategoryTree(root)
.flatMap(c => c.feeds)
.some(f => f.id === feedId)
if (!feed) {
// feed not found in the tree, reload the tree completely
thunkApi.dispatch(reloadTree())
} else {
thunkApi.dispatch(
incrementUnreadCount({
feedId,
amount,
})
)
}
}
)

View File

@@ -0,0 +1,173 @@
import { configureStore } from "@reduxjs/toolkit"
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"))
const createCategory = (id: string): Category => ({
id,
name: id,
children: [],
feeds: [],
expanded: true,
position: 0,
})
const createFeed = (id: number, unread: number): Subscription => ({
id,
name: String(id),
unread,
errorCount: 0,
position: 0,
feedUrl: "",
feedLink: "",
iconUrl: "",
pushNotificationsEnabled: true,
})
const root = createCategory("root")
const catA = createCategory("catA")
catA.feeds.push(createFeed(1, 0), createFeed(2, 0), createFeed(3, 1))
const catB = createCategory("catB")
const catC = createCategory("catC")
catC.feeds.push(createFeed(4, 1))
root.children.push(catA, catB, catC)
describe("selectNextUnreadTreeItem", () => {
it("selects the next unread category", async () => {
const store = configureStore({
reducer: reducers,
preloadedState: {
tree: {
rootCategory: root,
},
entries: {
source: {
type: "category",
id: "catA",
},
},
} as RootState,
})
await store.dispatch(selectNextUnreadTreeItem({ direction: "forward" }))
expect(store.getState().redirect.to).toBe("/app/category/catC")
})
it("selects the previous unread category", async () => {
const store = configureStore({
reducer: reducers,
preloadedState: {
tree: {
rootCategory: root,
},
entries: {
source: {
type: "category",
id: "catC",
},
},
} as RootState,
})
await store.dispatch(selectNextUnreadTreeItem({ direction: "backward" }))
expect(store.getState().redirect.to).toBe("/app/category/catA")
})
it("selects the next unread feed", async () => {
const store = configureStore({
reducer: reducers,
preloadedState: {
tree: {
rootCategory: root,
},
entries: {
source: {
type: "feed",
id: "1",
},
},
} as RootState,
})
await store.dispatch(selectNextUnreadTreeItem({ direction: "forward" }))
expect(store.getState().redirect.to).toBe("/app/feed/3")
})
it("selects the previous unread feed", async () => {
const store = configureStore({
reducer: reducers,
preloadedState: {
tree: {
rootCategory: root,
},
entries: {
source: {
type: "feed",
id: "4",
},
},
} as RootState,
})
await store.dispatch(selectNextUnreadTreeItem({ direction: "backward" }))
expect(store.getState().redirect.to).toBe("/app/feed/3")
})
})
describe("hasNewEntries", () => {
beforeEach(() => {
vi.resetAllMocks()
})
it("sets and clear flag for a feed", async () => {
vi.mocked(client.feed.getEntries).mockResolvedValue({
data: {
entries: [{ id: "3" } as Entry],
hasMore: false,
name: "my-feed",
errorCount: 3,
feedLink: "https://mysite.com/feed",
timestamp: 123,
ignoredReadStatus: false,
},
} as AxiosResponse<Entries>)
const store = configureStore({
reducer: reducers,
preloadedState: {
tree: {
rootCategory: root,
},
entries: {
source: {
type: "feed",
id: "1",
},
},
} as RootState,
})
// initial state
expect(store.getState().tree.rootCategory?.children[0].feeds[0].unread).toBe(0)
expect(store.getState().tree.rootCategory?.children[0].feeds[0].hasNewEntries).toBeFalsy()
// increments unread count and sets hasNewEntries to true
await store.dispatch(newFeedEntriesDiscovered({ feedId: 1, amount: 3 }))
expect(store.getState().tree.rootCategory?.children[0].feeds[0].unread).toBe(3)
expect(store.getState().tree.rootCategory?.children[0].feeds[0].hasNewEntries).toBe(true)
// reload entries and sets hasNewEntries to false
await store.dispatch(loadEntries({ source: { type: "feed", id: "1" }, clearSearch: true }))
expect(store.getState().tree.rootCategory?.children[0].feeds[0].hasNewEntries).toBe(false)
})
})

View File

@@ -28,6 +28,10 @@ export interface Subscription {
position: number
newestItemTime?: number
filter?: string
filterLegacy?: string
pushNotificationsEnabled: boolean
autoMarkAsReadAfterDays?: number
averageEntryIntervalMs?: number
}
export interface Category {
@@ -109,6 +113,8 @@ export interface FeedModificationRequest {
categoryId?: string
position?: number
filter?: string
pushNotificationsEnabled: boolean
autoMarkAsReadAfterDays?: number
}
export interface GetEntriesRequest {
@@ -196,6 +202,12 @@ export interface PasswordResetRequest {
email: string
}
export interface PasswordResetConfirmationRequest {
email: string
token: string
password: string
}
export interface ProfileModificationRequest {
currentPassword: string
email: string
@@ -209,17 +221,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 {
@@ -233,8 +255,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
@@ -243,12 +275,28 @@ export interface Settings {
customJs?: string
scrollSpeed: number
scrollMode: ScrollMode
entriesToKeepOnTopWhenScrolling: number
starIconDisplayMode: IconDisplayMode
externalLinkIconDisplayMode: IconDisplayMode
markAllAsReadConfirmation: boolean
markAllAsReadNavigateToNextUnread: boolean
customContextMenu: boolean
mobileFooter: boolean
unreadCountTitle: boolean
unreadCountFavicon: boolean
disablePullToRefresh: boolean
disableMobileSwipe: boolean
infrequentThresholdDays: number
primaryColor?: string
sharingSettings: SharingSettings
pushNotificationSettings: PushNotificationSettings
}
export interface LocalSettings {
viewMode: ViewMode
sidebarWidth: number
announcementHash: string
fontSizePercentage: number
}
export interface StarRequest {
@@ -278,6 +326,7 @@ export interface UserModel {
created: number
lastLogin?: number
admin: boolean
lastForceRefresh?: number
}
export interface AdminSaveUserRequest {

View File

@@ -1,13 +1,20 @@
import { t } from "@lingui/macro"
import { t } from "@lingui/core/macro"
import { showNotification } from "@mantine/notifications"
import { createSlice, isAnyOf } from "@reduxjs/toolkit"
import type { Settings, UserModel } from "app/types"
import { createSlice, isAnyOf, type PayloadAction } from "@reduxjs/toolkit"
import type { LocalSettings, Settings, UserModel, ViewMode } from "@/app/types"
import {
changeCustomContextMenu,
changeDisableMobileSwipe,
changeDisablePullToRefresh,
changeEntriesToKeepOnTopWhenScrolling,
changeExternalLinkIconDisplayMode,
changeInfrequentThresholdDays,
changeLanguage,
changeMarkAllAsReadConfirmation,
changeMarkAllAsReadNavigateToUnread,
changeMobileFooter,
changePrimaryColor,
changePushNotificationSettings,
changeReadingMode,
changeReadingOrder,
changeScrollMarks,
@@ -16,6 +23,8 @@ import {
changeSharingSetting,
changeShowRead,
changeStarIconDisplayMode,
changeUnreadCountFavicon,
changeUnreadCountTitle,
reloadProfile,
reloadSettings,
reloadTags,
@@ -23,16 +32,39 @@ import {
interface UserState {
settings?: Settings
localSettings: LocalSettings
profile?: UserModel
tags?: string[]
}
const initialState: UserState = {}
export const initialLocalSettings: LocalSettings = {
viewMode: "detailed",
sidebarWidth: 360,
announcementHash: "no-hash",
fontSizePercentage: 100,
}
const initialState: UserState = {
localSettings: initialLocalSettings,
}
export const userSlice = createSlice({
name: "user",
initialState,
reducers: {},
reducers: {
setViewMode: (state, action: PayloadAction<ViewMode>) => {
state.localSettings.viewMode = action.payload
},
setFontSizePercentage: (state, action: PayloadAction<number>) => {
state.localSettings.fontSizePercentage = action.payload
},
setSidebarWidth: (state, action: PayloadAction<number>) => {
state.localSettings.sidebarWidth = action.payload
},
setAnnouncementHash: (state, action: PayloadAction<string>) => {
state.localSettings.announcementHash = action.payload
},
},
extraReducers: builder => {
builder.addCase(reloadSettings.fulfilled, (state, action) => {
state.settings = action.payload
@@ -71,6 +103,10 @@ export const userSlice = createSlice({
if (!state.settings) return
state.settings.scrollMode = action.meta.arg
})
builder.addCase(changeEntriesToKeepOnTopWhenScrolling.pending, (state, action) => {
if (!state.settings) return
state.settings.entriesToKeepOnTopWhenScrolling = action.meta.arg
})
builder.addCase(changeStarIconDisplayMode.pending, (state, action) => {
if (!state.settings) return
state.settings.starIconDisplayMode = action.meta.arg
@@ -83,6 +119,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
@@ -91,10 +131,39 @@ export const userSlice = createSlice({
if (!state.settings) return
state.settings.mobileFooter = action.meta.arg
})
builder.addCase(changeUnreadCountTitle.pending, (state, action) => {
if (!state.settings) return
state.settings.unreadCountTitle = action.meta.arg
})
builder.addCase(changeUnreadCountFavicon.pending, (state, action) => {
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(changeDisableMobileSwipe.pending, (state, action) => {
if (!state.settings) return
state.settings.disableMobileSwipe = action.meta.arg
})
builder.addCase(changeInfrequentThresholdDays.pending, (state, action) => {
if (!state.settings) return
state.settings.infrequentThresholdDays = action.meta.arg
})
builder.addCase(changePrimaryColor.pending, (state, action) => {
if (!state.settings) return
state.settings.primaryColor = action.meta.arg
})
builder.addCase(changeSharingSetting.pending, (state, action) => {
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,
@@ -102,12 +171,21 @@ export const userSlice = createSlice({
changeShowRead.fulfilled,
changeScrollMarks.fulfilled,
changeScrollMode.fulfilled,
changeEntriesToKeepOnTopWhenScrolling.fulfilled,
changeStarIconDisplayMode.fulfilled,
changeExternalLinkIconDisplayMode.fulfilled,
changeMarkAllAsReadConfirmation.fulfilled,
changeMarkAllAsReadNavigateToUnread.fulfilled,
changeCustomContextMenu.fulfilled,
changeMobileFooter.fulfilled,
changeSharingSetting.fulfilled
changeUnreadCountTitle.fulfilled,
changeUnreadCountFavicon.fulfilled,
changeDisablePullToRefresh.fulfilled,
changeDisableMobileSwipe.fulfilled,
changeInfrequentThresholdDays.fulfilled,
changePrimaryColor.fulfilled,
changeSharingSetting.fulfilled,
changePushNotificationSettings.fulfilled
),
() => {
showNotification({
@@ -118,3 +196,5 @@ export const userSlice = createSlice({
)
},
})
export const { setViewMode, setSidebarWidth, setAnnouncementHash, setFontSizePercentage } = userSlice.actions

View File

@@ -1,48 +1,67 @@
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))
export const reloadProfile = createAppAsyncThunk("profile/reload", async () => await client.user.getProfile().then(r => r.data))
export const reloadTags = createAppAsyncThunk("entries/tags", async () => await client.entry.getTags().then(r => r.data))
export const changeReadingMode = createAppAsyncThunk("settings/readingMode", (readingMode: ReadingMode, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
client.user.saveSettings({ ...settings, readingMode })
thunkApi.dispatch(reloadEntries())
})
export const changeReadingOrder = createAppAsyncThunk("settings/readingOrder", (readingOrder: ReadingOrder, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
client.user.saveSettings({ ...settings, readingOrder })
thunkApi.dispatch(reloadEntries())
})
export const changeLanguage = createAppAsyncThunk("settings/language", (language: string, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
client.user.saveSettings({ ...settings, language })
})
export const changeScrollSpeed = createAppAsyncThunk("settings/scrollSpeed", (speed: boolean, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
client.user.saveSettings({ ...settings, scrollSpeed: speed ? 400 : 0 })
})
export const changeShowRead = createAppAsyncThunk("settings/showRead", (showRead: boolean, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
client.user.saveSettings({ ...settings, showRead })
})
export const changeScrollMarks = createAppAsyncThunk("settings/scrollMarks", (scrollMarks: boolean, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
client.user.saveSettings({ ...settings, scrollMarks })
})
export const changeScrollMode = createAppAsyncThunk("settings/scrollMode", (scrollMode: ScrollMode, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
client.user.saveSettings({ ...settings, scrollMode })
})
export const changeEntriesToKeepOnTopWhenScrolling = createAppAsyncThunk(
"settings/entriesToKeepOnTopWhenScrolling",
(entriesToKeepOnTopWhenScrolling: number, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
client.user.saveSettings({ ...settings, entriesToKeepOnTopWhenScrolling })
}
)
export const changeStarIconDisplayMode = createAppAsyncThunk(
"settings/starIconDisplayMode",
(starIconDisplayMode: IconDisplayMode, thunkApi) => {
@@ -51,6 +70,7 @@ export const changeStarIconDisplayMode = createAppAsyncThunk(
client.user.saveSettings({ ...settings, starIconDisplayMode })
}
)
export const changeExternalLinkIconDisplayMode = createAppAsyncThunk(
"settings/externalLinkIconDisplayMode",
(externalLinkIconDisplayMode: IconDisplayMode, thunkApi) => {
@@ -59,6 +79,7 @@ export const changeExternalLinkIconDisplayMode = createAppAsyncThunk(
client.user.saveSettings({ ...settings, externalLinkIconDisplayMode })
}
)
export const changeMarkAllAsReadConfirmation = createAppAsyncThunk(
"settings/markAllAsReadConfirmation",
(markAllAsReadConfirmation: boolean, thunkApi) => {
@@ -67,16 +88,61 @@ export const changeMarkAllAsReadConfirmation = createAppAsyncThunk(
client.user.saveSettings({ ...settings, markAllAsReadConfirmation })
}
)
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
client.user.saveSettings({ ...settings, customContextMenu })
})
export const changeMobileFooter = createAppAsyncThunk("settings/mobileFooter", (mobileFooter: boolean, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
client.user.saveSettings({ ...settings, mobileFooter })
})
export const changeUnreadCountTitle = createAppAsyncThunk("settings/unreadCountTitle", (unreadCountTitle: boolean, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
client.user.saveSettings({ ...settings, unreadCountTitle })
})
export const changeUnreadCountFavicon = createAppAsyncThunk("settings/unreadCountFavicon", (unreadCountFavicon: boolean, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
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 changeDisableMobileSwipe = createAppAsyncThunk("settings/disableMobileSwipe", (disableMobileSwipe: boolean, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
client.user.saveSettings({ ...settings, disableMobileSwipe })
})
export const changePrimaryColor = createAppAsyncThunk("settings/primaryColor", (primaryColor: string, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
client.user.saveSettings({ ...settings, primaryColor })
})
export const changeSharingSetting = createAppAsyncThunk(
"settings/sharingSetting",
(
@@ -97,3 +163,24 @@ export const changeSharingSetting = createAppAsyncThunk(
})
}
)
export const changeInfrequentThresholdDays = createAppAsyncThunk(
"settings/infrequentThresholdDays",
(infrequentThresholdDays: number, thunkApi) => {
const { settings } = thunkApi.getState().user
if (!settings) return
client.user.saveSettings({ ...settings, infrequentThresholdDays })
}
)
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,28 +1,50 @@
import { throttle } from "throttle-debounce"
import type { TreeCategory } from "@/app/tree/slice"
import type { Category } from "./types"
export function visitCategoryTree(category: Category, visitor: (category: Category) => void): void {
visitor(category)
for (const child of category.children) {
visitCategoryTree(child, visitor)
export function visitCategoryTree(
category: TreeCategory,
visitor: (category: TreeCategory) => void,
options?: {
childrenFirst?: boolean
}
): void {
const childrenFirst = options?.childrenFirst
if (!childrenFirst) visitor(category)
for (const child of category.children) {
visitCategoryTree(child, visitor, options)
}
if (childrenFirst) visitor(category)
}
export function flattenCategoryTree(category: Category): Category[] {
export function flattenCategoryTree(category: TreeCategory): TreeCategory[] {
const categories: Category[] = []
visitCategoryTree(category, c => categories.push(c))
return categories
}
export function categoryUnreadCount(category?: Category): number {
export function categoryUnreadCount(category?: TreeCategory, maxFrequencyThresholdMs?: number): number {
if (!category) return 0
return flattenCategoryTree(category)
.flatMap(c => c.feeds)
.filter(f => !maxFrequencyThresholdMs || (f.averageEntryIntervalMs && f.averageEntryIntervalMs >= maxFrequencyThresholdMs))
.map(f => f.unread)
.reduce((total, current) => total + current, 0)
}
export function categoryHasNewEntries(category?: TreeCategory, maxFrequencyThresholdMs?: number): boolean {
if (!category) return false
return flattenCategoryTree(category)
.flatMap(c => c.feeds)
.filter(f => !maxFrequencyThresholdMs || (f.averageEntryIntervalMs && f.averageEntryIntervalMs >= maxFrequencyThresholdMs))
.some(f => f.hasNewEntries)
}
export const calculatePlaceholderSize = ({ width, height, maxWidth }: { width?: number; height?: number; maxWidth: number }) => {
const placeholderWidth = width && Math.min(width, maxWidth)
const placeholderHeight = height && width && width > maxWidth ? height * (maxWidth / width) : height

View File

@@ -0,0 +1,53 @@
import type { I18nContext } from "@lingui/react"
import { MantineProvider } from "@mantine/core"
import { fireEvent, render, screen, waitFor } from "@testing-library/react"
import { describe, expect, it, vi } from "vitest"
import { useActionButton } from "@/hooks/useActionButton"
import { ActionButton } from "./ActionButton"
vi.mock(import("@lingui/react"), () => ({
useLingui: vi.fn().mockReturnValue({
_: msg => msg,
} as I18nContext),
}))
vi.mock(import("@/hooks/useActionButton"))
const label = "Test Label"
const icon = "Test Icon"
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,
})
expect(screen.getByText(label)).toBeInTheDocument()
expect(screen.getByText(icon)).toBeInTheDocument()
})
it("renders ActionIcon with tooltip on mobile", async () => {
vi.mocked(useActionButton).mockReturnValue({ mobile: true, spacing: 0 })
render(<ActionButton label={label} icon={icon} />, {
wrapper: MantineProvider,
})
expect(screen.queryByText(label)).not.toBeInTheDocument()
expect(screen.getByText(icon)).toBeInTheDocument()
fireEvent.mouseEnter(screen.getByRole("button"))
const tooltip = await waitFor(() => screen.getByRole("tooltip"))
expect(tooltip).toContainHTML(label)
})
it("calls onClick handler when clicked", () => {
vi.mocked(useActionButton).mockReturnValue({ mobile: false, spacing: 0 })
const clickListener = vi.fn()
render(<ActionButton label={label} icon={icon} onClick={clickListener} />, {
wrapper: MantineProvider,
})
fireEvent.click(screen.getByRole("button"))
expect(clickListener).toHaveBeenCalled()
})
})

View File

@@ -1,14 +1,14 @@
import type { MessageDescriptor } from "@lingui/core"
import { useLingui } from "@lingui/react"
import { ActionIcon, Button, type ButtonVariant, Tooltip, useMantineTheme } from "@mantine/core"
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
className?: string
icon?: ReactNode
label?: string | MessageDescriptor
onClick?: MouseEventHandler
variant?: ActionIconVariant & ButtonVariant
@@ -19,7 +19,7 @@ interface ActionButtonProps {
/**
* Switches between Button with label (desktop) and ActionIcon (mobile)
*/
export const ActionButton = forwardRef<HTMLButtonElement, ActionButtonProps>((props: ActionButtonProps, ref) => {
export const ActionButton = forwardRef<HTMLDivElement, ActionButtonProps>((props: ActionButtonProps, ref) => {
const { mobile } = useActionButton()
const theme = useMantineTheme()
const { _ } = useLingui()
@@ -27,31 +27,36 @@ export const ActionButton = forwardRef<HTMLButtonElement, ActionButtonProps>((pr
const label = typeof props.label === "string" ? props.label : props.label && _(props.label)
const variant = props.variant ?? "subtle"
const iconOnly = (mobile && !props.showLabelOnMobile) || (!mobile && props.hideLabelOnDesktop)
return iconOnly ? (
<Tooltip label={label} openDelay={Constants.tooltip.delay}>
<ActionIcon
ref={ref}
color={theme.primaryColor}
variant={variant}
className={props.className}
onClick={props.onClick}
aria-label={label}
>
{props.icon}
</ActionIcon>
</Tooltip>
) : (
<Button
ref={ref}
variant={variant}
size="xs"
className={props.className}
leftSection={props.icon}
onClick={props.onClick}
aria-label={label}
>
{label}
</Button>
return (
<Box ref={ref} className="cf-action-button">
{iconOnly && (
<Tooltip label={label} openDelay={Constants.tooltip.delay}>
<ActionIcon
color={theme.primaryColor}
variant={variant}
className={props.className}
onClick={props.onClick}
aria-label={label}
>
{props.icon}
</ActionIcon>
</Tooltip>
)}
{!iconOnly && (
<Button
variant={variant}
size="xs"
className={props.className}
leftSection={props.icon}
onClick={props.onClick}
aria-label={label}
>
{label}
</Button>
)}
</Box>
)
})
ActionButton.displayName = "HeaderButton"

View File

@@ -1,4 +1,4 @@
import { Trans } from "@lingui/macro"
import { Trans } from "@lingui/react/macro"
import { Box, Alert as MantineAlert } from "@mantine/core"
import { Fragment } from "react"
import { TbAlertCircle, TbAlertTriangle, TbCircleCheck } from "react-icons/tb"
@@ -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/macro"
import { Trans } from "@lingui/react/macro"
import { Box, Dialog, Text } from "@mantine/core"
import { useAppSelector } from "app/store"
import { Content } from "components/content/Content"
import { useAsync } from "react-async-hook"
import useLocalStorage from "use-local-storage"
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)
@@ -15,10 +15,11 @@ const sha256Hex = async (input: string | undefined) => {
export function AnnouncementDialog() {
const announcement = useAppSelector(state => state.server.serverInfos?.announcement)
const announcementHash = useAsync(sha256Hex, [announcement]).result
const [localStorageHash, setLocalStorageHash] = useLocalStorage("announcement-hash", "no-hash")
const existingAnnouncementHash = useAppSelector(state => state.user.localSettings.announcementHash)
const dispatch = useAppDispatch()
const opened = !!announcementHash && announcementHash !== localStorageHash
const onClosed = () => setLocalStorageHash(announcementHash)
const opened = !!announcementHash && announcementHash !== existingAnnouncementHash
const onClosed = () => announcementHash && dispatch(setAnnouncementHash(announcementHash))
if (!announcement) return null
return (

View File

@@ -1,15 +1,3 @@
import { Helmet } from "react-helmet"
export const DisablePullToRefresh = () => {
return (
<Helmet>
<style type="text/css">
{`
html, body {
overscroll-behavior: none;
}
`}
</style>
</Helmet>
)
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
@@ -9,6 +9,7 @@ interface ImageWithPlaceholderWhileLoadingProps {
title?: string
width?: number
height?: number | "auto"
style?: React.CSSProperties
placeholderWidth?: number
placeholderHeight?: number
placeholderBackgroundColor?: string
@@ -42,7 +43,8 @@ export function ImageWithPlaceholderWhileLoading({
src,
title,
width,
}: ImageWithPlaceholderWhileLoadingProps) {
style,
}: Readonly<ImageWithPlaceholderWhileLoadingProps>) {
const { classes } = useStyles({
placeholderWidth,
placeholderHeight,
@@ -68,7 +70,11 @@ export function ImageWithPlaceholderWhileLoading({
width={width}
height={height}
onLoad={() => setLoading(false)}
style={{ display: loading ? "none" : "block" }}
style={{
...style,
display: loading ? "none" : (style?.display ?? "initial"),
height: style?.width ? "auto" : style?.height,
}}
/>
</>
)

View File

@@ -1,7 +1,7 @@
import { Trans } from "@lingui/macro"
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"
@@ -33,6 +33,26 @@ export function KeyboardShortcutsHelp() {
<Kbd>K</Kbd>
</Table.Td>
</Table.Tr>
<Table.Tr>
<Table.Td>
<Trans>Select next unread feed/category</Trans>
</Table.Td>
<Table.Td>
<Kbd>Shift</Kbd>
<span> + </span>
<Kbd>J</Kbd>
</Table.Td>
</Table.Tr>
<Table.Tr>
<Table.Td>
<Trans>Select previous unread feed/category</Trans>
</Table.Td>
<Table.Td>
<Kbd>Shift</Kbd>
<span> + </span>
<Kbd>K</Kbd>
</Table.Td>
</Table.Tr>
<Table.Tr>
<Table.Td>
<Trans>Set focus on next entry without opening it</Trans>

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

@@ -0,0 +1,83 @@
import { Trans } from "@lingui/react/macro"
import { Button, Code, Group, Modal, Slider, Stack, Text } from "@mantine/core"
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)
const open = useAppSelector(state => state.entries.markAllAsReadConfirmationDialogOpen)
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 = async () => {
dispatch(setMarkAllAsReadConfirmationDialogOpen(false))
await dispatch(
markAllEntries({
sourceType: source.type,
req: {
id: source.id,
read: true,
olderThan: Date.now() - threshold * 24 * 60 * 60 * 1000,
insertedBefore: entriesTimestamp,
},
})
)
const isAllCategorySelected = source.type === "category" && source.id === Constants.categories.all.id
if (markAllAsReadNavigateToNextUnread && !isAllCategorySelected) await dispatch(selectNextUnreadTreeItem({ direction: "forward" }))
}
return (
<Modal
opened={open}
onClose={() => dispatch(setMarkAllAsReadConfirmationDialogOpen(false))}
title={<Trans>Mark all entries as read</Trans>}
>
<Stack>
<Text size="sm">
{threshold === 0 && (
<Trans>
Are you sure you want to mark all entries of <Code>{sourceLabel}</Code> as read?
</Trans>
)}
{threshold > 0 && (
<Trans>
Are you sure you want to mark entries older than {threshold} days of <Code>{sourceLabel}</Code> as read?
</Trans>
)}
</Text>
<Slider
py="xl"
min={0}
max={28}
marks={[
{ value: 0, label: "0" },
{ value: 7, label: "7" },
{ value: 14, label: "14" },
{ value: 21, label: "21" },
{ value: 28, label: "28" },
]}
value={threshold}
onChange={setThreshold}
data-autofocus
onKeyDown={e => e.key === "Enter" && onConfirm()}
/>
<Group justify="flex-end">
<Button variant="default" onClick={() => dispatch(setMarkAllAsReadConfirmationDialogOpen(false))}>
<Trans>Cancel</Trans>
</Button>
<Button color="red" onClick={onConfirm}>
<Trans>Confirm</Trans>
</Button>
</Group>
</Stack>
</Modal>
)
}

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,15 +1,15 @@
import { Trans } from "@lingui/macro"
import { Trans } from "@lingui/react/macro"
import { Tooltip } from "@mantine/core"
import { Constants } from "app/constants"
import dayjs from "dayjs"
import { useEffect, useState } from "react"
import { Constants } from "@/app/constants"
import { useNow } from "@/hooks/useNow"
export function RelativeDate(props: { date: Date | number | undefined }) {
const [now, setNow] = useState(new Date())
useEffect(() => {
const interval = setInterval(() => setNow(new Date()), 60 * 1000)
return () => clearInterval(interval)
}, [])
export function RelativeDate(
props: Readonly<{
date: Date | number | undefined
}>
) {
const now = useNow(60 * 1000)
if (!props.date) return <Trans>N/A</Trans>
const date = dayjs(props.date)

View File

@@ -1,11 +1,11 @@
import { Trans } from "@lingui/macro"
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,16 +1,17 @@
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
description?: ReactNode
language: "css" | "javascript"
value?: string
onChange: (value: string | undefined) => void
}
export function CodeEditor(props: CodeEditorProps) {
export function CodeEditor(props: Readonly<CodeEditorProps>) {
const mobile = useMobile()
return mobile ? (
@@ -19,6 +20,7 @@ export function CodeEditor(props: CodeEditorProps) {
autosize
minRows={4}
maxRows={15}
label={props.label}
description={props.description}
styles={{
input: {
@@ -29,7 +31,7 @@ export function CodeEditor(props: CodeEditorProps) {
onChange={e => props.onChange(e.currentTarget.value)}
/>
) : (
<Input.Wrapper description={props.description}>
<Input.Wrapper label={props.label} description={props.description}>
<RichCodeEditor height="30vh" language={props.language} value={props.value} onChange={props.onChange} />
</Input.Wrapper>
)

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,11 +1,24 @@
import { TypographyStylesProvider } from "@mantine/core"
import { Typography } from "@mantine/core"
import type { ReactNode } from "react"
import { tss } from "@/tss"
/**
* This component is used to provide basic styles to html typography elements.
*
* see https://mantine.dev/core/typography-styles-provider/
*/
const useStyles = tss.create(() => ({
// override mantine default typography styles
content: {
paddingLeft: 0,
"& img": {
marginBottom: 0,
},
},
}))
export const BasicHtmlStyles = (props: { children: ReactNode }) => {
return <TypographyStylesProvider pl={0}>{props.children}</TypographyStylesProvider>
const { classes } = useStyles()
return <Typography className={classes.content}>{props.children}</Typography>
}

View File

@@ -0,0 +1,26 @@
import { MantineProvider } from "@mantine/core"
import { render } from "@testing-library/react"
import { describe, expect, it } from "vitest"
import { Content } from "@/components/content/Content"
describe("Content component", () => {
it("renders basic content", () => {
const { container } = render(<Content content="<p>Hello World</p>" />, { wrapper: MantineProvider })
expect(container.querySelector("p")).toHaveTextContent("Hello World")
})
it("renders highlighted text when highlight prop is provided", () => {
const { container } = render(<Content content="Hello World" highlight="World" />, { wrapper: MantineProvider })
expect(container.querySelector("mark")).toHaveTextContent("World")
})
it("renders iframe tag when included in content", () => {
const { container } = render(<Content content='<iframe src="https://example.com"></iframe>' />, { wrapper: MantineProvider })
expect(container.querySelector("iframe")).toHaveAttribute("src", "https://example.com")
})
it("does not render unsupported tags", () => {
const { container } = render(<Content content='<script>alert("test")</script>' />, { wrapper: MantineProvider })
expect(container.querySelector("script")).toBeNull()
})
})

View File

@@ -1,12 +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 { 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 { tss } from "tss"
import styleToObject from "style-to-object"
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
@@ -42,6 +43,7 @@ const transform: TransformCallback = node => {
const nodeHeight = node.getAttribute("height")
const width = nodeWidth ? Number.parseInt(nodeWidth, 10) : undefined
const height = nodeHeight ? Number.parseInt(nodeHeight, 10) : undefined
const style = styleToObject(node.getAttribute("style") ?? "") ?? undefined
const placeholderSize = calculatePlaceholderSize({
width,
height,
@@ -55,6 +57,7 @@ const transform: TransformCallback = node => {
title={title}
width={width}
height="auto"
style={style}
placeholderWidth={placeholderSize.width}
placeholderHeight={placeholderSize.height}
/>
@@ -64,20 +67,19 @@ const transform: TransformCallback = node => {
}
class HighlightMatcher extends Matcher {
private readonly search: string
private readonly regexp: RegExp
constructor(search: string) {
super("highlight")
this.search = escapeStringRegexp(search)
this.regexp = new RegExp(escapeStringRegexp(search).split(" ").join("|"), "i")
}
match(string: string): MatchResponse<unknown> | null {
const pattern = this.search.split(" ").join("|")
return this.doMatch(string, new RegExp(pattern, "i"), () => ({}))
return this.doMatch(string, this.regexp, () => ({}))
}
replaceWith(children: ChildrenNode): Node {
return <Mark>{children}</Mark>
return <Mark key={0}>{children}</Mark>
}
asTag(): string {
@@ -85,6 +87,9 @@ class HighlightMatcher extends Matcher {
}
}
// allow iframe tag
const allowList = [...ALLOWED_TAG_LIST, "iframe"]
// memoize component because Interweave is costly
const Content = React.memo((props: ContentProps) => {
const { classes } = useStyles()
@@ -93,7 +98,7 @@ const Content = React.memo((props: ContentProps) => {
return (
<BasicHtmlStyles>
<Box className={classes.content}>
<Interweave content={props.content} transform={transform} matchers={matchers} />
<Interweave content={props.content} transform={transform} matchers={matchers} allowList={allowList} />
</Box>
</BasicHtmlStyles>
)

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")
@@ -19,7 +21,7 @@ export function Enclosure(props: {
)}
{hasAudio && (
// biome-ignore lint/a11y/useMediaCaption: we don't have any captions for audio
<audio controls>
<audio controls style={{ width: "100%" }}>
<source src={props.enclosureUrl} type={props.enclosureType} />
</audio>
)}

View File

@@ -1,36 +1,34 @@
import { Trans } from "@lingui/macro"
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,
markAllEntries,
markAllAsReadWithConfirmationIfRequired,
markEntry,
reloadEntries,
selectEntry,
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 { KeyboardShortcutsHelp } from "components/KeyboardShortcutsHelp"
import { Loader } from "components/Loader"
import { useBrowserExtension } from "hooks/useBrowserExtension"
import { useMousetrap } from "hooks/useMousetrap"
import { useViewMode } from "hooks/useViewMode"
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() {
const source = useAppSelector(state => state.entries.source)
const entries = useAppSelector(state => state.entries.entries)
const entriesTimestamp = useAppSelector(state => state.entries.timestamp)
const selectedEntryId = useAppSelector(state => state.entries.selectedEntryId)
const hasMore = useAppSelector(state => state.entries.hasMore)
const loading = useAppSelector(state => state.entries.loading)
@@ -38,7 +36,7 @@ export function FeedEntries() {
const scrollingToEntry = useAppSelector(state => state.entries.scrollingToEntry)
const sidebarVisible = useAppSelector(state => state.tree.sidebarVisible)
const customContextMenu = useAppSelector(state => state.user.settings?.customContextMenu)
const { viewMode } = useViewMode()
const viewMode = useAppSelector(state => state.user.localSettings.viewMode)
const dispatch = useAppDispatch()
const { openLinkInBackgroundTab } = useBrowserExtension()
@@ -173,6 +171,8 @@ export function FeedEntries() {
})
)
)
useMousetrap("shift+j", async () => await dispatch(selectNextUnreadTreeItem({ direction: "forward" })))
useMousetrap("shift+k", async () => await dispatch(selectNextUnreadTreeItem({ direction: "backward" })))
useMousetrap("space", () => {
if (selectedEntry) {
if (selectedEntry.expanded) {
@@ -273,17 +273,7 @@ export function FeedEntries() {
})
useMousetrap("shift+a", () => {
// mark all entries as read
dispatch(
markAllEntries({
sourceType: source.type,
req: {
id: source.id,
read: true,
olderThan: Date.now(),
insertedBefore: entriesTimestamp,
},
})
)
dispatch(markAllAsReadWithConfirmationIfRequired())
})
useMousetrap("g a", async () => await dispatch(redirectToRootCategory()))
useMousetrap("f", () => dispatch(toggleSidebar()))
@@ -297,33 +287,25 @@ export function FeedEntries() {
return (
<InfiniteScroll
id="entries"
className={`view-mode-${viewMode}`}
className={`cf-entries cf-view-mode-${viewMode}`}
initialLoad={false}
loadMore={async () => await (!loading && dispatch(loadMoreEntries()))}
hasMore={hasMore}
loader={<Box key={0}>{loading && <Loader />}</Box>}
>
{entries.map(entry => (
<article
<FeedEntry
key={entry.id}
ref={el => {
if (el) el.id = Constants.dom.entryId(entry)
}}
data-id={entry.id}
>
<FeedEntry
entry={entry}
expanded={!!entry.expanded || viewMode === "expanded"}
selected={entry.id === selectedEntryId}
showSelectionIndicator={entry.id === selectedEntryId && (!entry.expanded || viewMode === "expanded")}
maxWidth={sidebarVisible ? Constants.layout.entryMaxWidth : undefined}
onHeaderClick={event => headerClicked(entry, event)}
onHeaderRightClick={event => headerRightClicked(entry, event)}
onBodyClick={() => bodyClicked(entry)}
onSwipedLeft={async () => await swipedLeft(entry)}
/>
</article>
entry={entry}
expanded={!!entry.expanded || viewMode === "expanded"}
selected={entry.id === selectedEntryId}
showSelectionIndicator={entry.id === selectedEntryId && (!entry.expanded || viewMode === "expanded")}
maxWidth={sidebarVisible ? Constants.layout.entryMaxWidth : undefined}
onHeaderClick={event => headerClicked(entry, event)}
onHeaderRightClick={event => headerRightClicked(entry, event)}
onBodyClick={() => bodyClicked(entry)}
onSwipedLeft={async () => await swipedLeft(entry)}
/>
))}
</InfiniteScroll>
)

View File

@@ -1,14 +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 { useViewMode } from "hooks/useViewMode"
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"
@@ -33,8 +32,9 @@ const useStyles = tss
rtl: boolean
showSelectionIndicator: boolean
maxWidth?: number
fontSizePercentage: number
}>()
.create(({ theme, colorScheme, read, expanded, viewMode, rtl, showSelectionIndicator, maxWidth }) => {
.create(({ theme, colorScheme, read, expanded, viewMode, rtl, showSelectionIndicator, maxWidth, fontSizePercentage }) => {
let backgroundColor: string
if (colorScheme === "dark") {
backgroundColor = read ? "inherit" : theme.colors.dark[5]
@@ -84,18 +84,21 @@ const useStyles = tss
},
},
headerLink: {
fontSize: `${fontSizePercentage}%`,
color: "inherit",
textDecoration: "none",
},
body: {
fontSize: `${fontSizePercentage}%`,
direction: rtl ? "rtl" : "ltr",
maxWidth: maxWidth ?? "100%",
},
}
})
export function FeedEntry(props: FeedEntryProps) {
const { viewMode } = useViewMode()
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({
read: props.entry.read,
expanded: props.expanded,
@@ -103,6 +106,7 @@ export function FeedEntry(props: FeedEntryProps) {
rtl: props.entry.rtl,
showSelectionIndicator: props.showSelectionIndicator,
maxWidth: props.maxWidth,
fontSizePercentage,
})
const externalLinkDisplayMode = useAppSelector(state => state.user.settings?.externalLinkIconDisplayMode)
@@ -138,6 +142,10 @@ export function FeedEntry(props: FeedEntryProps) {
const compactHeader = !props.expanded && (viewMode === "title" || viewMode === "cozy")
return (
<Paper
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, {
@@ -177,10 +185,10 @@ export function FeedEntry(props: FeedEntryProps) {
</a>
{props.expanded && (
<Box px={paddingX} pb={paddingY} onClick={props.onBodyClick}>
<Box className={classes.body}>
<Box className={`${classes.body} cf-content`}>
<FeedEntryBody entry={props.entry} />
</Box>
<Divider variant="dashed" my={paddingY} />
<Divider variant="dashed" my={paddingY} className="cf-footer-divider" />
<FeedEntryFooter entry={props.entry} />
</Box>
)}

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/macro"
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/macro"
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()
@@ -37,7 +37,7 @@ export function FeedEntryFooter(props: FeedEntryFooterProps) {
)
return (
<Group justify="space-between">
<Group justify="space-between" className="cf-footer">
<Group gap={spacing}>
{props.entry.markable && (
<ActionButton

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/macro"
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

@@ -1,15 +1,16 @@
import { Trans, msg } from "@lingui/macro"
import { msg } from "@lingui/core/macro"
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

@@ -1,11 +1,11 @@
import { msg } from "@lingui/macro"
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

@@ -1,14 +1,15 @@
import { Trans, msg } from "@lingui/macro"
import { msg } from "@lingui/core/macro"
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/macro"
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() {
@@ -40,8 +40,7 @@ export function Subscribe() {
})
const subscribe = useAsyncCallback(client.feed.subscribe, {
onSuccess: sub => {
dispatch(reloadTree())
dispatch(redirectToFeed(sub.data))
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, Text } 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 { Box } from "@mantine/core"
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,
})
@@ -54,17 +54,17 @@ export function FeedEntryCompactHeader(props: FeedEntryHeaderProps) {
<FeedFavicon url={props.entry.iconUrl} />
</Box>
<OnDesktop>
<Text c="dimmed" className={classes.feedName}>
<Box c="dimmed" className={classes.feedName}>
{props.entry.feedName}
</Text>
</Box>
</OnDesktop>
<Box className={classes.title}>
<FeedEntryTitle entry={props.entry} />
</Box>
<OnDesktop>
<Text c="dimmed" className={classes.date}>
<Box c="dimmed" className={classes.date}>
<RelativeDate date={props.entry.date} />
</Text>
</Box>
</OnDesktop>
{props.showExternalLinkIcon && <OpenExternalLink entry={props.entry} />}
</Box>

View File

@@ -1,10 +1,10 @@
import { Box, Flex, Space, Text } 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 { Box, Flex, Space } from "@mantine/core"
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 {
@@ -22,18 +22,15 @@ const useStyles = tss
main: {
fontWeight: colorScheme === "light" && !read ? "bold" : "inherit",
},
details: {
fontSize: "90%",
},
}))
export function FeedEntryHeader(props: FeedEntryHeaderProps) {
export function FeedEntryHeader(props: Readonly<FeedEntryHeaderProps>) {
const { classes } = useStyles({
read: props.entry.read,
})
return (
<Box>
<Flex align="flex-start" justify="space-between">
<Box className="cf-header">
<Flex align="flex-start" justify="space-between" className="cf-header-title">
<Flex align="flex-start" className={classes.main}>
{props.showStarIcon && (
<Box ml={-5}>
@@ -44,22 +41,20 @@ export function FeedEntryHeader(props: FeedEntryHeaderProps) {
</Flex>
{props.showExternalLinkIcon && <OpenExternalLink entry={props.entry} />}
</Flex>
<Flex align="center" className={classes.details}>
<Flex align="center" className="cf-header-subtitle">
<FeedFavicon url={props.entry.iconUrl} />
<Space w={6} />
<Text c="dimmed">
<Box c="dimmed">
{props.entry.feedName}
<span> · </span>
<RelativeDate date={props.entry.date} />
</Text>
</Box>
</Flex>
{props.expanded && (
<Box className={classes.details}>
<Text c="dimmed">
{props.entry.author && <span>by {props.entry.author}</span>}
{props.entry.author && props.entry.categories && <span>&nbsp;·&nbsp;</span>}
{props.entry.categories && <span>{props.entry.categories}</span>}
</Text>
<Box className="cf-header-details">
{props.entry.author && <span>by {props.entry.author}</span>}
{props.entry.author && props.entry.categories && <span>&nbsp;·&nbsp;</span>}
{props.entry.categories && <span>{props.entry.categories}</span>}
</Box>
)}
</Box>

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/macro"
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/macro"
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

@@ -1,19 +1,12 @@
import { msg } from "@lingui/macro"
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 { 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,
TbArrowUp,
TbChecks,
TbExternalLink,
TbEye,
TbEyeOff,
@@ -24,7 +17,14 @@ import {
TbSortDescending,
TbUser,
} from "react-icons/tb"
import { MarkAllAsReadButton } from "./MarkAllAsReadButton"
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() {
@@ -42,11 +42,14 @@ function HeaderToolbar(props: { children: React.ReactNode }) {
display: "flex",
justifyContent: "space-between",
}}
className="cf-toolbar"
>
{props.children}
</Box>
) : (
<Group gap={spacing}>{props.children}</Group>
<Group gap={spacing} className="cf-toolbar">
{props.children}
</Group>
)
}
@@ -60,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(() => {
@@ -75,7 +74,7 @@ export function Header() {
if (!settings) return <Loader />
return (
<Center>
<Center className="cf-toolbar-wrapper">
<HeaderToolbar>
<ActionButton
icon={<TbArrowUp size={iconSize} />}
@@ -111,7 +110,11 @@ export function Header() {
label={msg`Refresh`}
onClick={async () => await dispatch(reloadEntries())}
/>
<MarkAllAsReadButton iconSize={iconSize} />
<ActionButton
icon={<TbChecks size={iconSize} />}
label={msg`Mark all as read`}
onClick={() => dispatch(markAllAsReadWithConfirmationIfRequired())}
/>
<HeaderDivider />

View File

@@ -1,97 +0,0 @@
import { Trans, msg } from "@lingui/macro"
import { Button, Code, Group, Modal, Slider, Stack, Text } from "@mantine/core"
import { markAllEntries } from "app/entries/thunks"
import { useAppDispatch, useAppSelector } from "app/store"
import { ActionButton } from "components/ActionButton"
import { useState } from "react"
import { TbChecks } from "react-icons/tb"
export function MarkAllAsReadButton(props: { iconSize: number }) {
const [opened, setOpened] = useState(false)
const [threshold, setThreshold] = useState(0)
const source = useAppSelector(state => state.entries.source)
const sourceLabel = useAppSelector(state => state.entries.sourceLabel)
const entriesTimestamp = useAppSelector(state => state.entries.timestamp) ?? Date.now()
const markAllAsReadConfirmation = useAppSelector(state => state.user.settings?.markAllAsReadConfirmation)
const dispatch = useAppDispatch()
const buttonClicked = () => {
if (markAllAsReadConfirmation) {
setThreshold(0)
setOpened(true)
} else {
dispatch(
markAllEntries({
sourceType: source.type,
req: {
id: source.id,
read: true,
olderThan: Date.now(),
insertedBefore: entriesTimestamp,
},
})
)
}
}
return (
<>
<Modal opened={opened} onClose={() => setOpened(false)} title={<Trans>Mark all entries as read</Trans>}>
<Stack>
<Text size="sm">
{threshold === 0 && (
<Trans>
Are you sure you want to mark all entries of <Code>{sourceLabel}</Code> as read?
</Trans>
)}
{threshold > 0 && (
<Trans>
Are you sure you want to mark entries older than {threshold} days of <Code>{sourceLabel}</Code> as read?
</Trans>
)}
</Text>
<Slider
py="xl"
min={0}
max={28}
marks={[
{ value: 0, label: "0" },
{ value: 7, label: "7" },
{ value: 14, label: "14" },
{ value: 21, label: "21" },
{ value: 28, label: "28" },
]}
value={threshold}
onChange={setThreshold}
/>
<Group justify="flex-end">
<Button variant="default" onClick={() => setOpened(false)}>
<Trans>Cancel</Trans>
</Button>
<Button
color="red"
onClick={() => {
setOpened(false)
dispatch(
markAllEntries({
sourceType: source.type,
req: {
id: source.id,
read: true,
olderThan: Date.now() - threshold * 24 * 60 * 60 * 1000,
insertedBefore: entriesTimestamp,
},
})
)
}}
>
<Trans>Confirm</Trans>
</Button>
</Group>
</Stack>
</Modal>
<ActionButton icon={<TbChecks size={props.iconSize} />} label={msg`Mark all as read`} onClick={buttonClicked} />
</>
)
}

View File

@@ -1,4 +1,4 @@
import { Trans } from "@lingui/macro"
import { Trans } from "@lingui/react/macro"
import {
Box,
Divider,
@@ -7,15 +7,12 @@ import {
Menu,
SegmentedControl,
type SegmentedControlItem,
Slider,
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 { useViewMode } from "hooks/useViewMode"
import { type ReactNode, useState } from "react"
import dayjs from "dayjs"
import { type ReactNode, useEffect, useState } from "react"
import {
TbChartLine,
TbHeartFilled,
@@ -32,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
@@ -90,14 +95,30 @@ const viewModeData: ViewModeControlItem[] = [
},
]
export function ProfileMenu(props: ProfileMenuProps) {
export function ProfileMenu(props: Readonly<ProfileMenuProps>) {
const [opened, setOpened] = useState(false)
const { viewMode, setViewMode } = useViewMode()
// 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)
const viewMode = useAppSelector(state => state.user.localSettings.viewMode)
const forceRefreshCooldownDuration = useAppSelector(state => state.server.serverInfos?.forceRefreshCooldownDuration)
const fontSizePercentage = useAppSelector(state => state.user.localSettings.fontSizePercentage)
const dispatch = useAppDispatch()
const { colorScheme, setColorScheme } = useMantineColorScheme()
const nextAvailableForceRefresh = profile?.lastForceRefresh
? profile.lastForceRefresh + (forceRefreshCooldownDuration ?? 0)
: now.getTime()
const forceRefreshEnabled = nextAvailableForceRefresh <= now.getTime()
const logout = () => {
window.location.href = "logout"
}
@@ -118,18 +139,32 @@ export function ProfileMenu(props: ProfileMenuProps) {
</Menu.Item>
<Menu.Item
leftSection={<TbWorldDownload size={iconSize} />}
onClick={async () =>
await client.feed.refreshAll().then(() => {
disabled={!forceRefreshEnabled}
onClick={async () => {
setOpened(false)
try {
await client.feed.refreshAll()
// reload profile to update last force refresh timestamp
await dispatch(reloadProfile())
showNotification({
message: <Trans>Your feeds have been queued for refresh.</Trans>,
color: "green",
autoClose: 1000,
})
setOpened(false)
})
}
} catch {
showNotification({
message: <Trans>Force fetching feeds is not yet available.</Trans>,
color: "red",
autoClose: 2000,
})
}
}}
>
<Trans>Fetch all my feeds now</Trans>
{!forceRefreshEnabled && <span> ({dayjs.duration(nextAvailableForceRefresh - now.getTime()).format("HH:mm:ss")})</span>}
</Menu.Item>
<Divider />
@@ -156,10 +191,26 @@ export function ProfileMenu(props: ProfileMenuProps) {
orientation="vertical"
data={viewModeData}
value={viewMode}
onChange={e => setViewMode(e as ViewMode)}
onChange={e => dispatch(setViewMode(e as ViewMode))}
mb="xs"
/>
<Divider />
<Menu.Label>
<Trans>Font size</Trans>
</Menu.Label>
<Slider
min={50}
max={150}
step={5}
marks={[{ value: 100 }]}
label={v => `${v}%`}
mb="xs"
value={fontSizePercentage}
onChange={value => dispatch(setFontSizePercentage(value))}
/>
{admin && (
<>
<Divider />

View File

@@ -1,9 +1,10 @@
import type { MetricGauge } from "app/types"
import { NumberFormatter } from "@mantine/core"
import type { MetricGauge } from "@/app/types"
interface MeterProps {
interface GaugeProps {
gauge: MetricGauge
}
export function Gauge(props: MeterProps) {
return <span>{props.gauge.value}</span>
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,14 +1,15 @@
import { Trans } from "@lingui/macro"
import { Box, Button, Group, Stack } from "@mantine/core"
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 { 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
@@ -57,13 +58,23 @@ export function CustomCodeSettings() {
<form onSubmit={form.onSubmit(saveCustomCode.execute)}>
<Stack>
<CodeEditor
description={<Trans>Custom CSS rules that will be applied</Trans>}
label={<Trans>Custom CSS rules that will be applied</Trans>}
description={
<Anchor
href={Constants.customCssDocumentationUrl}
target="_blank"
rel="noreferrer"
style={{ fontSize: "inherit" }}
>
<Trans>Link to the documentation</Trans>
</Anchor>
}
language="css"
{...form.getInputProps("customCss")}
/>
<CodeEditor
description={<Trans>Custom JS code that will be executed on page load</Trans>}
label={<Trans>Custom JS code that will be executed on page load</Trans>}
language="javascript"
{...form.getInputProps("customJs")}
/>

View File

@@ -1,25 +1,34 @@
import { Trans, msg } from "@lingui/macro"
import { msg } from "@lingui/core/macro"
import { useLingui } from "@lingui/react"
import { Divider, Group, Radio, Select, SimpleGrid, Stack, Switch } from "@mantine/core"
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,
changeDisableMobileSwipe,
changeDisablePullToRefresh,
changeEntriesToKeepOnTopWhenScrolling,
changeExternalLinkIconDisplayMode,
changeInfrequentThresholdDays,
changeLanguage,
changeMarkAllAsReadConfirmation,
changeMarkAllAsReadNavigateToUnread,
changeMobileFooter,
changePrimaryColor,
changeScrollMarks,
changeScrollMode,
changeScrollSpeed,
changeSharingSetting,
changeShowRead,
changeStarIconDisplayMode,
} from "app/user/thunks"
import { locales } from "i18n"
import type { ReactNode } from "react"
changeUnreadCountFavicon,
changeUnreadCountTitle,
} from "@/app/user/thunks"
import { locales } from "@/i18n"
export function DisplaySettings() {
const language = useAppSelector(state => state.user.settings?.language)
@@ -27,14 +36,22 @@ export function DisplaySettings() {
const showRead = useAppSelector(state => state.user.settings?.showRead)
const scrollMarks = useAppSelector(state => state.user.settings?.scrollMarks)
const scrollMode = useAppSelector(state => state.user.settings?.scrollMode)
const entriesToKeepOnTop = useAppSelector(state => state.user.settings?.entriesToKeepOnTopWhenScrolling)
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 disableMobileSwipe = useAppSelector(state => state.user.settings?.disableMobileSwipe)
const infrequentThresholdDays = useAppSelector(state => state.user.settings?.infrequentThresholdDays)
const sharingSettings = useAppSelector(state => state.user.settings?.sharingSettings)
const dispatch = useAppDispatch()
const primaryColor = useAppSelector(state => state.user.settings?.primaryColor) || Constants.theme.defaultPrimaryColor
const { _ } = useLingui()
const dispatch = useAppDispatch()
const scrollModeOptions: Record<ScrollMode, ReactNode> = {
always: <Trans>Always</Trans>,
@@ -61,10 +78,35 @@ export function DisplaySettings() {
},
]
const colorData: ComboboxData = [
{ value: "dark", label: _(msg`Dark`) },
{ value: "gray", label: _(msg`Gray`) },
{ value: "red", label: _(msg`Red`) },
{ value: "pink", label: _(msg`Pink`) },
{ value: "grape", label: _(msg`Grape`) },
{ value: "violet", label: _(msg`Violet`) },
{ value: "indigo", label: _(msg`Indigo`) },
{ value: "blue", label: _(msg`Blue`) },
{ value: "cyan", label: _(msg`Cyan`) },
{ value: "green", label: _(msg`Green`) },
{ value: "lime", label: _(msg`Lime`) },
{ value: "yellow", label: _(msg`Yellow`) },
{ value: "orange", label: _(msg`Orange`) },
{ value: "teal", label: _(msg`Teal`) },
].sort((a, b) => a.label.localeCompare(b.label))
const colorRenderer: SelectProps["renderOption"] = ({ option }) => (
<Group>
<Box h={18} w={18} bg={option.value} />
<Box>{option.label}</Box>
</Group>
)
return (
<Stack>
<Divider label={<Trans>Display</Trans>} labelPosition="center" />
<Select
description={<Trans>Language</Trans>}
label={<Trans>Language</Trans>}
value={language}
data={locales.map(l => ({
value: l.key,
@@ -73,6 +115,14 @@ export function DisplaySettings() {
onChange={async s => await (s && dispatch(changeLanguage(s)))}
/>
<Select
label={<Trans>Primary color</Trans>}
data={colorData}
value={primaryColor}
onChange={async value => value && (await dispatch(changePrimaryColor(value)))}
renderOption={colorRenderer}
/>
<Switch
label={<Trans>Show feeds and categories with no unread entries</Trans>}
checked={showRead}
@@ -85,36 +135,41 @@ 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>Entry headers</Trans>} labelPosition="center" />
<Select
description={<Trans>Show star icon</Trans>}
value={starIconDisplayMode}
data={displayModeData}
onChange={async s => await dispatch(changeStarIconDisplayMode(s as IconDisplayMode))}
/>
<Select
description={<Trans>Show external link icon</Trans>}
value={externalLinkIconDisplayMode}
data={displayModeData}
onChange={async s => await dispatch(changeExternalLinkIconDisplayMode(s as IconDisplayMode))}
/>
<Switch
label={<Trans>Show CommaFeed's own context menu on right click</Trans>}
checked={customContextMenu}
onChange={async e => await dispatch(changeCustomContextMenu(e.currentTarget.checked))}
label={<Trans>On mobile, disable swipe gesture to open the menu</Trans>}
checked={disableMobileSwipe}
onChange={async e => await dispatch(changeDisableMobileSwipe(e.currentTarget.checked))}
/>
<NumberInput
label={<Trans>Infrequent posts threshold (days)</Trans>}
description={<Trans>Feeds posting less often than this (on average) will appear in the Infrequent view</Trans>}
min={1}
value={infrequentThresholdDays}
onChange={async value => await dispatch(changeInfrequentThresholdDays(+value))}
/>
<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}
@@ -127,6 +182,14 @@ export function DisplaySettings() {
</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}
@@ -139,6 +202,42 @@ export function DisplaySettings() {
onChange={async e => await dispatch(changeScrollMarks(e.currentTarget.checked))}
/>
<Divider label={<Trans>Browser tab</Trans>} labelPosition="center" />
<Switch
label={<Trans>Show unread count in tab title</Trans>}
checked={unreadCountTitle}
onChange={async e => await dispatch(changeUnreadCountTitle(e.currentTarget.checked))}
/>
<Switch
label={<Trans>Show unread count in tab favicon</Trans>}
checked={unreadCountFavicon}
onChange={async e => await dispatch(changeUnreadCountFavicon(e.currentTarget.checked))}
/>
<Divider label={<Trans>Entry headers</Trans>} labelPosition="center" />
<Select
label={<Trans>Show star icon</Trans>}
value={starIconDisplayMode}
data={displayModeData}
onChange={async s => await dispatch(changeStarIconDisplayMode(s as IconDisplayMode))}
/>
<Select
label={<Trans>Show external link icon</Trans>}
value={externalLinkIconDisplayMode}
data={displayModeData}
onChange={async s => await dispatch(changeExternalLinkIconDisplayMode(s as IconDisplayMode))}
/>
<Switch
label={<Trans>Show CommaFeed's own context menu on right click</Trans>}
checked={customContextMenu}
onChange={async e => await dispatch(changeCustomContextMenu(e.currentTarget.checked))}
/>
<Divider label={<Trans>Sharing sites</Trans>} labelPosition="center" />
<SimpleGrid cols={2}>

View File

@@ -1,17 +1,18 @@
import { Trans, msg } from "@lingui/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
@@ -19,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
@@ -51,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(() => {
@@ -131,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/macro"
import { Trans } from "@lingui/react/macro"
import { Box, Stack } from "@mantine/core"
import { Constants } from "app/constants"
import React from "react"
import { TbChevronDown, TbChevronRight, TbClock, TbInbox, TbStar, TbTag } from "react-icons/tb"
import { Constants } from "@/app/constants"
import {
redirectToCategory,
redirectToCategoryDetails,
@@ -8,20 +10,20 @@ import {
redirectToFeedDetails,
redirectToTag,
redirectToTagDetails,
} from "app/redirect/thunks"
import { useAppDispatch, useAppSelector } from "app/store"
import { collapseTreeCategory } from "app/tree/thunks"
import type { Category, Subscription } from "app/types"
import { 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"
const allIcon = <TbInbox size={16} />
const starredIcon = <TbStar size={16} />
const infrequentIcon = <TbClock size={16} />
const tagIcon = <TbTag size={16} />
const expandedIcon = <TbChevronDown size={16} />
const collapsedIcon = <TbChevronRight size={16} />
@@ -33,8 +35,27 @@ export function Tree() {
const source = useAppSelector(state => state.entries.source)
const tags = useAppSelector(state => state.user.tags)
const showRead = useAppSelector(state => state.user.settings?.showRead)
const infrequentThresholdDays = useAppSelector(
state => state.user.settings?.infrequentThresholdDays ?? Constants.infrequentThresholdDaysDefault
)
const infrequentThresholdMs = infrequentThresholdDays * 24 * 3600 * 1000
const dispatch = useAppDispatch()
const isFeedDisplayed = (feed: Subscription) => {
const isCurrentFeed = source.type === "feed" && source.id === String(feed.id)
return isCurrentFeed || feed.unread > 0 || showRead
}
const isCategoryDisplayed = (category: Category): boolean => {
const isCurrentCategory = source.type === "category" && source.id === category.id
return (
isCurrentCategory ||
showRead ||
category.children.some(c => isCategoryDisplayed(c)) ||
category.feeds.some(f => isFeedDisplayed(f))
)
}
const feedClicked = (e: React.MouseEvent, id: string) => {
if (e.detail === 2) {
dispatch(redirectToFeedDetails(id))
@@ -74,10 +95,12 @@ export function Tree() {
name={<Trans>All</Trans>}
icon={allIcon}
unread={categoryUnreadCount(root)}
hasNewEntries={categoryHasNewEntries(root)}
selected={source.type === "category" && source.id === Constants.categories.all.id}
expanded={false}
level={0}
hasError={false}
hasWarning={false}
onClick={categoryClicked}
/>
)
@@ -88,30 +111,50 @@ export function Tree() {
name={<Trans>Starred</Trans>}
icon={starredIcon}
unread={0}
hasNewEntries={false}
selected={source.type === "category" && source.id === Constants.categories.starred.id}
expanded={false}
level={0}
hasError={false}
hasWarning={false}
onClick={categoryClicked}
/>
)
const infrequentCategoryNode = () => (
<TreeNode
id={Constants.categories.infrequent.id}
type="category"
name={<Trans>Infrequent</Trans>}
icon={infrequentIcon}
unread={categoryUnreadCount(root, infrequentThresholdMs)}
hasNewEntries={categoryHasNewEntries(root, infrequentThresholdMs)}
selected={source.type === "category" && source.id === Constants.categories.infrequent.id}
expanded={false}
level={0}
hasError={false}
hasWarning={false}
onClick={categoryClicked}
/>
)
const categoryNode = (category: Category, level = 0) => {
const unreadCount = categoryUnreadCount(category)
if (unreadCount === 0 && !showRead) return null
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}
type="category"
name={category.name}
icon={category.expanded ? expandedIcon : collapsedIcon}
unread={unreadCount}
unread={categoryUnreadCount(category)}
hasNewEntries={categoryHasNewEntries(category)}
selected={source.type === "category" && source.id === category.id}
expanded={category.expanded}
level={level}
hasError={hasError}
hasWarning={hasWarning}
onClick={categoryClicked}
onIconClick={e => categoryIconClicked(e, category)}
key={category.id}
@@ -119,8 +162,8 @@ export function Tree() {
)
}
const feedNode = (feed: Subscription, level = 0) => {
if (feed.unread === 0 && !showRead) return null
const feedNode = (feed: TreeSubscription, level = 0) => {
if (!isFeedDisplayed(feed)) return null
return (
<TreeNode
@@ -129,9 +172,11 @@ export function Tree() {
name={feed.name}
icon={feed.iconUrl}
unread={feed.unread}
hasNewEntries={!!feed.hasNewEntries}
selected={source.type === "feed" && source.id === String(feed.id)}
level={level}
hasError={feed.errorCount > errorThreshold}
hasWarning={!!feed.filterLegacy}
onClick={feedClicked}
key={feed.id}
/>
@@ -145,9 +190,11 @@ export function Tree() {
name={tag}
icon={tagIcon}
unread={0}
hasNewEntries={false}
selected={source.type === "tag" && source.id === tag}
level={0}
hasError={false}
hasWarning={false}
onClick={tagClicked}
key={tag}
/>
@@ -168,9 +215,10 @@ export function Tree() {
<OnDesktop>
<TreeSearch feeds={feeds} />
</OnDesktop>
<Box>
<Box className="cf-tree">
{allCategoryNode()}
{starredCategoryNode()}
{infrequentCategoryNode()}
{root.children.map(c => recursiveCategoryNode(c))}
{root.feeds.map(f => feedNode(f))}
{tags?.map(tag => tagNode(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,8 @@ 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
}
@@ -23,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 {
@@ -58,29 +63,30 @@ 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 (
<Box
py={1}
pl={props.level * 20}
className={classes.node}
className={`${classes.node} cf-treenode cf-treenode-${props.type}`}
onClick={(e: React.MouseEvent) => props.onClick(e, props.id)}
data-id={props.id}
data-type={props.type}
data-unread-count={props.unread}
>
<Box mr={6} onClick={(e: React.MouseEvent) => props.onIconClick?.(e, props.id)}>
<Box mr={6} onClick={(e: React.MouseEvent) => props.onIconClick?.(e, props.id)} className="cf-treenode-icon">
<Center>{typeof props.icon === "string" ? <FeedFavicon url={props.icon} /> : props.icon}</Center>
</Box>
<Box className={classes.nodeText}>{props.name}</Box>
{!props.expanded && (
<Box>
<UnreadCount unreadCount={props.unread} />
<Box className="cf-treenode-unread-count">
<UnreadCount unreadCount={props.unread} showIndicator={props.hasNewEntries} />
</Box>
)}
</Box>

View File

@@ -1,19 +1,20 @@
import { Trans, msg } from "@lingui/macro"
import { msg } from "@lingui/core/macro"
import { useLingui } from "@lingui/react"
import { TextInput } from "@mantine/core"
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()
@@ -32,7 +33,7 @@ export function TreeSearch(props: TreeSearchProps) {
useMousetrap("g u", () => spotlight.open())
return (
<>
<Box className="cf-treesearch">
<TextInput
placeholder={_(msg`Search`)}
leftSection={searchIcon}
@@ -57,6 +58,6 @@ export function TreeSearch(props: TreeSearchProps) {
}}
nothingFound={<Trans>Nothing found</Trans>}
/>
</>
</Box>
)
}

View File

@@ -1,16 +1,25 @@
import { Badge, Tooltip } from "@mantine/core"
import { Constants } from "app/constants"
import { tss } from "tss"
import { Badge, Indicator, Tooltip } from "@mantine/core"
import { Constants } from "@/app/constants"
import { tss } from "@/tss"
const useStyles = tss.create(() => ({
badge: {
width: "3.2rem",
// for some reason, mantine Badge has "cursor: 'default'"
cursor: "pointer",
cursor: "inherit",
},
indicator: {
// ensure the indicator is not shown above the app header
zIndex: 0,
},
}))
export function UnreadCount(props: { unreadCount: number }) {
export function UnreadCount(
props: Readonly<{
unreadCount: number
showIndicator: boolean
}>
) {
const { classes } = useStyles()
if (props.unreadCount <= 0) return null
@@ -18,9 +27,19 @@ export function UnreadCount(props: { unreadCount: number }) {
const count = props.unreadCount >= 10000 ? "10k+" : props.unreadCount
return (
<Tooltip label={props.unreadCount} disabled={props.unreadCount === count} openDelay={Constants.tooltip.delay}>
<Badge className={classes.badge} variant="light" fullWidth>
{count}
</Badge>
<Indicator
disabled={!props.showIndicator}
size={4}
offset={10}
position="middle-start"
classNames={{
indicator: classes.indicator,
}}
>
<Badge className={`${classes.badge} cf-badge`} variant="light" fullWidth>
{count}
</Badge>
</Indicator>
</Tooltip>
)
}

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/macro"
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
@@ -8,28 +8,28 @@ interface Step {
}
export const useAppLoading = () => {
const profile = useAppSelector(state => state.user.profile)
const settings = useAppSelector(state => state.user.settings)
const rootCategory = useAppSelector(state => state.tree.rootCategory)
const tags = useAppSelector(state => state.user.tags)
const profileLoaded = useAppSelector(state => !!state.user.profile)
const settingsLoaded = useAppSelector(state => !!state.user.settings)
const rootCategoryLoaded = useAppSelector(state => !!state.tree.rootCategory)
const tagsLoaded = useAppSelector(state => !!state.user.tags)
const { _ } = useLingui()
const steps: Step[] = [
{
label: _(msg`Loading settings...`),
done: !!settings,
done: settingsLoaded,
},
{
label: _(msg`Loading profile...`),
done: !!profile,
done: profileLoaded,
},
{
label: _(msg`Loading subscriptions...`),
done: !!rootCategory,
done: rootCategoryLoaded,
},
{
label: _(msg`Loading tags...`),
done: !!tags,
done: tagsLoaded,
},
]

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,10 @@
import { useEffect, useState } from "react"
export const useNow = (interval = 1000): Date => {
const [time, setTime] = useState(new Date())
useEffect(() => {
const t = setInterval(() => setTime(new Date()), interval)
return () => clearInterval(t)
}, [interval])
return time
}

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,7 +0,0 @@
import type { ViewMode } from "app/types"
import useLocalStorage from "use-local-storage"
export function useViewMode() {
const [viewMode, setViewMode] = useLocalStorage<ViewMode>("view-mode", "detailed")
return { viewMode, setViewMode }
}

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