forked from Archives/Athou_commafeed
Compare commits
414 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d37cf5bbcf | ||
|
|
045baba705 | ||
|
|
3623dc8e1d | ||
|
|
2610c37067 | ||
|
|
286b69a646 | ||
|
|
9673f27090 | ||
|
|
0722599f6d | ||
|
|
1df40d8370 | ||
|
|
457e4ec69e | ||
|
|
647310a45f | ||
|
|
e85c92f216 | ||
|
|
d93b0dbfd4 | ||
|
|
b4e61ef547 | ||
|
|
71dffbba46 | ||
|
|
2c0b0c4e3b | ||
|
|
d868e58e1e | ||
|
|
90eb2095bf | ||
|
|
62d3ed16e6 | ||
|
|
74f7c48818 | ||
|
|
23fe9c29ed | ||
|
|
8f7be8278a | ||
|
|
49118b6ea0 | ||
|
|
d97bd04ae2 | ||
|
|
8d11309b64 | ||
|
|
68c24e4cb8 | ||
|
|
4e43e0235f | ||
|
|
62b79a9625 | ||
|
|
cb0706808c | ||
|
|
ffd5704b1e | ||
|
|
3987077e5a | ||
|
|
2e01a76784 | ||
|
|
8254093f5f | ||
|
|
0b06526756 | ||
|
|
06731ae76d | ||
|
|
9a59453792 | ||
|
|
c195a52c89 | ||
|
|
3d7924f953 | ||
|
|
f29efd7fae | ||
|
|
157bff3c83 | ||
|
|
5c17bbc36d | ||
|
|
c85e72e70c | ||
|
|
01150f67e1 | ||
|
|
75aca7aa6f | ||
|
|
affde7e43c | ||
|
|
b9b1b53235 | ||
|
|
708ebb8abc | ||
|
|
83e763df0a | ||
|
|
0ff812c1ea | ||
|
|
3e9dd6d8e2 | ||
|
|
23af73e847 | ||
|
|
e79e4719fd | ||
|
|
23fef98432 | ||
|
|
22478252e7 | ||
|
|
76b1f3cd35 | ||
|
|
420d73ec6a | ||
|
|
e0211cfa0c | ||
|
|
25a92c651c | ||
|
|
0781205c69 | ||
|
|
5102dd5e30 | ||
|
|
6ccfc3fd67 | ||
|
|
2791ed91ab | ||
|
|
f40c198233 | ||
|
|
003dc63121 | ||
|
|
f8ef1e2a99 | ||
|
|
14c7078940 | ||
|
|
074836d3e8 | ||
|
|
0cdbc144b3 | ||
|
|
dc63ec24c0 | ||
|
|
6d4c6c36a5 | ||
|
|
464af5f4d9 | ||
|
|
aa94a46a3d | ||
|
|
8542197dc3 | ||
|
|
64d77eaef4 | ||
|
|
675ef8794c | ||
|
|
4bcdbeb516 | ||
|
|
a9f37739fb | ||
|
|
5ab0fc19da | ||
|
|
7b232425f3 | ||
|
|
c0e7668140 | ||
|
|
ae3f059257 | ||
|
|
d44c7c1e95 | ||
|
|
6cd9d134cf | ||
|
|
6f21ba8afc | ||
|
|
b2fe13c117 | ||
|
|
03ece7a262 | ||
|
|
697fde2d0e | ||
|
|
7f0f85b356 | ||
|
|
a7d41debfe | ||
|
|
57bf758108 | ||
|
|
b37d933047 | ||
|
|
80ffef4555 | ||
|
|
af5a0002aa | ||
|
|
cd24e412e3 | ||
|
|
a073d843ab | ||
|
|
8ccb59ed18 | ||
|
|
e6dc7d2d0d | ||
|
|
f7b21ca3f6 | ||
|
|
df3a1bcdb6 | ||
|
|
5bec494a7c | ||
|
|
d8eef4dd9f | ||
|
|
d80138caf3 | ||
|
|
d26c103aa5 | ||
|
|
249231f57e | ||
|
|
7a838cddad | ||
|
|
477f2cd6db | ||
|
|
9915f05f73 | ||
|
|
0a16bb2fba | ||
|
|
3d4faf2406 | ||
|
|
63de6fe833 | ||
|
|
9c6219a58a | ||
|
|
3e664d4287 | ||
|
|
4c4ffd84f3 | ||
|
|
f555f0e392 | ||
|
|
124166738b | ||
|
|
8b32dcc576 | ||
|
|
105651215a | ||
|
|
d9c6cbd072 | ||
|
|
b4c52e06fe | ||
|
|
2565dfe528 | ||
|
|
b5036c9148 | ||
|
|
e2c8ddb8f7 | ||
|
|
85fbd284fa | ||
|
|
559fb69a64 | ||
|
|
054c76716a | ||
|
|
ba17c9350f | ||
|
|
781015eea4 | ||
|
|
13e5c0e8d2 | ||
|
|
4d88a30848 | ||
|
|
19c03de9e4 | ||
|
|
e3169c9f2d | ||
|
|
e90fb0b56f | ||
|
|
69607a5122 | ||
|
|
21eb8e6d9f | ||
|
|
a28a6b9dc4 | ||
|
|
a9cadbafeb | ||
|
|
d491af5a8d | ||
|
|
39c7934fb8 | ||
|
|
76eba8cc63 | ||
|
|
7549ff2491 | ||
|
|
66cd18bc4b | ||
|
|
44d7a2c340 | ||
|
|
d6ee63a01f | ||
|
|
a495c9cacd | ||
|
|
530185d15c | ||
|
|
8dd28c25a7 | ||
|
|
50884b236c | ||
|
|
da9fe09e58 | ||
|
|
3c24c9aa7a | ||
|
|
9d10a4b46f | ||
|
|
d56ed3bd06 | ||
|
|
41c1c429d0 | ||
|
|
1a3d890b40 | ||
|
|
e3ec9b2ccd | ||
|
|
f69878a242 | ||
|
|
ea766706fb | ||
|
|
306507af80 | ||
|
|
67084783b2 | ||
|
|
7cbb75f717 | ||
|
|
1c335492d5 | ||
|
|
de92e74c8e | ||
|
|
9cbbd30618 | ||
|
|
f14f1493c4 | ||
|
|
e68c8fdbe1 | ||
|
|
e094972aa2 | ||
|
|
ff831c6d2b | ||
|
|
9957cda11a | ||
|
|
6809822000 | ||
|
|
8048b1a9aa | ||
|
|
8557bd018a | ||
|
|
183d5fd162 | ||
|
|
411f86fbeb | ||
|
|
5493046f25 | ||
|
|
42015015a5 | ||
|
|
f3d2808f7d | ||
|
|
906c353a7f | ||
|
|
93dea83cd3 | ||
|
|
1fc76ce1ad | ||
|
|
a337b01bc7 | ||
|
|
689e5c0004 | ||
|
|
d5a3c81c85 | ||
|
|
8230fde5d2 | ||
|
|
b35513ea84 | ||
|
|
42a7785ca1 | ||
|
|
ea5ee4f04f | ||
|
|
3e14b12d4f | ||
|
|
78cc30f828 | ||
|
|
6091c84e60 | ||
|
|
6ea95ad254 | ||
|
|
7f888d926e | ||
|
|
5e4e02474f | ||
|
|
bff8611b42 | ||
|
|
f674048af3 | ||
|
|
0265c24cf9 | ||
|
|
f8c3a229ec | ||
|
|
c424f40420 | ||
|
|
b77666cfe5 | ||
|
|
193d1604d9 | ||
|
|
4efc6296b5 | ||
|
|
f753a4bdda | ||
|
|
afaaaf9657 | ||
|
|
4d46896bf0 | ||
|
|
2ad28c927f | ||
|
|
b9680a66ef | ||
|
|
4f687d5857 | ||
|
|
9cca026834 | ||
|
|
058a9cd192 | ||
|
|
57d2ede86e | ||
|
|
e3abea4ec5 | ||
|
|
b831f1f35c | ||
|
|
74bce1308c | ||
|
|
98cfa6d2c8 | ||
|
|
99a02a2186 | ||
|
|
3431a813b1 | ||
|
|
e9e0e8d32b | ||
|
|
2d14409d35 | ||
|
|
a8200e5c58 | ||
|
|
79a8df8b06 | ||
|
|
061a5f0262 | ||
|
|
821bdb3b0f | ||
|
|
606dfa9299 | ||
|
|
131357c616 | ||
|
|
f6d3493bad | ||
|
|
0c6104e25b | ||
|
|
d73735a35d | ||
|
|
e725d2d6b6 | ||
|
|
f0e1279d68 | ||
|
|
c74c74d2c4 | ||
|
|
aa70cf5dcd | ||
|
|
1055259627 | ||
|
|
302d37b6ef | ||
|
|
8532a73d94 | ||
|
|
ffafb272cb | ||
|
|
22e0171a34 | ||
|
|
2b410f040c | ||
|
|
259e8ad4e5 | ||
|
|
21244dd9f5 | ||
|
|
bc6206180d | ||
|
|
6e22d21358 | ||
|
|
95bdb4e700 | ||
|
|
9b7dbc68ab | ||
|
|
dc86c9b0db | ||
|
|
cb92ed753f | ||
|
|
10a085e24e | ||
|
|
3400a39edf | ||
|
|
21efffa345 | ||
|
|
e2e80ba7e5 | ||
|
|
d988dba66e | ||
|
|
403201fbff | ||
|
|
3cc93b51bb | ||
|
|
6a7d83bb45 | ||
|
|
19c8db8b31 | ||
|
|
0d75688ec8 | ||
|
|
e01dcb2f5b | ||
|
|
57757e2c14 | ||
|
|
779cd2fcfe | ||
|
|
94919f22e4 | ||
|
|
d5cf690703 | ||
|
|
191574dace | ||
|
|
ee7c6792c9 | ||
|
|
e2962dc2eb | ||
|
|
8c335cb8fd | ||
|
|
461c18a591 | ||
|
|
363837ab26 | ||
|
|
a184485421 | ||
|
|
f992c3f1a6 | ||
|
|
3219a9e313 | ||
|
|
4717c31058 | ||
|
|
693844828b | ||
|
|
ef4b479638 | ||
|
|
8eefb1bcfb | ||
|
|
ada9a5039b | ||
|
|
cca2d49cc3 | ||
|
|
f4a43e9950 | ||
|
|
9a89b39b62 | ||
|
|
2dba844b6c | ||
|
|
3101dc91de | ||
|
|
83cacd97f3 | ||
|
|
aa179c21f8 | ||
|
|
31cf4d8bb2 | ||
|
|
19bcc2c0da | ||
|
|
ca803ff7ce | ||
|
|
0e26d975aa | ||
|
|
86a3cb67f2 | ||
|
|
6297463445 | ||
|
|
1a3a3076b1 | ||
|
|
7fb9cfeaf1 | ||
|
|
5c7dbe6304 | ||
|
|
c41fd9216a | ||
|
|
91a9ad79f0 | ||
|
|
906458dc96 | ||
|
|
2f4fddf539 | ||
|
|
a8157143b9 | ||
|
|
92576e28e9 | ||
|
|
a6e34a2960 | ||
|
|
306cf7aab7 | ||
|
|
f3b806686d | ||
|
|
6634cfb991 | ||
|
|
9930bb68b2 | ||
|
|
37722131e5 | ||
|
|
5f2d213419 | ||
|
|
e119941762 | ||
|
|
ba496c1395 | ||
|
|
9c3fc84542 | ||
|
|
b017ce936a | ||
|
|
d696b0581b | ||
|
|
e4b2880f2b | ||
|
|
e071049969 | ||
|
|
5e1f592951 | ||
|
|
231f82da28 | ||
|
|
9a28bc7334 | ||
|
|
00907e92ff | ||
|
|
5669798881 | ||
|
|
f3a62a5f75 | ||
|
|
3b20ed222c | ||
|
|
1f40f3f59c | ||
|
|
a8d890524f | ||
|
|
b635799e80 | ||
|
|
50ea66620d | ||
|
|
46581d0e22 | ||
|
|
a3562867a6 | ||
|
|
c0117ada93 | ||
|
|
a3dcb2c03e | ||
|
|
8f8aaa5a1d | ||
|
|
85482422fd | ||
|
|
643c969faf | ||
|
|
85f9469d6d | ||
|
|
0df0d50695 | ||
|
|
5e9256c197 | ||
|
|
b67e1a92f5 | ||
|
|
d250e4bc26 | ||
|
|
dcf1f41f2d | ||
|
|
3df6ba1457 | ||
|
|
b89928f6c6 | ||
|
|
2e014484e3 | ||
|
|
3b2b18fd2e | ||
|
|
ebf1e592ff | ||
|
|
88404b91d8 | ||
|
|
9cbb60313c | ||
|
|
b95d417f5e | ||
|
|
994f1fb121 | ||
|
|
e533c1fa4b | ||
|
|
d0d946ffe9 | ||
|
|
e3bcc824c7 | ||
|
|
357e4e207f | ||
|
|
2aee961600 | ||
|
|
3aa1987319 | ||
|
|
ae15f61fc2 | ||
|
|
e58f92a812 | ||
|
|
46383924b1 | ||
|
|
071920e864 | ||
|
|
012238e6a9 | ||
|
|
a565566c50 | ||
|
|
550804c666 | ||
|
|
f7a4a33f5e | ||
|
|
f1b19ebae3 | ||
|
|
4049fa2e17 | ||
|
|
28808cf4f5 | ||
|
|
870b46cf9d | ||
|
|
9c20dea99c | ||
|
|
63c7679067 | ||
|
|
764c1a6430 | ||
|
|
bb6578bdd0 | ||
|
|
748c8531ad | ||
|
|
a734fe68d2 | ||
|
|
cc5ebc55a4 | ||
|
|
aa396c1e1c | ||
|
|
fbf87ff291 | ||
|
|
e9f3ffddf4 | ||
|
|
695518d68b | ||
|
|
5d96c1e12b | ||
|
|
3a72a1cc04 | ||
|
|
54f5714108 | ||
|
|
04811c7eca | ||
|
|
6856736ddb | ||
|
|
db6c43993a | ||
|
|
508a22576a | ||
|
|
8fb012b3a1 | ||
|
|
133781d314 | ||
|
|
50cb12896e | ||
|
|
79a4315941 | ||
|
|
33a2f76521 | ||
|
|
d4041a1d88 | ||
|
|
09f2f56446 | ||
|
|
a0c3eda506 | ||
|
|
84de3199cc | ||
|
|
a7e8309d63 | ||
|
|
7e74d2f6f4 | ||
|
|
dc25d53dc0 | ||
|
|
ac1a927836 | ||
|
|
b50b69adb2 | ||
|
|
b112e912af | ||
|
|
ece55727d3 | ||
|
|
181dd24b57 | ||
|
|
10008ca0e8 | ||
|
|
134c4621a8 | ||
|
|
51f15bf487 | ||
|
|
49ae2c88ad | ||
|
|
43a628fc55 | ||
|
|
7f71f95f7c | ||
|
|
e8d5eab419 | ||
|
|
de3a6b1f20 | ||
|
|
849742e19a | ||
|
|
b6392b114c | ||
|
|
4db0c775ff | ||
|
|
ff9374f1ed | ||
|
|
ea86c9bb1f | ||
|
|
e6dd088abe | ||
|
|
c039d8f3a4 | ||
|
|
bffa6329fd | ||
|
|
b88e5d2847 | ||
|
|
0fc4fcd406 | ||
|
|
f04ca21394 | ||
|
|
a82fca130f | ||
|
|
70d494798c |
7
.github/FUNDING.yml
vendored
7
.github/FUNDING.yml
vendored
@@ -1,2 +1,5 @@
|
||||
github: [athou]
|
||||
custom: ['https://www.paypal.com/donate/?business=9CNQHMJG2ZJVY&no_recurring=0&item_name=CommaFeed¤cy_code=EUR']
|
||||
github: [ athou ]
|
||||
custom: [
|
||||
'https://github.com/sponsors/Athou',
|
||||
'https://www.paypal.com/donate/?business=9CNQHMJG2ZJVY&no_recurring=0&item_name=CommaFeed¤cy_code=EUR'
|
||||
]
|
||||
|
||||
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -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]:
|
||||
|
||||
|
||||
136
.github/workflows/ci.yml
vendored
136
.github/workflows/ci.yml
vendored
@@ -7,8 +7,57 @@ env:
|
||||
DOCKER_BUILD_SUMMARY: false
|
||||
|
||||
jobs:
|
||||
build-linux:
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ "ubuntu-latest", "ubuntu-24.04-arm", "windows-latest" ]
|
||||
database: [ "h2", "postgresql", "mysql", "mariadb" ]
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
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"
|
||||
|
||||
- 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' }}
|
||||
|
||||
# Upload artifacts
|
||||
- name: Upload cross-platform app
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: commafeed-${{ matrix.database }}-jvm
|
||||
path: commafeed-server/target/commafeed-*.zip
|
||||
overwrite: true
|
||||
|
||||
- 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:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
database: [ "h2", "postgresql", "mysql", "mariadb" ]
|
||||
@@ -27,29 +76,29 @@ jobs:
|
||||
- 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"
|
||||
- name: Install required packages
|
||||
run: sudo apt-get install -y rename unzip
|
||||
|
||||
# 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
|
||||
# Prepare artifacts
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: commafeed-${{ matrix.database }}-jvm
|
||||
path: commafeed-server/target/commafeed-*.zip
|
||||
pattern: commafeed-${{ matrix.database }}-*
|
||||
path: ./artifacts
|
||||
merge-multiple: true
|
||||
|
||||
- name: Upload native executable
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: commafeed-${{ matrix.database }}-${{ runner.os }}-${{ runner.arch }}
|
||||
path: commafeed-server/target/commafeed-*-runner
|
||||
- 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
|
||||
@@ -67,7 +116,7 @@ jobs:
|
||||
context: .
|
||||
file: commafeed-server/src/main/docker/Dockerfile.native
|
||||
push: true
|
||||
platforms: linux/amd64
|
||||
platforms: linux/amd64,linux/arm64/v8
|
||||
tags: |
|
||||
athou/commafeed:latest-${{ matrix.database }}
|
||||
athou/commafeed:${{ github.ref_name }}-${{ matrix.database }}
|
||||
@@ -92,7 +141,7 @@ jobs:
|
||||
context: .
|
||||
file: commafeed-server/src/main/docker/Dockerfile.native
|
||||
push: true
|
||||
platforms: linux/amd64
|
||||
platforms: linux/amd64,linux/arm64/v8
|
||||
tags: athou/commafeed:master-${{ matrix.database }}
|
||||
|
||||
- name: Docker build and push master - jvm
|
||||
@@ -105,46 +154,10 @@ jobs:
|
||||
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
|
||||
- build
|
||||
if: github.ref_type == 'tag'
|
||||
|
||||
steps:
|
||||
@@ -160,6 +173,9 @@ jobs:
|
||||
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@v2
|
||||
id: changelog_reader
|
||||
|
||||
65
CHANGELOG.md
65
CHANGELOG.md
@@ -1,5 +1,70 @@
|
||||
# Changelog
|
||||
|
||||
## [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
|
||||
|
||||
28
README.md
28
README.md
@@ -80,7 +80,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 +92,40 @@ 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)
|
||||
- a `config/application.properties` [properties](https://en.wikipedia.org/wiki/.properties) file relative to the working
|
||||
directory (keys in kebab-case)
|
||||
- Command line arguments 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.
|
||||
|
||||
All [CommaFeed settings](commafeed-server/doc/commafeed.md) 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 +137,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
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"$schema": "https://biomejs.dev/schemas/1.8.3/schema.json",
|
||||
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
|
||||
"formatter": {
|
||||
"indentStyle": "space",
|
||||
"indentWidth": 4,
|
||||
|
||||
6002
commafeed-client/package-lock.json
generated
6002
commafeed-client/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -15,24 +15,23 @@
|
||||
"i18n:extract": "lingui extract --clean"
|
||||
},
|
||||
"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",
|
||||
"@emotion/react": "^11.14.0",
|
||||
"@fontsource/open-sans": "^5.1.1",
|
||||
"@mantine/core": "^7.16.0",
|
||||
"@mantine/form": "^7.16.0",
|
||||
"@mantine/hooks": "^7.16.0",
|
||||
"@mantine/modals": "^7.16.0",
|
||||
"@mantine/notifications": "^7.16.0",
|
||||
"@mantine/spotlight": "^7.16.0",
|
||||
"@lingui/core": "^5.1.2",
|
||||
"@lingui/react": "^5.1.2",
|
||||
"@monaco-editor/react": "^4.6.0",
|
||||
"@reduxjs/toolkit": "^2.2.7",
|
||||
"axios": "^1.7.4",
|
||||
"dayjs": "^1.11.12",
|
||||
"@reduxjs/toolkit": "^2.5.0",
|
||||
"axios": "^1.7.9",
|
||||
"dayjs": "^1.11.13",
|
||||
"escape-string-regexp": "^5.0.0",
|
||||
"interweave": "^13.1.0",
|
||||
"monaco-editor": "^0.50.0",
|
||||
"monaco-editor": "^0.52.2",
|
||||
"mousetrap": "^1.6.5",
|
||||
"react": "^18.3.1",
|
||||
"react-async-hook": "^4.0.0",
|
||||
@@ -42,38 +41,40 @@
|
||||
"react-draggable": "^4.4.6",
|
||||
"react-ga4": "^2.1.0",
|
||||
"react-helmet": "^6.1.0",
|
||||
"react-icons": "^5.2.1",
|
||||
"react-icons": "^5.4.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-redux": "^9.2.0",
|
||||
"react-router-dom": "^7.1.2",
|
||||
"react-swipeable": "^7.0.2",
|
||||
"redoc": "^2.3.0",
|
||||
"style-to-object": "^1.0.8",
|
||||
"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.14",
|
||||
"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": "^1.9.4",
|
||||
"@lingui/babel-plugin-lingui-macro": "^5.1.2",
|
||||
"@lingui/cli": "^5.1.2",
|
||||
"@lingui/vite-plugin": "^5.1.2",
|
||||
"@types/mousetrap": "^1.6.15",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@types/react": "^18.3.18",
|
||||
"@types/react-dom": "^18.3.5",
|
||||
"@types/react-helmet": "^6.1.11",
|
||||
"@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",
|
||||
"@types/tinycon": "^0.6.7",
|
||||
"@vitejs/plugin-react": "^4.3.4",
|
||||
"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"
|
||||
"jsdom": "^26.0.0",
|
||||
"rollup-plugin-visualizer": "^5.13.1",
|
||||
"typescript": "^5.7.3",
|
||||
"vite": "^6.0.7",
|
||||
"vite-plugin-checker": "^0.8.0",
|
||||
"vite-tsconfig-paths": "^5.1.4",
|
||||
"vitest": "^3.0.1",
|
||||
"vitest-mock-extended": "^2.0.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,16 +6,16 @@
|
||||
<parent>
|
||||
<groupId>com.commafeed</groupId>
|
||||
<artifactId>commafeed</artifactId>
|
||||
<version>5.0.0</version>
|
||||
<version>5.4.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>
|
||||
<node.version>v22.13.0</node.version>
|
||||
<!-- renovate: datasource=npm depName=npm -->
|
||||
<npm.version>10.8.2</npm.version>
|
||||
<npm.version>11.0.0</npm.version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
@@ -23,7 +23,7 @@
|
||||
<plugin>
|
||||
<groupId>com.github.eirslett</groupId>
|
||||
<artifactId>frontend-maven-plugin</artifactId>
|
||||
<version>1.15.0</version>
|
||||
<version>1.15.1</version>
|
||||
<?m2e ignore?>
|
||||
<executions>
|
||||
<execution>
|
||||
|
||||
@@ -71,7 +71,7 @@ function Providers(props: { children: React.ReactNode }) {
|
||||
)
|
||||
}
|
||||
|
||||
// swagger-ui is very large, load only on-demand
|
||||
// api documentation page is very large, load only on-demand
|
||||
const ApiDocumentationPage = React.lazy(async () => await import("pages/app/ApiDocumentationPage"))
|
||||
|
||||
function AppRoutes() {
|
||||
@@ -142,16 +142,18 @@ function GoogleAnalyticsHandler() {
|
||||
return null
|
||||
}
|
||||
|
||||
function FaviconHandler() {
|
||||
const root = useAppSelector(state => state.tree.rootCategory)
|
||||
function UnreadCountTitleHandler({ unreadCount, enabled }: { unreadCount: number; enabled?: boolean }) {
|
||||
return <Helmet title={enabled && unreadCount > 0 ? `(${unreadCount}) CommaFeed` : "CommaFeed"} />
|
||||
}
|
||||
|
||||
function UnreadCountFaviconHandler({ unreadCount, enabled }: { unreadCount: number; enabled?: boolean }) {
|
||||
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
|
||||
}
|
||||
@@ -179,8 +181,13 @@ function CustomCode() {
|
||||
|
||||
export function App() {
|
||||
useI18n()
|
||||
const root = useAppSelector(state => state.tree.rootCategory)
|
||||
const unreadCountTitle = useAppSelector(state => state.user.settings?.unreadCountTitle)
|
||||
const unreadCountFavicon = useAppSelector(state => state.user.settings?.unreadCountFavicon)
|
||||
const dispatch = useAppDispatch()
|
||||
|
||||
const unreadCount = categoryUnreadCount(root)
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(reloadServerInfos())
|
||||
}, [dispatch])
|
||||
@@ -188,7 +195,8 @@ export function App() {
|
||||
return (
|
||||
<Providers>
|
||||
<>
|
||||
<FaviconHandler />
|
||||
<UnreadCountTitleHandler unreadCount={unreadCount} enabled={unreadCountTitle} />
|
||||
<UnreadCountFaviconHandler unreadCount={unreadCount} enabled={unreadCountFavicon} />
|
||||
<BrowserExtensionBadgeUnreadCountHandler />
|
||||
<HashRouter>
|
||||
<GoogleAnalyticsHandler />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { t } from "@lingui/macro"
|
||||
import { t } from "@lingui/core/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> = {
|
||||
@@ -50,10 +50,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",
|
||||
|
||||
@@ -166,22 +166,34 @@ 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 scrollToEntry = (entryElement: HTMLElement, margin: number, scrollSpeed: number | undefined, onScrollEnded: () => void) => {
|
||||
const header = document.getElementById(Constants.dom.headerId)?.getBoundingClientRect()
|
||||
const offset = (header?.bottom ?? 0) + 3
|
||||
const offset = (header?.bottom ?? 0) + margin
|
||||
scrollToWithCallback({
|
||||
options: {
|
||||
top: entryElement.offsetTop - offset,
|
||||
@@ -218,7 +230,7 @@ export const selectPreviousEntry = createAppAsyncThunk(
|
||||
)
|
||||
export const selectNextEntry = createAppAsyncThunk(
|
||||
"entries/entry/selectNext",
|
||||
(
|
||||
async (
|
||||
arg: {
|
||||
expand: boolean
|
||||
markAsRead: boolean
|
||||
@@ -227,12 +239,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,
|
||||
|
||||
@@ -3,7 +3,8 @@ 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 { LocalSettings } from "app/types"
|
||||
import { initialLocalSettings, userSlice } from "app/user/slice"
|
||||
import { type TypedUseSelectorHook, useDispatch, useSelector } from "react-redux"
|
||||
|
||||
export const reducers = {
|
||||
@@ -14,7 +15,36 @@ export const reducers = {
|
||||
user: userSlice.reducer,
|
||||
}
|
||||
|
||||
export const store = configureStore({ reducer: reducers })
|
||||
const loadLocalSettings = (): LocalSettings => {
|
||||
const json = localStorage.getItem("commafeed-local-settings")
|
||||
if (json) {
|
||||
return JSON.parse(json)
|
||||
}
|
||||
|
||||
// load old settings
|
||||
const viewMode = localStorage.getItem("view-mode")
|
||||
const sidebarWidth = localStorage.getItem("sidebar-width")
|
||||
const announcementHash = localStorage.getItem("announcement-hash")
|
||||
return {
|
||||
...initialLocalSettings,
|
||||
viewMode: viewMode ? JSON.parse(viewMode) : initialLocalSettings.viewMode,
|
||||
sidebarWidth: sidebarWidth ? JSON.parse(sidebarWidth) : initialLocalSettings.sidebarWidth,
|
||||
announcementHash: announcementHash ? JSON.parse(announcementHash) : initialLocalSettings.announcementHash,
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -220,6 +220,7 @@ export interface ServerInfo {
|
||||
websocketEnabled: boolean
|
||||
websocketPingInterval: number
|
||||
treeReloadInterval: number
|
||||
forceRefreshCooldownDuration: number
|
||||
}
|
||||
|
||||
export interface SharingSettings {
|
||||
@@ -243,14 +244,23 @@ export interface Settings {
|
||||
customJs?: string
|
||||
scrollSpeed: number
|
||||
scrollMode: ScrollMode
|
||||
entriesToKeepOnTopWhenScrolling: number
|
||||
starIconDisplayMode: IconDisplayMode
|
||||
externalLinkIconDisplayMode: IconDisplayMode
|
||||
markAllAsReadConfirmation: boolean
|
||||
customContextMenu: boolean
|
||||
mobileFooter: boolean
|
||||
unreadCountTitle: boolean
|
||||
unreadCountFavicon: boolean
|
||||
sharingSettings: SharingSettings
|
||||
}
|
||||
|
||||
export interface LocalSettings {
|
||||
viewMode: ViewMode
|
||||
sidebarWidth: number
|
||||
announcementHash: string
|
||||
}
|
||||
|
||||
export interface StarRequest {
|
||||
id: string
|
||||
feedId: number
|
||||
@@ -278,6 +288,7 @@ export interface UserModel {
|
||||
created: number
|
||||
lastLogin?: number
|
||||
admin: boolean
|
||||
lastForceRefresh?: number
|
||||
}
|
||||
|
||||
export interface AdminSaveUserRequest {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
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 { type PayloadAction, createSlice, isAnyOf } from "@reduxjs/toolkit"
|
||||
import type { LocalSettings, Settings, UserModel, ViewMode } from "app/types"
|
||||
import {
|
||||
changeCustomContextMenu,
|
||||
changeEntriesToKeepOnTopWhenScrolling,
|
||||
changeExternalLinkIconDisplayMode,
|
||||
changeLanguage,
|
||||
changeMarkAllAsReadConfirmation,
|
||||
@@ -16,6 +17,8 @@ import {
|
||||
changeSharingSetting,
|
||||
changeShowRead,
|
||||
changeStarIconDisplayMode,
|
||||
changeUnreadCountFavicon,
|
||||
changeUnreadCountTitle,
|
||||
reloadProfile,
|
||||
reloadSettings,
|
||||
reloadTags,
|
||||
@@ -23,16 +26,35 @@ 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",
|
||||
}
|
||||
|
||||
const initialState: UserState = {
|
||||
localSettings: initialLocalSettings,
|
||||
}
|
||||
|
||||
export const userSlice = createSlice({
|
||||
name: "user",
|
||||
initialState,
|
||||
reducers: {},
|
||||
reducers: {
|
||||
setViewMode: (state, action: PayloadAction<ViewMode>) => {
|
||||
state.localSettings.viewMode = 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 +93,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
|
||||
@@ -91,6 +117,14 @@ 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(changeSharingSetting.pending, (state, action) => {
|
||||
if (!state.settings) return
|
||||
state.settings.sharingSettings[action.meta.arg.site] = action.meta.arg.value
|
||||
@@ -102,11 +136,14 @@ export const userSlice = createSlice({
|
||||
changeShowRead.fulfilled,
|
||||
changeScrollMarks.fulfilled,
|
||||
changeScrollMode.fulfilled,
|
||||
changeEntriesToKeepOnTopWhenScrolling.fulfilled,
|
||||
changeStarIconDisplayMode.fulfilled,
|
||||
changeExternalLinkIconDisplayMode.fulfilled,
|
||||
changeMarkAllAsReadConfirmation.fulfilled,
|
||||
changeCustomContextMenu.fulfilled,
|
||||
changeMobileFooter.fulfilled,
|
||||
changeUnreadCountTitle.fulfilled,
|
||||
changeUnreadCountFavicon.fulfilled,
|
||||
changeSharingSetting.fulfilled
|
||||
),
|
||||
() => {
|
||||
@@ -118,3 +155,5 @@ export const userSlice = createSlice({
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
export const { setViewMode, setSidebarWidth, setAnnouncementHash } = userSlice.actions
|
||||
|
||||
@@ -43,6 +43,14 @@ export const changeScrollMode = createAppAsyncThunk("settings/scrollMode", (scro
|
||||
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) => {
|
||||
@@ -77,6 +85,16 @@ export const changeMobileFooter = createAppAsyncThunk("settings/mobileFooter", (
|
||||
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 changeSharingSetting = createAppAsyncThunk(
|
||||
"settings/sharingSetting",
|
||||
(
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 { useAppDispatch, useAppSelector } from "app/store"
|
||||
import { setAnnouncementHash } from "app/user/slice"
|
||||
import { Content } from "components/content/Content"
|
||||
import { useAsync } from "react-async-hook"
|
||||
import useLocalStorage from "use-local-storage"
|
||||
|
||||
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 (
|
||||
|
||||
@@ -9,6 +9,7 @@ interface ImageWithPlaceholderWhileLoadingProps {
|
||||
title?: string
|
||||
width?: number
|
||||
height?: number | "auto"
|
||||
style?: React.CSSProperties
|
||||
placeholderWidth?: number
|
||||
placeholderHeight?: number
|
||||
placeholderBackgroundColor?: string
|
||||
@@ -42,6 +43,7 @@ export function ImageWithPlaceholderWhileLoading({
|
||||
src,
|
||||
title,
|
||||
width,
|
||||
style,
|
||||
}: ImageWithPlaceholderWhileLoadingProps) {
|
||||
const { classes } = useStyles({
|
||||
placeholderWidth,
|
||||
@@ -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,
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
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"
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
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 { 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)
|
||||
}, [])
|
||||
const now = useNow(60 * 1000)
|
||||
|
||||
if (!props.date) return <Trans>N/A</Trans>
|
||||
const date = dayjs(props.date)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
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"
|
||||
|
||||
@@ -1,11 +1,24 @@
|
||||
import { TypographyStylesProvider } 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 <TypographyStylesProvider className={classes.content}>{props.children}</TypographyStylesProvider>
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ 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 React from "react"
|
||||
import styleToObject from "style-to-object"
|
||||
import { tss } from "tss"
|
||||
|
||||
export interface ContentProps {
|
||||
@@ -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}
|
||||
/>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
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"
|
||||
@@ -20,7 +20,6 @@ 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"
|
||||
@@ -38,7 +37,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()
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ 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"
|
||||
@@ -95,7 +94,7 @@ const useStyles = tss
|
||||
})
|
||||
|
||||
export function FeedEntry(props: FeedEntryProps) {
|
||||
const { viewMode } = useViewMode()
|
||||
const viewMode = useAppSelector(state => state.user.localSettings.viewMode)
|
||||
const { classes, cx } = useStyles({
|
||||
read: props.entry.read,
|
||||
expanded: props.expanded,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
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"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
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"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
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"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
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"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
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"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
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"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
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"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
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"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
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"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
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"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Trans, msg } from "@lingui/macro"
|
||||
import { msg } from "@lingui/core/macro"
|
||||
import { Trans } from "@lingui/react/macro"
|
||||
|
||||
import { Button, Code, Group, Modal, Slider, Stack, Text } from "@mantine/core"
|
||||
import { markAllEntries } from "app/entries/thunks"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Trans } from "@lingui/macro"
|
||||
import { Trans } from "@lingui/react/macro"
|
||||
import {
|
||||
Box,
|
||||
Divider,
|
||||
@@ -14,7 +14,10 @@ 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 { setViewMode } from "app/user/slice"
|
||||
import { reloadProfile } from "app/user/thunks"
|
||||
import dayjs from "dayjs"
|
||||
import { useNow } from "hooks/useNow"
|
||||
import { type ReactNode, useState } from "react"
|
||||
import {
|
||||
TbChartLine,
|
||||
@@ -92,12 +95,19 @@ const viewModeData: ViewModeControlItem[] = [
|
||||
|
||||
export function ProfileMenu(props: ProfileMenuProps) {
|
||||
const [opened, setOpened] = useState(false)
|
||||
const { viewMode, setViewMode } = useViewMode()
|
||||
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 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 +128,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 (error) {
|
||||
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,7 +180,7 @@ 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"
|
||||
/>
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { NumberFormatter } from "@mantine/core"
|
||||
import type { MetricGauge } from "app/types"
|
||||
|
||||
interface MeterProps {
|
||||
@@ -5,5 +6,5 @@ interface MeterProps {
|
||||
}
|
||||
|
||||
export function Gauge(props: MeterProps) {
|
||||
return <span>{props.gauge.value}</span>
|
||||
return <NumberFormatter value={props.gauge.value} thousandSeparator />
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Trans } from "@lingui/macro"
|
||||
import { Trans } from "@lingui/react/macro"
|
||||
import { Box, Button, Group, Stack } from "@mantine/core"
|
||||
import { useForm } from "@mantine/form"
|
||||
import { client, errorToStrings } from "app/client"
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
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 { Divider, Group, NumberInput, Radio, Select, 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 {
|
||||
changeCustomContextMenu,
|
||||
changeEntriesToKeepOnTopWhenScrolling,
|
||||
changeExternalLinkIconDisplayMode,
|
||||
changeLanguage,
|
||||
changeMarkAllAsReadConfirmation,
|
||||
@@ -17,6 +19,8 @@ import {
|
||||
changeSharingSetting,
|
||||
changeShowRead,
|
||||
changeStarIconDisplayMode,
|
||||
changeUnreadCountFavicon,
|
||||
changeUnreadCountTitle,
|
||||
} from "app/user/thunks"
|
||||
import { locales } from "i18n"
|
||||
import type { ReactNode } from "react"
|
||||
@@ -27,11 +31,14 @@ 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 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 sharingSettings = useAppSelector(state => state.user.settings?.sharingSettings)
|
||||
const dispatch = useAppDispatch()
|
||||
const { _ } = useLingui()
|
||||
@@ -91,6 +98,20 @@ export function DisplaySettings() {
|
||||
onChange={async e => await dispatch(changeMobileFooter(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
|
||||
@@ -127,6 +148,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}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Trans, msg } from "@lingui/macro"
|
||||
import { msg } from "@lingui/core/macro"
|
||||
import { useLingui } from "@lingui/react"
|
||||
import { Trans } from "@lingui/react/macro"
|
||||
import { Anchor, Box, Button, Checkbox, Divider, Group, Input, PasswordInput, Stack, Text, TextInput } from "@mantine/core"
|
||||
import { useForm } from "@mantine/form"
|
||||
import { openConfirmModal } from "@mantine/modals"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Trans } from "@lingui/macro"
|
||||
import { Trans } from "@lingui/react/macro"
|
||||
import { Box, Stack } from "@mantine/core"
|
||||
import { Constants } from "app/constants"
|
||||
import {
|
||||
@@ -35,6 +35,21 @@ export function Tree() {
|
||||
const showRead = useAppSelector(state => state.user.settings?.showRead)
|
||||
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))
|
||||
@@ -97,8 +112,7 @@ export function Tree() {
|
||||
)
|
||||
|
||||
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))
|
||||
return (
|
||||
@@ -107,7 +121,7 @@ export function Tree() {
|
||||
type="category"
|
||||
name={category.name}
|
||||
icon={category.expanded ? expandedIcon : collapsedIcon}
|
||||
unread={unreadCount}
|
||||
unread={categoryUnreadCount(category)}
|
||||
selected={source.type === "category" && source.id === category.id}
|
||||
expanded={category.expanded}
|
||||
level={level}
|
||||
@@ -120,7 +134,7 @@ export function Tree() {
|
||||
}
|
||||
|
||||
const feedNode = (feed: Subscription, level = 0) => {
|
||||
if (feed.unread === 0 && !showRead) return null
|
||||
if (!isFeedDisplayed(feed)) return null
|
||||
|
||||
return (
|
||||
<TreeNode
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Trans, msg } from "@lingui/macro"
|
||||
import { msg } from "@lingui/core/macro"
|
||||
import { useLingui } from "@lingui/react"
|
||||
import { Trans } from "@lingui/react/macro"
|
||||
import { TextInput } from "@mantine/core"
|
||||
import { Spotlight, type SpotlightActionData, spotlight } from "@mantine/spotlight"
|
||||
import { redirectToFeed } from "app/redirect/thunks"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { msg } from "@lingui/macro"
|
||||
import { msg } from "@lingui/core/macro"
|
||||
import { useLingui } from "@lingui/react"
|
||||
import { useAppSelector } from "app/store"
|
||||
|
||||
|
||||
10
commafeed-client/src/hooks/useNow.ts
Normal file
10
commafeed-client/src/hooks/useNow.ts
Normal 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
|
||||
}
|
||||
@@ -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 }
|
||||
}
|
||||
@@ -140,6 +140,10 @@ msgstr ""
|
||||
msgid "Browser extention"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Browser tab"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
@@ -317,6 +321,10 @@ msgstr "دخول"
|
||||
msgid "Enter your current password to change profile settings"
|
||||
msgstr "أدخل كلمة المرور الحالية لتغيير إعدادات ملف التعريف"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entries to keep above the selected entry when scrolling"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entry headers"
|
||||
msgstr ""
|
||||
@@ -368,6 +376,10 @@ msgstr ""
|
||||
msgid "Filtering expression"
|
||||
msgstr "تصفية التعبير"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Force fetching feeds is not yet available."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Forgot password?"
|
||||
msgstr "هل نسيت كلمة المرور؟"
|
||||
@@ -604,6 +616,10 @@ msgstr ""
|
||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Only applies to compact, cozy and detailed modes"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Oops!"
|
||||
msgstr "اوووه!"
|
||||
@@ -826,6 +842,14 @@ msgstr ""
|
||||
msgid "Show star icon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab favicon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab title"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/WelcomePage.tsx
|
||||
|
||||
@@ -140,6 +140,10 @@ msgstr "Extensió del navegador necessària per a Chrome"
|
||||
msgid "Browser extention"
|
||||
msgstr "Extensió del navegador"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Browser tab"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
@@ -317,6 +321,10 @@ msgstr "Entra"
|
||||
msgid "Enter your current password to change profile settings"
|
||||
msgstr "introduïu la vostra contrasenya actual per canviar la configuració del perfil"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entries to keep above the selected entry when scrolling"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entry headers"
|
||||
msgstr ""
|
||||
@@ -368,6 +376,10 @@ msgstr ""
|
||||
msgid "Filtering expression"
|
||||
msgstr "Expressió de filtratge"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Force fetching feeds is not yet available."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Forgot password?"
|
||||
msgstr "Heu oblidat la contrasenya?"
|
||||
@@ -604,6 +616,10 @@ msgstr ""
|
||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||
msgstr "Al mòbil, mostra els botons d'acció a la part inferior de la pantalla"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Only applies to compact, cozy and detailed modes"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Oops!"
|
||||
msgstr "Vaja!"
|
||||
@@ -826,6 +842,14 @@ msgstr "Mostra el menú natiu (escriptori)"
|
||||
msgid "Show star icon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab favicon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab title"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/WelcomePage.tsx
|
||||
|
||||
@@ -140,6 +140,10 @@ msgstr ""
|
||||
msgid "Browser extention"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Browser tab"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
@@ -317,6 +321,10 @@ msgstr "Vstupte"
|
||||
msgid "Enter your current password to change profile settings"
|
||||
msgstr "Zadejte své aktuální heslo pro změnu nastavení profilu"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entries to keep above the selected entry when scrolling"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entry headers"
|
||||
msgstr ""
|
||||
@@ -368,6 +376,10 @@ msgstr ""
|
||||
msgid "Filtering expression"
|
||||
msgstr "Filtrování výrazu"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Force fetching feeds is not yet available."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Forgot password?"
|
||||
msgstr "Zapomněli jste heslo?"
|
||||
@@ -604,6 +616,10 @@ msgstr ""
|
||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Only applies to compact, cozy and detailed modes"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Oops!"
|
||||
msgstr "Jejda!"
|
||||
@@ -826,6 +842,14 @@ msgstr ""
|
||||
msgid "Show star icon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab favicon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab title"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/WelcomePage.tsx
|
||||
|
||||
@@ -140,6 +140,10 @@ msgstr ""
|
||||
msgid "Browser extention"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Browser tab"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
@@ -317,6 +321,10 @@ msgstr "Ewch i mewn"
|
||||
msgid "Enter your current password to change profile settings"
|
||||
msgstr "Rhowch eich cyfrinair presennol i newid gosodiadau proffil"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entries to keep above the selected entry when scrolling"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entry headers"
|
||||
msgstr ""
|
||||
@@ -368,6 +376,10 @@ msgstr ""
|
||||
msgid "Filtering expression"
|
||||
msgstr "Hidlo mynegiant"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Force fetching feeds is not yet available."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Forgot password?"
|
||||
msgstr "Wedi anghofio cyfrinair?"
|
||||
@@ -604,6 +616,10 @@ msgstr ""
|
||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Only applies to compact, cozy and detailed modes"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Oops!"
|
||||
msgstr "Wps!"
|
||||
@@ -826,6 +842,14 @@ msgstr ""
|
||||
msgid "Show star icon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab favicon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab title"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/WelcomePage.tsx
|
||||
|
||||
@@ -140,6 +140,10 @@ msgstr ""
|
||||
msgid "Browser extention"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Browser tab"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
@@ -317,6 +321,10 @@ msgstr ""
|
||||
msgid "Enter your current password to change profile settings"
|
||||
msgstr "Indtast din nuværende adgangskode for at ændre profilindstillinger"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entries to keep above the selected entry when scrolling"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entry headers"
|
||||
msgstr ""
|
||||
@@ -368,6 +376,10 @@ msgstr ""
|
||||
msgid "Filtering expression"
|
||||
msgstr "Filtrerende udtryk"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Force fetching feeds is not yet available."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Forgot password?"
|
||||
msgstr "Glemt adgangskode?"
|
||||
@@ -604,6 +616,10 @@ msgstr ""
|
||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Only applies to compact, cozy and detailed modes"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Oops!"
|
||||
msgstr "Hovsa!"
|
||||
@@ -826,6 +842,14 @@ msgstr ""
|
||||
msgid "Show star icon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab favicon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab title"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/WelcomePage.tsx
|
||||
|
||||
@@ -140,6 +140,10 @@ msgstr "Browser-Erweiterung für Chrome benötigt"
|
||||
msgid "Browser extention"
|
||||
msgstr "Browser-Erweiterung"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Browser tab"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
@@ -317,6 +321,10 @@ msgstr "Eintreten"
|
||||
msgid "Enter your current password to change profile settings"
|
||||
msgstr "Geben Sie Ihr aktuelles Passwort ein, um die Profileinstellungen zu ändern"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entries to keep above the selected entry when scrolling"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entry headers"
|
||||
msgstr ""
|
||||
@@ -368,6 +376,10 @@ msgstr ""
|
||||
msgid "Filtering expression"
|
||||
msgstr "Filterausdruck"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Force fetching feeds is not yet available."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Forgot password?"
|
||||
msgstr "Passwort vergessen?"
|
||||
@@ -604,6 +616,10 @@ msgstr ""
|
||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||
msgstr "Auf mobilen Geräten die Aktion-Buttons am unteren Ende des Bildschirms anzeigen"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Only applies to compact, cozy and detailed modes"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Oops!"
|
||||
msgstr "Ups!"
|
||||
@@ -826,6 +842,14 @@ msgstr "Natives Menü anzeigen (Desktop)"
|
||||
msgid "Show star icon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab favicon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab title"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/WelcomePage.tsx
|
||||
|
||||
@@ -140,6 +140,10 @@ msgstr "Browser extension required for Chrome"
|
||||
msgid "Browser extention"
|
||||
msgstr "Browser extention"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Browser tab"
|
||||
msgstr "Browser tab"
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
@@ -317,6 +321,10 @@ msgstr "Enter"
|
||||
msgid "Enter your current password to change profile settings"
|
||||
msgstr "Enter your current password to change profile settings"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entries to keep above the selected entry when scrolling"
|
||||
msgstr "Entries to keep above the selected entry when scrolling"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entry headers"
|
||||
msgstr "Entry headers"
|
||||
@@ -368,6 +376,10 @@ msgstr "Fever API URL"
|
||||
msgid "Filtering expression"
|
||||
msgstr "Filtering expression"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Force fetching feeds is not yet available."
|
||||
msgstr "Force fetching feeds is not yet available."
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Forgot password?"
|
||||
msgstr "Forgot password?"
|
||||
@@ -604,6 +616,10 @@ msgstr "On mobile"
|
||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||
msgstr "On mobile, show action buttons at the bottom of the screen"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Only applies to compact, cozy and detailed modes"
|
||||
msgstr "Only applies to compact, cozy and detailed modes"
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Oops!"
|
||||
msgstr "Oops!"
|
||||
@@ -826,6 +842,14 @@ msgstr "Show native menu (desktop)"
|
||||
msgid "Show star icon"
|
||||
msgstr "Show star icon"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab favicon"
|
||||
msgstr "Show unread count in tab favicon"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab title"
|
||||
msgstr "Show unread count in tab title"
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/WelcomePage.tsx
|
||||
|
||||
@@ -1,25 +1,26 @@
|
||||
# SPDX-FileCopyrightText: 2024 victorhck <victorhck@mailbox.org>
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"POT-Creation-Date: 2022-10-28 13:47+0200\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: @lingui/cli\n"
|
||||
"X-Generator: Lokalize 24.08.0\n"
|
||||
"Language: es\n"
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"PO-Revision-Date: 2024-09-13 17:17+0200\n"
|
||||
"Last-Translator: victorhck <victorhck@mailbox.org>\n"
|
||||
"Language-Team: Spanish <kde-i18n-doc@kde.org>\n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#: src/pages/app/AboutPage.tsx
|
||||
msgid "<0>CommaFeed is an open-source project. Sources are hosted on </0><1>GitHub</1>."
|
||||
msgstr ""
|
||||
msgstr "<0>CommaFeed es un proyecto de código abierto. El código fuente está hospedado en </0><1>GitHub</1>."
|
||||
|
||||
#: src/pages/app/FeedDetailsPage.tsx
|
||||
msgid "<0>Complete syntax is available </0><1>here</1>."
|
||||
msgstr ""
|
||||
msgstr "<0>La sintaxis completa está disponible </0><1>aquí</1>."
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
msgid "<0>Have an account?</0><1>Log in!</1>"
|
||||
@@ -27,7 +28,7 @@ msgstr "<0>¿Tienes una cuenta?</0><1>¡Inicia sesión!</1>"
|
||||
|
||||
#: src/pages/app/DonatePage.tsx
|
||||
msgid "<0>Hey,</0><1>I'm Jérémie from Belgium and I've been working on CommaFeed in my free time for over 10 years now. Thanks for taking an interest in helping me continue supporting CommaFeed.</1>"
|
||||
msgstr ""
|
||||
msgstr "<0>Hola,</0><1>Soy Jérémie de Bélgica y he estado trabajando en CommaFeed en mi tiempo libre desde hace 10 años. Gracias por interesarte en ayudarme a seguir apoyando a CommaFeed.</1>"
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "<0>Need an account?</0><1>Sign up!</1>"
|
||||
@@ -36,7 +37,7 @@ msgstr "<0>¿Necesitas una cuenta?</0><1>¡Regístrate!</1>"
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
#: src/pages/app/AboutPage.tsx
|
||||
msgid "About"
|
||||
msgstr "Sobre"
|
||||
msgstr "Acerca de"
|
||||
|
||||
#: src/pages/admin/AdminUsersPage.tsx
|
||||
msgid "Actions"
|
||||
@@ -44,7 +45,7 @@ msgstr "Acciones"
|
||||
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
msgid "Add"
|
||||
msgstr "Agregar"
|
||||
msgstr "Añadir"
|
||||
|
||||
#: src/pages/app/AddPage.tsx
|
||||
msgid "Add category"
|
||||
@@ -70,55 +71,55 @@ msgstr "Todo"
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Always"
|
||||
msgstr ""
|
||||
msgstr "Siempre"
|
||||
|
||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||
msgid "An email has been sent if this address was registered. Check your inbox."
|
||||
msgstr "Se ha enviado un correo electrónico si se registró esta dirección. "
|
||||
msgstr "Se ha enviado un correo electrónico si esta dirección estaba registrada. Revisa tu bandeja de entrada."
|
||||
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
msgid "An opml file is an XML file containing feed URLs and categories. You can get an OPML file by exporting your data from other feed reading services."
|
||||
msgstr "Un archivo opml es un archivo XML que contiene categorías y direcciones URL de fuentes. "
|
||||
msgstr "Un archivo opml es un archivo XML que contiene categorías y las URL de los feeds. Puedes obtener un archivo OPML exportando tus datos desde otros servicios de lectura de feeds."
|
||||
|
||||
#: src/components/content/add/Subscribe.tsx
|
||||
msgid "Analyze feed"
|
||||
msgstr "Analizar alimentación"
|
||||
msgstr "Analizar feed"
|
||||
|
||||
#: src/components/AnnouncementDialog.tsx
|
||||
msgid "Announcement"
|
||||
msgstr ""
|
||||
msgstr "Anuncio"
|
||||
|
||||
#: src/components/settings/ProfileSettings.tsx
|
||||
msgid "API key"
|
||||
msgstr "clave API"
|
||||
msgstr "Clave API"
|
||||
|
||||
#: src/pages/app/CategoryDetailsPage.tsx
|
||||
msgid "Are you sure you want to delete category <0>{categoryName}</0>?"
|
||||
msgstr "¿Está seguro de que desea eliminar la categoría <0>{categoryName}</0>?"
|
||||
msgstr "¿Estás seguro de que deseas eliminar la categoría <0>{categoryName}</0>?"
|
||||
|
||||
#: src/pages/admin/AdminUsersPage.tsx
|
||||
msgid "Are you sure you want to delete user <0>{userName}</0> ?"
|
||||
msgstr "¿Está seguro de que desea eliminar el usuario <0>{userName}</0> ?"
|
||||
msgstr "¿Estás seguro de que deseas eliminar el usuario <0>{userName}</0> ?"
|
||||
|
||||
#: src/components/settings/ProfileSettings.tsx
|
||||
msgid "Are you sure you want to delete your account? There's no turning back!"
|
||||
msgstr "¿Está seguro de que desea eliminar su cuenta? "
|
||||
msgstr "¿Estás seguro de que quieres eliminar tu cuenta? ¡No hay vuelta atrás!"
|
||||
|
||||
#: src/components/header/MarkAllAsReadButton.tsx
|
||||
msgid "Are you sure you want to mark all entries of <0>{sourceLabel}</0> as read?"
|
||||
msgstr "¿Está seguro de que desea marcar todas las entradas de <0>{sourceLabel}</0> como leídas?"
|
||||
msgstr "¿Estás seguro de que deseas marcar todas las entradas de <0>{sourceLabel}</0> como leídas?"
|
||||
|
||||
#: src/components/header/MarkAllAsReadButton.tsx
|
||||
msgid "Are you sure you want to mark entries older than {threshold} days of <0>{sourceLabel}</0> as read?"
|
||||
msgstr "¿Está seguro de que desea marcar las entradas anteriores a {threshold} días de <0>{sourceLabel}</0> como leídas?"
|
||||
msgstr "¿Estás seguro de que deseas marcar las entradas anteriores a {threshold} días de <0>{sourceLabel}</0> como leídas?"
|
||||
|
||||
#: src/pages/app/FeedDetailsPage.tsx
|
||||
msgid "Are you sure you want to unsubscribe from <0>{feedName}</0>?"
|
||||
msgstr "¿Está seguro de que desea darse de baja de <0>{feedName}</0>?"
|
||||
msgstr "¿Estás seguro de que deseas darte de baja de <0>{feedName}</0>?"
|
||||
|
||||
#: src/components/header/Header.tsx
|
||||
msgid "Asc"
|
||||
msgstr "ASC"
|
||||
msgstr "Asc"
|
||||
|
||||
#: src/pages/app/FeedDetailsPage.tsx
|
||||
msgid "Available variables are 'title', 'content', 'url' 'author' and 'categories' and their content is converted to lower case to ease string comparison."
|
||||
@@ -134,11 +135,15 @@ msgstr "Volver a iniciar sesión"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Browser extension required for Chrome"
|
||||
msgstr ""
|
||||
msgstr "Se requiere extensión de navegador para Chrome"
|
||||
|
||||
#: src/pages/app/AboutPage.tsx
|
||||
msgid "Browser extention"
|
||||
msgstr ""
|
||||
msgstr "Extensión del navegador"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Browser tab"
|
||||
msgstr "Pestaña del navegador"
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
@@ -170,23 +175,23 @@ msgstr "Cambiar la contraseña generará una nueva clave API"
|
||||
|
||||
#: src/components/content/add/Subscribe.tsx
|
||||
msgid "Check that the feed is working"
|
||||
msgstr "Compruebe que el feed funciona"
|
||||
msgstr "Comprueba que el feed funciona"
|
||||
|
||||
#: src/pages/app/Layout.tsx
|
||||
msgid "Close menu"
|
||||
msgstr ""
|
||||
msgstr "Cerrar menú"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Cmd"
|
||||
msgstr ""
|
||||
msgstr "Cmd"
|
||||
|
||||
#: src/pages/app/AboutPage.tsx
|
||||
msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
||||
msgstr ""
|
||||
msgstr "Versión de la extensión del navegador CommaFeed {browserExtensionVersion}."
|
||||
|
||||
#: src/components/settings/ProfileSettings.tsx
|
||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||
msgstr ""
|
||||
msgstr "CommaFeed es compatible con Fever API. Utilice la siguiente URL en su cliente móvil compatible con Fever. Inicie sesión con su nombre de usuario y su <0>clave API</0>."
|
||||
|
||||
#: src/pages/app/AboutPage.tsx
|
||||
msgid "CommaFeed next unread item"
|
||||
@@ -194,7 +199,7 @@ msgstr "CommaFeed siguiente elemento no leído"
|
||||
|
||||
#: src/pages/app/AboutPage.tsx
|
||||
msgid "CommaFeed version {version} ({revision})."
|
||||
msgstr ""
|
||||
msgstr "Versión de CommaFeed {version} ({revision})."
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Compact"
|
||||
@@ -218,7 +223,7 @@ msgstr "Acogedor"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Ctrl"
|
||||
msgstr ""
|
||||
msgstr "Ctrl"
|
||||
|
||||
#: src/components/settings/ProfileSettings.tsx
|
||||
msgid "Current password"
|
||||
@@ -226,19 +231,19 @@ msgstr "Contraseña actual"
|
||||
|
||||
#: src/pages/app/SettingsPage.tsx
|
||||
msgid "Custom code"
|
||||
msgstr ""
|
||||
msgstr "Código personalizado"
|
||||
|
||||
#: src/components/settings/CustomCodeSettings.tsx
|
||||
msgid "Custom CSS rules that will be applied"
|
||||
msgstr ""
|
||||
msgstr "Reglas CSS personalizadas que se aplicarán"
|
||||
|
||||
#: src/components/settings/CustomCodeSettings.tsx
|
||||
msgid "Custom JS code that will be executed on page load"
|
||||
msgstr ""
|
||||
msgstr "Código JS personalizado que se ejecutará al cargar la página"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Dark"
|
||||
msgstr ""
|
||||
msgstr "Oscuro"
|
||||
|
||||
#: src/pages/admin/AdminUsersPage.tsx
|
||||
msgid "Date created"
|
||||
@@ -263,25 +268,25 @@ msgstr "Borrar usuario"
|
||||
|
||||
#: src/components/header/Header.tsx
|
||||
msgid "Desc"
|
||||
msgstr ""
|
||||
msgstr "Desc"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Detailed"
|
||||
msgstr ""
|
||||
msgstr "Detallado"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
#: src/pages/app/SettingsPage.tsx
|
||||
msgid "Display"
|
||||
msgstr "Pantalla"
|
||||
msgstr "Mostrar"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
#: src/pages/app/DonatePage.tsx
|
||||
msgid "Donate"
|
||||
msgstr ""
|
||||
msgstr "Donar"
|
||||
|
||||
#: src/components/settings/ProfileSettings.tsx
|
||||
msgid "Download"
|
||||
msgstr "descargar"
|
||||
msgstr "Descargar"
|
||||
|
||||
#: src/pages/app/AboutPage.tsx
|
||||
msgid "Drag link to bookmark bar"
|
||||
@@ -298,7 +303,7 @@ msgstr "Correo electrónico"
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
msgid "E-mail address"
|
||||
msgstr "dirección de correo electrónico"
|
||||
msgstr "Dirección de correo electrónico"
|
||||
|
||||
#: src/pages/admin/AdminUsersPage.tsx
|
||||
msgid "Edit user"
|
||||
@@ -315,15 +320,19 @@ msgstr "Entrar"
|
||||
|
||||
#: src/components/settings/ProfileSettings.tsx
|
||||
msgid "Enter your current password to change profile settings"
|
||||
msgstr "Ingrese su contraseña actual para cambiar la configuración del perfil"
|
||||
msgstr "Ingresa tu contraseña actual para cambiar la configuración del perfil"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entries to keep above the selected entry when scrolling"
|
||||
msgstr "Entradas para mantener encima de la entrada seleccionada al desplazarse"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entry headers"
|
||||
msgstr ""
|
||||
msgstr "Encabezados de las entradas"
|
||||
|
||||
#: src/components/Alert.tsx
|
||||
msgid "Error"
|
||||
msgstr ""
|
||||
msgstr "Error"
|
||||
|
||||
#: src/pages/app/FeedDetailsPage.tsx
|
||||
msgid "Example: {example}."
|
||||
@@ -335,39 +344,43 @@ msgstr "Expandido"
|
||||
|
||||
#: src/components/settings/ProfileSettings.tsx
|
||||
msgid "Export your subscriptions and categories as an OPML file that can be imported in other feed reading services"
|
||||
msgstr "Exporte sus suscripciones y categorías como un archivo OPML que se puede importar en otros servicios de lectura de feeds"
|
||||
msgstr "Exporta tus suscripciones y categorías como un archivo OPML que se puede importar en otros servicios de lectura de feeds"
|
||||
|
||||
#: src/components/header/Header.tsx
|
||||
#: src/pages/WelcomePage.tsx
|
||||
msgid "Extension options"
|
||||
msgstr ""
|
||||
msgstr "Opciones de la extensión"
|
||||
|
||||
#: src/components/content/add/Subscribe.tsx
|
||||
msgid "Feed name"
|
||||
msgstr "Nombre de alimentación"
|
||||
msgstr "Nombre del feed"
|
||||
|
||||
#: src/components/content/add/Subscribe.tsx
|
||||
#: src/components/content/add/Subscribe.tsx
|
||||
#: src/pages/app/FeedDetailsPage.tsx
|
||||
msgid "Feed URL"
|
||||
msgstr "URL de fuente"
|
||||
msgstr "URL del feed"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Fetch all my feeds now"
|
||||
msgstr ""
|
||||
msgstr "Obtener todos mis feeds ahora"
|
||||
|
||||
#: src/components/settings/ProfileSettings.tsx
|
||||
msgid "Fever API"
|
||||
msgstr ""
|
||||
msgstr "API de Fever"
|
||||
|
||||
#: src/components/settings/ProfileSettings.tsx
|
||||
msgid "Fever API URL"
|
||||
msgstr ""
|
||||
msgstr "URL de la API de Fever"
|
||||
|
||||
#: src/pages/app/FeedDetailsPage.tsx
|
||||
msgid "Filtering expression"
|
||||
msgstr "Expresión de filtrado"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Force fetching feeds is not yet available."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Forgot password?"
|
||||
msgstr "¿Olvidaste la contraseña?"
|
||||
@@ -390,7 +403,7 @@ msgstr "URL del feed generado"
|
||||
|
||||
#: src/components/content/FeedEntryContextMenu.tsx
|
||||
msgid "Go to {0}"
|
||||
msgstr ""
|
||||
msgstr "Ir a {0}"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Go to the All view"
|
||||
@@ -402,7 +415,7 @@ msgstr "Ir a la documentación de la API."
|
||||
|
||||
#: src/pages/app/AboutPage.tsx
|
||||
msgid "Goodies"
|
||||
msgstr "golosinas"
|
||||
msgstr "Golosinas"
|
||||
|
||||
#: src/pages/admin/AdminUsersPage.tsx
|
||||
msgid "Id"
|
||||
@@ -410,15 +423,15 @@ msgstr "Identificación"
|
||||
|
||||
#: src/pages/app/FeedDetailsPage.tsx
|
||||
msgid "If not empty, an expression evaluating to 'true' or 'false'. If false, new entries for this feed will be marked as read automatically."
|
||||
msgstr "Si no está vacío, una expresión que se evalúa como 'verdadero' o 'falso'. "
|
||||
msgstr "Si no está vacía, una expresión que se evalúa como \"verdadera\" o \"falso\". Si es falso, las nuevas entradas de este feed se marcarán como leídas automáticamente."
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "If the entry doesn't entirely fit on the screen"
|
||||
msgstr ""
|
||||
msgstr "Si la entrada no cabe completamente en la pantalla"
|
||||
|
||||
#: src/pages/app/AboutPage.tsx
|
||||
msgid "If you encounter an issue, please report it on the issues page of the GitHub project."
|
||||
msgstr "Si encuentra un problema, infórmelo en la página de problemas del proyecto GitHub."
|
||||
msgstr "Si encuentras un problema, informa sobre ello en la página de problemas del proyecto en GitHub."
|
||||
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
msgid "Import"
|
||||
@@ -426,7 +439,7 @@ msgstr "Importar"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "In expanded view, scrolling through entries mark them as read"
|
||||
msgstr "En la vista ampliada, al desplazarse por las entradas, márquelas como leídas"
|
||||
msgstr "En la vista ampliada, al desplazarse por las entradas marcarlas como leídas"
|
||||
|
||||
#: src/components/content/FeedEntryContextMenu.tsx
|
||||
#: src/components/content/FeedEntryFooter.tsx
|
||||
@@ -436,7 +449,7 @@ msgstr "Mantener sin leer"
|
||||
#: src/components/content/FeedEntries.tsx
|
||||
#: src/pages/app/AboutPage.tsx
|
||||
msgid "Keyboard shortcuts"
|
||||
msgstr "atajos de teclado"
|
||||
msgstr "Atajos de teclado"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Language"
|
||||
@@ -444,7 +457,7 @@ msgstr "Idioma"
|
||||
|
||||
#: src/pages/admin/AdminUsersPage.tsx
|
||||
msgid "Last login date"
|
||||
msgstr "fecha del último inicio de sesión"
|
||||
msgstr "Fecha del último inicio de sesión"
|
||||
|
||||
#: src/pages/app/FeedDetailsPage.tsx
|
||||
msgid "Last refresh"
|
||||
@@ -456,7 +469,7 @@ msgstr "Último mensaje de actualización"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Light"
|
||||
msgstr ""
|
||||
msgstr "Claro"
|
||||
|
||||
#: src/pages/app/CategoryDetailsPage.tsx
|
||||
#: src/pages/app/FeedDetailsPage.tsx
|
||||
@@ -488,11 +501,11 @@ msgstr "Iniciar sesión"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Logout"
|
||||
msgstr "Salir"
|
||||
msgstr "Cerrar sesión"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Long press"
|
||||
msgstr ""
|
||||
msgstr "Pulsación larga"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
#: src/pages/admin/AdminUsersPage.tsx
|
||||
@@ -524,7 +537,7 @@ msgstr "Métricas"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Middle click"
|
||||
msgstr ""
|
||||
msgstr "Clic central"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Move the page down"
|
||||
@@ -548,12 +561,12 @@ msgstr "Nombre"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Navigate to a subscription by entering its name"
|
||||
msgstr "Navegar a una suscripción ingresando su nombre"
|
||||
msgstr "Navegar a una suscripción introduciendo su nombre"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Never"
|
||||
msgstr ""
|
||||
msgstr "Nunca"
|
||||
|
||||
#: src/components/settings/ProfileSettings.tsx
|
||||
msgid "New password"
|
||||
@@ -561,7 +574,7 @@ msgstr "Nueva contraseña"
|
||||
|
||||
#: src/pages/app/AboutPage.tsx
|
||||
msgid "Newest first"
|
||||
msgstr "más reciente primero"
|
||||
msgstr "Las más recientes primero"
|
||||
|
||||
#: src/components/content/add/Subscribe.tsx
|
||||
#: src/components/header/Header.tsx
|
||||
@@ -574,7 +587,7 @@ msgstr "Próxima actualización"
|
||||
|
||||
#: src/pages/app/AboutPage.tsx
|
||||
msgid "Next unread item bookmarklet"
|
||||
msgstr "Bookmarklet del siguiente elemento no leído"
|
||||
msgstr "Siguiente elemento no leído de los marcadores"
|
||||
|
||||
#: src/pages/app/FeedEntriesPage.tsx
|
||||
msgid "No more entries"
|
||||
@@ -582,7 +595,7 @@ msgstr "No más entradas"
|
||||
|
||||
#: src/components/content/ShareButtons.tsx
|
||||
msgid "No sharing options available."
|
||||
msgstr ""
|
||||
msgstr "No hay opciones para compartir disponibles."
|
||||
|
||||
#: src/components/sidebar/TreeSearch.tsx
|
||||
msgid "Nothing found"
|
||||
@@ -590,19 +603,23 @@ msgstr "Nada encontrado"
|
||||
|
||||
#: src/pages/app/AboutPage.tsx
|
||||
msgid "Oldest first"
|
||||
msgstr "más antigua primero"
|
||||
msgstr "Las más antiguas primero"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "On desktop"
|
||||
msgstr ""
|
||||
msgstr "En el escritorio"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "On mobile"
|
||||
msgstr ""
|
||||
msgstr "En dispositivos móviles"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||
msgstr ""
|
||||
msgstr "En dispositivos móviles, mostrar los botones de acción en la parte inferior de la pantalla"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Only applies to compact, cozy and detailed modes"
|
||||
msgstr "Sólo se aplica a los modos compacto, acogedor y detallado"
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Oops!"
|
||||
@@ -610,7 +627,7 @@ msgstr "¡Ups!"
|
||||
|
||||
#: src/components/header/Header.tsx
|
||||
msgid "Open CommaFeed"
|
||||
msgstr ""
|
||||
msgstr "Abrir Commafeed"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Open current entry in a new tab"
|
||||
@@ -627,15 +644,15 @@ msgstr "Abrir enlace"
|
||||
|
||||
#: src/components/content/FeedEntryContextMenu.tsx
|
||||
msgid "Open link in new background tab"
|
||||
msgstr ""
|
||||
msgstr "Abrir enlace en una nueva pestaña en segundo plano"
|
||||
|
||||
#: src/components/content/FeedEntryContextMenu.tsx
|
||||
msgid "Open link in new tab"
|
||||
msgstr ""
|
||||
msgstr "Abrir el enlace en una nueva pestaña"
|
||||
|
||||
#: src/pages/app/Layout.tsx
|
||||
msgid "Open menu"
|
||||
msgstr ""
|
||||
msgstr "Abrir menú"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Open next entry"
|
||||
@@ -651,20 +668,20 @@ msgstr "Abrir/cerrar entrada actual"
|
||||
|
||||
#: src/pages/app/AddPage.tsx
|
||||
msgid "OPML"
|
||||
msgstr ""
|
||||
msgstr "OPML"
|
||||
|
||||
#: src/components/settings/ProfileSettings.tsx
|
||||
msgid "OPML export"
|
||||
msgstr "Exportación OPML"
|
||||
msgstr "Exportar OPML"
|
||||
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
msgid "OPML file"
|
||||
msgstr "archivo OPML"
|
||||
msgstr "Archivo OPML"
|
||||
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
msgid "OPML file is required"
|
||||
msgstr ""
|
||||
msgstr "Es necesario un archivo OPML"
|
||||
|
||||
#: src/pages/app/AboutPage.tsx
|
||||
msgid "Order"
|
||||
@@ -701,7 +718,7 @@ msgstr "Posición"
|
||||
|
||||
#: src/components/header/Header.tsx
|
||||
msgid "Previous"
|
||||
msgstr ""
|
||||
msgstr "Previo"
|
||||
|
||||
#: src/pages/app/SettingsPage.tsx
|
||||
msgid "Profile"
|
||||
@@ -727,7 +744,7 @@ msgstr "API REST"
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Right click"
|
||||
msgstr ""
|
||||
msgstr "Clic derecho"
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/settings/CustomCodeSettings.tsx
|
||||
@@ -739,7 +756,7 @@ msgstr "Guardar"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Scroll selected entry to the top of the page"
|
||||
msgstr ""
|
||||
msgstr "Desplazar la entrada seleccionada hasta la parte superior de la página"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Scroll smoothly when navigating between entries"
|
||||
@@ -747,7 +764,7 @@ msgstr "Desplazarse suavemente al navegar entre entradas"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Scrolling"
|
||||
msgstr ""
|
||||
msgstr "Desplazarse"
|
||||
|
||||
#: src/components/header/Header.tsx
|
||||
#: src/components/header/Header.tsx
|
||||
@@ -762,15 +779,15 @@ msgstr "La búsqueda requiere al menos 3 caracteres"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Set focus on next entry without opening it"
|
||||
msgstr "Establezca el foco en la siguiente entrada sin abrirla"
|
||||
msgstr "Establecer el foco en la siguiente entrada sin abrirla"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Set focus on previous entry without opening it"
|
||||
msgstr "Poner el foco en la entrada anterior sin abrirla"
|
||||
msgstr "Establecer el foco en la entrada anterior sin abrirla"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Settings"
|
||||
msgstr "Configuraciones"
|
||||
msgstr "Ajustes"
|
||||
|
||||
#: src/app/user/slice.ts
|
||||
msgid "Settings saved."
|
||||
@@ -788,27 +805,27 @@ msgstr "Compartir sitios"
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Shift"
|
||||
msgstr "Cambio"
|
||||
msgstr "Shift"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show CommaFeed's own context menu on right click"
|
||||
msgstr ""
|
||||
msgstr "Mostrar el menú contextual propio de CommaFeed al hacer clic derecho"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show confirmation when marking all entries as read"
|
||||
msgstr ""
|
||||
msgstr "Mostrar confirmación al marcar todas las entradas como leídas"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Show entry menu (desktop)"
|
||||
msgstr ""
|
||||
msgstr "Mostrar menú de entrada (escritorio)"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Show entry menu (mobile)"
|
||||
msgstr ""
|
||||
msgstr "Mostrar menú de entrada (móvil)"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show external link icon"
|
||||
msgstr ""
|
||||
msgstr "Mostrar icono de enlace externo"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show feeds and categories with no unread entries"
|
||||
@@ -816,15 +833,23 @@ msgstr "Mostrar feeds y categorías sin entradas no leídas"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Show keyboard shortcut help"
|
||||
msgstr "Mostrar ayuda de atajo de teclado"
|
||||
msgstr "Mostrar la ayuda de los atajos de teclado"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Show native menu (desktop)"
|
||||
msgstr ""
|
||||
msgstr "Mostrar menú nativo (escritorio)"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show star icon"
|
||||
msgstr ""
|
||||
msgstr "Mostrar el icono de la estrella"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab favicon"
|
||||
msgstr "Mostrar recuento de no leídos en la pestaña favicon"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab title"
|
||||
msgstr "Mostrar recuento de no leídos en el título de la pestaña"
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
@@ -845,7 +870,7 @@ msgstr "Espacio"
|
||||
#: src/components/content/FeedEntryFooter.tsx
|
||||
#: src/components/content/header/Star.tsx
|
||||
msgid "Star"
|
||||
msgstr "estrella"
|
||||
msgstr "Estrella"
|
||||
|
||||
#: src/app/constants.ts
|
||||
#: src/components/sidebar/Tree.tsx
|
||||
@@ -860,7 +885,7 @@ msgstr "Suscribirse"
|
||||
|
||||
#: src/components/content/add/Subscribe.tsx
|
||||
msgid "Subscribe to the feed"
|
||||
msgstr "Suscríbete a la fuente"
|
||||
msgstr "Suscríbete al feed"
|
||||
|
||||
#: src/pages/app/AboutPage.tsx
|
||||
msgid "Subscribe URL"
|
||||
@@ -872,7 +897,7 @@ msgstr "Éxito"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Swipe header to the left"
|
||||
msgstr ""
|
||||
msgstr "Desliza el encabezado hacia la izquierda"
|
||||
|
||||
#: src/pages/WelcomePage.tsx
|
||||
msgid "Switch to dark theme"
|
||||
@@ -884,7 +909,7 @@ msgstr "Cambiar a tema claro"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "System"
|
||||
msgstr ""
|
||||
msgstr "Sistema"
|
||||
|
||||
#: src/components/content/FeedEntryFooter.tsx
|
||||
#: src/components/content/FeedEntryFooter.tsx
|
||||
@@ -893,7 +918,7 @@ msgstr "Etiquetas"
|
||||
|
||||
#: src/components/content/add/Subscribe.tsx
|
||||
msgid "The URL for the feed you want to subscribe to. You can also use the website's url directly and CommaFeed will try to find the feed in the page."
|
||||
msgstr "La URL de la fuente a la que desea suscribirse. "
|
||||
msgstr "La URL del feed al que desea suscribirse. También puede utilizar la URL del sitio web directamente y CommaFeed intentará encontrar el feed en la página."
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Theme"
|
||||
@@ -901,7 +926,7 @@ msgstr "Tema"
|
||||
|
||||
#: src/components/settings/ProfileSettings.tsx
|
||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||
msgstr ""
|
||||
msgstr "Esta es su clave API. Se puede utilizar para algunas operaciones API de solo lectura y otorga acceso a Fever API. Utilice el formulario en la parte inferior de la página para generar una nueva clave API"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Toggle read status of current entry"
|
||||
@@ -909,19 +934,19 @@ msgstr "Alternar estado de lectura de la entrada actual"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Toggle sidebar"
|
||||
msgstr ""
|
||||
msgstr "Alternar barra lateral"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Toggle starred status of current entry"
|
||||
msgstr ""
|
||||
msgstr "Alternar estado destacado de la entrada actual"
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Try out CommaFeed with the demo account: demo/demo"
|
||||
msgstr "Pruebe CommaFeed con la cuenta demo: demo/demo"
|
||||
msgstr "Prueba CommaFeed con la cuenta de demostración: demo/demo"
|
||||
|
||||
#: src/pages/WelcomePage.tsx
|
||||
msgid "Try the demo!"
|
||||
msgstr ""
|
||||
msgstr "¡Prueba la demostración!"
|
||||
|
||||
#: src/components/header/Header.tsx
|
||||
msgid "Unread"
|
||||
@@ -957,8 +982,8 @@ msgstr "Sitio web"
|
||||
|
||||
#: src/pages/app/FeedEntriesPage.tsx
|
||||
msgid "You don't have any subscriptions yet. Why not try adding one by clicking on the + sign at the top of the page?"
|
||||
msgstr "Todavía no tienes ninguna suscripción. "
|
||||
msgstr "Aún no tienes ninguna suscripción. ¿Por qué no intentas agregar una haciendo clic en el signo + en la parte superior de la página?"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Your feeds have been queued for refresh."
|
||||
msgstr ""
|
||||
msgstr "Tus feeds se han puesto en cola para actualizarse."
|
||||
|
||||
@@ -140,6 +140,10 @@ msgstr ""
|
||||
msgid "Browser extention"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Browser tab"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
@@ -317,6 +321,10 @@ msgstr "وارد شوید"
|
||||
msgid "Enter your current password to change profile settings"
|
||||
msgstr "رمز عبور فعلی خود را برای تغییر تنظیمات نمایه وارد کنید"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entries to keep above the selected entry when scrolling"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entry headers"
|
||||
msgstr ""
|
||||
@@ -368,6 +376,10 @@ msgstr ""
|
||||
msgid "Filtering expression"
|
||||
msgstr "بیان فیلتر"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Force fetching feeds is not yet available."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Forgot password?"
|
||||
msgstr "رمز عبور را فراموش کرده اید؟"
|
||||
@@ -604,6 +616,10 @@ msgstr ""
|
||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Only applies to compact, cozy and detailed modes"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Oops!"
|
||||
msgstr "اوه!"
|
||||
@@ -826,6 +842,14 @@ msgstr ""
|
||||
msgid "Show star icon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab favicon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab title"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/WelcomePage.tsx
|
||||
|
||||
@@ -140,6 +140,10 @@ msgstr ""
|
||||
msgid "Browser extention"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Browser tab"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
@@ -317,6 +321,10 @@ msgstr ""
|
||||
msgid "Enter your current password to change profile settings"
|
||||
msgstr "Anna nykyinen salasanasi muuttaaksesi profiiliasetuksia"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entries to keep above the selected entry when scrolling"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entry headers"
|
||||
msgstr ""
|
||||
@@ -368,6 +376,10 @@ msgstr ""
|
||||
msgid "Filtering expression"
|
||||
msgstr "Suodattava lauseke"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Force fetching feeds is not yet available."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Forgot password?"
|
||||
msgstr "Unohditko salasanan?"
|
||||
@@ -604,6 +616,10 @@ msgstr ""
|
||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Only applies to compact, cozy and detailed modes"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Oops!"
|
||||
msgstr "Hups!"
|
||||
@@ -826,6 +842,14 @@ msgstr ""
|
||||
msgid "Show star icon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab favicon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab title"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/WelcomePage.tsx
|
||||
|
||||
@@ -140,6 +140,10 @@ msgstr "L'extension navigateur est nécessaire sur Chrome"
|
||||
msgid "Browser extention"
|
||||
msgstr "Extension navigateur"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Browser tab"
|
||||
msgstr "Onglet navigateur"
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
@@ -178,7 +182,7 @@ msgstr "Fermer le menu"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Cmd"
|
||||
msgstr ""
|
||||
msgstr "Cmd"
|
||||
|
||||
#: src/pages/app/AboutPage.tsx
|
||||
msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
||||
@@ -317,9 +321,13 @@ msgstr "Entrer"
|
||||
msgid "Enter your current password to change profile settings"
|
||||
msgstr "Entrez votre mot de passe actuel pour changer les paramètres du profil"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entries to keep above the selected entry when scrolling"
|
||||
msgstr "Nombre d'entrées à conserver au-dessus de l'entrée sélectionnée lors d'un défilement"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entry headers"
|
||||
msgstr ""
|
||||
msgstr "En-têtes de l'entrée"
|
||||
|
||||
#: src/components/Alert.tsx
|
||||
msgid "Error"
|
||||
@@ -368,6 +376,10 @@ msgstr "URL API Fever"
|
||||
msgid "Filtering expression"
|
||||
msgstr "Expression de filtrage"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Force fetching feeds is not yet available."
|
||||
msgstr "La récupération forcée des flux n'est pas encore disponible."
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Forgot password?"
|
||||
msgstr "Mot de passe oublié ?"
|
||||
@@ -582,7 +594,7 @@ msgstr "Fin de la liste"
|
||||
|
||||
#: src/components/content/ShareButtons.tsx
|
||||
msgid "No sharing options available."
|
||||
msgstr ""
|
||||
msgstr "Aucune option de partage disponible"
|
||||
|
||||
#: src/components/sidebar/TreeSearch.tsx
|
||||
msgid "Nothing found"
|
||||
@@ -594,16 +606,20 @@ msgstr "Du plus ancien au plus récent"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "On desktop"
|
||||
msgstr ""
|
||||
msgstr "Version PC"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "On mobile"
|
||||
msgstr ""
|
||||
msgstr "Version mobile"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||
msgstr "Sur mobile, afficher les boutons d'action en bas de l'écran"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Only applies to compact, cozy and detailed modes"
|
||||
msgstr "Ne fonctionne que dans les modes Compact, Cozy, et Vue détaillée"
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Oops!"
|
||||
msgstr "Oups !"
|
||||
@@ -664,7 +680,7 @@ msgstr "Fichier OPML"
|
||||
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
msgid "OPML file is required"
|
||||
msgstr ""
|
||||
msgstr "Vous devez fournir un fichier OPML"
|
||||
|
||||
#: src/pages/app/AboutPage.tsx
|
||||
msgid "Order"
|
||||
@@ -808,7 +824,7 @@ msgstr "Afficher les options de l'entrée (mobile)"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show external link icon"
|
||||
msgstr ""
|
||||
msgstr "Afficher l'icône du lien distant"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show feeds and categories with no unread entries"
|
||||
@@ -824,7 +840,15 @@ msgstr "Afficher les options du navigateur (ordinateur)"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show star icon"
|
||||
msgstr ""
|
||||
msgstr "Afficher l'icône Favori"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab favicon"
|
||||
msgstr "Afficher le nombre d'entrées non lues dans la favicône de l'onglet"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab title"
|
||||
msgstr "Afficher le nombre d'entrées non lues dans le titre de l'onglet"
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
|
||||
@@ -140,6 +140,10 @@ msgstr ""
|
||||
msgid "Browser extention"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Browser tab"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
@@ -317,6 +321,10 @@ msgstr "Entra"
|
||||
msgid "Enter your current password to change profile settings"
|
||||
msgstr "Introduce o teu contrasinal actual para cambiar a configuración do perfil"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entries to keep above the selected entry when scrolling"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entry headers"
|
||||
msgstr ""
|
||||
@@ -368,6 +376,10 @@ msgstr ""
|
||||
msgid "Filtering expression"
|
||||
msgstr "Expresión de filtrado"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Force fetching feeds is not yet available."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Forgot password?"
|
||||
msgstr "Esqueceches o contrasinal?"
|
||||
@@ -604,6 +616,10 @@ msgstr ""
|
||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Only applies to compact, cozy and detailed modes"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Oops!"
|
||||
msgstr "Vaia!"
|
||||
@@ -826,6 +842,14 @@ msgstr ""
|
||||
msgid "Show star icon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab favicon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab title"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/WelcomePage.tsx
|
||||
|
||||
@@ -140,6 +140,10 @@ msgstr ""
|
||||
msgid "Browser extention"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Browser tab"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
@@ -317,6 +321,10 @@ msgstr ""
|
||||
msgid "Enter your current password to change profile settings"
|
||||
msgstr "Adja meg jelenlegi jelszavát a profilbeállítások módosításához"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entries to keep above the selected entry when scrolling"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entry headers"
|
||||
msgstr ""
|
||||
@@ -368,6 +376,10 @@ msgstr ""
|
||||
msgid "Filtering expression"
|
||||
msgstr "Szűrő kifejezés"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Force fetching feeds is not yet available."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Forgot password?"
|
||||
msgstr "Elfelejtette a jelszavát?"
|
||||
@@ -604,6 +616,10 @@ msgstr ""
|
||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Only applies to compact, cozy and detailed modes"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Oops!"
|
||||
msgstr "Hoppá!"
|
||||
@@ -826,6 +842,14 @@ msgstr ""
|
||||
msgid "Show star icon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab favicon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab title"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/WelcomePage.tsx
|
||||
|
||||
@@ -140,6 +140,10 @@ msgstr ""
|
||||
msgid "Browser extention"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Browser tab"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
@@ -317,6 +321,10 @@ msgstr "Masuk"
|
||||
msgid "Enter your current password to change profile settings"
|
||||
msgstr "Masukkan kata sandi Anda saat ini untuk mengubah pengaturan profil"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entries to keep above the selected entry when scrolling"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entry headers"
|
||||
msgstr ""
|
||||
@@ -368,6 +376,10 @@ msgstr ""
|
||||
msgid "Filtering expression"
|
||||
msgstr "Memfilter ekspresi"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Force fetching feeds is not yet available."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Forgot password?"
|
||||
msgstr "Lupa kata sandi?"
|
||||
@@ -604,6 +616,10 @@ msgstr ""
|
||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Only applies to compact, cozy and detailed modes"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Oops!"
|
||||
msgstr "Ups!"
|
||||
@@ -826,6 +842,14 @@ msgstr ""
|
||||
msgid "Show star icon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab favicon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab title"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/WelcomePage.tsx
|
||||
|
||||
@@ -140,6 +140,10 @@ msgstr ""
|
||||
msgid "Browser extention"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Browser tab"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
@@ -317,6 +321,10 @@ msgstr "Invio"
|
||||
msgid "Enter your current password to change profile settings"
|
||||
msgstr "Inserisci la tua password attuale per modificare le impostazioni del profilo"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entries to keep above the selected entry when scrolling"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entry headers"
|
||||
msgstr ""
|
||||
@@ -368,6 +376,10 @@ msgstr ""
|
||||
msgid "Filtering expression"
|
||||
msgstr "Espressione filtrante"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Force fetching feeds is not yet available."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Forgot password?"
|
||||
msgstr "Password dimenticata?"
|
||||
@@ -604,6 +616,10 @@ msgstr ""
|
||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Only applies to compact, cozy and detailed modes"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Oops!"
|
||||
msgstr "Ops!"
|
||||
@@ -826,6 +842,14 @@ msgstr ""
|
||||
msgid "Show star icon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab favicon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab title"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/WelcomePage.tsx
|
||||
|
||||
@@ -9,17 +9,17 @@ msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Last-Translator: https://github.com/dai\n"
|
||||
"Language-Team: \n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#: src/pages/app/AboutPage.tsx
|
||||
msgid "<0>CommaFeed is an open-source project. Sources are hosted on </0><1>GitHub</1>."
|
||||
msgstr ""
|
||||
msgstr "<0>CommaFeed はオープンソースのプロジェクトです。 ソースは以下でホストされています </0><1>GitHub</1>。"
|
||||
|
||||
#: src/pages/app/FeedDetailsPage.tsx
|
||||
msgid "<0>Complete syntax is available </0><1>here</1>."
|
||||
msgstr ""
|
||||
msgstr "<0>完全な syntax </0><1>こちら</1>で利用可能です。"
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
msgid "<0>Have an account?</0><1>Log in!</1>"
|
||||
@@ -27,7 +27,7 @@ msgstr "<0>アカウントをお持ちですか?</0><1>ログインしてくだ
|
||||
|
||||
#: src/pages/app/DonatePage.tsx
|
||||
msgid "<0>Hey,</0><1>I'm Jérémie from Belgium and I've been working on CommaFeed in my free time for over 10 years now. Thanks for taking an interest in helping me continue supporting CommaFeed.</1>"
|
||||
msgstr ""
|
||||
msgstr "<0>こんにちは、</0><1>私はベルギーのジェレミーです。私はこれまで 10 年以上、CommaFeed のオープンソースプロジェクトを無料で開発してきました。あなたの関心に感謝します。</1>"
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "<0>Need an account?</0><1>Sign up!</1>"
|
||||
@@ -36,7 +36,7 @@ msgstr "<0>アカウントが必要ですか?</0><1>サインアップ!</1>"
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
#: src/pages/app/AboutPage.tsx
|
||||
msgid "About"
|
||||
msgstr "約"
|
||||
msgstr "About"
|
||||
|
||||
#: src/pages/admin/AdminUsersPage.tsx
|
||||
msgid "Actions"
|
||||
@@ -44,7 +44,7 @@ msgstr "アクション"
|
||||
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
msgid "Add"
|
||||
msgstr "追記"
|
||||
msgstr "追加"
|
||||
|
||||
#: src/pages/app/AddPage.tsx
|
||||
msgid "Add category"
|
||||
@@ -58,27 +58,27 @@ msgstr "ユーザー追加"
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
#: src/pages/admin/AdminUsersPage.tsx
|
||||
msgid "Admin"
|
||||
msgstr "管理人"
|
||||
msgstr "管理者"
|
||||
|
||||
#: src/app/constants.ts
|
||||
#: src/components/content/add/CategorySelect.tsx
|
||||
#: src/components/header/Header.tsx
|
||||
#: src/components/sidebar/Tree.tsx
|
||||
msgid "All"
|
||||
msgstr "全員"
|
||||
msgstr "すべて"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Always"
|
||||
msgstr ""
|
||||
msgstr "常に"
|
||||
|
||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||
msgid "An email has been sent if this address was registered. Check your inbox."
|
||||
msgstr "このアドレスが登録されていれば、メールが送信されました。"
|
||||
msgstr "このアドレスに確認メールを送信しました。受信箱を確認してください。"
|
||||
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
msgid "An opml file is an XML file containing feed URLs and categories. You can get an OPML file by exporting your data from other feed reading services."
|
||||
msgstr "opml ファイルは、フィードの URL とカテゴリを含む XML ファイルです。"
|
||||
msgstr "opmlファイルは、フィードのURLとカテゴリを含むXMLファイルです。OPMLファイルは他のフィードサービスからエクスポートして取得することができます"
|
||||
|
||||
#: src/components/content/add/Subscribe.tsx
|
||||
msgid "Analyze feed"
|
||||
@@ -86,7 +86,7 @@ msgstr "フィードを分析する"
|
||||
|
||||
#: src/components/AnnouncementDialog.tsx
|
||||
msgid "Announcement"
|
||||
msgstr ""
|
||||
msgstr "お知らせ"
|
||||
|
||||
#: src/components/settings/ProfileSettings.tsx
|
||||
msgid "API key"
|
||||
@@ -94,27 +94,27 @@ msgstr "APIキー"
|
||||
|
||||
#: src/pages/app/CategoryDetailsPage.tsx
|
||||
msgid "Are you sure you want to delete category <0>{categoryName}</0>?"
|
||||
msgstr "カテゴリ <0>{categoryName}</0> を削除してもよろしいですか?"
|
||||
msgstr "カテゴリ <0>{categoryName}</0> を削除してもよろしいですか?"
|
||||
|
||||
#: src/pages/admin/AdminUsersPage.tsx
|
||||
msgid "Are you sure you want to delete user <0>{userName}</0> ?"
|
||||
msgstr "ユーザー <0>{userName}</0> を削除してもよろしいですか?"
|
||||
msgstr "ユーザー <0>{userName}</0> を削除してもよろしいですか?"
|
||||
|
||||
#: src/components/settings/ProfileSettings.tsx
|
||||
msgid "Are you sure you want to delete your account? There's no turning back!"
|
||||
msgstr "本当にアカウントを削除しますか?"
|
||||
msgstr "本当にアカウントを削除しますか?元には戻せません!"
|
||||
|
||||
#: src/components/header/MarkAllAsReadButton.tsx
|
||||
msgid "Are you sure you want to mark all entries of <0>{sourceLabel}</0> as read?"
|
||||
msgstr "<0>{sourceLabel}</0> のすべてのエントリを既読にしますか?"
|
||||
msgstr "<0>{sourceLabel}</0> のすべてのエントリーを既読にしますか?"
|
||||
|
||||
#: src/components/header/MarkAllAsReadButton.tsx
|
||||
msgid "Are you sure you want to mark entries older than {threshold} days of <0>{sourceLabel}</0> as read?"
|
||||
msgstr "<0>{sourceLabel}</0> の {threshold} 日より前のエントリを既読としてマークしてもよろしいですか?"
|
||||
msgstr "<0>{sourceLabel}</0> の {threshold} 日より前のエントリーを既読としてマークしてもよろしいですか?"
|
||||
|
||||
#: src/pages/app/FeedDetailsPage.tsx
|
||||
msgid "Are you sure you want to unsubscribe from <0>{feedName}</0>?"
|
||||
msgstr "<0>{feedName}</0> の登録を解除してもよろしいですか?"
|
||||
msgstr "<0>{feedName}</0> の登録を解除してもよろしいですか?"
|
||||
|
||||
#: src/components/header/Header.tsx
|
||||
msgid "Asc"
|
||||
@@ -126,7 +126,7 @@ msgstr "使用可能な変数は「title」、「content」、「url」、「aut
|
||||
|
||||
#: src/components/content/add/Subscribe.tsx
|
||||
msgid "Back"
|
||||
msgstr "裏"
|
||||
msgstr "戻る"
|
||||
|
||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||
msgid "Back to log in"
|
||||
@@ -134,11 +134,15 @@ msgstr "ログインに戻る"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Browser extension required for Chrome"
|
||||
msgstr ""
|
||||
msgstr "Chromeのブラウザー拡張が必要です"
|
||||
|
||||
#: src/pages/app/AboutPage.tsx
|
||||
msgid "Browser extention"
|
||||
msgstr ""
|
||||
msgstr "ブラウザー拡張"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Browser tab"
|
||||
msgstr "ブラウザータブ"
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
@@ -166,7 +170,7 @@ msgstr "カテゴリー"
|
||||
|
||||
#: src/components/settings/ProfileSettings.tsx
|
||||
msgid "Changing password will generate a new API key"
|
||||
msgstr "パスワードを変更すると、新しい API キーが生成されます"
|
||||
msgstr "パスワードを変更すると、新しいAPIキーが生成されます"
|
||||
|
||||
#: src/components/content/add/Subscribe.tsx
|
||||
msgid "Check that the feed is working"
|
||||
@@ -174,27 +178,27 @@ msgstr "フィードが動作していることを確認してください"
|
||||
|
||||
#: src/pages/app/Layout.tsx
|
||||
msgid "Close menu"
|
||||
msgstr ""
|
||||
msgstr "メニューを閉じる"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Cmd"
|
||||
msgstr ""
|
||||
msgstr "Cmd"
|
||||
|
||||
#: src/pages/app/AboutPage.tsx
|
||||
msgid "CommaFeed browser extension version {browserExtensionVersion}."
|
||||
msgstr ""
|
||||
msgstr "CommaFeed ブラウザー拡張機能のバージョンは {browserExtensionVersion} です。"
|
||||
|
||||
#: src/components/settings/ProfileSettings.tsx
|
||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||
msgstr ""
|
||||
msgstr "CommaFeedはFever APIと互換性があります。Fever互換のモバイルクライアントで次のURLを使用してください。ユーザー名と <0>API キー</0> でログインしてください。"
|
||||
|
||||
#: src/pages/app/AboutPage.tsx
|
||||
msgid "CommaFeed next unread item"
|
||||
msgstr "次の未読アイテムをカンマフィード"
|
||||
msgstr "CommaFeed 次の未読アイテム"
|
||||
|
||||
#: src/pages/app/AboutPage.tsx
|
||||
msgid "CommaFeed version {version} ({revision})."
|
||||
msgstr ""
|
||||
msgstr "CommaFeed バージョン {version} ({revision})。"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Compact"
|
||||
@@ -214,11 +218,11 @@ msgstr "パスワード確認"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Cozy"
|
||||
msgstr "コージー"
|
||||
msgstr "Cozy"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Ctrl"
|
||||
msgstr "コントロール"
|
||||
msgstr "Ctrl"
|
||||
|
||||
#: src/components/settings/ProfileSettings.tsx
|
||||
msgid "Current password"
|
||||
@@ -226,19 +230,19 @@ msgstr "現在のパスワード"
|
||||
|
||||
#: src/pages/app/SettingsPage.tsx
|
||||
msgid "Custom code"
|
||||
msgstr ""
|
||||
msgstr "カスタムコード"
|
||||
|
||||
#: src/components/settings/CustomCodeSettings.tsx
|
||||
msgid "Custom CSS rules that will be applied"
|
||||
msgstr ""
|
||||
msgstr "適用されるカスタムCSSルール"
|
||||
|
||||
#: src/components/settings/CustomCodeSettings.tsx
|
||||
msgid "Custom JS code that will be executed on page load"
|
||||
msgstr ""
|
||||
msgstr "ページ読み込み時に実行されるカスタムJSコード"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Dark"
|
||||
msgstr ""
|
||||
msgstr "ダーク"
|
||||
|
||||
#: src/pages/admin/AdminUsersPage.tsx
|
||||
msgid "Date created"
|
||||
@@ -255,7 +259,7 @@ msgstr "アカウント削除"
|
||||
|
||||
#: src/pages/app/CategoryDetailsPage.tsx
|
||||
msgid "Delete Category"
|
||||
msgstr "カテゴリを削除"
|
||||
msgstr "カテゴリーを削除"
|
||||
|
||||
#: src/pages/admin/AdminUsersPage.tsx
|
||||
msgid "Delete user"
|
||||
@@ -267,7 +271,7 @@ msgstr "説明"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Detailed"
|
||||
msgstr ""
|
||||
msgstr "詳細"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
#: src/pages/app/SettingsPage.tsx
|
||||
@@ -277,7 +281,7 @@ msgstr "ディスプレイ"
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
#: src/pages/app/DonatePage.tsx
|
||||
msgid "Donate"
|
||||
msgstr ""
|
||||
msgstr "寄付"
|
||||
|
||||
#: src/components/settings/ProfileSettings.tsx
|
||||
msgid "Download"
|
||||
@@ -302,7 +306,7 @@ msgstr "メールアドレス"
|
||||
|
||||
#: src/pages/admin/AdminUsersPage.tsx
|
||||
msgid "Edit user"
|
||||
msgstr "ユーザー編集"
|
||||
msgstr "ユーザーの編集"
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/pages/admin/AdminUsersPage.tsx
|
||||
@@ -317,9 +321,13 @@ msgstr "入力"
|
||||
msgid "Enter your current password to change profile settings"
|
||||
msgstr "プロファイル設定を変更するには、現在のパスワードを入力してください"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entries to keep above the selected entry when scrolling"
|
||||
msgstr "エントリーを選択したとき、読みやすさに応じたスクロール調整を行います。"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entry headers"
|
||||
msgstr ""
|
||||
msgstr "エントリーヘッダー"
|
||||
|
||||
#: src/components/Alert.tsx
|
||||
msgid "Error"
|
||||
@@ -327,7 +335,7 @@ msgstr "エラー"
|
||||
|
||||
#: src/pages/app/FeedDetailsPage.tsx
|
||||
msgid "Example: {example}."
|
||||
msgstr "例: {例}."
|
||||
msgstr "例: {example}."
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Expanded"
|
||||
@@ -340,7 +348,7 @@ msgstr "サブスクリプションとカテゴリを、他のフィード読み
|
||||
#: src/components/header/Header.tsx
|
||||
#: src/pages/WelcomePage.tsx
|
||||
msgid "Extension options"
|
||||
msgstr ""
|
||||
msgstr "拡張機能オプション"
|
||||
|
||||
#: src/components/content/add/Subscribe.tsx
|
||||
msgid "Feed name"
|
||||
@@ -354,43 +362,47 @@ msgstr "フィード URL"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Fetch all my feeds now"
|
||||
msgstr ""
|
||||
msgstr "すべてのフィードを今すぐ取得"
|
||||
|
||||
#: src/components/settings/ProfileSettings.tsx
|
||||
msgid "Fever API"
|
||||
msgstr ""
|
||||
msgstr "Fever API"
|
||||
|
||||
#: src/components/settings/ProfileSettings.tsx
|
||||
msgid "Fever API URL"
|
||||
msgstr ""
|
||||
msgstr "Fever API URL"
|
||||
|
||||
#: src/pages/app/FeedDetailsPage.tsx
|
||||
msgid "Filtering expression"
|
||||
msgstr "フィルタリング式"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Force fetching feeds is not yet available."
|
||||
msgstr "フィードの強制フェッチはまだ利用できません。"
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Forgot password?"
|
||||
msgstr "パスワードをお忘れですか?"
|
||||
msgstr "パスワードをお忘れですか?"
|
||||
|
||||
#: src/pages/app/CategoryDetailsPage.tsx
|
||||
#: src/pages/app/FeedDetailsPage.tsx
|
||||
#: src/pages/app/TagDetailsPage.tsx
|
||||
msgid "Generate an API key in your profile first."
|
||||
msgstr "最初にプロファイルで API キーを生成します。"
|
||||
msgstr "最初にプロファイルでAPIキーを生成します。"
|
||||
|
||||
#: src/components/settings/ProfileSettings.tsx
|
||||
msgid "Generate new API key"
|
||||
msgstr "新しい API キーを生成する"
|
||||
msgstr "新しいAPIキーを生成する"
|
||||
|
||||
#: src/pages/app/CategoryDetailsPage.tsx
|
||||
#: src/pages/app/FeedDetailsPage.tsx
|
||||
#: src/pages/app/TagDetailsPage.tsx
|
||||
msgid "Generated feed url"
|
||||
msgstr "生成されたフィード URL"
|
||||
msgstr "生成されたフィードURL"
|
||||
|
||||
#: src/components/content/FeedEntryContextMenu.tsx
|
||||
msgid "Go to {0}"
|
||||
msgstr ""
|
||||
msgstr "{0} に移動"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Go to the All view"
|
||||
@@ -398,11 +410,11 @@ msgstr "すべてのビューに移動"
|
||||
|
||||
#: src/pages/app/AboutPage.tsx
|
||||
msgid "Go to the API documentation."
|
||||
msgstr "API ドキュメントに移動します。"
|
||||
msgstr "APIドキュメントに移動します。"
|
||||
|
||||
#: src/pages/app/AboutPage.tsx
|
||||
msgid "Goodies"
|
||||
msgstr "グッディーズ"
|
||||
msgstr "グッズ"
|
||||
|
||||
#: src/pages/admin/AdminUsersPage.tsx
|
||||
msgid "Id"
|
||||
@@ -410,15 +422,15 @@ msgstr "ID"
|
||||
|
||||
#: src/pages/app/FeedDetailsPage.tsx
|
||||
msgid "If not empty, an expression evaluating to 'true' or 'false'. If false, new entries for this feed will be marked as read automatically."
|
||||
msgstr "空でない場合は、'true' または 'false' に評価される式。 "
|
||||
msgstr "空でない場合は、'true' または 'false' に評価される式。 'false' の場合、このフィードの新しいエントリーは自動的に既読としてマークされます。"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "If the entry doesn't entirely fit on the screen"
|
||||
msgstr ""
|
||||
msgstr "エントリーが画面に完全に収まらない場合"
|
||||
|
||||
#: src/pages/app/AboutPage.tsx
|
||||
msgid "If you encounter an issue, please report it on the issues page of the GitHub project."
|
||||
msgstr "問題が発生した場合は、GitHub プロジェクトの問題ページで報告してください。"
|
||||
msgstr "問題が発生した場合は、GitHubプロジェクトのissuesページで報告してください。"
|
||||
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
msgid "Import"
|
||||
@@ -426,7 +438,7 @@ msgstr "インポート"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "In expanded view, scrolling through entries mark them as read"
|
||||
msgstr "展開ビューでエントリをスクロールすると、それらが既読としてマークされます"
|
||||
msgstr "展開ビューでエントリーをスクロールすると、それらが既読としてマークされます"
|
||||
|
||||
#: src/components/content/FeedEntryContextMenu.tsx
|
||||
#: src/components/content/FeedEntryFooter.tsx
|
||||
@@ -456,7 +468,7 @@ msgstr "最終更新メッセージ"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Light"
|
||||
msgstr ""
|
||||
msgstr "ライト"
|
||||
|
||||
#: src/pages/app/CategoryDetailsPage.tsx
|
||||
#: src/pages/app/FeedDetailsPage.tsx
|
||||
@@ -492,7 +504,7 @@ msgstr "ログアウト"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Long press"
|
||||
msgstr ""
|
||||
msgstr "長押し"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
#: src/pages/admin/AdminUsersPage.tsx
|
||||
@@ -506,7 +518,7 @@ msgstr "すべて既読にする"
|
||||
#: src/components/header/MarkAllAsReadButton.tsx
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Mark all entries as read"
|
||||
msgstr "すべてのエントリを既読にする"
|
||||
msgstr "すべてのエントリーを既読にする"
|
||||
|
||||
#: src/components/content/FeedEntryContextMenu.tsx
|
||||
#: src/components/content/FeedEntryFooter.tsx
|
||||
@@ -520,11 +532,11 @@ msgstr "ここまで既読にする"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Metrics"
|
||||
msgstr "メトリクス"
|
||||
msgstr "メトリックス"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Middle click"
|
||||
msgstr ""
|
||||
msgstr "中クリック"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Move the page down"
|
||||
@@ -553,7 +565,7 @@ msgstr "名前を入力してサブスクリプションに移動します"
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Never"
|
||||
msgstr ""
|
||||
msgstr "しない"
|
||||
|
||||
#: src/components/settings/ProfileSettings.tsx
|
||||
msgid "New password"
|
||||
@@ -578,11 +590,11 @@ msgstr "次の未読アイテムのブックマークレット"
|
||||
|
||||
#: src/pages/app/FeedEntriesPage.tsx
|
||||
msgid "No more entries"
|
||||
msgstr "これ以上エントリはありません"
|
||||
msgstr "これ以上エントリーはありません"
|
||||
|
||||
#: src/components/content/ShareButtons.tsx
|
||||
msgid "No sharing options available."
|
||||
msgstr ""
|
||||
msgstr "共有オプションは利用できません。"
|
||||
|
||||
#: src/components/sidebar/TreeSearch.tsx
|
||||
msgid "Nothing found"
|
||||
@@ -594,15 +606,19 @@ msgstr "古い順"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "On desktop"
|
||||
msgstr ""
|
||||
msgstr "デスクトップ"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "On mobile"
|
||||
msgstr ""
|
||||
msgstr "モバイル"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||
msgstr ""
|
||||
msgstr "モバイルでは、画面の下部にアクションボタンを表示します"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Only applies to compact, cozy and detailed modes"
|
||||
msgstr "これはコンパクト/cozy/詳細モードでのみ適用されます"
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Oops!"
|
||||
@@ -610,15 +626,15 @@ msgstr "おっと!"
|
||||
|
||||
#: src/components/header/Header.tsx
|
||||
msgid "Open CommaFeed"
|
||||
msgstr ""
|
||||
msgstr "CommaFeedを開く"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Open current entry in a new tab"
|
||||
msgstr "現在のエントリを新しいタブで開く"
|
||||
msgstr "現在のエントリーを新しいタブで開く"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Open current entry in a new tab in the background"
|
||||
msgstr "現在のエントリをバックグラウンドで新しいタブで開く"
|
||||
msgstr "現在のエントリーを新しいバックグラウンドタブで開く"
|
||||
|
||||
#: src/components/content/FeedEntryFooter.tsx
|
||||
#: src/components/content/header/OpenExternalLink.tsx
|
||||
@@ -627,31 +643,31 @@ msgstr "リンクを開く"
|
||||
|
||||
#: src/components/content/FeedEntryContextMenu.tsx
|
||||
msgid "Open link in new background tab"
|
||||
msgstr ""
|
||||
msgstr "リンクを新しいバックグラウンドタブで開く"
|
||||
|
||||
#: src/components/content/FeedEntryContextMenu.tsx
|
||||
msgid "Open link in new tab"
|
||||
msgstr ""
|
||||
msgstr "リンクを新しいタブで開く"
|
||||
|
||||
#: src/pages/app/Layout.tsx
|
||||
msgid "Open menu"
|
||||
msgstr ""
|
||||
msgstr "メニューを開く"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Open next entry"
|
||||
msgstr "次のエントリを開く"
|
||||
msgstr "次のエントリーを開く"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Open previous entry"
|
||||
msgstr "前のエントリを開く"
|
||||
msgstr "前のエントリーを開く"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Open/close current entry"
|
||||
msgstr "現在のエントリを開く/閉じる"
|
||||
msgstr "現在のエントリーを開く/閉じる"
|
||||
|
||||
#: src/pages/app/AddPage.tsx
|
||||
msgid "OPML"
|
||||
msgstr ""
|
||||
msgstr "OPML"
|
||||
|
||||
#: src/components/settings/ProfileSettings.tsx
|
||||
msgid "OPML export"
|
||||
@@ -664,7 +680,7 @@ msgstr "OPMLファイル"
|
||||
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
msgid "OPML file is required"
|
||||
msgstr ""
|
||||
msgstr "OPMLファイルは必要です"
|
||||
|
||||
#: src/pages/app/AboutPage.tsx
|
||||
msgid "Order"
|
||||
@@ -701,7 +717,7 @@ msgstr "位置"
|
||||
|
||||
#: src/components/header/Header.tsx
|
||||
msgid "Previous"
|
||||
msgstr ""
|
||||
msgstr "前へ"
|
||||
|
||||
#: src/pages/app/SettingsPage.tsx
|
||||
msgid "Profile"
|
||||
@@ -718,16 +734,16 @@ msgstr "リフレッシュ"
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
msgid "Registrations are closed on this CommaFeed instance"
|
||||
msgstr "この CommaFeed インスタンスの登録は終了しています"
|
||||
msgstr "このCommaFeedインスタンスの登録は終了しています"
|
||||
|
||||
#: src/pages/app/AboutPage.tsx
|
||||
msgid "REST API"
|
||||
msgstr ""
|
||||
msgstr "REST API"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Right click"
|
||||
msgstr ""
|
||||
msgstr "右クリック"
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/settings/CustomCodeSettings.tsx
|
||||
@@ -739,15 +755,15 @@ msgstr "保存"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Scroll selected entry to the top of the page"
|
||||
msgstr ""
|
||||
msgstr "エントリーを選択したときのスクロール調整"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Scroll smoothly when navigating between entries"
|
||||
msgstr "エントリ間を移動するときにスムーズにスクロールする"
|
||||
msgstr "エントリー間を移動するときにスムーズにスクロールする"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Scrolling"
|
||||
msgstr ""
|
||||
msgstr "スクロール"
|
||||
|
||||
#: src/components/header/Header.tsx
|
||||
#: src/components/header/Header.tsx
|
||||
@@ -758,15 +774,15 @@ msgstr "検索"
|
||||
|
||||
#: src/components/header/Header.tsx
|
||||
msgid "Search requires at least 3 characters"
|
||||
msgstr "検索には少なくとも 3 文字が必要です"
|
||||
msgstr "検索には少なくとも3文字が必要です"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Set focus on next entry without opening it"
|
||||
msgstr "次のエントリを開かずにフォーカスを設定する"
|
||||
msgstr "次のエントリーを開かずにフォーカスする"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Set focus on previous entry without opening it"
|
||||
msgstr "前のエントリを開かずにフォーカスを設定する"
|
||||
msgstr "前のエントリーを開かずにフォーカスする"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Settings"
|
||||
@@ -788,31 +804,31 @@ msgstr "共有サイト"
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Shift"
|
||||
msgstr "シフト"
|
||||
msgstr "Shift"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show CommaFeed's own context menu on right click"
|
||||
msgstr ""
|
||||
msgstr "右クリックでCommaFeedのコンテキストメニューを表示する"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show confirmation when marking all entries as read"
|
||||
msgstr ""
|
||||
msgstr "すべてのエントリーを既読にするときに確認を表示する"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Show entry menu (desktop)"
|
||||
msgstr ""
|
||||
msgstr "エントリーメニューを表示する(デスクトップ)"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Show entry menu (mobile)"
|
||||
msgstr ""
|
||||
msgstr "エントリーメニューを表示する(モバイル)"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show external link icon"
|
||||
msgstr ""
|
||||
msgstr "外部リンクアイコンを表示する"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show feeds and categories with no unread entries"
|
||||
msgstr "未読エントリのないフィードとカテゴリを表示する"
|
||||
msgstr "未読エントリーのないフィードとカテゴリーを表示する"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Show keyboard shortcut help"
|
||||
@@ -820,11 +836,19 @@ msgstr "キーボード ショートカットのヘルプを表示"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Show native menu (desktop)"
|
||||
msgstr ""
|
||||
msgstr "ネイティブメニューを表示する(デスクトップ)"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show star icon"
|
||||
msgstr ""
|
||||
msgstr "スターアイコンを表示する"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab favicon"
|
||||
msgstr "未読数をタブのアイコンに表示する"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab title"
|
||||
msgstr "未読数をタブのタイトルに表示する"
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
@@ -834,12 +858,12 @@ msgstr "サインアップ"
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Something bad just happened..."
|
||||
msgstr "何か悪いことが起こった..."
|
||||
msgstr "何か悪いことが起きました..."
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Space"
|
||||
msgstr "スペース"
|
||||
msgstr "Space"
|
||||
|
||||
#: src/components/content/FeedEntryContextMenu.tsx
|
||||
#: src/components/content/FeedEntryFooter.tsx
|
||||
@@ -872,7 +896,7 @@ msgstr "成功"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Swipe header to the left"
|
||||
msgstr ""
|
||||
msgstr "ヘッダーを左にスワイプ"
|
||||
|
||||
#: src/pages/WelcomePage.tsx
|
||||
msgid "Switch to dark theme"
|
||||
@@ -884,7 +908,7 @@ msgstr "ライトテーマに切り替え"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "System"
|
||||
msgstr ""
|
||||
msgstr "システム"
|
||||
|
||||
#: src/components/content/FeedEntryFooter.tsx
|
||||
#: src/components/content/FeedEntryFooter.tsx
|
||||
@@ -893,7 +917,7 @@ msgstr "タグ"
|
||||
|
||||
#: src/components/content/add/Subscribe.tsx
|
||||
msgid "The URL for the feed you want to subscribe to. You can also use the website's url directly and CommaFeed will try to find the feed in the page."
|
||||
msgstr "購読したいフィードのURL。 "
|
||||
msgstr "購読したいフィードのURL。ウェブサイトのURLを直接使用して、CommaFeedはページ内のフィードを検索します。"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Theme"
|
||||
@@ -901,27 +925,27 @@ msgstr "テーマ"
|
||||
|
||||
#: src/components/settings/ProfileSettings.tsx
|
||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
||||
msgstr ""
|
||||
msgstr "これはあなたのAPIキーです。いくつかの読み取り専用API操作に使用できます。これにより、Fever APIへのアクセスが可能になります。ページの下部のフォームを使用して新しいAPIキーを生成します。"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Toggle read status of current entry"
|
||||
msgstr "現在のエントリの読み取りステータスを切り替えます"
|
||||
msgstr "現在のエントリーの読み取りステータスを切り替えます"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Toggle sidebar"
|
||||
msgstr ""
|
||||
msgstr "サイドバーを切り替える"
|
||||
|
||||
#: src/components/KeyboardShortcutsHelp.tsx
|
||||
msgid "Toggle starred status of current entry"
|
||||
msgstr ""
|
||||
msgstr "現在のエントリーのスターステータスを切り替える"
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Try out CommaFeed with the demo account: demo/demo"
|
||||
msgstr "デモアカウントで CommaFeed を試す: demo/demo"
|
||||
msgstr "デモアカウントでCommaFeedを試す: demo/demo"
|
||||
|
||||
#: src/pages/WelcomePage.tsx
|
||||
msgid "Try the demo!"
|
||||
msgstr ""
|
||||
msgstr "デモを試す!"
|
||||
|
||||
#: src/components/header/Header.tsx
|
||||
msgid "Unread"
|
||||
@@ -957,8 +981,8 @@ msgstr "ウェブサイト"
|
||||
|
||||
#: src/pages/app/FeedEntriesPage.tsx
|
||||
msgid "You don't have any subscriptions yet. Why not try adding one by clicking on the + sign at the top of the page?"
|
||||
msgstr "まだサブスクリプションがありません。"
|
||||
msgstr "まだサブスクリプションがありません。上部の + 記号をクリックして1つ追加してみませんか?"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Your feeds have been queued for refresh."
|
||||
msgstr ""
|
||||
msgstr "フィードの更新がキューに登録されました。"
|
||||
|
||||
@@ -140,6 +140,10 @@ msgstr ""
|
||||
msgid "Browser extention"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Browser tab"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
@@ -317,6 +321,10 @@ msgstr "입력"
|
||||
msgid "Enter your current password to change profile settings"
|
||||
msgstr "프로필 설정을 변경하려면 현재 비밀번호를 입력하세요."
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entries to keep above the selected entry when scrolling"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entry headers"
|
||||
msgstr ""
|
||||
@@ -368,6 +376,10 @@ msgstr ""
|
||||
msgid "Filtering expression"
|
||||
msgstr "필터링 표현식"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Force fetching feeds is not yet available."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Forgot password?"
|
||||
msgstr "비밀번호를 잊으셨나요?"
|
||||
@@ -604,6 +616,10 @@ msgstr ""
|
||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Only applies to compact, cozy and detailed modes"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Oops!"
|
||||
msgstr "앗!"
|
||||
@@ -826,6 +842,14 @@ msgstr ""
|
||||
msgid "Show star icon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab favicon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab title"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/WelcomePage.tsx
|
||||
|
||||
@@ -140,6 +140,10 @@ msgstr ""
|
||||
msgid "Browser extention"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Browser tab"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
@@ -317,6 +321,10 @@ msgstr "Masuk"
|
||||
msgid "Enter your current password to change profile settings"
|
||||
msgstr "Masukkan kata laluan semasa anda untuk menukar tetapan profil"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entries to keep above the selected entry when scrolling"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entry headers"
|
||||
msgstr ""
|
||||
@@ -368,6 +376,10 @@ msgstr ""
|
||||
msgid "Filtering expression"
|
||||
msgstr "Ungkapan penapisan"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Force fetching feeds is not yet available."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Forgot password?"
|
||||
msgstr "Lupa kata laluan?"
|
||||
@@ -604,6 +616,10 @@ msgstr ""
|
||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Only applies to compact, cozy and detailed modes"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Oops!"
|
||||
msgstr "Aduh!"
|
||||
@@ -826,6 +842,14 @@ msgstr ""
|
||||
msgid "Show star icon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab favicon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab title"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/WelcomePage.tsx
|
||||
|
||||
@@ -140,6 +140,10 @@ msgstr ""
|
||||
msgid "Browser extention"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Browser tab"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
@@ -317,6 +321,10 @@ msgstr ""
|
||||
msgid "Enter your current password to change profile settings"
|
||||
msgstr "Skriv inn ditt nåværende passord for å endre profilinnstillinger"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entries to keep above the selected entry when scrolling"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entry headers"
|
||||
msgstr ""
|
||||
@@ -368,6 +376,10 @@ msgstr ""
|
||||
msgid "Filtering expression"
|
||||
msgstr "Filtrerende uttrykk"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Force fetching feeds is not yet available."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Forgot password?"
|
||||
msgstr "Glemt passord?"
|
||||
@@ -604,6 +616,10 @@ msgstr ""
|
||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Only applies to compact, cozy and detailed modes"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Oops!"
|
||||
msgstr "Beklager!"
|
||||
@@ -826,6 +842,14 @@ msgstr ""
|
||||
msgid "Show star icon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab favicon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab title"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/WelcomePage.tsx
|
||||
|
||||
@@ -140,6 +140,10 @@ msgstr ""
|
||||
msgid "Browser extention"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Browser tab"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
@@ -317,6 +321,10 @@ msgstr ""
|
||||
msgid "Enter your current password to change profile settings"
|
||||
msgstr "Voer uw huidige wachtwoord in om de profielinstellingen te wijzigen"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entries to keep above the selected entry when scrolling"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entry headers"
|
||||
msgstr ""
|
||||
@@ -368,6 +376,10 @@ msgstr ""
|
||||
msgid "Filtering expression"
|
||||
msgstr "Uitdrukking filteren"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Force fetching feeds is not yet available."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Forgot password?"
|
||||
msgstr "Wachtwoord vergeten?"
|
||||
@@ -604,6 +616,10 @@ msgstr ""
|
||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Only applies to compact, cozy and detailed modes"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Oops!"
|
||||
msgstr "Oeps!"
|
||||
@@ -826,6 +842,14 @@ msgstr ""
|
||||
msgid "Show star icon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab favicon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab title"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/WelcomePage.tsx
|
||||
|
||||
@@ -140,6 +140,10 @@ msgstr ""
|
||||
msgid "Browser extention"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Browser tab"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
@@ -317,6 +321,10 @@ msgstr ""
|
||||
msgid "Enter your current password to change profile settings"
|
||||
msgstr "Skriv inn ditt nåværende passord for å endre profilinnstillinger"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entries to keep above the selected entry when scrolling"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entry headers"
|
||||
msgstr ""
|
||||
@@ -368,6 +376,10 @@ msgstr ""
|
||||
msgid "Filtering expression"
|
||||
msgstr "Filtrerende uttrykk"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Force fetching feeds is not yet available."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Forgot password?"
|
||||
msgstr "Glemt passord?"
|
||||
@@ -604,6 +616,10 @@ msgstr ""
|
||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Only applies to compact, cozy and detailed modes"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Oops!"
|
||||
msgstr "Beklager!"
|
||||
@@ -826,6 +842,14 @@ msgstr ""
|
||||
msgid "Show star icon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab favicon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab title"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/WelcomePage.tsx
|
||||
|
||||
@@ -140,6 +140,10 @@ msgstr ""
|
||||
msgid "Browser extention"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Browser tab"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
@@ -317,6 +321,10 @@ msgstr "Wprowadź"
|
||||
msgid "Enter your current password to change profile settings"
|
||||
msgstr "Wprowadź swoje aktualne hasło, aby zmienić ustawienia profilu"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entries to keep above the selected entry when scrolling"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entry headers"
|
||||
msgstr ""
|
||||
@@ -368,6 +376,10 @@ msgstr ""
|
||||
msgid "Filtering expression"
|
||||
msgstr "Wyrażenie filtrujące"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Force fetching feeds is not yet available."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Forgot password?"
|
||||
msgstr "Zapomniałeś hasła?"
|
||||
@@ -604,6 +616,10 @@ msgstr ""
|
||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Only applies to compact, cozy and detailed modes"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Oops!"
|
||||
msgstr "Ups!"
|
||||
@@ -826,6 +842,14 @@ msgstr ""
|
||||
msgid "Show star icon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab favicon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab title"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/WelcomePage.tsx
|
||||
|
||||
@@ -140,6 +140,10 @@ msgstr ""
|
||||
msgid "Browser extention"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Browser tab"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
@@ -317,6 +321,10 @@ msgstr "Entrar"
|
||||
msgid "Enter your current password to change profile settings"
|
||||
msgstr "Digite sua senha atual para alterar as configurações do perfil"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entries to keep above the selected entry when scrolling"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entry headers"
|
||||
msgstr ""
|
||||
@@ -368,6 +376,10 @@ msgstr ""
|
||||
msgid "Filtering expression"
|
||||
msgstr "Filtrando expressão"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Force fetching feeds is not yet available."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Forgot password?"
|
||||
msgstr "Esqueceu a senha?"
|
||||
@@ -604,6 +616,10 @@ msgstr ""
|
||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Only applies to compact, cozy and detailed modes"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Oops!"
|
||||
msgstr "Opa!"
|
||||
@@ -826,6 +842,14 @@ msgstr ""
|
||||
msgid "Show star icon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab favicon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab title"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/WelcomePage.tsx
|
||||
|
||||
@@ -140,6 +140,10 @@ msgstr "Для браузера Chrome требуется расширение"
|
||||
msgid "Browser extention"
|
||||
msgstr "Расширение для браузера"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Browser tab"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
@@ -317,6 +321,10 @@ msgstr "Ввод"
|
||||
msgid "Enter your current password to change profile settings"
|
||||
msgstr "Введите текущий пароль, чтобы изменить настройки профиля."
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entries to keep above the selected entry when scrolling"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entry headers"
|
||||
msgstr ""
|
||||
@@ -368,6 +376,10 @@ msgstr "Ссылка Fever API"
|
||||
msgid "Filtering expression"
|
||||
msgstr "Выражение фильтрации"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Force fetching feeds is not yet available."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Forgot password?"
|
||||
msgstr "Забыли пароль?"
|
||||
@@ -604,6 +616,10 @@ msgstr ""
|
||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||
msgstr "На мобильных устройствах отображать кнопки действий в нижней части экрана"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Only applies to compact, cozy and detailed modes"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Oops!"
|
||||
msgstr "Ой!"
|
||||
@@ -826,6 +842,14 @@ msgstr "Показать родное меню (ПК)"
|
||||
msgid "Show star icon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab favicon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab title"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/WelcomePage.tsx
|
||||
|
||||
@@ -140,6 +140,10 @@ msgstr ""
|
||||
msgid "Browser extention"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Browser tab"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
@@ -317,6 +321,10 @@ msgstr "Vstúpte"
|
||||
msgid "Enter your current password to change profile settings"
|
||||
msgstr "Ak chcete zmeniť nastavenia profilu, zadajte svoje aktuálne heslo"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entries to keep above the selected entry when scrolling"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entry headers"
|
||||
msgstr ""
|
||||
@@ -368,6 +376,10 @@ msgstr ""
|
||||
msgid "Filtering expression"
|
||||
msgstr "Filtrovanie výrazu"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Force fetching feeds is not yet available."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Forgot password?"
|
||||
msgstr "Zabudli ste heslo?"
|
||||
@@ -604,6 +616,10 @@ msgstr ""
|
||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Only applies to compact, cozy and detailed modes"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Oops!"
|
||||
msgstr "Ojoj!"
|
||||
@@ -826,6 +842,14 @@ msgstr ""
|
||||
msgid "Show star icon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab favicon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab title"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/WelcomePage.tsx
|
||||
|
||||
@@ -140,6 +140,10 @@ msgstr ""
|
||||
msgid "Browser extention"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Browser tab"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
@@ -317,6 +321,10 @@ msgstr ""
|
||||
msgid "Enter your current password to change profile settings"
|
||||
msgstr "Ange ditt nuvarande lösenord för att ändra profilinställningar"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entries to keep above the selected entry when scrolling"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entry headers"
|
||||
msgstr ""
|
||||
@@ -368,6 +376,10 @@ msgstr ""
|
||||
msgid "Filtering expression"
|
||||
msgstr "Filtrerande uttryck"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Force fetching feeds is not yet available."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Forgot password?"
|
||||
msgstr "Glömt lösenord?"
|
||||
@@ -604,6 +616,10 @@ msgstr ""
|
||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Only applies to compact, cozy and detailed modes"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Oops!"
|
||||
msgstr "Hoppsan!"
|
||||
@@ -826,6 +842,14 @@ msgstr ""
|
||||
msgid "Show star icon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab favicon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab title"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/WelcomePage.tsx
|
||||
|
||||
@@ -140,6 +140,10 @@ msgstr ""
|
||||
msgid "Browser extention"
|
||||
msgstr "Tarayıcı eklentisi"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Browser tab"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
@@ -317,6 +321,10 @@ msgstr "Girin"
|
||||
msgid "Enter your current password to change profile settings"
|
||||
msgstr "Profil ayarlarını değiştirmek için mevcut şifrenizi girin"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entries to keep above the selected entry when scrolling"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entry headers"
|
||||
msgstr ""
|
||||
@@ -368,6 +376,10 @@ msgstr ""
|
||||
msgid "Filtering expression"
|
||||
msgstr "Filtreleme ifadesi"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Force fetching feeds is not yet available."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Forgot password?"
|
||||
msgstr "Parolanızı mı unuttunuz?"
|
||||
@@ -604,6 +616,10 @@ msgstr ""
|
||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Only applies to compact, cozy and detailed modes"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Oops!"
|
||||
msgstr "Hata!"
|
||||
@@ -826,6 +842,14 @@ msgstr "Orijinal tarayıcı menüsünü göster (masaüstü)"
|
||||
msgid "Show star icon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab favicon"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab title"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/WelcomePage.tsx
|
||||
|
||||
@@ -140,6 +140,10 @@ msgstr "浏览器扩展"
|
||||
msgid "Browser extention"
|
||||
msgstr "浏览器扩展"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Browser tab"
|
||||
msgstr "浏览器标签页"
|
||||
|
||||
#: src/components/admin/UserEdit.tsx
|
||||
#: src/components/content/add/AddCategory.tsx
|
||||
#: src/components/content/add/ImportOpml.tsx
|
||||
@@ -317,6 +321,10 @@ msgstr "回车"
|
||||
msgid "Enter your current password to change profile settings"
|
||||
msgstr "输入您当前的密码以更改配置文件设置"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entries to keep above the selected entry when scrolling"
|
||||
msgstr "滚动时固定在顶部的条目"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Entry headers"
|
||||
msgstr "条目头部"
|
||||
@@ -368,6 +376,10 @@ msgstr "Fever API 网址"
|
||||
msgid "Filtering expression"
|
||||
msgstr "过滤表达式"
|
||||
|
||||
#: src/components/header/ProfileMenu.tsx
|
||||
msgid "Force fetching feeds is not yet available."
|
||||
msgstr "强制获取订阅源功能不可用。"
|
||||
|
||||
#: src/pages/auth/LoginPage.tsx
|
||||
msgid "Forgot password?"
|
||||
msgstr "忘记密码?"
|
||||
@@ -604,6 +616,10 @@ msgstr "移动端"
|
||||
msgid "On mobile, show action buttons at the bottom of the screen"
|
||||
msgstr "在移动端,显示屏幕底部的操作按钮"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Only applies to compact, cozy and detailed modes"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/ErrorPage.tsx
|
||||
msgid "Oops!"
|
||||
msgstr "哎呀!"
|
||||
@@ -826,6 +842,14 @@ msgstr "显示原生菜单(桌面端)"
|
||||
msgid "Show star icon"
|
||||
msgstr "显示星标图标"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab favicon"
|
||||
msgstr "在标签页图标上显示未读数量"
|
||||
|
||||
#: src/components/settings/DisplaySettings.tsx
|
||||
msgid "Show unread count in tab title"
|
||||
msgstr "在标签页标题中显示未读数量"
|
||||
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/auth/RegistrationPage.tsx
|
||||
#: src/pages/WelcomePage.tsx
|
||||
|
||||
@@ -6,11 +6,13 @@ import "react-contexify/ReactContexify.css"
|
||||
import { App } from "App"
|
||||
import { store } from "app/store"
|
||||
import dayjs from "dayjs"
|
||||
import duration from "dayjs/plugin/duration"
|
||||
import relativeTime from "dayjs/plugin/relativeTime"
|
||||
import ReactDOM from "react-dom/client"
|
||||
import { Provider } from "react-redux"
|
||||
|
||||
dayjs.extend(relativeTime)
|
||||
dayjs.extend(duration)
|
||||
|
||||
const root = document.getElementById("root")
|
||||
root &&
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Trans } from "@lingui/macro"
|
||||
import { Trans } from "@lingui/react/macro"
|
||||
import { Box, Button, Container, Group, Text, Title } from "@mantine/core"
|
||||
import { TbRefresh } from "react-icons/tb"
|
||||
import { tss } from "tss"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { msg } from "@lingui/macro"
|
||||
import { msg } from "@lingui/core/macro"
|
||||
import { Anchor, Box, Center, Container, Divider, Group, Image, Space, Title, useMantineColorScheme } from "@mantine/core"
|
||||
import { client } from "app/client"
|
||||
import { redirectToApiDocumentation, redirectToLogin, redirectToRegistration, redirectToRootCategory } from "app/redirect/thunks"
|
||||
@@ -9,7 +9,7 @@ import { ActionButton } from "components/ActionButton"
|
||||
import { useBrowserExtension } from "hooks/useBrowserExtension"
|
||||
import { useMobile } from "hooks/useMobile"
|
||||
import { useAsyncCallback } from "react-async-hook"
|
||||
import { SiGithub, SiTwitter } from "react-icons/si"
|
||||
import { SiGithub, SiX } from "react-icons/si"
|
||||
import { TbClock, TbKey, TbMoon, TbSettings, TbSun, TbUserPlus } from "react-icons/tb"
|
||||
import { PageTitle } from "./PageTitle"
|
||||
|
||||
@@ -140,8 +140,8 @@ function Footer() {
|
||||
<Anchor variant="text" href="https://github.com/Athou/commafeed/" target="_blank" rel="noreferrer">
|
||||
<SiGithub />
|
||||
</Anchor>
|
||||
<Anchor variant="text" href="https://twitter.com/CommaFeed" target="_blank" rel="noreferrer">
|
||||
<SiTwitter />
|
||||
<Anchor variant="text" href="https://x.com/CommaFeed" target="_blank" rel="noreferrer">
|
||||
<SiX />
|
||||
</Anchor>
|
||||
</Group>
|
||||
<Box>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Trans } from "@lingui/macro"
|
||||
import { Trans } from "@lingui/react/macro"
|
||||
import { ActionIcon, Box, Code, Container, Group, Table, Text, Title, useMantineTheme } from "@mantine/core"
|
||||
import { closeAllModals, openConfirmModal, openModal } from "@mantine/modals"
|
||||
import { client, errorToStrings } from "app/client"
|
||||
|
||||
@@ -23,6 +23,8 @@ const shownGauges: Record<string, string> = {
|
||||
"com.commafeed.backend.HttpGetter.pool.size": "HttpGetter current pool size",
|
||||
"com.commafeed.backend.HttpGetter.pool.leased": "HttpGetter active connections",
|
||||
"com.commafeed.backend.HttpGetter.pool.pending": "HttpGetter waiting for a connection",
|
||||
"com.commafeed.backend.HttpGetter.cache.size": "HttpGetter cached entries",
|
||||
"com.commafeed.backend.HttpGetter.cache.memoryUsage": "HttpGetter cache memory usage",
|
||||
"com.commafeed.frontend.ws.WebSocketSessions.users": "WebSocket users",
|
||||
"com.commafeed.frontend.ws.WebSocketSessions.sessions": "WebSocket sessions",
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Trans, msg } from "@lingui/macro"
|
||||
import { msg } from "@lingui/core/macro"
|
||||
import { useLingui } from "@lingui/react"
|
||||
import { Trans } from "@lingui/react/macro"
|
||||
import { Anchor, Box, Container, List, NativeSelect, SimpleGrid, Title } from "@mantine/core"
|
||||
import { Constants } from "app/constants"
|
||||
import { redirectToApiDocumentation } from "app/redirect/thunks"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Trans } from "@lingui/macro"
|
||||
import { Trans } from "@lingui/react/macro"
|
||||
import { Container, Tabs } from "@mantine/core"
|
||||
import { AddCategory } from "components/content/add/AddCategory"
|
||||
import { ImportOpml } from "components/content/add/ImportOpml"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Trans } from "@lingui/macro"
|
||||
import { Trans } from "@lingui/react/macro"
|
||||
import { Anchor, Box, Button, Code, Container, Divider, Group, Input, NumberInput, Stack, Text, TextInput, Title } from "@mantine/core"
|
||||
import { useForm } from "@mantine/form"
|
||||
import { openConfirmModal } from "@mantine/modals"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Trans } from "@lingui/macro"
|
||||
import { Trans } from "@lingui/react/macro"
|
||||
import { Anchor, Box, Code, Container, Group, List, Title } from "@mantine/core"
|
||||
import { Constants } from "app/constants"
|
||||
import React from "react"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Trans } from "@lingui/macro"
|
||||
import { Trans } from "@lingui/react/macro"
|
||||
import { Anchor, Box, Button, Code, Container, Divider, Group, Input, NumberInput, Stack, Text, TextInput, Title } from "@mantine/core"
|
||||
import { useForm } from "@mantine/form"
|
||||
import { openConfirmModal } from "@mantine/modals"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Trans } from "@lingui/macro"
|
||||
import { Trans } from "@lingui/react/macro"
|
||||
import { ActionIcon, Box, Center, Divider, Group, Title, useMantineTheme } from "@mantine/core"
|
||||
import { useViewportSize } from "@mantine/hooks"
|
||||
import { Constants } from "app/constants"
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { msg } from "@lingui/macro"
|
||||
import { msg } from "@lingui/core/macro"
|
||||
import { ActionIcon, AppShell, Box, Center, Group, ScrollArea, Title, useMantineTheme } from "@mantine/core"
|
||||
import { Constants } from "app/constants"
|
||||
import { redirectToAdd, redirectToRootCategory } from "app/redirect/thunks"
|
||||
import { useAppDispatch, useAppSelector } from "app/store"
|
||||
import { setMobileMenuOpen } from "app/tree/slice"
|
||||
import { reloadTree } from "app/tree/thunks"
|
||||
import { setSidebarWidth } from "app/user/slice"
|
||||
import { reloadProfile, reloadSettings, reloadTags } from "app/user/thunks"
|
||||
import { ActionButton } from "components/ActionButton"
|
||||
import { AnnouncementDialog } from "components/AnnouncementDialog"
|
||||
@@ -17,13 +18,12 @@ import { useBrowserExtension } from "hooks/useBrowserExtension"
|
||||
import { useMobile } from "hooks/useMobile"
|
||||
import { useWebSocket } from "hooks/useWebSocket"
|
||||
import { LoadingPage } from "pages/LoadingPage"
|
||||
import { type ReactNode, Suspense, useEffect } from "react"
|
||||
import { type ReactNode, Suspense, useEffect, useRef } from "react"
|
||||
import Draggable from "react-draggable"
|
||||
import { TbMenu2, TbPlus, TbX } from "react-icons/tb"
|
||||
import { Outlet } from "react-router-dom"
|
||||
import { useSwipeable } from "react-swipeable"
|
||||
import { tss } from "tss"
|
||||
import useLocalStorage from "use-local-storage"
|
||||
|
||||
interface LayoutProps {
|
||||
sidebar: ReactNode
|
||||
@@ -64,21 +64,24 @@ export default function Layout(props: LayoutProps) {
|
||||
const theme = useMantineTheme()
|
||||
const mobile = useMobile()
|
||||
const { isBrowserExtensionPopup } = useBrowserExtension()
|
||||
const [sidebarWidth, setSidebarWidth] = useLocalStorage("sidebar-width", 350)
|
||||
const draggableSeparator = useRef<HTMLDivElement>(null)
|
||||
|
||||
const { loading } = useAppLoading()
|
||||
const mobileMenuOpen = useAppSelector(state => state.tree.mobileMenuOpen)
|
||||
const webSocketConnected = useAppSelector(state => state.server.webSocketConnected)
|
||||
const treeReloadInterval = useAppSelector(state => state.server.serverInfos?.treeReloadInterval)
|
||||
const mobileFooter = useAppSelector(state => state.user.settings?.mobileFooter)
|
||||
const sidebarWidth = useAppSelector(state => state.user.localSettings.sidebarWidth)
|
||||
const headerInFooter = mobile && !isBrowserExtensionPopup && mobileFooter
|
||||
const dispatch = useAppDispatch()
|
||||
useWebSocket()
|
||||
|
||||
const sidebarPadding = theme.spacing.xs
|
||||
const { classes } = useStyles({
|
||||
sidebarWidth,
|
||||
sidebarPadding,
|
||||
sidebarRightBorderWidth: "1px",
|
||||
})
|
||||
const { loading } = useAppLoading()
|
||||
const mobileMenuOpen = useAppSelector(state => state.tree.mobileMenuOpen)
|
||||
const webSocketConnected = useAppSelector(state => state.server.webSocketConnected)
|
||||
const treeReloadInterval = useAppSelector(state => state.server.serverInfos?.treeReloadInterval)
|
||||
const mobileFooter = useAppSelector(state => state.user.settings?.mobileFooter)
|
||||
const headerInFooter = mobile && !isBrowserExtensionPopup && mobileFooter
|
||||
const dispatch = useAppDispatch()
|
||||
useWebSocket()
|
||||
|
||||
useEffect(() => {
|
||||
// load initial data
|
||||
@@ -182,6 +185,7 @@ export default function Layout(props: LayoutProps) {
|
||||
</AppShell.Navbar>
|
||||
<OnDesktop>
|
||||
<Draggable
|
||||
nodeRef={draggableSeparator}
|
||||
axis="x"
|
||||
defaultPosition={{
|
||||
x: sidebarWidth,
|
||||
@@ -192,9 +196,13 @@ export default function Layout(props: LayoutProps) {
|
||||
right: 1000,
|
||||
}}
|
||||
grid={[30, 30]}
|
||||
onDrag={(_e, data) => setSidebarWidth(data.x)}
|
||||
onDrag={(_e, data) => {
|
||||
dispatch(setSidebarWidth(data.x))
|
||||
return
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
ref={draggableSeparator}
|
||||
style={{
|
||||
position: "fixed",
|
||||
height: "100%",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Trans } from "@lingui/macro"
|
||||
import { Trans } from "@lingui/react/macro"
|
||||
import { Container, Tabs } from "@mantine/core"
|
||||
import { CustomCodeSettings } from "components/settings/CustomCodeSettings"
|
||||
import { DisplaySettings } from "components/settings/DisplaySettings"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Trans } from "@lingui/macro"
|
||||
import { Trans } from "@lingui/react/macro"
|
||||
|
||||
import { Anchor, Box, Button, Container, Group, Input, Stack, Title } from "@mantine/core"
|
||||
import { Constants } from "app/constants"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Trans, msg } from "@lingui/macro"
|
||||
import { msg } from "@lingui/core/macro"
|
||||
import { useLingui } from "@lingui/react"
|
||||
import { Trans } from "@lingui/react/macro"
|
||||
import { Anchor, Box, Button, Center, Container, Group, Paper, PasswordInput, Stack, TextInput, Title } from "@mantine/core"
|
||||
import { useForm } from "@mantine/form"
|
||||
import { client, errorToStrings } from "app/client"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Trans, msg } from "@lingui/macro"
|
||||
import { msg } from "@lingui/core/macro"
|
||||
import { useLingui } from "@lingui/react"
|
||||
import { Trans } from "@lingui/react/macro"
|
||||
import { Anchor, Box, Button, Center, Container, Group, Paper, Stack, TextInput, Title } from "@mantine/core"
|
||||
import { useForm } from "@mantine/form"
|
||||
import { client, errorToStrings } from "app/client"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Trans, msg } from "@lingui/macro"
|
||||
import { msg } from "@lingui/core/macro"
|
||||
import { useLingui } from "@lingui/react"
|
||||
import { Trans } from "@lingui/react/macro"
|
||||
import { Anchor, Box, Button, Center, Container, Group, Paper, PasswordInput, Stack, TextInput, Title } from "@mantine/core"
|
||||
import { useForm } from "@mantine/form"
|
||||
import { client, errorToStrings } from "app/client"
|
||||
|
||||
@@ -2,24 +2,25 @@ import { lingui } from "@lingui/vite-plugin"
|
||||
import react from "@vitejs/plugin-react"
|
||||
import { visualizer } from "rollup-plugin-visualizer"
|
||||
import { defineConfig } from "vite"
|
||||
import biomePlugin from "vite-plugin-biome"
|
||||
import checker from "vite-plugin-checker"
|
||||
import tsconfigPaths from "vite-tsconfig-paths"
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig(env => ({
|
||||
export default defineConfig(() => ({
|
||||
plugins: [
|
||||
react({
|
||||
babel: {
|
||||
// babel-macro is needed for lingui
|
||||
plugins: ["macros"],
|
||||
plugins: ["@lingui/babel-plugin-lingui-macro"],
|
||||
},
|
||||
}),
|
||||
lingui(),
|
||||
tsconfigPaths(),
|
||||
visualizer(),
|
||||
biomePlugin({
|
||||
mode: "check",
|
||||
failOnError: env.mode !== "development",
|
||||
checker({
|
||||
typescript: true,
|
||||
biome: {
|
||||
command: "check",
|
||||
},
|
||||
}),
|
||||
],
|
||||
base: "./",
|
||||
@@ -49,4 +50,7 @@ export default defineConfig(env => ({
|
||||
},
|
||||
},
|
||||
},
|
||||
test: {
|
||||
environment: "jsdom",
|
||||
},
|
||||
}))
|
||||
|
||||
799
commafeed-server/doc/commafeed.md
Normal file
799
commafeed-server/doc/commafeed.md
Normal file
@@ -0,0 +1,799 @@
|
||||
🔒: Configuration property fixed at build time - All other configuration properties are overridable at runtime
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th align="left">Configuration property</th>
|
||||
<th>Type</th>
|
||||
<th>Default</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.hide-from-web-crawlers`
|
||||
|
||||
Whether to expose a robots.txt file that disallows web crawlers and search engine indexers.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_HIDE_FROM_WEB_CRAWLERS`</td>
|
||||
<td>
|
||||
|
||||
boolean
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`true`
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.image-proxy-enabled`
|
||||
|
||||
If enabled, images in feed entries will be proxied through the server instead of accessed directly by the browser.
|
||||
|
||||
This is useful if commafeed is accessed through a restricting proxy that blocks some feeds that are followed.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_IMAGE_PROXY_ENABLED`</td>
|
||||
<td>
|
||||
|
||||
boolean
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`false`
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.password-recovery-enabled`
|
||||
|
||||
Enable password recovery via email.
|
||||
|
||||
Quarkus mailer will need to be configured.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_PASSWORD_RECOVERY_ENABLED`</td>
|
||||
<td>
|
||||
|
||||
boolean
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`false`
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.announcement`
|
||||
|
||||
Message displayed in a notification at the bottom of the page.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_ANNOUNCEMENT`</td>
|
||||
<td>
|
||||
|
||||
string
|
||||
</td>
|
||||
<td>
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.google-analytics-tracking-code`
|
||||
|
||||
Google Analytics tracking code.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_GOOGLE_ANALYTICS_TRACKING_CODE`</td>
|
||||
<td>
|
||||
|
||||
string
|
||||
</td>
|
||||
<td>
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.google-auth-key`
|
||||
|
||||
Google Auth key for fetching Youtube channel favicons.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_GOOGLE_AUTH_KEY`</td>
|
||||
<td>
|
||||
|
||||
string
|
||||
</td>
|
||||
<td>
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<thead>
|
||||
<tr>
|
||||
<th align="left" colspan="3">
|
||||
HTTP client configuration
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.http-client.user-agent`
|
||||
|
||||
User-Agent string that will be used by the http client, leave empty for the default one.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_HTTP_CLIENT_USER_AGENT`</td>
|
||||
<td>
|
||||
|
||||
string
|
||||
</td>
|
||||
<td>
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.http-client.connect-timeout`
|
||||
|
||||
Time to wait for a connection to be established.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_HTTP_CLIENT_CONNECT_TIMEOUT`</td>
|
||||
<td>
|
||||
|
||||
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`5S`
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.http-client.ssl-handshake-timeout`
|
||||
|
||||
Time to wait for SSL handshake to complete.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_HTTP_CLIENT_SSL_HANDSHAKE_TIMEOUT`</td>
|
||||
<td>
|
||||
|
||||
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`5S`
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.http-client.socket-timeout`
|
||||
|
||||
Time to wait between two packets before timeout.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_HTTP_CLIENT_SOCKET_TIMEOUT`</td>
|
||||
<td>
|
||||
|
||||
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`10S`
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.http-client.response-timeout`
|
||||
|
||||
Time to wait for the full response to be received.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_HTTP_CLIENT_RESPONSE_TIMEOUT`</td>
|
||||
<td>
|
||||
|
||||
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`10S`
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.http-client.connection-time-to-live`
|
||||
|
||||
Time to live for a connection in the pool.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_HTTP_CLIENT_CONNECTION_TIME_TO_LIVE`</td>
|
||||
<td>
|
||||
|
||||
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`30S`
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.http-client.idle-connections-eviction-interval`
|
||||
|
||||
Time between eviction runs for idle connections.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_HTTP_CLIENT_IDLE_CONNECTIONS_EVICTION_INTERVAL`</td>
|
||||
<td>
|
||||
|
||||
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`1M`
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.http-client.max-response-size`
|
||||
|
||||
If a feed is larger than this, it will be discarded to prevent memory issues while parsing the feed.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_HTTP_CLIENT_MAX_RESPONSE_SIZE`</td>
|
||||
<td>
|
||||
|
||||
MemorySize [🛈](#memory-size-note-anchor)
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`5M`
|
||||
</td>
|
||||
</tr>
|
||||
<thead>
|
||||
<tr>
|
||||
<th align="left" colspan="3">
|
||||
HTTP client cache configuration
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.http-client.cache.enabled`
|
||||
|
||||
Whether to enable the cache. This cache is used to avoid spamming feeds in short bursts (e.g. when subscribing to a feed for the
|
||||
first time or when clicking "fetch all my feeds now").
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_HTTP_CLIENT_CACHE_ENABLED`</td>
|
||||
<td>
|
||||
|
||||
boolean
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`true`
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.http-client.cache.maximum-memory-size`
|
||||
|
||||
Maximum amount of memory the cache can use.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_HTTP_CLIENT_CACHE_MAXIMUM_MEMORY_SIZE`</td>
|
||||
<td>
|
||||
|
||||
MemorySize [🛈](#memory-size-note-anchor)
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`10M`
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.http-client.cache.expiration`
|
||||
|
||||
Duration after which an entry is removed from the cache.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_HTTP_CLIENT_CACHE_EXPIRATION`</td>
|
||||
<td>
|
||||
|
||||
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`1M`
|
||||
</td>
|
||||
</tr>
|
||||
<thead>
|
||||
<tr>
|
||||
<th align="left" colspan="3">
|
||||
Feed refresh engine settings
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.feed-refresh.interval`
|
||||
|
||||
Amount of time CommaFeed will wait before refreshing the same feed.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_FEED_REFRESH_INTERVAL`</td>
|
||||
<td>
|
||||
|
||||
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`5M`
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.feed-refresh.interval-empirical`
|
||||
|
||||
If true, CommaFeed will calculate the next refresh time based on the feed's average time between entries and the time since the
|
||||
last entry was published. The interval will be somewhere between the default refresh interval and 24h.
|
||||
|
||||
See <code>FeedRefreshIntervalCalculator</code> for details.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_FEED_REFRESH_INTERVAL_EMPIRICAL`</td>
|
||||
<td>
|
||||
|
||||
boolean
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`false`
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.feed-refresh.http-threads`
|
||||
|
||||
Amount of http threads used to fetch feeds.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_FEED_REFRESH_HTTP_THREADS`</td>
|
||||
<td>
|
||||
|
||||
int
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`3`
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.feed-refresh.database-threads`
|
||||
|
||||
Amount of threads used to insert new entries in the database.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_FEED_REFRESH_DATABASE_THREADS`</td>
|
||||
<td>
|
||||
|
||||
int
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`1`
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.feed-refresh.user-inactivity-period`
|
||||
|
||||
Duration after which a user is considered inactive. Feeds for inactive users are not refreshed until they log in again.
|
||||
|
||||
0 to disable.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_FEED_REFRESH_USER_INACTIVITY_PERIOD`</td>
|
||||
<td>
|
||||
|
||||
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`0S`
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.feed-refresh.filtering-expression-evaluation-timeout`
|
||||
|
||||
Duration after which the evaluation of a filtering expresion to mark an entry as read is considered to have timed out.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_FEED_REFRESH_FILTERING_EXPRESSION_EVALUATION_TIMEOUT`</td>
|
||||
<td>
|
||||
|
||||
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`500MS`
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.feed-refresh.force-refresh-cooldown-duration`
|
||||
|
||||
Duration after which the "Fetch all my feeds now" action is available again after use to avoid spamming feeds.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_FEED_REFRESH_FORCE_REFRESH_COOLDOWN_DURATION`</td>
|
||||
<td>
|
||||
|
||||
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`0S`
|
||||
</td>
|
||||
</tr>
|
||||
<thead>
|
||||
<tr>
|
||||
<th align="left" colspan="3">
|
||||
Database settings
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.database.query-timeout`
|
||||
|
||||
Timeout applied to all database queries.
|
||||
|
||||
0 to disable.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_DATABASE_QUERY_TIMEOUT`</td>
|
||||
<td>
|
||||
|
||||
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`0S`
|
||||
</td>
|
||||
</tr>
|
||||
<thead>
|
||||
<tr>
|
||||
<th align="left" colspan="3">
|
||||
Database cleanup settings
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.database.cleanup.entries-max-age`
|
||||
|
||||
Maximum age of feed entries in the database. Older entries will be deleted.
|
||||
|
||||
0 to disable.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_DATABASE_CLEANUP_ENTRIES_MAX_AGE`</td>
|
||||
<td>
|
||||
|
||||
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`365D`
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.database.cleanup.statuses-max-age`
|
||||
|
||||
Maximum age of feed entry statuses (read/unread) in the database. Older statuses will be deleted.
|
||||
|
||||
0 to disable.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_DATABASE_CLEANUP_STATUSES_MAX_AGE`</td>
|
||||
<td>
|
||||
|
||||
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`0S`
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.database.cleanup.max-feed-capacity`
|
||||
|
||||
Maximum number of entries per feed to keep in the database.
|
||||
|
||||
0 to disable.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_DATABASE_CLEANUP_MAX_FEED_CAPACITY`</td>
|
||||
<td>
|
||||
|
||||
int
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`500`
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.database.cleanup.max-feeds-per-user`
|
||||
|
||||
Limit the number of feeds a user can subscribe to.
|
||||
|
||||
0 to disable.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_DATABASE_CLEANUP_MAX_FEEDS_PER_USER`</td>
|
||||
<td>
|
||||
|
||||
int
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`0`
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.database.cleanup.batch-size`
|
||||
|
||||
Rows to delete per query while cleaning up old entries.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_DATABASE_CLEANUP_BATCH_SIZE`</td>
|
||||
<td>
|
||||
|
||||
int
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`100`
|
||||
</td>
|
||||
</tr>
|
||||
<thead>
|
||||
<tr>
|
||||
<th align="left" colspan="3">
|
||||
Users settings
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.users.allow-registrations`
|
||||
|
||||
Whether to let users create accounts for themselves.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_USERS_ALLOW_REGISTRATIONS`</td>
|
||||
<td>
|
||||
|
||||
boolean
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`false`
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.users.strict-password-policy`
|
||||
|
||||
Whether to enable strict password validation (1 uppercase char, 1 lowercase char, 1 digit, 1 special char).
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_USERS_STRICT_PASSWORD_POLICY`</td>
|
||||
<td>
|
||||
|
||||
boolean
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`true`
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.users.create-demo-account`
|
||||
|
||||
Whether to create a demo account the first time the app starts.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_USERS_CREATE_DEMO_ACCOUNT`</td>
|
||||
<td>
|
||||
|
||||
boolean
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`false`
|
||||
</td>
|
||||
</tr>
|
||||
<thead>
|
||||
<tr>
|
||||
<th align="left" colspan="3">
|
||||
Websocket settings
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.websocket.enabled`
|
||||
|
||||
Enable websocket connection so the server can notify web clients that there are new entries for feeds.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_WEBSOCKET_ENABLED`</td>
|
||||
<td>
|
||||
|
||||
boolean
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`true`
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.websocket.ping-interval`
|
||||
|
||||
Interval at which the client will send a ping message on the websocket to keep the connection alive.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_WEBSOCKET_PING_INTERVAL`</td>
|
||||
<td>
|
||||
|
||||
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`15M`
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`commafeed.websocket.tree-reload-interval`
|
||||
|
||||
If the websocket connection is disabled or the connection is lost, the client will reload the feed tree at this interval.
|
||||
|
||||
|
||||
|
||||
Environment variable: `COMMAFEED_WEBSOCKET_TREE_RELOAD_INTERVAL`</td>
|
||||
<td>
|
||||
|
||||
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
|
||||
</td>
|
||||
<td>
|
||||
|
||||
`30S`
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<a name="duration-note-anchor"></a>
|
||||
|
||||
> [!NOTE]
|
||||
> ### About the Duration format
|
||||
>
|
||||
> To write duration values, use the standard `java.time.Duration` format.
|
||||
> See the [Duration#parse()](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html#parse(java.lang.CharSequence)) Java API documentation] for more information.
|
||||
>
|
||||
> You can also use a simplified format, starting with a number:
|
||||
>
|
||||
> * If the value is only a number, it represents time in seconds.
|
||||
> * If the value is a number followed by `ms`, it represents time in milliseconds.
|
||||
>
|
||||
> In other cases, the simplified format is translated to the `java.time.Duration` format for parsing:
|
||||
>
|
||||
> * If the value is a number followed by `h`, `m`, or `s`, it is prefixed with `PT`.
|
||||
> * If the value is a number followed by `d`, it is prefixed with `P`.
|
||||
<a name="memory-size-note-anchor"></a>
|
||||
|
||||
> [!NOTE]
|
||||
> ### About the MemorySize format
|
||||
>
|
||||
> A size configuration option recognizes strings in this format (shown as a regular expression): `[0-9]+[KkMmGgTtPpEeZzYy]?`.
|
||||
>
|
||||
> If no suffix is given, assume bytes.
|
||||
@@ -1,19 +0,0 @@
|
||||
version: "3.1"
|
||||
|
||||
services:
|
||||
mysql:
|
||||
image: mariadb
|
||||
environment:
|
||||
- MYSQL_ROOT_PASSWORD=commafeed
|
||||
- MYSQL_DATABASE=commafeed
|
||||
ports:
|
||||
- "3306:3306"
|
||||
|
||||
postgresql:
|
||||
image: postgres
|
||||
environment:
|
||||
- POSTGRES_USER=commafeed
|
||||
- POSTGRES_PASSWORD=commafeed
|
||||
- POSTGRES_DB=commafeed
|
||||
ports:
|
||||
- "5432:5432"
|
||||
@@ -6,16 +6,16 @@
|
||||
<parent>
|
||||
<groupId>com.commafeed</groupId>
|
||||
<artifactId>commafeed</artifactId>
|
||||
<version>5.0.0</version>
|
||||
<version>5.4.0</version>
|
||||
</parent>
|
||||
<artifactId>commafeed-server</artifactId>
|
||||
<name>CommaFeed Server</name>
|
||||
|
||||
<properties>
|
||||
<quarkus.version>3.13.2</quarkus.version>
|
||||
<querydsl.version>6.6</querydsl.version>
|
||||
<quarkus.version>3.17.7</quarkus.version>
|
||||
<querydsl.version>6.10.1</querydsl.version>
|
||||
<rome.version>2.1.0</rome.version>
|
||||
<properties-plugin.version>1.2.1</properties-plugin.version>
|
||||
<swagger.version>2.2.28</swagger.version>
|
||||
|
||||
<build.database>h2</build.database>
|
||||
</properties>
|
||||
@@ -43,7 +43,7 @@
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-help-plugin</artifactId>
|
||||
<version>3.4.1</version>
|
||||
<version>3.5.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>initialize</phase>
|
||||
@@ -53,7 +53,26 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>properties-maven-plugin</artifactId>
|
||||
<version>1.2.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>set-system-properties</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<properties>
|
||||
<property>
|
||||
<name>quarkus.datasource.db-kind</name>
|
||||
<value>${build.database}</value>
|
||||
</property>
|
||||
</properties>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>io.quarkus.platform</groupId>
|
||||
<artifactId>quarkus-maven-plugin</artifactId>
|
||||
@@ -78,6 +97,24 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-config-doc-maven-plugin</artifactId>
|
||||
<version>${quarkus.version}</version>
|
||||
<extensions>true</extensions>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>default-generate-config-doc</id>
|
||||
<phase>process-test-resources</phase>
|
||||
<goals>
|
||||
<goal>generate-config-doc</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<format>markdown</format>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
@@ -101,17 +138,18 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.3.1</version>
|
||||
<version>3.5.2</version>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
|
||||
<quarkus.datasource.db-kind>${build.database}</quarkus.datasource.db-kind>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<version>3.3.1</version>
|
||||
<version>3.5.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
@@ -125,8 +163,32 @@
|
||||
<native.image.path>${project.build.directory}/${project.build.finalName}-runner
|
||||
</native.image.path>
|
||||
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
|
||||
<quarkus.datasource.db-kind>${build.database}</quarkus.datasource.db-kind>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
<!-- failsafe plugin does not seem to be able to pick up dependencies declared in profiles -->
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-jdbc-h2</artifactId>
|
||||
<version>${quarkus.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-jdbc-mysql</artifactId>
|
||||
<version>${quarkus.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-jdbc-mariadb</artifactId>
|
||||
<version>${quarkus.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-jdbc-postgresql</artifactId>
|
||||
<version>${quarkus.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>io.github.git-commit-id</groupId>
|
||||
@@ -150,7 +212,7 @@
|
||||
<plugin>
|
||||
<groupId>io.swagger.core.v3</groupId>
|
||||
<artifactId>swagger-maven-plugin-jakarta</artifactId>
|
||||
<version>2.2.22</version>
|
||||
<version>${swagger.version}</version>
|
||||
<?m2e ignore?>
|
||||
<configuration>
|
||||
<outputPath>${project.build.directory}/classes/META-INF/resources</outputPath>
|
||||
@@ -174,7 +236,14 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<version>3.4.0</version>
|
||||
<version>3.6.0</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.puppycrawl.tools</groupId>
|
||||
<artifactId>checkstyle</artifactId>
|
||||
<version>10.21.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>validate</id>
|
||||
@@ -201,7 +270,7 @@
|
||||
<plugin>
|
||||
<groupId>com.diffplug.spotless</groupId>
|
||||
<artifactId>spotless-maven-plugin</artifactId>
|
||||
<version>2.43.0</version>
|
||||
<version>2.44.2</version>
|
||||
<?m2e ignore?>
|
||||
<executions>
|
||||
<execution>
|
||||
@@ -228,13 +297,14 @@
|
||||
<dependency>
|
||||
<groupId>com.commafeed</groupId>
|
||||
<artifactId>commafeed-client</artifactId>
|
||||
<version>5.0.0</version>
|
||||
<version>5.4.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- compile-time processors -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.34</version>
|
||||
<version>1.18.36</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -243,7 +313,14 @@
|
||||
<version>1.11</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-extension-processor</artifactId>
|
||||
<version>${quarkus.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- quarkus dependencies -->
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-arc</artifactId>
|
||||
@@ -280,35 +357,17 @@
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-liquibase</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-jdbc-h2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-jdbc-mysql</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-jdbc-mariadb</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-jdbc-postgresql</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.dropwizard.metrics</groupId>
|
||||
<artifactId>metrics-json</artifactId>
|
||||
<version>4.2.26</version>
|
||||
<version>4.2.30</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.swagger.core.v3</groupId>
|
||||
<artifactId>swagger-annotations</artifactId>
|
||||
<version>2.2.22</version>
|
||||
<version>${swagger.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign.querydsl</groupId>
|
||||
<artifactId>querydsl-apt</artifactId>
|
||||
@@ -321,7 +380,10 @@
|
||||
<artifactId>querydsl-jpa</artifactId>
|
||||
<version>${querydsl.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
@@ -346,9 +408,8 @@
|
||||
<dependency>
|
||||
<groupId>org.passay</groupId>
|
||||
<artifactId>passay</artifactId>
|
||||
<version>1.6.4</version>
|
||||
<version>1.6.6</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.rometools</groupId>
|
||||
<artifactId>rome</artifactId>
|
||||
@@ -364,7 +425,6 @@
|
||||
<artifactId>rome-opml</artifactId>
|
||||
<version>${rome.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.ahocorasick</groupId>
|
||||
<artifactId>ahocorasick</artifactId>
|
||||
@@ -373,12 +433,12 @@
|
||||
<dependency>
|
||||
<groupId>org.jsoup</groupId>
|
||||
<artifactId>jsoup</artifactId>
|
||||
<version>1.18.1</version>
|
||||
<version>1.18.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.ibm.icu</groupId>
|
||||
<artifactId>icu4j</artifactId>
|
||||
<version>75.1</version>
|
||||
<version>76.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.cssparser</groupId>
|
||||
@@ -390,15 +450,10 @@
|
||||
<artifactId>urlcanon</artifactId>
|
||||
<version>0.4.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gwtproject</groupId>
|
||||
<artifactId>gwt-servlet</artifactId>
|
||||
<version>2.11.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents.client5</groupId>
|
||||
<artifactId>httpclient5</artifactId>
|
||||
<version>5.3.1</version>
|
||||
<version>5.4.1</version>
|
||||
</dependency>
|
||||
<!-- add brotli support for httpclient5 -->
|
||||
<dependency>
|
||||
@@ -406,32 +461,16 @@
|
||||
<artifactId>dec</artifactId>
|
||||
<version>0.1.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.github.hakky54</groupId>
|
||||
<artifactId>sslcontext-kickstart-for-apache5</artifactId>
|
||||
<version>8.3.6</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.apis</groupId>
|
||||
<artifactId>google-api-services-youtube</artifactId>
|
||||
<version>v3-rev20240514-2.0.0</version>
|
||||
<version>9.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- test dependencies -->
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-junit5</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-junit-jupiter</artifactId>
|
||||
<artifactId>quarkus-junit5-mockito</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -453,7 +492,7 @@
|
||||
<dependency>
|
||||
<groupId>com.microsoft.playwright</groupId>
|
||||
<artifactId>playwright</artifactId>
|
||||
<version>1.46.0</version>
|
||||
<version>1.49.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -462,7 +501,6 @@
|
||||
<version>0.10.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
@@ -486,120 +524,48 @@
|
||||
<properties>
|
||||
<build.database>h2</build.database>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>properties-maven-plugin</artifactId>
|
||||
<version>${properties-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>set-system-properties</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<properties>
|
||||
<property>
|
||||
<name>quarkus.datasource.db-kind</name>
|
||||
<value>h2</value>
|
||||
</property>
|
||||
</properties>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-jdbc-h2</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>mysql</id>
|
||||
<properties>
|
||||
<build.database>mysql</build.database>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>properties-maven-plugin</artifactId>
|
||||
<version>${properties-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>set-system-properties</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<properties>
|
||||
<property>
|
||||
<name>quarkus.datasource.db-kind</name>
|
||||
<value>mysql</value>
|
||||
</property>
|
||||
</properties>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-jdbc-mysql</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>mariadb</id>
|
||||
<properties>
|
||||
<build.database>mariadb</build.database>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>properties-maven-plugin</artifactId>
|
||||
<version>${properties-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>set-system-properties</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<properties>
|
||||
<property>
|
||||
<name>quarkus.datasource.db-kind</name>
|
||||
<value>mariadb</value>
|
||||
</property>
|
||||
</properties>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-jdbc-mariadb</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>postgresql</id>
|
||||
<properties>
|
||||
<build.database>postgresql</build.database>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>properties-maven-plugin</artifactId>
|
||||
<version>${properties-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>set-system-properties</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<properties>
|
||||
<property>
|
||||
<name>quarkus.datasource.db-kind</name>
|
||||
<value>postgresql</value>
|
||||
</property>
|
||||
</properties>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-jdbc-postgresql</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
FROM ibm-semeru-runtimes:open-21.0.4_7-jre
|
||||
|
||||
FROM ibm-semeru-runtimes:open-21.0.5_11-jre
|
||||
EXPOSE 8082
|
||||
|
||||
RUN mkdir -p /commafeed/data
|
||||
VOLUME /commafeed/data
|
||||
|
||||
COPY commafeed-server/target/quarkus-app/ /commafeed
|
||||
COPY artifacts/extracted-jvm-package/quarkus-app/ /commafeed
|
||||
WORKDIR /commafeed
|
||||
|
||||
CMD ["java", \
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
FROM debian:12.6
|
||||
FROM debian:12.9
|
||||
ARG TARGETARCH
|
||||
|
||||
EXPOSE 8082
|
||||
|
||||
RUN mkdir -p /commafeed/data
|
||||
VOLUME /commafeed/data
|
||||
|
||||
COPY commafeed-server/target/commafeed-*-runner /commafeed/application
|
||||
COPY artifacts/commafeed-*-${TARGETARCH}-runner /commafeed/application
|
||||
WORKDIR /commafeed
|
||||
|
||||
CMD ["./application"]
|
||||
|
||||
@@ -4,7 +4,7 @@ Official docker images for https://github.com/Athou/commafeed/
|
||||
|
||||
## Quickstart
|
||||
|
||||
Start CommaFeed with an embedded database. Then login as `admin/admin` on http://localhost:8082/
|
||||
Start CommaFeed with a H2 embedded database. Then login as `admin/admin` on http://localhost:8082/
|
||||
|
||||
### docker
|
||||
|
||||
@@ -29,8 +29,8 @@ services:
|
||||
|
||||
## Advanced
|
||||
|
||||
While using the embedded database is perfectly fine for small instances, you may want to have more control over the
|
||||
database. Here's an example that uses postgresql (note the different docker tag):
|
||||
While using the H2 embedded database is perfectly fine for small instances, you may want to have more control over the
|
||||
database. Here's an example that uses PostgreSQL (note the image tag change from `latest-h2` to `latest-postgresql`):
|
||||
|
||||
```
|
||||
services:
|
||||
@@ -59,28 +59,37 @@ services:
|
||||
- /path/to/commafeed/db:/var/lib/postgresql/data
|
||||
```
|
||||
|
||||
CommaFeed also supports:
|
||||
|
||||
- MySQL:
|
||||
`QUARKUS_DATASOURCE_JDBC_URL=jdbc:mysql://localhost/commafeed?autoReconnect=true&failOverReadOnly=false&maxReconnects=20&rewriteBatchedStatements=true&timezone=UTC`
|
||||
- MariaDB:
|
||||
`QUARKUS_DATASOURCE_JDBC_URL=jdbc:mariadb://localhost/commafeed?autoReconnect=true&failOverReadOnly=false&maxReconnects=20&rewriteBatchedStatements=true&timezone=UTC`
|
||||
|
||||
## Configuration
|
||||
|
||||
All [CommaFeed settings](https://github.com/Athou/commafeed/blob/master/commafeed-server/src/main/java/com/commafeed/CommaFeedConfiguration.java)
|
||||
are optional and have sensible default values.
|
||||
All [CommaFeed settings](https://github.com/Athou/commafeed/blob/master/commafeed-server/doc/commafeed.md) are
|
||||
optional and have sensible default values.
|
||||
|
||||
Settings are overrideable with environment variables. For instance, `config.feedRefresh().intervalEmpirical()` can be
|
||||
set
|
||||
with the `COMMAFEED_FEED_REFRESH_INTERVAL_EMPIRICAL=true` variable.
|
||||
Settings are overrideable with environment variables. For instance, `commafeed.feed-refresh.interval-empirical` can be
|
||||
set with the `COMMAFEED_FEED_REFRESH_INTERVAL_EMPIRICAL` variable.
|
||||
|
||||
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).
|
||||
`QUARKUS_HTTP_AUTH_SESSION_ENCRYPTION_KEY` variable to a fixed value (min. 16 characters).
|
||||
All other Quarkus settings can be found [here](https://quarkus.io/guides/all-config).
|
||||
|
||||
### 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.
|
||||
|
||||
## Docker tags
|
||||
|
||||
Tags are of the form `<version>-<database>[-jvm]` where:
|
||||
|
||||
- `<version>` is either:
|
||||
- a specific CommaFeed version (e.g. `4.6.0`)
|
||||
- a specific CommaFeed version (e.g. `5.0.0`)
|
||||
- `latest` (always points to the latest version)
|
||||
- `master` (always points to the latest git commit)
|
||||
- `<database>` is the database to use (`h2`, `postgresql`, `mysql` or `mariadb`)
|
||||
- `-jvm` is optional and indicates that CommaFeed is running on a JVM, and not compiled natively. This image supports
|
||||
the
|
||||
arm64 platform which is not yet supported by the native image.
|
||||
- `-jvm` is optional and indicates that CommaFeed is running on a JVM, and not compiled natively.
|
||||
|
||||
@@ -6,6 +6,9 @@ import java.util.Optional;
|
||||
|
||||
import com.commafeed.backend.feed.FeedRefreshIntervalCalculator;
|
||||
|
||||
import io.quarkus.runtime.annotations.ConfigDocSection;
|
||||
import io.quarkus.runtime.annotations.ConfigPhase;
|
||||
import io.quarkus.runtime.annotations.ConfigRoot;
|
||||
import io.quarkus.runtime.configuration.MemorySize;
|
||||
import io.smallrye.config.ConfigMapping;
|
||||
import io.smallrye.config.WithDefault;
|
||||
@@ -18,6 +21,7 @@ import jakarta.validation.constraints.Positive;
|
||||
* Default values are for production, they can be overridden in application.properties for other profiles
|
||||
*/
|
||||
@ConfigMapping(prefix = "commafeed")
|
||||
@ConfigRoot(phase = ConfigPhase.RUN_TIME)
|
||||
public interface CommaFeedConfiguration {
|
||||
/**
|
||||
* Whether to expose a robots.txt file that disallows web crawlers and search engine indexers.
|
||||
@@ -59,26 +63,31 @@ public interface CommaFeedConfiguration {
|
||||
/**
|
||||
* HTTP client configuration
|
||||
*/
|
||||
@ConfigDocSection
|
||||
HttpClient httpClient();
|
||||
|
||||
/**
|
||||
* Feed refresh engine settings.
|
||||
*/
|
||||
@ConfigDocSection
|
||||
FeedRefresh feedRefresh();
|
||||
|
||||
/**
|
||||
* Database settings.
|
||||
*/
|
||||
@ConfigDocSection
|
||||
Database database();
|
||||
|
||||
/**
|
||||
* Users settings.
|
||||
*/
|
||||
@ConfigDocSection
|
||||
Users users();
|
||||
|
||||
/**
|
||||
* Websocket settings.
|
||||
*/
|
||||
@ConfigDocSection
|
||||
Websocket websocket();
|
||||
|
||||
interface HttpClient {
|
||||
@@ -128,6 +137,33 @@ public interface CommaFeedConfiguration {
|
||||
*/
|
||||
@WithDefault("5M")
|
||||
MemorySize maxResponseSize();
|
||||
|
||||
/**
|
||||
* HTTP client cache configuration
|
||||
*/
|
||||
@ConfigDocSection
|
||||
HttpClientCache cache();
|
||||
}
|
||||
|
||||
interface HttpClientCache {
|
||||
/**
|
||||
* Whether to enable the cache. This cache is used to avoid spamming feeds in short bursts (e.g. when subscribing to a feed for the
|
||||
* first time or when clicking "fetch all my feeds now").
|
||||
*/
|
||||
@WithDefault("true")
|
||||
boolean enabled();
|
||||
|
||||
/**
|
||||
* Maximum amount of memory the cache can use.
|
||||
*/
|
||||
@WithDefault("10M")
|
||||
MemorySize maximumMemorySize();
|
||||
|
||||
/**
|
||||
* Duration after which an entry is removed from the cache.
|
||||
*/
|
||||
@WithDefault("1m")
|
||||
Duration expiration();
|
||||
}
|
||||
|
||||
interface FeedRefresh {
|
||||
@@ -173,17 +209,27 @@ public interface CommaFeedConfiguration {
|
||||
*/
|
||||
@WithDefault("500ms")
|
||||
Duration filteringExpressionEvaluationTimeout();
|
||||
|
||||
/**
|
||||
* Duration after which the "Fetch all my feeds now" action is available again after use to avoid spamming feeds.
|
||||
*/
|
||||
@WithDefault("0")
|
||||
Duration forceRefreshCooldownDuration();
|
||||
}
|
||||
|
||||
interface Database {
|
||||
/**
|
||||
* Database query timeout.
|
||||
* Timeout applied to all database queries.
|
||||
*
|
||||
* 0 to disable.
|
||||
*/
|
||||
@WithDefault("0")
|
||||
Duration queryTimeout();
|
||||
|
||||
/**
|
||||
* Database cleanup settings.
|
||||
*/
|
||||
@ConfigDocSection
|
||||
Cleanup cleanup();
|
||||
|
||||
interface Cleanup {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user