mirror of
https://github.com/Athou/commafeed.git
synced 2026-10-24 14:09:23 +00:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5dc5b3795e | ||
|
|
f5f77a80a3 | ||
|
|
1d1099492e | ||
|
|
ccc2564929 | ||
|
|
084574ffd4 | ||
|
|
6a6978c491 | ||
|
|
0399375288 | ||
|
|
394346fbc1 | ||
|
|
0feec109bd | ||
|
|
fdb5c9b536 | ||
|
|
f7ad8aed60 | ||
|
|
4621d7e79f | ||
|
|
b64a49cfb0 | ||
|
|
aaddfbaf40 | ||
|
|
994da5e1ee | ||
|
|
811e282e28 | ||
|
|
892fcf8168 | ||
|
|
032ee9243f | ||
|
|
30cdf34d56 | ||
|
|
fd52caa3fd | ||
|
|
9788712808 | ||
|
|
af9d086f05 | ||
|
|
fc7190868e |
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -141,7 +141,7 @@ jobs:
|
|||||||
|
|
||||||
# Docker
|
# Docker
|
||||||
- name: Login to Container Registry
|
- name: Login to Container Registry
|
||||||
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
|
uses: docker/login-action@81c6f93d4bc991e510b342a00b419b3bb4efc5c6 # v4.7.0
|
||||||
if: ${{ env.DOCKERHUB_USERNAME != '' }}
|
if: ${{ env.DOCKERHUB_USERNAME != '' }}
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [7.4.1]
|
||||||
|
|
||||||
|
- Fix entries being marked as read when scrolling back to an entry that was explicitly marked as unread (#2337)
|
||||||
|
- Add a global failsafe timeout to the new HTTP/2 client to prevent it from hanging indefinitely
|
||||||
|
- Add OCI source label to container images (#2335)
|
||||||
|
|
||||||
## [7.4.0]
|
## [7.4.0]
|
||||||
|
|
||||||
- Add support for HTTP/2 when fetching feeds (#2317)
|
- Add support for HTTP/2 when fetching feeds (#2317)
|
||||||
|
|||||||
226
commafeed-client/package-lock.json
generated
226
commafeed-client/package-lock.json
generated
@@ -10,15 +10,15 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/react": "11.14.0",
|
"@emotion/react": "11.14.0",
|
||||||
"@fontsource/open-sans": "5.3.0",
|
"@fontsource/open-sans": "5.3.0",
|
||||||
"@lingui/core": "6.9.1",
|
"@lingui/core": "6.10.0",
|
||||||
"@lingui/react": "6.9.1",
|
"@lingui/react": "6.10.0",
|
||||||
"@mantine/core": "9.7.2",
|
"@mantine/core": "9.7.3",
|
||||||
"@mantine/dates": "9.7.2",
|
"@mantine/dates": "9.7.3",
|
||||||
"@mantine/form": "9.7.2",
|
"@mantine/form": "9.7.3",
|
||||||
"@mantine/hooks": "9.7.2",
|
"@mantine/hooks": "9.7.3",
|
||||||
"@mantine/modals": "9.7.2",
|
"@mantine/modals": "9.7.3",
|
||||||
"@mantine/notifications": "9.7.2",
|
"@mantine/notifications": "9.7.3",
|
||||||
"@mantine/spotlight": "9.7.2",
|
"@mantine/spotlight": "9.7.3",
|
||||||
"@monaco-editor/react": "4.7.0",
|
"@monaco-editor/react": "4.7.0",
|
||||||
"@react-querybuilder/mantine": "8.25.0",
|
"@react-querybuilder/mantine": "8.25.0",
|
||||||
"@reduxjs/toolkit": "2.13.0",
|
"@reduxjs/toolkit": "2.13.0",
|
||||||
@@ -49,8 +49,8 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/types": "^8.0.6",
|
"@babel/types": "^8.0.6",
|
||||||
"@biomejs/biome": "2.5.15",
|
"@biomejs/biome": "2.5.15",
|
||||||
"@lingui/cli": "6.9.1",
|
"@lingui/cli": "6.10.0",
|
||||||
"@lingui/vite-plugin": "6.9.1",
|
"@lingui/vite-plugin": "6.10.0",
|
||||||
"@testing-library/jest-dom": "7.0.1",
|
"@testing-library/jest-dom": "7.0.1",
|
||||||
"@testing-library/react": "16.3.3",
|
"@testing-library/react": "16.3.3",
|
||||||
"@testing-library/user-event": "14.6.8",
|
"@testing-library/user-event": "14.6.8",
|
||||||
@@ -64,7 +64,7 @@
|
|||||||
"babel-plugin-react-compiler": "^1.0.0",
|
"babel-plugin-react-compiler": "^1.0.0",
|
||||||
"jsdom": "30.1.3",
|
"jsdom": "30.1.3",
|
||||||
"typescript": "7.0.2",
|
"typescript": "7.0.2",
|
||||||
"vite": "8.3.4",
|
"vite": "8.3.5",
|
||||||
"vite-plugin-checker": "0.14.5",
|
"vite-plugin-checker": "0.14.5",
|
||||||
"vitest": "5.0.5",
|
"vitest": "5.0.5",
|
||||||
"yaml": "2.9.1"
|
"yaml": "2.9.1"
|
||||||
@@ -1216,27 +1216,26 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@lingui/babel-plugin-extract-messages": {
|
"node_modules/@lingui/babel-plugin-extract-messages": {
|
||||||
"version": "6.9.1",
|
"version": "6.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/@lingui/babel-plugin-extract-messages/-/babel-plugin-extract-messages-6.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/@lingui/babel-plugin-extract-messages/-/babel-plugin-extract-messages-6.10.0.tgz",
|
||||||
"integrity": "sha512-oRN0J93Oq0+1FXV7nOGSlKTuqJz3TfvadebqG+N4YuN9ZxNgkInW8XH6+2sjDBDucJbjUivgw7J5xvOWsgDm0A==",
|
"integrity": "sha512-CGA6MdExnxm+QWI0Ebi6GhSSrD9hofVrYFdh6GxRZ2h3FMV06OJmmjoMm8D8EdH7T6N2wRISM14RI4InvbV5RA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@lingui/conf": "6.9.1"
|
"@lingui/conf": "6.10.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=22.19.0"
|
"node": ">=22.19.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@lingui/babel-plugin-lingui-macro": {
|
"node_modules/@lingui/babel-plugin-lingui-macro": {
|
||||||
"version": "6.9.1",
|
"version": "6.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/@lingui/babel-plugin-lingui-macro/-/babel-plugin-lingui-macro-6.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/@lingui/babel-plugin-lingui-macro/-/babel-plugin-lingui-macro-6.10.0.tgz",
|
||||||
"integrity": "sha512-KhOXhdBoWbyCAb76r49+9QojBkWyMfFqD5PF9Irl0av4x0rGdxknm/bj3PzB8nx1tq2+b3mAgyQCJAMwdvY2Jg==",
|
"integrity": "sha512-g9COw73hIICzmu4glu0CpwPWymEmcYCVZAOX6EyvtRLGQRCtNAuP/33ClcqW0c1NsE7wwKL/TYy3g5kCGrYdUg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/types": "^7.20.7",
|
"@lingui/conf": "6.10.0",
|
||||||
"@lingui/conf": "6.9.1",
|
"@lingui/message-utils": "6.10.0"
|
||||||
"@lingui/message-utils": "6.9.1"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=22.19.0"
|
"node": ">=22.19.0"
|
||||||
@@ -1250,41 +1249,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@lingui/babel-plugin-lingui-macro/node_modules/@babel/helper-string-parser": {
|
|
||||||
"version": "7.29.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
|
|
||||||
"integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.9.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@lingui/babel-plugin-lingui-macro/node_modules/@babel/helper-validator-identifier": {
|
|
||||||
"version": "7.29.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
|
|
||||||
"integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.9.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@lingui/babel-plugin-lingui-macro/node_modules/@babel/types": {
|
|
||||||
"version": "7.29.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz",
|
|
||||||
"integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/helper-string-parser": "^7.29.7",
|
|
||||||
"@babel/helper-validator-identifier": "^7.29.7"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.9.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@lingui/cli": {
|
"node_modules/@lingui/cli": {
|
||||||
"version": "6.9.1",
|
"version": "6.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/@lingui/cli/-/cli-6.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/@lingui/cli/-/cli-6.10.0.tgz",
|
||||||
"integrity": "sha512-X00XHnA980zzUwOsyKlbRkC4QhcgGXQG5LD6IHDYeI27iqtFNxBwi73jzJ9hO62o+qanNVusI+1gIqd4ZKagag==",
|
"integrity": "sha512-h8fk9GkASZDW5s1ZGSeIz0CCA6v9pm8zr9hJEuWtsrjT+YJKxHPVyLuSlAavZzsi4l2DypkQeJHqbBW1POAZaA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -1292,12 +1260,12 @@
|
|||||||
"@babel/generator": "^7.28.5",
|
"@babel/generator": "^7.28.5",
|
||||||
"@babel/parser": "^7.22.0",
|
"@babel/parser": "^7.22.0",
|
||||||
"@babel/types": "^7.21.2",
|
"@babel/types": "^7.21.2",
|
||||||
"@lingui/babel-plugin-extract-messages": "6.9.1",
|
"@lingui/babel-plugin-extract-messages": "6.10.0",
|
||||||
"@lingui/babel-plugin-lingui-macro": "6.9.1",
|
"@lingui/babel-plugin-lingui-macro": "6.10.0",
|
||||||
"@lingui/conf": "6.9.1",
|
"@lingui/conf": "6.10.0",
|
||||||
"@lingui/core": "6.9.1",
|
"@lingui/core": "6.10.0",
|
||||||
"@lingui/format-po": "6.9.1",
|
"@lingui/format-po": "6.10.0",
|
||||||
"@lingui/message-utils": "6.9.1",
|
"@lingui/message-utils": "6.10.0",
|
||||||
"@lingui/native-tools": "^0.1.6",
|
"@lingui/native-tools": "^0.1.6",
|
||||||
"chokidar": "5.0.0",
|
"chokidar": "5.0.0",
|
||||||
"cli-table3": "^0.6.5",
|
"cli-table3": "^0.6.5",
|
||||||
@@ -1375,9 +1343,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@lingui/conf": {
|
"node_modules/@lingui/conf": {
|
||||||
"version": "6.9.1",
|
"version": "6.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/@lingui/conf/-/conf-6.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/@lingui/conf/-/conf-6.10.0.tgz",
|
||||||
"integrity": "sha512-9kDH5v9AToFOemUzNrhDO9NjDngu0mvTUjdO4r9gSOUO7xydpKh0oL7itHGT2PKx1HIbpDXUJxkIzGZ7FcW2GQ==",
|
"integrity": "sha512-eyaJH0q9w/jRokuuozk54n23CPKxw0bGRECTzdIjrebeLXn96dK408cuNjjf/d6FNL6iM8ciZuW8YuGLvGneaA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"jest-validate": "^29.4.3",
|
"jest-validate": "^29.4.3",
|
||||||
@@ -1390,13 +1358,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@lingui/core": {
|
"node_modules/@lingui/core": {
|
||||||
"version": "6.9.1",
|
"version": "6.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/@lingui/core/-/core-6.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/@lingui/core/-/core-6.10.0.tgz",
|
||||||
"integrity": "sha512-/WsHqJMxx1ONTI9i8iWMJmWodZhV6GjS93JziTmot2x18fF2WlmVQBjDAzGLK3ZcX/2D/6SF7vv72MIJip3Jkg==",
|
"integrity": "sha512-A6phbNlbpsShJMYiOZMrVSubeb71FWeuOuEktBfbSmPpKqLIzf16Mod/t7mmG6m3ei4HCVUPKE8RuknHirrNjA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@lingui/babel-plugin-lingui-macro": "6.9.1",
|
"@lingui/babel-plugin-lingui-macro": "6.10.0",
|
||||||
"@lingui/message-utils": "6.9.1"
|
"@lingui/message-utils": "6.10.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=22.19.0"
|
"node": ">=22.19.0"
|
||||||
@@ -1411,14 +1379,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@lingui/format-po": {
|
"node_modules/@lingui/format-po": {
|
||||||
"version": "6.9.1",
|
"version": "6.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/@lingui/format-po/-/format-po-6.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/@lingui/format-po/-/format-po-6.10.0.tgz",
|
||||||
"integrity": "sha512-dSq4XIiD35jYkrcCBOWm7Sw/hH2QNNDZRExinVabjLLLk8+XCVRinCDu5ZaREv1H3CeJD0ipjc9ro9Z68cqJPg==",
|
"integrity": "sha512-6LfRGmgu2jadzbweaBtp9/CISvRMHymGvV1GGd6OBWdeQsSPw9g1pisfqsfZMhWFuok5yiLpHairWbUTus/CRA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@lingui/conf": "6.9.1",
|
"@lingui/conf": "6.10.0",
|
||||||
"@lingui/message-utils": "6.9.1",
|
"@lingui/message-utils": "6.10.0",
|
||||||
"pofile-ts": "^4.0.3"
|
"pofile-ts": "^4.0.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -1426,9 +1394,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@lingui/message-utils": {
|
"node_modules/@lingui/message-utils": {
|
||||||
"version": "6.9.1",
|
"version": "6.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/@lingui/message-utils/-/message-utils-6.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/@lingui/message-utils/-/message-utils-6.10.0.tgz",
|
||||||
"integrity": "sha512-pEfdWUhZoNrE8+06KOsv1r8VTKkdRvaT0gcXVO/FEVfphGiszSMQtoNhv3ftFbet7HKen2xx0LrzJ93mx3zVAw==",
|
"integrity": "sha512-Mc5eL3TPP/yDCa05IK3UQH3/Xy2Yzpz9KMCkKeJ+Q8nDb+xaW/CnOpkOMsBbgdbLxP0cXV8CER3F1PE/F29g0Q==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@messageformat/date-skeleton": "^1.1.0",
|
"@messageformat/date-skeleton": "^1.1.0",
|
||||||
@@ -1632,13 +1600,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@lingui/react": {
|
"node_modules/@lingui/react": {
|
||||||
"version": "6.9.1",
|
"version": "6.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/@lingui/react/-/react-6.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/@lingui/react/-/react-6.10.0.tgz",
|
||||||
"integrity": "sha512-mc0yX+unl9hLzpoYQZ4IsuhCdU0zTlUpZXqM9ElGS/SZTPA2BVV7CmcVpQ8hXm/GomGn2ewQRg2jNDkB+P/R6Q==",
|
"integrity": "sha512-W0V66a9mc5sRZ3dMS/HJjhqOLxKsO93bOsA925mDULFICRZ1i5Wxtu0TR/jgen+4cJw8qErWEJ9IL76NmcGYfg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@lingui/babel-plugin-lingui-macro": "6.9.1",
|
"@lingui/babel-plugin-lingui-macro": "6.10.0",
|
||||||
"@lingui/core": "6.9.1",
|
"@lingui/core": "6.10.0",
|
||||||
"use-sync-external-store": "^1.6.0"
|
"use-sync-external-store": "^1.6.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -1655,14 +1623,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@lingui/vite-plugin": {
|
"node_modules/@lingui/vite-plugin": {
|
||||||
"version": "6.9.1",
|
"version": "6.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/@lingui/vite-plugin/-/vite-plugin-6.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/@lingui/vite-plugin/-/vite-plugin-6.10.0.tgz",
|
||||||
"integrity": "sha512-95qeAWrRr8kZv3aZnVesW4azu9KdohV1Kjwx2J+EI/X8KRZ5lM7DpJwAa2oMKyoLJQzY8FGoShYy9kZBR6aNdQ==",
|
"integrity": "sha512-tp1sVK0X0Ff5mSBdDY2urqer0S21yZqRE4i8o9GZoCmoaOn9GbXsY4xEv/ZdBHkHWqBtMheZYkc66ZFECRGBEA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@lingui/cli": "6.9.1",
|
"@lingui/cli": "6.10.0",
|
||||||
"@lingui/conf": "6.9.1",
|
"@lingui/conf": "6.10.0",
|
||||||
"@lingui/native-tools": "^0.1.6"
|
"@lingui/native-tools": "^0.1.6"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -1691,9 +1659,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@mantine/core": {
|
"node_modules/@mantine/core": {
|
||||||
"version": "9.7.2",
|
"version": "9.7.3",
|
||||||
"resolved": "https://registry.npmjs.org/@mantine/core/-/core-9.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/@mantine/core/-/core-9.7.3.tgz",
|
||||||
"integrity": "sha512-+cggJDD0PO057SwZU/dKlWPjp0LaAn1nEM9W1m/Ia4Cjb/Hy9DjZ4I7R7xirp/eZ6xnV7OqeGmPFSJ8zeGa5kQ==",
|
"integrity": "sha512-wYJ9Bd82a7HqwJ+hubFqUIocBGMuw6txzdPnnleHvv1h0NlnkESevK/WHTRh4FtOw33B5N2ADT34s3x1/8d8jg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@floating-ui/react": "^0.27.20",
|
"@floating-ui/react": "^0.27.20",
|
||||||
@@ -1703,31 +1671,31 @@
|
|||||||
"type-fest": "^5.10.0"
|
"type-fest": "^5.10.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@mantine/hooks": "9.7.2",
|
"@mantine/hooks": "9.7.3",
|
||||||
"react": "^19.2.0",
|
"react": "^19.2.0",
|
||||||
"react-dom": "^19.2.0"
|
"react-dom": "^19.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@mantine/dates": {
|
"node_modules/@mantine/dates": {
|
||||||
"version": "9.7.2",
|
"version": "9.7.3",
|
||||||
"resolved": "https://registry.npmjs.org/@mantine/dates/-/dates-9.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/@mantine/dates/-/dates-9.7.3.tgz",
|
||||||
"integrity": "sha512-z57sziOW1/hyGlR43I1kBE78hvfKvEWzRqznK0qTeKADLBflzGxUsZRL0GMQ1LUbQCp+Jog6MQnzgRFV3FHwsg==",
|
"integrity": "sha512-Ea7coqQp3iNs+1XTEjbcoPLP5M9DG5jcxWuEmJC21KUwpBmZKq+RyT0ovxoS8PrWBqvtu/bss8qbjE97wxyqrw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"clsx": "^2.1.1"
|
"clsx": "^2.1.1"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@mantine/core": "9.7.2",
|
"@mantine/core": "9.7.3",
|
||||||
"@mantine/hooks": "9.7.2",
|
"@mantine/hooks": "9.7.3",
|
||||||
"dayjs": ">=1.0.0",
|
"dayjs": ">=1.0.0",
|
||||||
"react": "^19.2.0",
|
"react": "^19.2.0",
|
||||||
"react-dom": "^19.2.0"
|
"react-dom": "^19.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@mantine/form": {
|
"node_modules/@mantine/form": {
|
||||||
"version": "9.7.2",
|
"version": "9.7.3",
|
||||||
"resolved": "https://registry.npmjs.org/@mantine/form/-/form-9.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/@mantine/form/-/form-9.7.3.tgz",
|
||||||
"integrity": "sha512-+EskrnXLI0tzLzYh634pD3gcwZsaos5PjfxNW0Kpg7O15gugescdJnFcm4CCrNX57Saw/6fZn9IEqPx8/AcvRQ==",
|
"integrity": "sha512-Y5FrEi3Tsh6kwZLEQV86MUs0HgrSIaoXPzwcRjsjRXdz067eeI55JVuPaXezTfHi00arTqIjgJbhBIJRHl4V+w==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@standard-schema/spec": "^1.1.0",
|
"@standard-schema/spec": "^1.1.0",
|
||||||
@@ -1739,61 +1707,61 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@mantine/hooks": {
|
"node_modules/@mantine/hooks": {
|
||||||
"version": "9.7.2",
|
"version": "9.7.3",
|
||||||
"resolved": "https://registry.npmjs.org/@mantine/hooks/-/hooks-9.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/@mantine/hooks/-/hooks-9.7.3.tgz",
|
||||||
"integrity": "sha512-11emsRp/Mg+vfaKVyoMwiMdCHmO/15XOL6JG9fACkclVZnLPBVvRIaDdRBudsR3ALGZ5iTzrArPJDjjoeO6X4w==",
|
"integrity": "sha512-GMHoMS1qul1dBLIHd/N9ef2Pr8UKYYHfuM+g2ej3gYqU0kH4sTiR9FNHksoTQi0PzATRoaNlUYjjMe9rbDRw5A==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "^19.2.0"
|
"react": "^19.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@mantine/modals": {
|
"node_modules/@mantine/modals": {
|
||||||
"version": "9.7.2",
|
"version": "9.7.3",
|
||||||
"resolved": "https://registry.npmjs.org/@mantine/modals/-/modals-9.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/@mantine/modals/-/modals-9.7.3.tgz",
|
||||||
"integrity": "sha512-punZaWfh+nkGItIKtRF3TawjBoa241Ek8YTnOJrllXtheYyN4kgtoxgNd6B+9KwsT6UnfgYTEFfY9Jr9WsW/Ew==",
|
"integrity": "sha512-0VIKpWAhObk5WSvsYvSJMc89VL5yCU2SwxY4c6OoffqjG/5RlDYT+epIobAdrj2i5y95BDAjyA+ZIYf97QYtWw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@mantine/core": "9.7.2",
|
"@mantine/core": "9.7.3",
|
||||||
"@mantine/hooks": "9.7.2",
|
"@mantine/hooks": "9.7.3",
|
||||||
"react": "^19.2.0",
|
"react": "^19.2.0",
|
||||||
"react-dom": "^19.2.0"
|
"react-dom": "^19.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@mantine/notifications": {
|
"node_modules/@mantine/notifications": {
|
||||||
"version": "9.7.2",
|
"version": "9.7.3",
|
||||||
"resolved": "https://registry.npmjs.org/@mantine/notifications/-/notifications-9.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/@mantine/notifications/-/notifications-9.7.3.tgz",
|
||||||
"integrity": "sha512-Lf/oS2bpWgalgJ7Uy2Gh2V/kqnIIM3zkeWYy+GZKunfbiQGyuDBasOGd/4RYu5ga7b8vxJzC/zINi/UdpFuxoQ==",
|
"integrity": "sha512-ebsyKnA9oYYOtRwPD8uO2mQvHsJC3nlOt0hJsciFV+zMaS9OIoONDVN8nD5HvuAVe0UWTxxZ3i8jw7QEs4rxEA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mantine/store": "9.7.2",
|
"@mantine/store": "9.7.3",
|
||||||
"react-transition-group": "4.4.5"
|
"react-transition-group": "4.4.5"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@mantine/core": "9.7.2",
|
"@mantine/core": "9.7.3",
|
||||||
"@mantine/hooks": "9.7.2",
|
"@mantine/hooks": "9.7.3",
|
||||||
"react": "^19.2.0",
|
"react": "^19.2.0",
|
||||||
"react-dom": "^19.2.0"
|
"react-dom": "^19.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@mantine/spotlight": {
|
"node_modules/@mantine/spotlight": {
|
||||||
"version": "9.7.2",
|
"version": "9.7.3",
|
||||||
"resolved": "https://registry.npmjs.org/@mantine/spotlight/-/spotlight-9.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/@mantine/spotlight/-/spotlight-9.7.3.tgz",
|
||||||
"integrity": "sha512-QvpxQ0Axy1Pa3pWuAMyNK8mhzR0/PqhSsz9tA7iTpi5zUgVAqODFP36FyPk6ajRL9hvlF094Pjj5b/UKHLKk+w==",
|
"integrity": "sha512-vJbZDAG3LG+VTWsTtbpZBUV2O6RuBi7oI25H+WtijD/lekqYCAVJ2XWx7woyZeYOZYe3+wPGpGULrsD1xGBHfg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mantine/store": "9.7.2"
|
"@mantine/store": "9.7.3"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@mantine/core": "9.7.2",
|
"@mantine/core": "9.7.3",
|
||||||
"@mantine/hooks": "9.7.2",
|
"@mantine/hooks": "9.7.3",
|
||||||
"react": "^19.2.0",
|
"react": "^19.2.0",
|
||||||
"react-dom": "^19.2.0"
|
"react-dom": "^19.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@mantine/store": {
|
"node_modules/@mantine/store": {
|
||||||
"version": "9.7.2",
|
"version": "9.7.3",
|
||||||
"resolved": "https://registry.npmjs.org/@mantine/store/-/store-9.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/@mantine/store/-/store-9.7.3.tgz",
|
||||||
"integrity": "sha512-ERjk46CbQeSqytWTq5cAzT4o9MBAzzvVXpPlD36B5NwB5hmbjQfdUKcr0PlZfG04a/PDPdLPvAiVp7Eeh0tk8A==",
|
"integrity": "sha512-Z8BD1cw4LxSrH7l0zzVeFntzcYzO4vTP/I5aezizKdar6nbeladQKQnsBV2aReamp05vlVybZG3IKQdRBfXrOg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "^19.2.0"
|
"react": "^19.2.0"
|
||||||
@@ -6069,16 +6037,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vite": {
|
"node_modules/vite": {
|
||||||
"version": "8.3.4",
|
"version": "8.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/vite/-/vite-8.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/vite/-/vite-8.3.5.tgz",
|
||||||
"integrity": "sha512-IftLE8phJhdNRIGNEV4JCCvfNScoZQVfcXaN8TQropWGJtOHcu+iAB9pHcuGvmEb/kddw0LBe/jS8ztdC6xdiQ==",
|
"integrity": "sha512-z1YpjieJ9g0ebTmQpLBv/oq9E3F9EIlOe+7LahW8SrE3LTiG3udBRUXQOlYXP9b+IC2q2phHeVxj9xGlw34OEQ==",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lightningcss": "^1.33.0",
|
"lightningcss": "^1.33.0",
|
||||||
"picomatch": "^4.0.7",
|
"picomatch": "^4.0.7",
|
||||||
"postcss": "^8.5.29",
|
"postcss": "^8.5.30",
|
||||||
"rolldown": "~1.2.12",
|
"rolldown": "~1.2.14",
|
||||||
"tinyglobby": "^0.2.17"
|
"tinyglobby": "^0.2.17"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -6095,7 +6063,7 @@
|
|||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@types/node": "^20.19.0 || >=22.12.0",
|
"@types/node": "^20.19.0 || >=22.12.0",
|
||||||
"@vitejs/devtools": "^0.7.1",
|
"@vitejs/devtools": "^0.7.1 || ^0.8.0",
|
||||||
"esbuild": "^0.27.0 || ^0.28.0",
|
"esbuild": "^0.27.0 || ^0.28.0",
|
||||||
"jiti": ">=1.21.0",
|
"jiti": ">=1.21.0",
|
||||||
"less": "^4.0.0",
|
"less": "^4.0.0",
|
||||||
|
|||||||
@@ -17,15 +17,15 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/react": "11.14.0",
|
"@emotion/react": "11.14.0",
|
||||||
"@fontsource/open-sans": "5.3.0",
|
"@fontsource/open-sans": "5.3.0",
|
||||||
"@lingui/core": "6.9.1",
|
"@lingui/core": "6.10.0",
|
||||||
"@lingui/react": "6.9.1",
|
"@lingui/react": "6.10.0",
|
||||||
"@mantine/core": "9.7.2",
|
"@mantine/core": "9.7.3",
|
||||||
"@mantine/dates": "9.7.2",
|
"@mantine/dates": "9.7.3",
|
||||||
"@mantine/form": "9.7.2",
|
"@mantine/form": "9.7.3",
|
||||||
"@mantine/hooks": "9.7.2",
|
"@mantine/hooks": "9.7.3",
|
||||||
"@mantine/modals": "9.7.2",
|
"@mantine/modals": "9.7.3",
|
||||||
"@mantine/notifications": "9.7.2",
|
"@mantine/notifications": "9.7.3",
|
||||||
"@mantine/spotlight": "9.7.2",
|
"@mantine/spotlight": "9.7.3",
|
||||||
"@monaco-editor/react": "4.7.0",
|
"@monaco-editor/react": "4.7.0",
|
||||||
"@react-querybuilder/mantine": "8.25.0",
|
"@react-querybuilder/mantine": "8.25.0",
|
||||||
"@reduxjs/toolkit": "2.13.0",
|
"@reduxjs/toolkit": "2.13.0",
|
||||||
@@ -56,8 +56,8 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/types": "^8.0.6",
|
"@babel/types": "^8.0.6",
|
||||||
"@biomejs/biome": "2.5.15",
|
"@biomejs/biome": "2.5.15",
|
||||||
"@lingui/cli": "6.9.1",
|
"@lingui/cli": "6.10.0",
|
||||||
"@lingui/vite-plugin": "6.9.1",
|
"@lingui/vite-plugin": "6.10.0",
|
||||||
"@testing-library/jest-dom": "7.0.1",
|
"@testing-library/jest-dom": "7.0.1",
|
||||||
"@testing-library/react": "16.3.3",
|
"@testing-library/react": "16.3.3",
|
||||||
"@testing-library/user-event": "14.6.8",
|
"@testing-library/user-event": "14.6.8",
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
"babel-plugin-react-compiler": "^1.0.0",
|
"babel-plugin-react-compiler": "^1.0.0",
|
||||||
"jsdom": "30.1.3",
|
"jsdom": "30.1.3",
|
||||||
"typescript": "7.0.2",
|
"typescript": "7.0.2",
|
||||||
"vite": "8.3.4",
|
"vite": "8.3.5",
|
||||||
"vite-plugin-checker": "0.14.5",
|
"vite-plugin-checker": "0.14.5",
|
||||||
"vitest": "5.0.5",
|
"vitest": "5.0.5",
|
||||||
"yaml": "2.9.1"
|
"yaml": "2.9.1"
|
||||||
|
|||||||
@@ -6,16 +6,16 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.commafeed</groupId>
|
<groupId>com.commafeed</groupId>
|
||||||
<artifactId>commafeed</artifactId>
|
<artifactId>commafeed</artifactId>
|
||||||
<version>7.4.0</version>
|
<version>7.4.1</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>commafeed-client</artifactId>
|
<artifactId>commafeed-client</artifactId>
|
||||||
<name>CommaFeed Client</name>
|
<name>CommaFeed Client</name>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<!-- renovate: datasource=node-version depName=node -->
|
<!-- renovate: datasource=node-version depName=node -->
|
||||||
<node.version>v24.22.0</node.version>
|
<node.version>v24.22.1</node.version>
|
||||||
<!-- renovate: datasource=npm depName=npm -->
|
<!-- renovate: datasource=npm depName=npm -->
|
||||||
<npm.version>12.2.0</npm.version>
|
<npm.version>12.2.1</npm.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@@ -116,6 +116,30 @@ describe("entries", () => {
|
|||||||
expect(client.entry.mark).toHaveBeenCalledWith({ id: "3", read: true })
|
expect(client.entry.mark).toHaveBeenCalledWith({ id: "3", read: true })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("flags an entry marked as unread by the user until entries are reloaded", async () => {
|
||||||
|
vi.mocked(client.feed.getEntries).mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
entries: [{ id: "3", read: true, markable: true } as Entry],
|
||||||
|
hasMore: false,
|
||||||
|
name: "my-feed",
|
||||||
|
errorCount: 0,
|
||||||
|
feedLink: "https://mysite.com/feed",
|
||||||
|
timestamp: 123,
|
||||||
|
ignoredReadStatus: false,
|
||||||
|
},
|
||||||
|
} as AxiosResponse<Entries>)
|
||||||
|
|
||||||
|
const store = configureStore({ reducer: reducers })
|
||||||
|
await store.dispatch(loadEntries({ source: { type: "feed", id: "feed-id" }, clearSearch: true }))
|
||||||
|
|
||||||
|
store.dispatch(markEntry({ entry: store.getState().entries.entries[0], read: false }))
|
||||||
|
expect(store.getState().entries.entries[0].keepUnread).toBe(true)
|
||||||
|
|
||||||
|
// reloading the entry list resets the flag
|
||||||
|
await store.dispatch(loadEntries({ source: { type: "feed", id: "feed-id" }, clearSearch: false }))
|
||||||
|
expect(store.getState().entries.entries[0].keepUnread).toBeUndefined()
|
||||||
|
})
|
||||||
|
|
||||||
it("marks all entries as read", () => {
|
it("marks all entries as read", () => {
|
||||||
const store = configureStore({
|
const store = configureStore({
|
||||||
reducer: reducers,
|
reducer: reducers,
|
||||||
|
|||||||
@@ -10,7 +10,11 @@ export interface EntrySource {
|
|||||||
id: string
|
id: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ExpendableEntry = Entry & { expanded?: boolean }
|
export type ExpendableEntry = Entry & {
|
||||||
|
expanded?: boolean
|
||||||
|
/** set when the user explicitly marks the entry as unread, prevents it from being marked as read again by scrolling in expanded mode until the entry list is reloaded */
|
||||||
|
keepUnread?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
interface EntriesState {
|
interface EntriesState {
|
||||||
/** selected source */
|
/** selected source */
|
||||||
@@ -71,11 +75,13 @@ export const entriesSlice = createSlice({
|
|||||||
builder.addCase(markEntry.pending, (state, action) => {
|
builder.addCase(markEntry.pending, (state, action) => {
|
||||||
for (const e of state.entries.filter(e => e.id === action.meta.arg.entry.id)) {
|
for (const e of state.entries.filter(e => e.id === action.meta.arg.entry.id)) {
|
||||||
e.read = action.meta.arg.read
|
e.read = action.meta.arg.read
|
||||||
|
if (!action.meta.arg.read) e.keepUnread = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
builder.addCase(markMultipleEntries.pending, (state, action) => {
|
builder.addCase(markMultipleEntries.pending, (state, action) => {
|
||||||
for (const e of state.entries.filter(e => action.meta.arg.entries.some(e2 => e2.id === e.id))) {
|
for (const e of state.entries.filter(e => action.meta.arg.entries.some(e2 => e2.id === e.id))) {
|
||||||
e.read = action.meta.arg.read
|
e.read = action.meta.arg.read
|
||||||
|
if (!action.meta.arg.read) e.keepUnread = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
builder.addCase(markAllEntries.pending, (state, action) => {
|
builder.addCase(markAllEntries.pending, (state, action) => {
|
||||||
|
|||||||
@@ -111,12 +111,13 @@ export function FeedEntries() {
|
|||||||
const el = document.getElementById(Constants.dom.entryId(e))
|
const el = document.getElementById(Constants.dom.entryId(e))
|
||||||
return el && !Constants.layout.isTopVisible(el)
|
return el && !Constants.layout.isTopVisible(el)
|
||||||
})
|
})
|
||||||
if (currentEntry) {
|
if (currentEntry && currentEntry.id !== selectedEntryId) {
|
||||||
dispatch(
|
dispatch(
|
||||||
selectEntry({
|
selectEntry({
|
||||||
entry: currentEntry,
|
entry: currentEntry,
|
||||||
expand: false,
|
expand: false,
|
||||||
markAsRead: !!scrollMarks,
|
// don't mark as read entries that the user explicitly marked as unread
|
||||||
|
markAsRead: !!scrollMarks && !currentEntry.keepUnread,
|
||||||
scrollToEntry: false,
|
scrollToEntry: false,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@@ -124,7 +125,7 @@ export function FeedEntries() {
|
|||||||
})
|
})
|
||||||
window.addEventListener("scroll", listener)
|
window.addEventListener("scroll", listener)
|
||||||
return () => window.removeEventListener("scroll", listener)
|
return () => window.removeEventListener("scroll", listener)
|
||||||
}, [dispatch, entries, viewMode, scrollMarks, scrollingToEntry])
|
}, [dispatch, entries, viewMode, scrollMarks, scrollingToEntry, selectedEntryId])
|
||||||
|
|
||||||
useMousetrap("r", async () => await dispatch(reloadEntries()))
|
useMousetrap("r", async () => await dispatch(reloadEntries()))
|
||||||
useMousetrap(
|
useMousetrap(
|
||||||
|
|||||||
@@ -6,14 +6,14 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.commafeed</groupId>
|
<groupId>com.commafeed</groupId>
|
||||||
<artifactId>commafeed</artifactId>
|
<artifactId>commafeed</artifactId>
|
||||||
<version>7.4.0</version>
|
<version>7.4.1</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>commafeed-server</artifactId>
|
<artifactId>commafeed-server</artifactId>
|
||||||
<name>CommaFeed Server</name>
|
<name>CommaFeed Server</name>
|
||||||
<packaging>quarkus</packaging>
|
<packaging>quarkus</packaging>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<quarkus.version>3.40.1</quarkus.version>
|
<quarkus.version>3.40.1.1</quarkus.version>
|
||||||
<querydsl.version>7.7</querydsl.version>
|
<querydsl.version>7.7</querydsl.version>
|
||||||
<rome.version>2.1.0</rome.version>
|
<rome.version>2.1.0</rome.version>
|
||||||
<!-- renovate: depName=com.google.googlejavaformat:google-java-format -->
|
<!-- renovate: depName=com.google.googlejavaformat:google-java-format -->
|
||||||
@@ -302,7 +302,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.commafeed</groupId>
|
<groupId>com.commafeed</groupId>
|
||||||
<artifactId>commafeed-client</artifactId>
|
<artifactId>commafeed-client</artifactId>
|
||||||
<version>7.4.0</version>
|
<version>7.4.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- compile-time processors -->
|
<!-- compile-time processors -->
|
||||||
@@ -439,7 +439,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.ibm.icu</groupId>
|
<groupId>com.ibm.icu</groupId>
|
||||||
<artifactId>icu4j</artifactId>
|
<artifactId>icu4j</artifactId>
|
||||||
<version>78.3</version>
|
<version>79.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.sourceforge.cssparser</groupId>
|
<groupId>net.sourceforge.cssparser</groupId>
|
||||||
@@ -481,8 +481,8 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mock-server</groupId>
|
<groupId>org.mock-server</groupId>
|
||||||
<artifactId>mockserver-junit-jupiter</artifactId>
|
<artifactId>mockserver-junit-jupiter-no-dependencies</artifactId>
|
||||||
<version>7.6.0</version>
|
<version>9.1.0</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
FROM ibm-semeru-runtimes:open-jdk-25.0.4.15-jre@sha256:630c738228597b4cd31d9823e479384729b03684bac23478b33fdbda13ae31b8
|
FROM ibm-semeru-runtimes:open-jdk-25.0.4.15-jre@sha256:630c738228597b4cd31d9823e479384729b03684bac23478b33fdbda13ae31b8
|
||||||
|
LABEL org.opencontainers.image.source="https://github.com/Athou/commafeed"
|
||||||
|
|
||||||
EXPOSE 8082
|
EXPOSE 8082
|
||||||
|
|
||||||
RUN mkdir -p /commafeed/data
|
RUN mkdir -p /commafeed/data
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
FROM debian:13.7@sha256:913f6706df59a68922d1dd08f78c2476560a8d367897200a6005b00e5f67c2d5
|
FROM debian:13.7@sha256:4c25275446ca371766b8b093c696782eabce06263fccacb8d5d813b3dc44b308
|
||||||
|
LABEL org.opencontainers.image.source="https://github.com/Athou/commafeed"
|
||||||
|
|
||||||
ARG TARGETARCH
|
ARG TARGETARCH
|
||||||
|
|
||||||
EXPOSE 8082
|
EXPOSE 8082
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ import org.apache.hc.core5.http.nio.AsyncRequestProducer;
|
|||||||
import org.apache.hc.core5.http.nio.AsyncResponseConsumer;
|
import org.apache.hc.core5.http.nio.AsyncResponseConsumer;
|
||||||
import org.apache.hc.core5.http.nio.entity.AbstractBinAsyncEntityConsumer;
|
import org.apache.hc.core5.http.nio.entity.AbstractBinAsyncEntityConsumer;
|
||||||
import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
|
import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
|
||||||
import org.apache.hc.core5.util.Timeout;
|
|
||||||
import org.jboss.resteasy.reactive.common.headers.CacheControlDelegate;
|
import org.jboss.resteasy.reactive.common.headers.CacheControlDelegate;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
@@ -54,6 +53,8 @@ import java.time.InstantSource;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
/** Smart HTTP getter: handles gzip, ssl, last modified, and etag headers */
|
/** Smart HTTP getter: handles gzip, ssl, last modified, and etag headers */
|
||||||
@Singleton
|
@Singleton
|
||||||
@@ -162,7 +163,6 @@ public class HttpGetter {
|
|||||||
HttpClientContext context = HttpClientContext.create();
|
HttpClientContext context = HttpClientContext.create();
|
||||||
context.setRequestConfig(
|
context.setRequestConfig(
|
||||||
RequestConfig.custom()
|
RequestConfig.custom()
|
||||||
.setResponseTimeout(Timeout.of(config.httpClient().responseTimeout()))
|
|
||||||
// causes issues with some feeds
|
// causes issues with some feeds
|
||||||
// see https://github.com/Athou/commafeed/issues/1572
|
// see https://github.com/Athou/commafeed/issues/1572
|
||||||
// and https://issues.apache.org/jira/browse/HTTPCLIENT-2344
|
// and https://issues.apache.org/jira/browse/HTTPCLIENT-2344
|
||||||
@@ -191,7 +191,8 @@ public class HttpGetter {
|
|||||||
client.execute(req, resp, context, callback);
|
client.execute(req, resp, context, callback);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Message<org.apache.hc.core5.http.HttpResponse, byte[]> message = future.get();
|
Message<org.apache.hc.core5.http.HttpResponse, byte[]> message =
|
||||||
|
future.get(config.httpClient().responseTimeout().toSeconds(), TimeUnit.SECONDS);
|
||||||
|
|
||||||
byte[] content = message.getBody();
|
byte[] content = message.getBody();
|
||||||
int code = message.getHead().getCode();
|
int code = message.getHead().getCode();
|
||||||
@@ -245,7 +246,11 @@ public class HttpGetter {
|
|||||||
future.cancel(true);
|
future.cancel(true);
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
throw new RuntimeException("interrupted while fetching " + request.getUrl(), e);
|
throw new RuntimeException("interrupted while fetching " + request.getUrl(), e);
|
||||||
|
} catch (TimeoutException e) {
|
||||||
|
future.cancel(true);
|
||||||
|
throw new IOException("timed out while fetching " + request.getUrl(), e);
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
|
future.cancel(true);
|
||||||
throw Lombok.sneakyThrow(e.getCause());
|
throw Lombok.sneakyThrow(e.getCause());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
|
import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleRequestProducer;
|
import org.apache.hc.client5.http.async.methods.SimpleRequestProducer;
|
||||||
import org.apache.hc.client5.http.config.RequestConfig;
|
|
||||||
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
||||||
import org.apache.hc.core5.http.ContentType;
|
import org.apache.hc.core5.http.ContentType;
|
||||||
import org.apache.hc.core5.http.HttpResponse;
|
import org.apache.hc.core5.http.HttpResponse;
|
||||||
@@ -29,7 +28,6 @@ import org.apache.hc.core5.http.message.BasicNameValuePair;
|
|||||||
import org.apache.hc.core5.http.nio.entity.DiscardingEntityConsumer;
|
import org.apache.hc.core5.http.nio.entity.DiscardingEntityConsumer;
|
||||||
import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
|
import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
|
||||||
import org.apache.hc.core5.net.WWWFormCodec;
|
import org.apache.hc.core5.net.WWWFormCodec;
|
||||||
import org.apache.hc.core5.util.Timeout;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
@@ -37,6 +35,8 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@@ -105,10 +105,6 @@ public class PushNotificationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SimpleRequestBuilder request = SimpleRequestBuilder.post(serverUrl + "/" + topic);
|
SimpleRequestBuilder request = SimpleRequestBuilder.post(serverUrl + "/" + topic);
|
||||||
request.setRequestConfig(
|
|
||||||
RequestConfig.custom()
|
|
||||||
.setResponseTimeout(Timeout.of(config.httpClient().responseTimeout()))
|
|
||||||
.build());
|
|
||||||
request.addHeader("Title", feedTitle);
|
request.addHeader("Title", feedTitle);
|
||||||
request.setBody(entryTitle, ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8));
|
request.setBody(entryTitle, ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8));
|
||||||
|
|
||||||
@@ -152,10 +148,6 @@ public class PushNotificationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SimpleRequestBuilder request = SimpleRequestBuilder.post(serverUrl + "/message");
|
SimpleRequestBuilder request = SimpleRequestBuilder.post(serverUrl + "/message");
|
||||||
request.setRequestConfig(
|
|
||||||
RequestConfig.custom()
|
|
||||||
.setResponseTimeout(Timeout.of(config.httpClient().responseTimeout()))
|
|
||||||
.build());
|
|
||||||
request.addHeader("X-Gotify-Key", token);
|
request.addHeader("X-Gotify-Key", token);
|
||||||
request.setBody(json.toString(), ContentType.APPLICATION_JSON);
|
request.setBody(json.toString(), ContentType.APPLICATION_JSON);
|
||||||
|
|
||||||
@@ -187,10 +179,6 @@ public class PushNotificationService {
|
|||||||
|
|
||||||
SimpleRequestBuilder request =
|
SimpleRequestBuilder request =
|
||||||
SimpleRequestBuilder.post("https://api.pushover.net/1/messages.json");
|
SimpleRequestBuilder.post("https://api.pushover.net/1/messages.json");
|
||||||
request.setRequestConfig(
|
|
||||||
RequestConfig.custom()
|
|
||||||
.setResponseTimeout(Timeout.of(config.httpClient().responseTimeout()))
|
|
||||||
.build());
|
|
||||||
request.setBody(
|
request.setBody(
|
||||||
WWWFormCodec.format(params, StandardCharsets.UTF_8),
|
WWWFormCodec.format(params, StandardCharsets.UTF_8),
|
||||||
ContentType.APPLICATION_FORM_URLENCODED.withCharset(StandardCharsets.UTF_8));
|
ContentType.APPLICATION_FORM_URLENCODED.withCharset(StandardCharsets.UTF_8));
|
||||||
@@ -205,7 +193,9 @@ public class PushNotificationService {
|
|||||||
new BasicResponseConsumer<>(new DiscardingEntityConsumer<>()),
|
new BasicResponseConsumer<>(new DiscardingEntityConsumer<>()),
|
||||||
null);
|
null);
|
||||||
try {
|
try {
|
||||||
HttpResponse response = future.get().getHead();
|
HttpResponse response =
|
||||||
|
future.get(config.httpClient().responseTimeout().toSeconds(), TimeUnit.SECONDS)
|
||||||
|
.getHead();
|
||||||
if (response.getCode() >= 400) {
|
if (response.getCode() >= 400) {
|
||||||
throw new PushNotificationException(
|
throw new PushNotificationException(
|
||||||
name + " notification failed with status " + response.getCode());
|
name + " notification failed with status " + response.getCode());
|
||||||
@@ -214,7 +204,11 @@ public class PushNotificationService {
|
|||||||
future.cancel(true);
|
future.cancel(true);
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
throw new IOException("interrupted while sending " + name + " notification", e);
|
throw new IOException("interrupted while sending " + name + " notification", e);
|
||||||
|
} catch (TimeoutException e) {
|
||||||
|
future.cancel(true);
|
||||||
|
throw new IOException("timed out while sending " + name + " notification", e);
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
|
future.cancel(true);
|
||||||
throw new IOException(e.getCause());
|
throw new IOException(e.getCause());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.NoRouteToHostException;
|
import java.net.NoRouteToHostException;
|
||||||
import java.net.SocketTimeoutException;
|
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
@@ -241,7 +240,7 @@ class HttpGetterTest {
|
|||||||
.when(HttpRequest.request().withMethod("GET"))
|
.when(HttpRequest.request().withMethod("GET"))
|
||||||
.respond(HttpResponse.response().withDelay(Delay.milliseconds(1000)));
|
.respond(HttpResponse.response().withDelay(Delay.milliseconds(1000)));
|
||||||
|
|
||||||
Assertions.assertThrows(SocketTimeoutException.class, () -> getter.get(this.feedUrl));
|
Assertions.assertThrows(IOException.class, () -> getter.get(this.feedUrl));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
2
pom.xml
2
pom.xml
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
<groupId>com.commafeed</groupId>
|
<groupId>com.commafeed</groupId>
|
||||||
<artifactId>commafeed</artifactId>
|
<artifactId>commafeed</artifactId>
|
||||||
<version>7.4.0</version>
|
<version>7.4.1</version>
|
||||||
<name>CommaFeed</name>
|
<name>CommaFeed</name>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user