mirror of
https://github.com/Athou/commafeed.git
synced 2026-11-03 02:44:47 +00:00
Compare commits
421 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e1e5257b4 | ||
|
|
bc6e767953 | ||
|
|
b9eceaae73 | ||
|
|
8ad9ba7d74 | ||
|
|
10bb4b7936 | ||
|
|
ab3127cef9 | ||
|
|
5d64e2f21e | ||
|
|
e404c9ce3b | ||
|
|
0c5a71650c | ||
|
|
8ce9eb8537 | ||
|
|
1ce0e4af97 | ||
|
|
44ad42a8a5 | ||
|
|
f213726c40 | ||
|
|
972d424846 | ||
|
|
6049263137 | ||
|
|
ae2dc7f066 | ||
|
|
503d129f22 | ||
|
|
543ec3bbb1 | ||
|
|
bed45127c4 | ||
|
|
71f10b0a62 | ||
|
|
cb235289c4 | ||
|
|
0b07c65320 | ||
|
|
868f65d7c9 | ||
|
|
07715383f4 | ||
|
|
29d10debdb | ||
|
|
cd640da960 | ||
|
|
56ecb4a2f4 | ||
|
|
00161fd549 | ||
|
|
a602ce17cd | ||
|
|
672588d08b | ||
|
|
5fa2579275 | ||
|
|
09bc317797 | ||
|
|
440c1ada50 | ||
|
|
911a5ca099 | ||
|
|
65017f6b76 | ||
|
|
64fb5ef3a2 | ||
|
|
dda389a50f | ||
|
|
419ad4fb6a | ||
|
|
ebae46f06b | ||
|
|
ac25accb31 | ||
|
|
3c7eb90e50 | ||
|
|
4b3973f3fa | ||
|
|
6ddbe40c3c | ||
|
|
d5164750e4 | ||
|
|
822fbd8add | ||
|
|
3a341d0707 | ||
|
|
23884fcbda | ||
|
|
3b16674f98 | ||
|
|
d5eb3e1bb1 | ||
|
|
8d47b38fd4 | ||
|
|
04fb3282fa | ||
|
|
bcce130b82 | ||
|
|
e5d336f6ba | ||
|
|
2d741f6e1e | ||
|
|
2968dff118 | ||
|
|
0c244ec154 | ||
|
|
34cd337992 | ||
|
|
1703cb7b93 | ||
|
|
dc89faa4a1 | ||
|
|
3eccfe8ccc | ||
|
|
6e34f6831c | ||
|
|
b7ebcd6a23 | ||
|
|
8b7efe056d | ||
|
|
87cb392516 | ||
|
|
aa11cb48f2 | ||
|
|
36a29a393c | ||
|
|
99f1b45866 | ||
|
|
9e8d529af3 | ||
|
|
bb80641b40 | ||
|
|
a2ed16c6fd | ||
|
|
4f10f57837 | ||
|
|
28f40cd6fe | ||
|
|
89a84a0c83 | ||
|
|
ebcda50a34 | ||
|
|
8640e62b77 | ||
|
|
d0418eea89 | ||
|
|
41ba067daf | ||
|
|
53346997b6 | ||
|
|
87a632761e | ||
|
|
998ebc43a3 | ||
|
|
945e312c41 | ||
|
|
963a562100 | ||
|
|
4be961b68b | ||
|
|
02a9140c13 | ||
|
|
5ea60ce6d6 | ||
|
|
e9e7be0fc6 | ||
|
|
60c30f2683 | ||
|
|
a17e69d37d | ||
|
|
157f75d33e | ||
|
|
30a14c73ff | ||
|
|
27cece3afb | ||
|
|
8124ecb51f | ||
|
|
e67c4c8670 | ||
|
|
fcc6798d63 | ||
|
|
d313ebfc69 | ||
|
|
6edb8f00f6 | ||
|
|
98a261d457 | ||
|
|
e97a69f475 | ||
|
|
e9dc284b26 | ||
|
|
856c52c64b | ||
|
|
386a4a32ef | ||
|
|
dbdb40ff01 | ||
|
|
1bd9b71215 | ||
|
|
f4dc279ec9 | ||
|
|
ca8438623d | ||
|
|
b81aac71f5 | ||
|
|
a4e0d28fa2 | ||
|
|
56d4e4bbb1 | ||
|
|
af1d10529b | ||
|
|
a5f84a3f6d | ||
|
|
69dfbc81cc | ||
|
|
34408ccdb0 | ||
|
|
b0522a6e5d | ||
|
|
2a559a07c0 | ||
|
|
bdf2a6a915 | ||
|
|
e814f75872 | ||
|
|
c0e0791854 | ||
|
|
17dbdb66bf | ||
|
|
6e3e9add36 | ||
|
|
5b25011853 | ||
|
|
804b24b2d6 | ||
|
|
de98b0f7c2 | ||
|
|
709de70fa9 | ||
|
|
1b7bc11f9d | ||
|
|
bbcaacf3dd | ||
|
|
e816b1262c | ||
|
|
fc019333dc | ||
|
|
56b0ddbc34 | ||
|
|
bb74d27d52 | ||
|
|
7b1d19ca71 | ||
|
|
af961678bd | ||
|
|
1579242644 | ||
|
|
2a45f5c596 | ||
|
|
c4560c49b0 | ||
|
|
2b7f75d9ef | ||
|
|
5f68bcbd46 | ||
|
|
c93c072259 | ||
|
|
516344a993 | ||
|
|
4d42fe5a0b | ||
|
|
47bf132fff | ||
|
|
04a9d48505 | ||
|
|
3716ddcf15 | ||
|
|
6c3ab40cb6 | ||
|
|
b7270974e5 | ||
|
|
9bfc53e77a | ||
|
|
f34fac8d17 | ||
|
|
555c11649e | ||
|
|
c308c5d606 | ||
|
|
54e9615994 | ||
|
|
b0b3b323fd | ||
|
|
f740a0b8ba | ||
|
|
e154675e72 | ||
|
|
2b3d3261de | ||
|
|
fab525ca56 | ||
|
|
1c273d1c1a | ||
|
|
90d684367c | ||
|
|
1ffc544ab0 | ||
|
|
cde0cceee1 | ||
|
|
1604fbc55c | ||
|
|
6f586e8866 | ||
|
|
c53455ad61 | ||
|
|
77b3c609f3 | ||
|
|
3b84598d99 | ||
|
|
6f536c0981 | ||
|
|
1f881ea252 | ||
|
|
b14df1b3cb | ||
|
|
e13763baa3 | ||
|
|
502ef67a71 | ||
|
|
05cab626df | ||
|
|
c7d54af7ad | ||
|
|
ad195fcd80 | ||
|
|
b87c68d598 | ||
|
|
33af37ed2e | ||
|
|
c4113fc92b | ||
|
|
ed40025d26 | ||
|
|
752008a551 | ||
|
|
a8bf970dca | ||
|
|
5b94bcdfdd | ||
|
|
a66a0e9485 | ||
|
|
80755e15b8 | ||
|
|
8cede0c6e0 | ||
|
|
9556f0f7d2 | ||
|
|
1b80f3060c | ||
|
|
00811f0be3 | ||
|
|
0fdfc2c59c | ||
|
|
8d25562a76 | ||
|
|
1d0d9d4be6 | ||
|
|
9ed4559625 | ||
|
|
2a53e8f15d | ||
|
|
15fbd18f31 | ||
|
|
2c248a7ca1 | ||
|
|
94d8fdb4ab | ||
|
|
3596439ed4 | ||
|
|
bc732a52ce | ||
|
|
ef096899a2 | ||
|
|
bf4bcf740e | ||
|
|
679281ac26 | ||
|
|
bde3d1408b | ||
|
|
3621a96d3f | ||
|
|
6583ad114f | ||
|
|
f4e42165bf | ||
|
|
00d7be735a | ||
|
|
1388fba8e4 | ||
|
|
c43644861f | ||
|
|
831ca599b8 | ||
|
|
43fbd03292 | ||
|
|
1efd04f6c5 | ||
|
|
e89ccfd74b | ||
|
|
622486160c | ||
|
|
6d172cae9e | ||
|
|
91b60fb147 | ||
|
|
3f9b7f48d5 | ||
|
|
3599fdec65 | ||
|
|
00e86974b3 | ||
|
|
2aa897eb80 | ||
|
|
ce9706b860 | ||
|
|
e140dfe556 | ||
|
|
4a1b845ac2 | ||
|
|
573f8af57e | ||
|
|
33445c93e8 | ||
|
|
f7fcb659f7 | ||
|
|
b0aa723c2f | ||
|
|
48dca41738 | ||
|
|
873d6f487f | ||
|
|
c8d73b129e | ||
|
|
c63e9e1cd2 | ||
|
|
def2ad84bb | ||
|
|
52510e9817 | ||
|
|
69a95488ce | ||
|
|
636841f647 | ||
|
|
1ea521236c | ||
|
|
6966efeda5 | ||
|
|
66ad0c3548 | ||
|
|
e061ccbf79 | ||
|
|
30cc6a111d | ||
|
|
8416ce5124 | ||
|
|
0cacfe391b | ||
|
|
c0eaab48cd | ||
|
|
c696bc3545 | ||
|
|
72505954a9 | ||
|
|
49159dba5c | ||
|
|
41e2d89abc | ||
|
|
6e7de97d93 | ||
|
|
2f20e6b498 | ||
|
|
ecf9158fd7 | ||
|
|
dc7e7321f3 | ||
|
|
0f087ad2a0 | ||
|
|
ff19a6e9eb | ||
|
|
8cec0c0779 | ||
|
|
314384f8e7 | ||
|
|
6c75ad95ad | ||
|
|
76e3b3caff | ||
|
|
c8f71480c9 | ||
|
|
9172a0cf9c | ||
|
|
eb476c6023 | ||
|
|
da4f3bd38e | ||
|
|
c65d628a36 | ||
|
|
589b8c3afc | ||
|
|
2684051da0 | ||
|
|
200db68d05 | ||
|
|
f6d8d32a01 | ||
|
|
72d5af5bb0 | ||
|
|
aabbc54cbb | ||
|
|
09b523bf56 | ||
|
|
5dc7f522bf | ||
|
|
fd58a42824 | ||
|
|
0a6d1c85ed | ||
|
|
13f84a260c | ||
|
|
4132ad9a97 | ||
|
|
1faba92ecc | ||
|
|
b93fc86663 | ||
|
|
7123036e8d | ||
|
|
cce4ea4dc6 | ||
|
|
b8f7df1555 | ||
|
|
ba8cc0477c | ||
|
|
010026bc88 | ||
|
|
a1ba34caf2 | ||
|
|
1214380bee | ||
|
|
03eb09c68c | ||
|
|
055d503862 | ||
|
|
5755ff762b | ||
|
|
88e24787e8 | ||
|
|
ed32d07ac4 | ||
|
|
3a917fcebe | ||
|
|
3535068ca8 | ||
|
|
4c39d4b96b | ||
|
|
8e864c6793 | ||
|
|
aeffecced3 | ||
|
|
4be42dc1e2 | ||
|
|
bdf6c62c29 | ||
|
|
a4592e5199 | ||
|
|
a5268f082d | ||
|
|
b556e72922 | ||
|
|
3602d2533a | ||
|
|
681f2c766a | ||
|
|
6e0a136cd1 | ||
|
|
9e9945a1cc | ||
|
|
3368cead8b | ||
|
|
a7b5126b4a | ||
|
|
a9ef1a03dc | ||
|
|
bc0ec8dbfa | ||
|
|
7bef009922 | ||
|
|
9a467bc27b | ||
|
|
e3934c9403 | ||
|
|
af337aa4d0 | ||
|
|
313d3a01ec | ||
|
|
feb9876cf5 | ||
|
|
9c3a5cb820 | ||
|
|
e219f781bf | ||
|
|
21ecd6ae05 | ||
|
|
2449902c3d | ||
|
|
c1a55037ba | ||
|
|
646a8122c0 | ||
|
|
edc4e6c508 | ||
|
|
5ddeb7b156 | ||
|
|
306624e55f | ||
|
|
6a9ca65cbc | ||
|
|
7db0026a0c | ||
|
|
7358705248 | ||
|
|
0b9ee2eec9 | ||
|
|
42eaf7fc39 | ||
|
|
6783cac9b4 | ||
|
|
628106ce88 | ||
|
|
1ce69b31a7 | ||
|
|
912ac11842 | ||
|
|
5f2fad560c | ||
|
|
b300f364a7 | ||
|
|
049ec41d13 | ||
|
|
f0d17bc84e | ||
|
|
cc442d7409 | ||
|
|
80bac26f21 | ||
|
|
015c39e6f4 | ||
|
|
e0ec3a4ebd | ||
|
|
a022de5cc3 | ||
|
|
a7b5e1e18c | ||
|
|
b8695df1c8 | ||
|
|
5e4382d1d2 | ||
|
|
ce983f4906 | ||
|
|
4a8be29616 | ||
|
|
1622eb642a | ||
|
|
422d992484 | ||
|
|
1065af1233 | ||
|
|
dde39d83be | ||
|
|
94fe7617bf | ||
|
|
e781d85b7c | ||
|
|
c30c9ca380 | ||
|
|
c395916af9 | ||
|
|
1a4037e360 | ||
|
|
f207bfaddd | ||
|
|
3dd298c0c8 | ||
|
|
8e2e4da7c3 | ||
|
|
418e3c109c | ||
|
|
cfda63a609 | ||
|
|
ba68276bfb | ||
|
|
97c700024a | ||
|
|
d4f67d726c | ||
|
|
ea87fa3e5a | ||
|
|
d12d247b3e | ||
|
|
c4a23915bd | ||
|
|
8645c57d13 | ||
|
|
b170e0bc17 | ||
|
|
4199f514f9 | ||
|
|
c96efb3bb4 | ||
|
|
d5571e0196 | ||
|
|
9f7f87b4ae | ||
|
|
4b03fce85d | ||
|
|
4b28d1c635 | ||
|
|
a5e803177f | ||
|
|
9462f284a4 | ||
|
|
4b0f6bd61b | ||
|
|
d6c85214ef | ||
|
|
de770cf801 | ||
|
|
dae0f740c2 | ||
|
|
9452c3e74c | ||
|
|
f826f1d543 | ||
|
|
fd13c80e5a | ||
|
|
75871348d5 | ||
|
|
0140e88595 | ||
|
|
e620b1254b | ||
|
|
77cfcf6c58 | ||
|
|
04e9df3d0a | ||
|
|
a953134089 | ||
|
|
88b9c0d783 | ||
|
|
ff7e0ba95b | ||
|
|
53dfbcaf00 | ||
|
|
d8fca22c00 | ||
|
|
4fb5963bd9 | ||
|
|
862d81f446 | ||
|
|
8ae7943b94 | ||
|
|
46e947d779 | ||
|
|
7780d6020f | ||
|
|
e5803b46f2 | ||
|
|
d776090298 | ||
|
|
f2f3111d49 | ||
|
|
dff1b957cd | ||
|
|
b1ec50c3cb | ||
|
|
85aa188287 | ||
|
|
e7d6526da9 | ||
|
|
d67c6fcc00 | ||
|
|
d9bf084300 | ||
|
|
da3977b0e2 | ||
|
|
7df930bccc | ||
|
|
11f73a1a53 | ||
|
|
2bbcd55e48 | ||
|
|
43890b8d5c | ||
|
|
b6b8e3741b | ||
|
|
c39f00c336 | ||
|
|
e48eaacfef | ||
|
|
6d97691388 | ||
|
|
d64cc996bc | ||
|
|
617d66c9b9 | ||
|
|
0fc50d2105 | ||
|
|
2bb9f28569 | ||
|
|
c1580b8359 | ||
|
|
dde235825d | ||
|
|
eac13b4025 | ||
|
|
59cc9c2706 | ||
|
|
40e20a0d33 | ||
|
|
a42679acaa | ||
|
|
fd2e8fcdb8 | ||
|
|
ebd5a15152 |
52
.github/workflows/ci.yml
vendored
52
.github/workflows/ci.yml
vendored
@@ -23,18 +23,24 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
# Checkout
|
# Checkout
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
# Setup
|
# Setup
|
||||||
- name: Set up GraalVM
|
- name: Set up GraalVM
|
||||||
uses: graalvm/setup-graalvm@60c26726de13f8b90771df4bc1641a52a3159994 # v1
|
uses: graalvm/setup-graalvm@0def53c0fd8534bc13416c9469f5be45265824fd # v1.6.3
|
||||||
with:
|
with:
|
||||||
java-version: ${{ env.JAVA_VERSION }}
|
java-version: ${{ env.JAVA_VERSION }}
|
||||||
distribution: "graalvm"
|
distribution: "graalvm"
|
||||||
cache: "maven"
|
cache: "maven"
|
||||||
|
|
||||||
|
- name: Set up NodeJS cache
|
||||||
|
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||||
|
with:
|
||||||
|
cache: "npm"
|
||||||
|
cache-dependency-path: 'commafeed-client/package-lock.json'
|
||||||
|
|
||||||
- name: Install Playwright dependencies
|
- name: Install Playwright dependencies
|
||||||
run: sudo apt-get install -y libgbm1
|
run: sudo apt-get install -y libgbm1
|
||||||
if: matrix.os != 'windows-latest'
|
if: matrix.os != 'windows-latest'
|
||||||
@@ -67,20 +73,20 @@ jobs:
|
|||||||
|
|
||||||
# Upload artifacts
|
# Upload artifacts
|
||||||
- name: Upload cross-platform app
|
- name: Upload cross-platform app
|
||||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
if: matrix.os == 'ubuntu-latest' # we only need to upload the cross-platform artifact once per database
|
if: matrix.os == 'ubuntu-latest' # we only need to upload the cross-platform artifact once per database
|
||||||
with:
|
with:
|
||||||
name: commafeed-${{ matrix.database }}-jvm
|
name: commafeed-${{ matrix.database }}-jvm
|
||||||
path: commafeed-server/target/commafeed-*.zip
|
path: commafeed-server/target/commafeed-*.zip
|
||||||
|
|
||||||
- name: Upload native executable
|
- name: Upload native executable
|
||||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
name: commafeed-${{ matrix.database }}-${{ runner.os }}-${{ runner.arch }}
|
name: commafeed-${{ matrix.database }}-${{ runner.os }}-${{ runner.arch }}
|
||||||
path: commafeed-server/target/commafeed-*-runner*
|
path: commafeed-server/target/commafeed-*-runner*
|
||||||
|
|
||||||
- name: Upload pages
|
- name: Upload pages
|
||||||
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5
|
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
|
||||||
if: matrix.os == 'ubuntu-latest' && matrix.database == 'h2' # we only need to upload the pages once
|
if: matrix.os == 'ubuntu-latest' && matrix.database == 'h2' # we only need to upload the pages once
|
||||||
with:
|
with:
|
||||||
path: target/pages
|
path: target/pages
|
||||||
@@ -98,23 +104,23 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
# Checkout
|
# Checkout
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
# Setup
|
# Setup
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4
|
uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4.2.0
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4
|
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
|
||||||
|
|
||||||
- name: Install required packages
|
- name: Install required packages
|
||||||
run: sudo apt-get install -y rename unzip
|
run: sudo apt-get install -y rename unzip
|
||||||
|
|
||||||
# Prepare artifacts
|
# Prepare artifacts
|
||||||
- name: Download artifacts
|
- name: Download artifacts
|
||||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||||
with:
|
with:
|
||||||
pattern: commafeed-${{ matrix.database }}-*
|
pattern: commafeed-${{ matrix.database }}-*
|
||||||
path: ./artifacts
|
path: ./artifacts
|
||||||
@@ -135,7 +141,7 @@ jobs:
|
|||||||
|
|
||||||
# Docker
|
# Docker
|
||||||
- name: Login to Container Registry
|
- name: Login to Container Registry
|
||||||
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4
|
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
|
||||||
if: ${{ env.DOCKERHUB_USERNAME != '' }}
|
if: ${{ env.DOCKERHUB_USERNAME != '' }}
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
@@ -143,7 +149,7 @@ jobs:
|
|||||||
|
|
||||||
## build but don't push for PRs and renovate
|
## build but don't push for PRs and renovate
|
||||||
- name: Docker build - native
|
- name: Docker build - native
|
||||||
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7
|
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: commafeed-server/src/main/docker/Dockerfile.native
|
file: commafeed-server/src/main/docker/Dockerfile.native
|
||||||
@@ -151,7 +157,7 @@ jobs:
|
|||||||
platforms: linux/amd64,linux/arm64/v8
|
platforms: linux/amd64,linux/arm64/v8
|
||||||
|
|
||||||
- name: Docker build - jvm
|
- name: Docker build - jvm
|
||||||
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7
|
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: commafeed-server/src/main/docker/Dockerfile.jvm
|
file: commafeed-server/src/main/docker/Dockerfile.jvm
|
||||||
@@ -160,7 +166,7 @@ jobs:
|
|||||||
|
|
||||||
## build and push tag
|
## build and push tag
|
||||||
- name: Docker build and push tag - native
|
- name: Docker build and push tag - native
|
||||||
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7
|
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
|
||||||
if: ${{ github.ref_type == 'tag' }}
|
if: ${{ github.ref_type == 'tag' }}
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
@@ -172,7 +178,7 @@ jobs:
|
|||||||
athou/commafeed:${{ github.ref_name }}-${{ matrix.database }}
|
athou/commafeed:${{ github.ref_name }}-${{ matrix.database }}
|
||||||
|
|
||||||
- name: Docker build and push tag - jvm
|
- name: Docker build and push tag - jvm
|
||||||
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7
|
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
|
||||||
if: ${{ github.ref_type == 'tag' }}
|
if: ${{ github.ref_type == 'tag' }}
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
@@ -185,7 +191,7 @@ jobs:
|
|||||||
|
|
||||||
## build and push master
|
## build and push master
|
||||||
- name: Docker build and push master - native
|
- name: Docker build and push master - native
|
||||||
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7
|
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
|
||||||
if: ${{ github.ref_name == 'master' }}
|
if: ${{ github.ref_name == 'master' }}
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
@@ -195,7 +201,7 @@ jobs:
|
|||||||
tags: athou/commafeed:master-${{ matrix.database }}
|
tags: athou/commafeed:master-${{ matrix.database }}
|
||||||
|
|
||||||
- name: Docker build and push master - jvm
|
- name: Docker build and push master - jvm
|
||||||
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7
|
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
|
||||||
if: ${{ github.ref_name == 'master' }}
|
if: ${{ github.ref_name == 'master' }}
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
@@ -215,12 +221,12 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Download artifacts
|
- name: Download artifacts
|
||||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||||
with:
|
with:
|
||||||
pattern: commafeed-*
|
pattern: commafeed-*
|
||||||
path: ./artifacts
|
path: ./artifacts
|
||||||
@@ -230,13 +236,13 @@ jobs:
|
|||||||
run: chmod +x artifacts/*-runner
|
run: chmod +x artifacts/*-runner
|
||||||
|
|
||||||
- name: Extract Changelog Entry
|
- name: Extract Changelog Entry
|
||||||
uses: mindsers/changelog-reader-action@32aa5b4c155d76c94e4ec883a223c947b2f02656 # v2
|
uses: mindsers/changelog-reader-action@1faaf50aa09d5793d9a100819973df801febfb31 # v2.4.0
|
||||||
id: changelog_reader
|
id: changelog_reader
|
||||||
with:
|
with:
|
||||||
version: ${{ github.ref_name }}
|
version: ${{ github.ref_name }}
|
||||||
|
|
||||||
- name: Create GitHub release
|
- name: Create GitHub release
|
||||||
uses: ncipollo/release-action@339a81892b84b4eeb0f6e744e4574d79d0d9b8dd # v1
|
uses: ncipollo/release-action@339a81892b84b4eeb0f6e744e4574d79d0d9b8dd # v1.21.0
|
||||||
with:
|
with:
|
||||||
name: CommaFeed ${{ github.ref_name }}
|
name: CommaFeed ${{ github.ref_name }}
|
||||||
body: ${{ steps.changelog_reader.outputs.changes }}
|
body: ${{ steps.changelog_reader.outputs.changes }}
|
||||||
@@ -249,12 +255,12 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Update Docker Hub Description
|
- name: Update Docker Hub Description
|
||||||
uses: peter-evans/dockerhub-description@1b9a80c056b620d92cedb9d9b5a223409c68ddfa # v5
|
uses: peter-evans/dockerhub-description@1b9a80c056b620d92cedb9d9b5a223409c68ddfa # v5.0.0
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
@@ -274,5 +280,5 @@ jobs:
|
|||||||
url: ${{ steps.deployment.outputs.page_url }}
|
url: ${{ steps.deployment.outputs.page_url }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5
|
- uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0
|
||||||
id: deployment
|
id: deployment
|
||||||
|
|||||||
2
.mvn/wrapper/maven-wrapper.properties
vendored
2
.mvn/wrapper/maven-wrapper.properties
vendored
@@ -1,3 +1,3 @@
|
|||||||
wrapperVersion=3.3.4
|
wrapperVersion=3.3.4
|
||||||
distributionType=only-script
|
distributionType=only-script
|
||||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.14/apache-maven-3.9.14-bin.zip
|
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.16/apache-maven-3.9.16-bin.zip
|
||||||
|
|||||||
16
CHANGELOG.md
16
CHANGELOG.md
@@ -1,5 +1,21 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [7.2.1]
|
||||||
|
|
||||||
|
- correctly handle favicons hosted at the root of the domain for feeds with non-default ports
|
||||||
|
- prevent XXS injections in third party apps. The CommaFeed React client was already stripping malicious "javascript:" URLs, they are now filtered during feed parsing and no longer stored in the database/served through the REST API.
|
||||||
|
|
||||||
|
## [7.2.0]
|
||||||
|
|
||||||
|
- Add support for icons declared in feeds. This is useful for feeds exposed by RSS bridges (#2048)
|
||||||
|
- Search now also works for starred entries (#2217)
|
||||||
|
- The error message when subscribing to a feed is now properly displayed again
|
||||||
|
- Small performance improvements to the feed refresh engine
|
||||||
|
- Removed the Pocket sharing feature because the Pocket service has been discontinued
|
||||||
|
- Prevent the image proxy feature to access any URL to avoid SSRF attacks
|
||||||
|
- Strengthened the SSRF protection by also blocking ULA and CGNAT ranges
|
||||||
|
- Prevent DDOS attacks by filtering OPML files during imports
|
||||||
|
|
||||||
## [7.1.0]
|
## [7.1.0]
|
||||||
|
|
||||||
- Display the unread count in the header on mobile, since the tree is hidden by default and the unread count is not visible otherwise (#2055)
|
- Display the unread count in the header on mobile, since the tree is hidden by default and the unread count is not visible otherwise (#2055)
|
||||||
|
|||||||
@@ -70,8 +70,8 @@ memory usage.
|
|||||||
./mvnw clean package [-P<database> [-Pnative]] [-DskipTests]
|
./mvnw clean package [-P<database> [-Pnative]] [-DskipTests]
|
||||||
|
|
||||||
- `<database>` can be one of `h2`, `postgresql`, `mysql` or `mariadb`. The default is `h2`.
|
- `<database>` can be one of `h2`, `postgresql`, `mysql` or `mariadb`. The default is `h2`.
|
||||||
- `-Pnative` compiles the application to native code. This requires GraalVM to be installed (`GRAALVM_HOME` environment
|
- `-Pnative` compiles the application to native code. This requires either GraalVM to be installed (`GRAALVM_HOME` environment
|
||||||
variable pointing to a GraalVM installation).
|
variable pointing to a GraalVM installation) or a container environment to be available (docker/podman/...).
|
||||||
- `-DskipTests` to speed up the build process by skipping tests.
|
- `-DskipTests` to speed up the build process by skipping tests.
|
||||||
|
|
||||||
When the build is complete:
|
When the build is complete:
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
cd commafeed-client && npx lint-staged
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://biomejs.dev/schemas/2.4.11/schema.json",
|
"$schema": "https://biomejs.dev/schemas/2.5.6/schema.json",
|
||||||
"formatter": {
|
"formatter": {
|
||||||
"indentStyle": "space",
|
"indentStyle": "space",
|
||||||
"indentWidth": 4,
|
"indentWidth": 4,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { LinguiConfig } from "@lingui/conf"
|
import type { LinguiConfig } from "@lingui/conf"
|
||||||
|
import { formatter } from "@lingui/format-po"
|
||||||
|
|
||||||
const config: LinguiConfig = {
|
const config: LinguiConfig = {
|
||||||
locales: [
|
locales: [
|
||||||
@@ -38,11 +39,9 @@ const config: LinguiConfig = {
|
|||||||
exclude: ["src/locales/**"],
|
exclude: ["src/locales/**"],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
format: "po",
|
format: formatter({
|
||||||
formatOptions: {
|
|
||||||
origins: true,
|
|
||||||
lineNumbers: false,
|
lineNumbers: false,
|
||||||
},
|
}),
|
||||||
sourceLocale: "en",
|
sourceLocale: "en",
|
||||||
fallbackLocales: {
|
fallbackLocales: {
|
||||||
default: "en",
|
default: "en",
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
export default {
|
|
||||||
"src/**/*.{js,jsx,ts,tsx}": () => ["npm run i18n:extract", "git diff --exit-code commafeed-client/src/locales/en/messages.po"],
|
|
||||||
}
|
|
||||||
3930
commafeed-client/package-lock.json
generated
3930
commafeed-client/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -12,75 +12,73 @@
|
|||||||
"test:ci": "vitest run",
|
"test:ci": "vitest run",
|
||||||
"lint": "biome check",
|
"lint": "biome check",
|
||||||
"lint:fix": "biome check --write",
|
"lint:fix": "biome check --write",
|
||||||
"i18n:extract": "lingui extract --clean",
|
"i18n:extract": "lingui extract --clean"
|
||||||
"prepare": "cd .. && husky ./commafeed-client/.husky"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/react": "^11.14.0",
|
"@emotion/react": "11.14.0",
|
||||||
"@fontsource/open-sans": "^5.2.7",
|
"@fontsource/open-sans": "5.3.0",
|
||||||
"@lingui/core": "^5.9.5",
|
"@lingui/core": "6.6.0",
|
||||||
"@lingui/react": "^5.9.5",
|
"@lingui/react": "6.6.0",
|
||||||
"@mantine/core": "^9.0.1",
|
"@mantine/core": "9.5.0",
|
||||||
"@mantine/form": "^9.0.1",
|
"@mantine/dates": "9.5.0",
|
||||||
"@mantine/hooks": "^9.0.1",
|
"@mantine/form": "9.5.0",
|
||||||
"@mantine/modals": "^9.0.1",
|
"@mantine/hooks": "9.5.0",
|
||||||
"@mantine/notifications": "^9.0.1",
|
"@mantine/modals": "9.5.0",
|
||||||
"@mantine/spotlight": "^9.0.1",
|
"@mantine/notifications": "9.5.0",
|
||||||
"@monaco-editor/react": "^4.7.0",
|
"@mantine/spotlight": "9.5.0",
|
||||||
"@react-querybuilder/mantine": "^8.14.4",
|
"@monaco-editor/react": "4.7.0",
|
||||||
"@reduxjs/toolkit": "^2.11.2",
|
"@react-querybuilder/mantine": "8.21.2",
|
||||||
"@rolldown/plugin-babel": "^0.2.2",
|
"@reduxjs/toolkit": "2.12.0",
|
||||||
"axios": "^1.15.0",
|
"@rolldown/plugin-babel": "0.2.3",
|
||||||
"dayjs": "^1.11.20",
|
"axios": "1.19.0",
|
||||||
"escape-string-regexp": "^5.0.0",
|
"dayjs": "1.11.21",
|
||||||
"interweave": "^13.1.1",
|
"escape-string-regexp": "5.0.0",
|
||||||
"monaco-editor": "^0.55.1",
|
"interweave": "13.1.1",
|
||||||
"mousetrap": "^1.6.5",
|
"monaco-editor": "0.56.0",
|
||||||
"react": "^19.2.5",
|
"mousetrap": "1.6.5",
|
||||||
"react-async-hook": "^4.0.0",
|
"react": "19.2.8",
|
||||||
"react-contexify": "^6.0.0",
|
"react-async-hook": "4.0.0",
|
||||||
"react-dom": "^19.2.5",
|
"react-contexify": "6.0.0",
|
||||||
"react-draggable": "^4.5.0",
|
"react-dom": "19.2.8",
|
||||||
"react-icons": "^5.6.0",
|
"react-draggable": "4.7.1",
|
||||||
"react-infinite-scroller": "^1.2.6",
|
"react-icons": "5.7.0",
|
||||||
"react-querybuilder": "^8.14.4",
|
"react-infinite-scroller": "1.2.6",
|
||||||
"react-redux": "^9.2.0",
|
"react-querybuilder": "8.21.2",
|
||||||
"react-router-dom": "^7.14.0",
|
"react-redux": "9.3.0",
|
||||||
"react-swipeable": "^7.0.2",
|
"react-router-dom": "7.18.2",
|
||||||
"style-to-object": "^1.0.14",
|
"react-swipeable": "7.0.2",
|
||||||
"throttle-debounce": "^5.0.2",
|
"style-to-object": "2.0.2",
|
||||||
"tinycon": "^0.6.8",
|
"throttle-debounce": "5.0.2",
|
||||||
"tss-react": "^4.9.20",
|
"tinycon": "0.6.8",
|
||||||
"websocket-heartbeat-js": "^1.1.3"
|
"tss-react": "4.9.21",
|
||||||
|
"websocket-heartbeat-js": "1.1.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "^2.4.11",
|
"@biomejs/biome": "2.5.6",
|
||||||
"@lingui/babel-plugin-lingui-macro": "^5.9.5",
|
"@lingui/babel-plugin-lingui-macro": "6.6.0",
|
||||||
"@lingui/cli": "^5.9.5",
|
"@lingui/cli": "6.6.0",
|
||||||
"@lingui/vite-plugin": "^5.9.5",
|
"@lingui/vite-plugin": "6.6.0",
|
||||||
"@testing-library/jest-dom": "^6.9.1",
|
"@testing-library/jest-dom": "7.0.0",
|
||||||
"@testing-library/react": "^16.3.2",
|
"@testing-library/react": "16.3.2",
|
||||||
"@testing-library/user-event": "^14.6.1",
|
"@testing-library/user-event": "14.6.1",
|
||||||
"@types/mousetrap": "^1.6.15",
|
"@types/mousetrap": "1.6.15",
|
||||||
"@types/react": "^19.2.14",
|
"@types/react": "19.2.18",
|
||||||
"@types/react-dom": "^19.2.3",
|
"@types/react-dom": "19.2.4",
|
||||||
"@types/react-infinite-scroller": "^1.2.5",
|
"@types/react-infinite-scroller": "1.2.5",
|
||||||
"@types/throttle-debounce": "^5.0.2",
|
"@types/throttle-debounce": "5.0.2",
|
||||||
"@types/tinycon": "^0.6.7",
|
"@types/tinycon": "0.6.7",
|
||||||
"@vitejs/plugin-react": "^6.0.1",
|
"@vitejs/plugin-react": "6.0.5",
|
||||||
"babel-plugin-react-compiler": "1.0.0",
|
"babel-plugin-react-compiler": "1.0.0",
|
||||||
"husky": "^9.1.7",
|
"jsdom": "30.0.1",
|
||||||
"jsdom": "^29.0.2",
|
"typescript": "7.0.2",
|
||||||
"lint-staged": "^16.4.0",
|
"vite": "8.2.0",
|
||||||
"typescript": "^6.0.2",
|
"vite-plugin-checker": "0.14.5",
|
||||||
"vite": "^8.0.8",
|
"vitest": "4.1.10",
|
||||||
"vite-plugin-checker": "^0.12.0",
|
"yaml": "2.9.0"
|
||||||
"vitest": "^4.1.4",
|
|
||||||
"yaml": "^2.8.3"
|
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"react-infinite-scroller": {
|
"react-infinite-scroller": {
|
||||||
"react": "^19.2.5"
|
"react": "19.2.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,16 +6,16 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.commafeed</groupId>
|
<groupId>com.commafeed</groupId>
|
||||||
<artifactId>commafeed</artifactId>
|
<artifactId>commafeed</artifactId>
|
||||||
<version>7.1.0</version>
|
<version>7.2.1</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>commafeed-client</artifactId>
|
<artifactId>commafeed-client</artifactId>
|
||||||
<name>CommaFeed Client</name>
|
<name>CommaFeed Client</name>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<!-- renovate: datasource=node-version depName=node -->
|
<!-- renovate: datasource=node-version depName=node -->
|
||||||
<node.version>v24.14.1</node.version>
|
<node.version>v24.18.1</node.version>
|
||||||
<!-- renovate: datasource=npm depName=npm -->
|
<!-- renovate: datasource=npm depName=npm -->
|
||||||
<npm.version>11.12.1</npm.version>
|
<npm.version>12.0.2</npm.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>com.github.eirslett</groupId>
|
<groupId>com.github.eirslett</groupId>
|
||||||
<artifactId>frontend-maven-plugin</artifactId>
|
<artifactId>frontend-maven-plugin</artifactId>
|
||||||
<version>2.0.0</version>
|
<version>2.0.2</version>
|
||||||
<?m2e ignore?>
|
<?m2e ignore?>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
|
|||||||
@@ -5,32 +5,10 @@
|
|||||||
viewBox="0 0 5.0480766 5.0480766"
|
viewBox="0 0 5.0480766 5.0480766"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
id="svg3"
|
id="svg3"
|
||||||
sodipodi:docname="favicon.svg"
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
<title>CommaFeed favicon</title>
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg">
|
|
||||||
<defs
|
<defs
|
||||||
id="defs3" />
|
id="defs3" />
|
||||||
<sodipodi:namedview
|
|
||||||
id="namedview3"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#000000"
|
|
||||||
borderopacity="0.25"
|
|
||||||
inkscape:showpageshadow="2"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#d1d1d1"
|
|
||||||
inkscape:zoom="1.21875"
|
|
||||||
inkscape:cx="207.17949"
|
|
||||||
inkscape:cy="187.07692"
|
|
||||||
inkscape:window-width="1440"
|
|
||||||
inkscape:window-height="855"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="svg3" />
|
|
||||||
<rect
|
<rect
|
||||||
fill="#f88a14"
|
fill="#f88a14"
|
||||||
rx="0.53846151"
|
rx="0.53846151"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.1 KiB |
@@ -4,21 +4,16 @@ import { MantineProvider, v8CssVariablesResolver } from "@mantine/core"
|
|||||||
import { ModalsProvider } from "@mantine/modals"
|
import { ModalsProvider } from "@mantine/modals"
|
||||||
import { Notifications } from "@mantine/notifications"
|
import { Notifications } from "@mantine/notifications"
|
||||||
import type React from "react"
|
import type React from "react"
|
||||||
import { useEffect, useState } from "react"
|
import { useEffect } from "react"
|
||||||
import { HashRouter, Navigate, Route, Routes, useNavigate } from "react-router-dom"
|
import { HashRouter, Navigate, Route, Routes, useNavigate } from "react-router-dom"
|
||||||
import Tinycon from "tinycon"
|
|
||||||
import { Constants } from "@/app/constants"
|
import { Constants } from "@/app/constants"
|
||||||
import { redirectTo } from "@/app/redirect/slice"
|
import { redirectTo } from "@/app/redirect/slice"
|
||||||
import { redirectToInitialSetup } from "@/app/redirect/thunks"
|
import { redirectToInitialSetup } from "@/app/redirect/thunks"
|
||||||
import { reloadServerInfos } from "@/app/server/thunks"
|
import { reloadServerInfos } from "@/app/server/thunks"
|
||||||
import { useAppDispatch, useAppSelector } from "@/app/store"
|
import { useAppDispatch, useAppSelector } from "@/app/store"
|
||||||
import { categoryUnreadCount } from "@/app/utils"
|
|
||||||
import { DisablePullToRefresh } from "@/components/DisablePullToRefresh"
|
|
||||||
import { ErrorBoundary } from "@/components/ErrorBoundary"
|
import { ErrorBoundary } from "@/components/ErrorBoundary"
|
||||||
import { Header } from "@/components/header/Header"
|
import { Header } from "@/components/header/Header"
|
||||||
import { Tree } from "@/components/sidebar/Tree"
|
import { Tree } from "@/components/sidebar/Tree"
|
||||||
import { useAppLoading } from "@/hooks/useAppLoading"
|
|
||||||
import { useBrowserExtension } from "@/hooks/useBrowserExtension"
|
|
||||||
import { useI18n } from "@/i18n"
|
import { useI18n } from "@/i18n"
|
||||||
import { AdminUsersPage } from "@/pages/admin/AdminUsersPage"
|
import { AdminUsersPage } from "@/pages/admin/AdminUsersPage"
|
||||||
import { MetricsPage } from "@/pages/admin/MetricsPage"
|
import { MetricsPage } from "@/pages/admin/MetricsPage"
|
||||||
@@ -146,83 +141,8 @@ function RedirectHandler() {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
function UnreadCountTitleHandler({
|
|
||||||
enabled,
|
|
||||||
}: Readonly<{
|
|
||||||
enabled?: boolean
|
|
||||||
}>) {
|
|
||||||
const root = useAppSelector(state => state.tree.rootCategory)
|
|
||||||
const unreadCount = categoryUnreadCount(root)
|
|
||||||
return <title>{enabled && unreadCount > 0 ? `(${unreadCount}) CommaFeed` : "CommaFeed"}</title>
|
|
||||||
}
|
|
||||||
|
|
||||||
function UnreadCountFaviconHandler({ enabled }: { enabled?: boolean }) {
|
|
||||||
const root = useAppSelector(state => state.tree.rootCategory)
|
|
||||||
const unreadCount = categoryUnreadCount(root)
|
|
||||||
useEffect(() => {
|
|
||||||
if (enabled && unreadCount > 0) {
|
|
||||||
Tinycon.setBubble(unreadCount)
|
|
||||||
} else {
|
|
||||||
Tinycon.reset()
|
|
||||||
}
|
|
||||||
}, [unreadCount, enabled])
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
function BrowserExtensionBadgeUnreadCountHandler() {
|
|
||||||
const root = useAppSelector(state => state.tree.rootCategory)
|
|
||||||
const { setBadgeUnreadCount } = useBrowserExtension()
|
|
||||||
useEffect(() => {
|
|
||||||
if (!root) return
|
|
||||||
const unreadCount = categoryUnreadCount(root)
|
|
||||||
setBadgeUnreadCount(unreadCount)
|
|
||||||
}, [root, setBadgeUnreadCount])
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
function CustomJsHandler() {
|
|
||||||
const [scriptLoaded, setScriptLoaded] = useState(false)
|
|
||||||
const { loading } = useAppLoading()
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (scriptLoaded || loading) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const script = document.createElement("script")
|
|
||||||
script.src = "custom_js.js"
|
|
||||||
script.async = true
|
|
||||||
document.body.appendChild(script)
|
|
||||||
|
|
||||||
setScriptLoaded(true)
|
|
||||||
|
|
||||||
return () => script.remove()
|
|
||||||
}, [scriptLoaded, loading])
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
function CustomCssHandler() {
|
|
||||||
useEffect(() => {
|
|
||||||
const link = document.createElement("link")
|
|
||||||
link.rel = "stylesheet"
|
|
||||||
link.type = "text/css"
|
|
||||||
link.href = "custom_css.css"
|
|
||||||
document.head.appendChild(link)
|
|
||||||
|
|
||||||
return () => link.remove()
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
export function App() {
|
export function App() {
|
||||||
useI18n()
|
useI18n()
|
||||||
const unreadCountTitle = useAppSelector(state => state.user.settings?.unreadCountTitle)
|
|
||||||
const unreadCountFavicon = useAppSelector(state => state.user.settings?.unreadCountFavicon)
|
|
||||||
const disablePullToRefresh = useAppSelector(state => state.user.settings?.disablePullToRefresh)
|
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -231,13 +151,6 @@ export function App() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Providers>
|
<Providers>
|
||||||
<UnreadCountTitleHandler enabled={unreadCountTitle} />
|
|
||||||
<UnreadCountFaviconHandler enabled={unreadCountFavicon} />
|
|
||||||
<BrowserExtensionBadgeUnreadCountHandler />
|
|
||||||
<CustomJsHandler />
|
|
||||||
<CustomCssHandler />
|
|
||||||
<DisablePullToRefresh enabled={disablePullToRefresh} />
|
|
||||||
|
|
||||||
<HashRouter>
|
<HashRouter>
|
||||||
<InitialSetupHandler />
|
<InitialSetupHandler />
|
||||||
<RedirectHandler />
|
<RedirectHandler />
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { IconType } from "react-icons"
|
import type { IconType } from "react-icons"
|
||||||
import { FaAt } from "react-icons/fa"
|
import { FaAt } from "react-icons/fa"
|
||||||
import { SiBuffer, SiFacebook, SiGmail, SiInstapaper, SiPocket, SiTumblr, SiX } from "react-icons/si"
|
import { SiBuffer, SiFacebook, SiGmail, SiInstapaper, SiTumblr, SiX } from "react-icons/si"
|
||||||
import type { Category, Entry, SharingSettings } from "./types"
|
import type { Category, Entry, SharingSettings } from "./types"
|
||||||
|
|
||||||
const categories: Record<string, Omit<Category, "name">> = {
|
const categories: Record<string, Omit<Category, "name">> = {
|
||||||
@@ -58,12 +58,6 @@ const sharing: {
|
|||||||
color: "#375672",
|
color: "#375672",
|
||||||
url: (url, desc) => `https://www.tumblr.com/share/link?url=${url}&name=${desc}`,
|
url: (url, desc) => `https://www.tumblr.com/share/link?url=${url}&name=${desc}`,
|
||||||
},
|
},
|
||||||
pocket: {
|
|
||||||
label: "Pocket",
|
|
||||||
icon: SiPocket,
|
|
||||||
color: "#EF4154",
|
|
||||||
url: (url, desc) => `https://getpocket.com/save?url=${url}&title=${desc}`,
|
|
||||||
},
|
|
||||||
instapaper: {
|
instapaper: {
|
||||||
label: "Instapaper",
|
label: "Instapaper",
|
||||||
icon: SiInstapaper,
|
icon: SiInstapaper,
|
||||||
|
|||||||
@@ -249,7 +249,6 @@ export interface SharingSettings {
|
|||||||
facebook: boolean
|
facebook: boolean
|
||||||
twitter: boolean
|
twitter: boolean
|
||||||
tumblr: boolean
|
tumblr: boolean
|
||||||
pocket: boolean
|
|
||||||
instapaper: boolean
|
instapaper: boolean
|
||||||
buffer: boolean
|
buffer: boolean
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,32 +1,8 @@
|
|||||||
import { t } from "@lingui/core/macro"
|
import { t } from "@lingui/core/macro"
|
||||||
import { showNotification } from "@mantine/notifications"
|
import { showNotification } from "@mantine/notifications"
|
||||||
import { createSlice, isAnyOf, type PayloadAction } from "@reduxjs/toolkit"
|
import { createSlice, type PayloadAction } from "@reduxjs/toolkit"
|
||||||
import type { LocalSettings, Settings, UserModel, ViewMode } from "@/app/types"
|
import type { LocalSettings, Settings, UserModel, ViewMode } from "@/app/types"
|
||||||
import {
|
import { changeSettings, reloadProfile, reloadSettings, reloadTags } from "./thunks"
|
||||||
changeCustomContextMenu,
|
|
||||||
changeDisablePullToRefresh,
|
|
||||||
changeEntriesToKeepOnTopWhenScrolling,
|
|
||||||
changeExternalLinkIconDisplayMode,
|
|
||||||
changeLanguage,
|
|
||||||
changeMarkAllAsReadConfirmation,
|
|
||||||
changeMarkAllAsReadNavigateToUnread,
|
|
||||||
changeMobileFooter,
|
|
||||||
changePrimaryColor,
|
|
||||||
changePushNotificationSettings,
|
|
||||||
changeReadingMode,
|
|
||||||
changeReadingOrder,
|
|
||||||
changeScrollMarks,
|
|
||||||
changeScrollMode,
|
|
||||||
changeScrollSpeed,
|
|
||||||
changeSharingSetting,
|
|
||||||
changeShowRead,
|
|
||||||
changeStarIconDisplayMode,
|
|
||||||
changeUnreadCountFavicon,
|
|
||||||
changeUnreadCountTitle,
|
|
||||||
reloadProfile,
|
|
||||||
reloadSettings,
|
|
||||||
reloadTags,
|
|
||||||
} from "./thunks"
|
|
||||||
|
|
||||||
interface UserState {
|
interface UserState {
|
||||||
settings?: Settings
|
settings?: Settings
|
||||||
@@ -73,115 +49,16 @@ export const userSlice = createSlice({
|
|||||||
builder.addCase(reloadTags.fulfilled, (state, action) => {
|
builder.addCase(reloadTags.fulfilled, (state, action) => {
|
||||||
state.tags = action.payload
|
state.tags = action.payload
|
||||||
})
|
})
|
||||||
builder.addCase(changeReadingMode.pending, (state, action) => {
|
builder.addCase(changeSettings.pending, (state, action) => {
|
||||||
if (!state.settings) return
|
if (!state.settings) return
|
||||||
state.settings.readingMode = action.meta.arg
|
state.settings = { ...state.settings, ...action.meta.arg }
|
||||||
})
|
})
|
||||||
builder.addCase(changeReadingOrder.pending, (state, action) => {
|
builder.addCase(changeSettings.fulfilled, () => {
|
||||||
if (!state.settings) return
|
|
||||||
state.settings.readingOrder = action.meta.arg
|
|
||||||
})
|
|
||||||
builder.addCase(changeLanguage.pending, (state, action) => {
|
|
||||||
if (!state.settings) return
|
|
||||||
state.settings.language = action.meta.arg
|
|
||||||
})
|
|
||||||
builder.addCase(changeScrollSpeed.pending, (state, action) => {
|
|
||||||
if (!state.settings) return
|
|
||||||
state.settings.scrollSpeed = action.meta.arg ? 400 : 0
|
|
||||||
})
|
|
||||||
builder.addCase(changeShowRead.pending, (state, action) => {
|
|
||||||
if (!state.settings) return
|
|
||||||
state.settings.showRead = action.meta.arg
|
|
||||||
})
|
|
||||||
builder.addCase(changeScrollMarks.pending, (state, action) => {
|
|
||||||
if (!state.settings) return
|
|
||||||
state.settings.scrollMarks = action.meta.arg
|
|
||||||
})
|
|
||||||
builder.addCase(changeScrollMode.pending, (state, action) => {
|
|
||||||
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
|
|
||||||
})
|
|
||||||
builder.addCase(changeExternalLinkIconDisplayMode.pending, (state, action) => {
|
|
||||||
if (!state.settings) return
|
|
||||||
state.settings.externalLinkIconDisplayMode = action.meta.arg
|
|
||||||
})
|
|
||||||
builder.addCase(changeMarkAllAsReadConfirmation.pending, (state, action) => {
|
|
||||||
if (!state.settings) return
|
|
||||||
state.settings.markAllAsReadConfirmation = action.meta.arg
|
|
||||||
})
|
|
||||||
builder.addCase(changeMarkAllAsReadNavigateToUnread.pending, (state, action) => {
|
|
||||||
if (!state.settings) return
|
|
||||||
state.settings.markAllAsReadNavigateToNextUnread = action.meta.arg
|
|
||||||
})
|
|
||||||
builder.addCase(changeCustomContextMenu.pending, (state, action) => {
|
|
||||||
if (!state.settings) return
|
|
||||||
state.settings.customContextMenu = action.meta.arg
|
|
||||||
})
|
|
||||||
builder.addCase(changeMobileFooter.pending, (state, action) => {
|
|
||||||
if (!state.settings) return
|
|
||||||
state.settings.mobileFooter = action.meta.arg
|
|
||||||
})
|
|
||||||
builder.addCase(changeUnreadCountTitle.pending, (state, action) => {
|
|
||||||
if (!state.settings) return
|
|
||||||
state.settings.unreadCountTitle = action.meta.arg
|
|
||||||
})
|
|
||||||
builder.addCase(changeUnreadCountFavicon.pending, (state, action) => {
|
|
||||||
if (!state.settings) return
|
|
||||||
state.settings.unreadCountFavicon = action.meta.arg
|
|
||||||
})
|
|
||||||
builder.addCase(changeDisablePullToRefresh.pending, (state, action) => {
|
|
||||||
if (!state.settings) return
|
|
||||||
state.settings.disablePullToRefresh = action.meta.arg
|
|
||||||
})
|
|
||||||
builder.addCase(changePrimaryColor.pending, (state, action) => {
|
|
||||||
if (!state.settings) return
|
|
||||||
state.settings.primaryColor = action.meta.arg
|
|
||||||
})
|
|
||||||
builder.addCase(changeSharingSetting.pending, (state, action) => {
|
|
||||||
if (!state.settings) return
|
|
||||||
state.settings.sharingSettings[action.meta.arg.site] = action.meta.arg.value
|
|
||||||
})
|
|
||||||
builder.addCase(changePushNotificationSettings.pending, (state, action) => {
|
|
||||||
if (!state.settings) return
|
|
||||||
state.settings.pushNotificationSettings = action.meta.arg
|
|
||||||
})
|
|
||||||
|
|
||||||
builder.addMatcher(
|
|
||||||
isAnyOf(
|
|
||||||
changeLanguage.fulfilled,
|
|
||||||
changeScrollSpeed.fulfilled,
|
|
||||||
changeShowRead.fulfilled,
|
|
||||||
changeScrollMarks.fulfilled,
|
|
||||||
changeScrollMode.fulfilled,
|
|
||||||
changeEntriesToKeepOnTopWhenScrolling.fulfilled,
|
|
||||||
changeStarIconDisplayMode.fulfilled,
|
|
||||||
changeExternalLinkIconDisplayMode.fulfilled,
|
|
||||||
changeMarkAllAsReadConfirmation.fulfilled,
|
|
||||||
changeMarkAllAsReadNavigateToUnread.fulfilled,
|
|
||||||
changeCustomContextMenu.fulfilled,
|
|
||||||
changeMobileFooter.fulfilled,
|
|
||||||
changeUnreadCountTitle.fulfilled,
|
|
||||||
changeUnreadCountFavicon.fulfilled,
|
|
||||||
changeDisablePullToRefresh.fulfilled,
|
|
||||||
changePrimaryColor.fulfilled,
|
|
||||||
changeSharingSetting.fulfilled,
|
|
||||||
changePushNotificationSettings.fulfilled
|
|
||||||
),
|
|
||||||
() => {
|
|
||||||
showNotification({
|
showNotification({
|
||||||
message: t`Settings saved.`,
|
message: t`Settings saved.`,
|
||||||
color: "green",
|
color: "green",
|
||||||
})
|
})
|
||||||
}
|
})
|
||||||
)
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { createAppAsyncThunk } from "@/app/async-thunk"
|
import { createAppAsyncThunk } from "@/app/async-thunk"
|
||||||
import { client } from "@/app/client"
|
import { client } from "@/app/client"
|
||||||
import { reloadEntries } from "@/app/entries/thunks"
|
import type { Settings } from "@/app/types"
|
||||||
import type { IconDisplayMode, PushNotificationSettings, ReadingMode, ReadingOrder, ScrollMode, SharingSettings } from "@/app/types"
|
|
||||||
|
|
||||||
export const reloadSettings = createAppAsyncThunk("settings/reload", async () => await client.user.getSettings().then(r => r.data))
|
export const reloadSettings = createAppAsyncThunk("settings/reload", async () => await client.user.getSettings().then(r => r.data))
|
||||||
|
|
||||||
@@ -9,163 +8,8 @@ export const reloadProfile = createAppAsyncThunk("profile/reload", async () => a
|
|||||||
|
|
||||||
export const reloadTags = createAppAsyncThunk("entries/tags", async () => await client.entry.getTags().then(r => r.data))
|
export const reloadTags = createAppAsyncThunk("entries/tags", async () => await client.entry.getTags().then(r => r.data))
|
||||||
|
|
||||||
export const changeReadingMode = createAppAsyncThunk("settings/readingMode", (readingMode: ReadingMode, thunkApi) => {
|
export const changeSettings = createAppAsyncThunk("settings/change", async (newSettings: Partial<Settings>, thunkApi) => {
|
||||||
const { settings } = thunkApi.getState().user
|
const { settings } = thunkApi.getState().user
|
||||||
if (!settings) return
|
if (!settings) return
|
||||||
client.user.saveSettings({ ...settings, readingMode })
|
await client.user.saveSettings({ ...settings, ...newSettings })
|
||||||
thunkApi.dispatch(reloadEntries())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
export const changeReadingOrder = createAppAsyncThunk("settings/readingOrder", (readingOrder: ReadingOrder, thunkApi) => {
|
|
||||||
const { settings } = thunkApi.getState().user
|
|
||||||
if (!settings) return
|
|
||||||
client.user.saveSettings({ ...settings, readingOrder })
|
|
||||||
thunkApi.dispatch(reloadEntries())
|
|
||||||
})
|
|
||||||
|
|
||||||
export const changeLanguage = createAppAsyncThunk("settings/language", (language: string, thunkApi) => {
|
|
||||||
const { settings } = thunkApi.getState().user
|
|
||||||
if (!settings) return
|
|
||||||
client.user.saveSettings({ ...settings, language })
|
|
||||||
})
|
|
||||||
|
|
||||||
export const changeScrollSpeed = createAppAsyncThunk("settings/scrollSpeed", (speed: boolean, thunkApi) => {
|
|
||||||
const { settings } = thunkApi.getState().user
|
|
||||||
if (!settings) return
|
|
||||||
client.user.saveSettings({ ...settings, scrollSpeed: speed ? 400 : 0 })
|
|
||||||
})
|
|
||||||
|
|
||||||
export const changeShowRead = createAppAsyncThunk("settings/showRead", (showRead: boolean, thunkApi) => {
|
|
||||||
const { settings } = thunkApi.getState().user
|
|
||||||
if (!settings) return
|
|
||||||
client.user.saveSettings({ ...settings, showRead })
|
|
||||||
})
|
|
||||||
|
|
||||||
export const changeScrollMarks = createAppAsyncThunk("settings/scrollMarks", (scrollMarks: boolean, thunkApi) => {
|
|
||||||
const { settings } = thunkApi.getState().user
|
|
||||||
if (!settings) return
|
|
||||||
client.user.saveSettings({ ...settings, scrollMarks })
|
|
||||||
})
|
|
||||||
|
|
||||||
export const changeScrollMode = createAppAsyncThunk("settings/scrollMode", (scrollMode: ScrollMode, thunkApi) => {
|
|
||||||
const { settings } = thunkApi.getState().user
|
|
||||||
if (!settings) return
|
|
||||||
client.user.saveSettings({ ...settings, scrollMode })
|
|
||||||
})
|
|
||||||
|
|
||||||
export const changeEntriesToKeepOnTopWhenScrolling = createAppAsyncThunk(
|
|
||||||
"settings/entriesToKeepOnTopWhenScrolling",
|
|
||||||
(entriesToKeepOnTopWhenScrolling: number, thunkApi) => {
|
|
||||||
const { settings } = thunkApi.getState().user
|
|
||||||
if (!settings) return
|
|
||||||
client.user.saveSettings({ ...settings, entriesToKeepOnTopWhenScrolling })
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
export const changeStarIconDisplayMode = createAppAsyncThunk(
|
|
||||||
"settings/starIconDisplayMode",
|
|
||||||
(starIconDisplayMode: IconDisplayMode, thunkApi) => {
|
|
||||||
const { settings } = thunkApi.getState().user
|
|
||||||
if (!settings) return
|
|
||||||
client.user.saveSettings({ ...settings, starIconDisplayMode })
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
export const changeExternalLinkIconDisplayMode = createAppAsyncThunk(
|
|
||||||
"settings/externalLinkIconDisplayMode",
|
|
||||||
(externalLinkIconDisplayMode: IconDisplayMode, thunkApi) => {
|
|
||||||
const { settings } = thunkApi.getState().user
|
|
||||||
if (!settings) return
|
|
||||||
client.user.saveSettings({ ...settings, externalLinkIconDisplayMode })
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
export const changeMarkAllAsReadConfirmation = createAppAsyncThunk(
|
|
||||||
"settings/markAllAsReadConfirmation",
|
|
||||||
(markAllAsReadConfirmation: boolean, thunkApi) => {
|
|
||||||
const { settings } = thunkApi.getState().user
|
|
||||||
if (!settings) return
|
|
||||||
client.user.saveSettings({ ...settings, markAllAsReadConfirmation })
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
export const changeMarkAllAsReadNavigateToUnread = createAppAsyncThunk(
|
|
||||||
"settings/markAllAsReadNavigateToUnread",
|
|
||||||
(markAllAsReadNavigateToNextUnread: boolean, thunkApi) => {
|
|
||||||
const { settings } = thunkApi.getState().user
|
|
||||||
if (!settings) return
|
|
||||||
client.user.saveSettings({ ...settings, markAllAsReadNavigateToNextUnread })
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
export const changeCustomContextMenu = createAppAsyncThunk("settings/customContextMenu", (customContextMenu: boolean, thunkApi) => {
|
|
||||||
const { settings } = thunkApi.getState().user
|
|
||||||
if (!settings) return
|
|
||||||
client.user.saveSettings({ ...settings, customContextMenu })
|
|
||||||
})
|
|
||||||
|
|
||||||
export const changeMobileFooter = createAppAsyncThunk("settings/mobileFooter", (mobileFooter: boolean, thunkApi) => {
|
|
||||||
const { settings } = thunkApi.getState().user
|
|
||||||
if (!settings) return
|
|
||||||
client.user.saveSettings({ ...settings, mobileFooter })
|
|
||||||
})
|
|
||||||
|
|
||||||
export const changeUnreadCountTitle = createAppAsyncThunk("settings/unreadCountTitle", (unreadCountTitle: boolean, thunkApi) => {
|
|
||||||
const { settings } = thunkApi.getState().user
|
|
||||||
if (!settings) return
|
|
||||||
client.user.saveSettings({ ...settings, unreadCountTitle })
|
|
||||||
})
|
|
||||||
|
|
||||||
export const changeUnreadCountFavicon = createAppAsyncThunk("settings/unreadCountFavicon", (unreadCountFavicon: boolean, thunkApi) => {
|
|
||||||
const { settings } = thunkApi.getState().user
|
|
||||||
if (!settings) return
|
|
||||||
client.user.saveSettings({ ...settings, unreadCountFavicon })
|
|
||||||
})
|
|
||||||
|
|
||||||
export const changeDisablePullToRefresh = createAppAsyncThunk(
|
|
||||||
"settings/disablePullToRefresh",
|
|
||||||
(disablePullToRefresh: boolean, thunkApi) => {
|
|
||||||
const { settings } = thunkApi.getState().user
|
|
||||||
if (!settings) return
|
|
||||||
client.user.saveSettings({ ...settings, disablePullToRefresh })
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
export const changePrimaryColor = createAppAsyncThunk("settings/primaryColor", (primaryColor: string, thunkApi) => {
|
|
||||||
const { settings } = thunkApi.getState().user
|
|
||||||
if (!settings) return
|
|
||||||
client.user.saveSettings({ ...settings, primaryColor })
|
|
||||||
})
|
|
||||||
|
|
||||||
export const changeSharingSetting = createAppAsyncThunk(
|
|
||||||
"settings/sharingSetting",
|
|
||||||
(
|
|
||||||
sharingSetting: {
|
|
||||||
site: keyof SharingSettings
|
|
||||||
value: boolean
|
|
||||||
},
|
|
||||||
thunkApi
|
|
||||||
) => {
|
|
||||||
const { settings } = thunkApi.getState().user
|
|
||||||
if (!settings) return
|
|
||||||
client.user.saveSettings({
|
|
||||||
...settings,
|
|
||||||
sharingSettings: {
|
|
||||||
...settings.sharingSettings,
|
|
||||||
[sharingSetting.site]: sharingSetting.value,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
export const changePushNotificationSettings = createAppAsyncThunk(
|
|
||||||
"settings/pushNotificationSettings",
|
|
||||||
(pushNotificationSettings: PushNotificationSettings, thunkApi) => {
|
|
||||||
const { settings } = thunkApi.getState().user
|
|
||||||
if (!settings) return
|
|
||||||
client.user.saveSettings({
|
|
||||||
...settings,
|
|
||||||
pushNotificationSettings,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<svg height="512" width="512" viewBox="0 0 6.5625 6.5625" xmlns="http://www.w3.org/2000/svg">
|
<svg height="512" width="512" viewBox="0 0 6.5625 6.5625" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<title>CommaFeed logo</title>
|
||||||
<rect fill="#f88a14" rx="0.7" ry="0.7" height="6.5625" width="6.5625" />
|
<rect fill="#f88a14" rx="0.7" ry="0.7" height="6.5625" width="6.5625" />
|
||||||
<path d="m1.9761,1.5289c2.9002,0,2.9002,2.9101,2.9002,2.9101" fill="none" stroke="#FFF" stroke-linecap="round"
|
<path d="m1.9761,1.5289c2.9002,0,2.9002,2.9101,2.9002,2.9101" fill="none" stroke="#FFF" stroke-linecap="round"
|
||||||
stroke-width="0.78125" />
|
stroke-width="0.78125" />
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 791 B After Width: | Height: | Size: 831 B |
@@ -14,6 +14,7 @@ interface ImageWithPlaceholderWhileLoadingProps {
|
|||||||
placeholderHeight?: number
|
placeholderHeight?: number
|
||||||
placeholderBackgroundColor?: string
|
placeholderBackgroundColor?: string
|
||||||
placeholderIconSize?: number
|
placeholderIconSize?: number
|
||||||
|
onError?: (e: React.SyntheticEvent<HTMLImageElement, Event>) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const useStyles = tss
|
const useStyles = tss
|
||||||
@@ -44,6 +45,7 @@ export function ImageWithPlaceholderWhileLoading({
|
|||||||
title,
|
title,
|
||||||
width,
|
width,
|
||||||
style,
|
style,
|
||||||
|
onError,
|
||||||
}: Readonly<ImageWithPlaceholderWhileLoadingProps>) {
|
}: Readonly<ImageWithPlaceholderWhileLoadingProps>) {
|
||||||
const { classes } = useStyles({
|
const { classes } = useStyles({
|
||||||
placeholderWidth,
|
placeholderWidth,
|
||||||
@@ -70,6 +72,7 @@ export function ImageWithPlaceholderWhileLoading({
|
|||||||
width={width}
|
width={width}
|
||||||
height={height}
|
height={height}
|
||||||
onLoad={() => setLoading(false)}
|
onLoad={() => setLoading(false)}
|
||||||
|
onError={onError}
|
||||||
style={{
|
style={{
|
||||||
...style,
|
...style,
|
||||||
display: loading ? "none" : (style?.display ?? "initial"),
|
display: loading ? "none" : (style?.display ?? "initial"),
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ const init = async () => {
|
|||||||
async getWorker(_, label) {
|
async getWorker(_, label) {
|
||||||
let worker: typeof import("*?worker")
|
let worker: typeof import("*?worker")
|
||||||
if (label === "css") {
|
if (label === "css") {
|
||||||
worker = await import("monaco-editor/esm/vs/language/css/css.worker?worker")
|
worker = await import("monaco-editor/language/css/css.worker?worker")
|
||||||
} else if (label === "javascript") {
|
} else if (label === "javascript") {
|
||||||
worker = await import("monaco-editor/esm/vs/language/typescript/ts.worker?worker")
|
worker = await import("monaco-editor/language/typescript/ts.worker?worker")
|
||||||
} else {
|
} else {
|
||||||
worker = await import("monaco-editor/esm/vs/editor/editor.worker?worker")
|
worker = await import("monaco-editor/editor/editor.worker?worker")
|
||||||
}
|
}
|
||||||
return new worker.default()
|
return new worker.default()
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { useTimeout } from "@mantine/hooks"
|
||||||
|
import { useState } from "react"
|
||||||
import { ImageWithPlaceholderWhileLoading } from "@/components/ImageWithPlaceholderWhileLoading"
|
import { ImageWithPlaceholderWhileLoading } from "@/components/ImageWithPlaceholderWhileLoading"
|
||||||
|
|
||||||
export interface FeedFaviconProps {
|
export interface FeedFaviconProps {
|
||||||
@@ -6,9 +8,23 @@ export interface FeedFaviconProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function FeedFavicon({ url, size = 18 }: Readonly<FeedFaviconProps>) {
|
export function FeedFavicon({ url, size = 18 }: Readonly<FeedFaviconProps>) {
|
||||||
|
// the backend always returns a favicon except when the feed has never been fetched
|
||||||
|
// this can happen when the user subscribes to a feed, the feed is added to the tree but the feed has not been fetched yet
|
||||||
|
// in this case we retry every second up to 3 times until the feed is fetched and the favicon is available
|
||||||
|
const [timestamp, setTimestamp] = useState(0)
|
||||||
|
const [retryCount, setRetryCount] = useState(0)
|
||||||
|
const { start: retry } = useTimeout(() => setTimestamp(Date.now()), 1000)
|
||||||
|
|
||||||
|
const urlWithTimestamp = url + (timestamp === 0 ? "" : `?t=${timestamp}`)
|
||||||
|
const handleError = () => {
|
||||||
|
if (retryCount < 3) {
|
||||||
|
setRetryCount(c => c + 1)
|
||||||
|
retry()
|
||||||
|
}
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<ImageWithPlaceholderWhileLoading
|
<ImageWithPlaceholderWhileLoading
|
||||||
src={url}
|
src={urlWithTimestamp}
|
||||||
alt="feed favicon"
|
alt="feed favicon"
|
||||||
width={size}
|
width={size}
|
||||||
height={size}
|
height={size}
|
||||||
@@ -16,6 +32,7 @@ export function FeedFavicon({ url, size = 18 }: Readonly<FeedFaviconProps>) {
|
|||||||
placeholderHeight={size}
|
placeholderHeight={size}
|
||||||
placeholderBackgroundColor="inherit"
|
placeholderBackgroundColor="inherit"
|
||||||
placeholderIconSize={size}
|
placeholderIconSize={size}
|
||||||
|
onError={handleError}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,30 @@
|
|||||||
import { Highlight } from "@mantine/core"
|
import { Highlight } from "@mantine/core"
|
||||||
import { useAppSelector } from "@/app/store"
|
import { useAppSelector } from "@/app/store"
|
||||||
import type { Entry } from "@/app/types"
|
import type { Entry } from "@/app/types"
|
||||||
|
import { tss } from "@/tss"
|
||||||
|
|
||||||
export interface FeedEntryTitleProps {
|
export interface FeedEntryTitleProps {
|
||||||
entry: Entry
|
entry: Entry
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const useStyles = tss.create(() => ({
|
||||||
|
content: {
|
||||||
|
textWrap: "inherit",
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
|
||||||
export function FeedEntryTitle(props: Readonly<FeedEntryTitleProps>) {
|
export function FeedEntryTitle(props: Readonly<FeedEntryTitleProps>) {
|
||||||
const search = useAppSelector(state => state.entries.search)
|
const search = useAppSelector(state => state.entries.search)
|
||||||
const keywords = search?.split(" ")
|
const keywords = search?.split(" ")
|
||||||
|
|
||||||
|
const { classes } = useStyles()
|
||||||
return (
|
return (
|
||||||
<Highlight
|
<Highlight
|
||||||
inherit
|
inherit
|
||||||
highlight={keywords ?? ""}
|
highlight={keywords ?? ""}
|
||||||
// make sure ellipsis is shown when title is too long
|
// make sure ellipsis is shown when title is too long
|
||||||
span
|
span
|
||||||
|
className={classes.content}
|
||||||
>
|
>
|
||||||
{props.entry.title}
|
{props.entry.title}
|
||||||
</Highlight>
|
</Highlight>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import {
|
|||||||
} from "react-icons/tb"
|
} from "react-icons/tb"
|
||||||
import { markAllAsReadWithConfirmationIfRequired, reloadEntries, search, selectNextEntry, selectPreviousEntry } from "@/app/entries/thunks"
|
import { markAllAsReadWithConfirmationIfRequired, reloadEntries, search, selectNextEntry, selectPreviousEntry } from "@/app/entries/thunks"
|
||||||
import { useAppDispatch, useAppSelector } from "@/app/store"
|
import { useAppDispatch, useAppSelector } from "@/app/store"
|
||||||
import { changeReadingMode, changeReadingOrder } from "@/app/user/thunks"
|
import { changeSettings } from "@/app/user/thunks"
|
||||||
import { ActionButton } from "@/components/ActionButton"
|
import { ActionButton } from "@/components/ActionButton"
|
||||||
import { Loader } from "@/components/Loader"
|
import { Loader } from "@/components/Loader"
|
||||||
import { useActionButton } from "@/hooks/useActionButton"
|
import { useActionButton } from "@/hooks/useActionButton"
|
||||||
@@ -73,6 +73,25 @@ export function Header() {
|
|||||||
}, [setValues, searchFromStore])
|
}, [setValues, searchFromStore])
|
||||||
|
|
||||||
if (!settings) return <Loader />
|
if (!settings) return <Loader />
|
||||||
|
|
||||||
|
const toggleReadingMode = async () => {
|
||||||
|
await dispatch(
|
||||||
|
changeSettings({
|
||||||
|
readingMode: settings.readingMode === "all" ? "unread" : "all",
|
||||||
|
})
|
||||||
|
)
|
||||||
|
dispatch(reloadEntries())
|
||||||
|
}
|
||||||
|
|
||||||
|
const toggleReadingOrder = async () => {
|
||||||
|
await dispatch(
|
||||||
|
changeSettings({
|
||||||
|
readingOrder: settings.readingOrder === "asc" ? "desc" : "asc",
|
||||||
|
})
|
||||||
|
)
|
||||||
|
dispatch(reloadEntries())
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Center className="cf-toolbar-wrapper">
|
<Center className="cf-toolbar-wrapper">
|
||||||
<HeaderToolbar>
|
<HeaderToolbar>
|
||||||
@@ -121,12 +140,12 @@ export function Header() {
|
|||||||
<ActionButton
|
<ActionButton
|
||||||
icon={settings.readingMode === "all" ? <TbEye size={iconSize} /> : <TbEyeOff size={iconSize} />}
|
icon={settings.readingMode === "all" ? <TbEye size={iconSize} /> : <TbEyeOff size={iconSize} />}
|
||||||
label={settings.readingMode === "all" ? msg`All` : msg`Unread`}
|
label={settings.readingMode === "all" ? msg`All` : msg`Unread`}
|
||||||
onClick={async () => await dispatch(changeReadingMode(settings.readingMode === "all" ? "unread" : "all"))}
|
onClick={toggleReadingMode}
|
||||||
/>
|
/>
|
||||||
<ActionButton
|
<ActionButton
|
||||||
icon={settings.readingOrder === "asc" ? <TbSortAscending size={iconSize} /> : <TbSortDescending size={iconSize} />}
|
icon={settings.readingOrder === "asc" ? <TbSortAscending size={iconSize} /> : <TbSortDescending size={iconSize} />}
|
||||||
label={settings.readingOrder === "asc" ? msg`Asc` : msg`Desc`}
|
label={settings.readingOrder === "asc" ? msg`Asc` : msg`Desc`}
|
||||||
onClick={async () => await dispatch(changeReadingOrder(settings.readingOrder === "asc" ? "desc" : "asc"))}
|
onClick={toggleReadingOrder}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Popover>
|
<Popover>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
type ComboboxData,
|
type ComboboxData,
|
||||||
Divider,
|
Divider,
|
||||||
Group,
|
Group,
|
||||||
|
Loader,
|
||||||
NumberInput,
|
NumberInput,
|
||||||
Radio,
|
Radio,
|
||||||
Select,
|
Select,
|
||||||
@@ -18,45 +19,11 @@ import type { ReactNode } from "react"
|
|||||||
import { Constants } from "@/app/constants"
|
import { Constants } from "@/app/constants"
|
||||||
import { useAppDispatch, useAppSelector } from "@/app/store"
|
import { useAppDispatch, useAppSelector } from "@/app/store"
|
||||||
import type { IconDisplayMode, ScrollMode, SharingSettings } from "@/app/types"
|
import type { IconDisplayMode, ScrollMode, SharingSettings } from "@/app/types"
|
||||||
import {
|
import { changeSettings } from "@/app/user/thunks"
|
||||||
changeCustomContextMenu,
|
|
||||||
changeDisablePullToRefresh,
|
|
||||||
changeEntriesToKeepOnTopWhenScrolling,
|
|
||||||
changeExternalLinkIconDisplayMode,
|
|
||||||
changeLanguage,
|
|
||||||
changeMarkAllAsReadConfirmation,
|
|
||||||
changeMarkAllAsReadNavigateToUnread,
|
|
||||||
changeMobileFooter,
|
|
||||||
changePrimaryColor,
|
|
||||||
changeScrollMarks,
|
|
||||||
changeScrollMode,
|
|
||||||
changeScrollSpeed,
|
|
||||||
changeSharingSetting,
|
|
||||||
changeShowRead,
|
|
||||||
changeStarIconDisplayMode,
|
|
||||||
changeUnreadCountFavicon,
|
|
||||||
changeUnreadCountTitle,
|
|
||||||
} from "@/app/user/thunks"
|
|
||||||
import { locales } from "@/i18n"
|
import { locales } from "@/i18n"
|
||||||
|
|
||||||
export function DisplaySettings() {
|
export function DisplaySettings() {
|
||||||
const language = useAppSelector(state => state.user.settings?.language)
|
const settings = useAppSelector(state => state.user.settings)
|
||||||
const scrollSpeed = useAppSelector(state => state.user.settings?.scrollSpeed)
|
|
||||||
const showRead = useAppSelector(state => state.user.settings?.showRead)
|
|
||||||
const scrollMarks = useAppSelector(state => state.user.settings?.scrollMarks)
|
|
||||||
const scrollMode = useAppSelector(state => state.user.settings?.scrollMode)
|
|
||||||
const entriesToKeepOnTop = useAppSelector(state => state.user.settings?.entriesToKeepOnTopWhenScrolling)
|
|
||||||
const starIconDisplayMode = useAppSelector(state => state.user.settings?.starIconDisplayMode)
|
|
||||||
const externalLinkIconDisplayMode = useAppSelector(state => state.user.settings?.externalLinkIconDisplayMode)
|
|
||||||
const markAllAsReadConfirmation = useAppSelector(state => state.user.settings?.markAllAsReadConfirmation)
|
|
||||||
const markAllAsReadNavigateToNextUnread = useAppSelector(state => state.user.settings?.markAllAsReadNavigateToNextUnread)
|
|
||||||
const customContextMenu = useAppSelector(state => state.user.settings?.customContextMenu)
|
|
||||||
const mobileFooter = useAppSelector(state => state.user.settings?.mobileFooter)
|
|
||||||
const unreadCountTitle = useAppSelector(state => state.user.settings?.unreadCountTitle)
|
|
||||||
const unreadCountFavicon = useAppSelector(state => state.user.settings?.unreadCountFavicon)
|
|
||||||
const disablePullToRefresh = useAppSelector(state => state.user.settings?.disablePullToRefresh)
|
|
||||||
const sharingSettings = useAppSelector(state => state.user.settings?.sharingSettings)
|
|
||||||
const primaryColor = useAppSelector(state => state.user.settings?.primaryColor) || Constants.theme.defaultPrimaryColor
|
|
||||||
const { _ } = useLingui()
|
const { _ } = useLingui()
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
|
|
||||||
@@ -108,50 +75,51 @@ export function DisplaySettings() {
|
|||||||
</Group>
|
</Group>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (!settings) return <Loader />
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack>
|
||||||
<Divider label={<Trans>Display</Trans>} labelPosition="center" />
|
<Divider label={<Trans>Display</Trans>} labelPosition="center" />
|
||||||
|
|
||||||
<Select
|
<Select
|
||||||
label={<Trans>Language</Trans>}
|
label={<Trans>Language</Trans>}
|
||||||
value={language}
|
value={settings.language}
|
||||||
data={locales.map(l => ({
|
data={locales.map(l => ({
|
||||||
value: l.key,
|
value: l.key,
|
||||||
label: l.label,
|
label: l.label,
|
||||||
}))}
|
}))}
|
||||||
onChange={async s => await (s && dispatch(changeLanguage(s)))}
|
onChange={language => language && dispatch(changeSettings({ language }))}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Select
|
<Select
|
||||||
label={<Trans>Primary color</Trans>}
|
label={<Trans>Primary color</Trans>}
|
||||||
data={colorData}
|
data={colorData}
|
||||||
value={primaryColor}
|
value={settings.primaryColor}
|
||||||
onChange={async value => value && (await dispatch(changePrimaryColor(value)))}
|
onChange={primaryColor => primaryColor && dispatch(changeSettings({ primaryColor }))}
|
||||||
renderOption={colorRenderer}
|
renderOption={colorRenderer}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
label={<Trans>Show feeds and categories with no unread entries</Trans>}
|
label={<Trans>Show feeds and categories with no unread entries</Trans>}
|
||||||
checked={showRead}
|
checked={settings.showRead}
|
||||||
onChange={async e => await dispatch(changeShowRead(e.currentTarget.checked))}
|
onChange={e => dispatch(changeSettings({ showRead: e.currentTarget.checked }))}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
label={<Trans>Show confirmation when marking all entries as read</Trans>}
|
label={<Trans>Show confirmation when marking all entries as read</Trans>}
|
||||||
checked={markAllAsReadConfirmation}
|
checked={settings.markAllAsReadConfirmation}
|
||||||
onChange={async e => await dispatch(changeMarkAllAsReadConfirmation(e.currentTarget.checked))}
|
onChange={e => dispatch(changeSettings({ markAllAsReadConfirmation: e.currentTarget.checked }))}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
label={<Trans>Navigate to the next category/feed with unread entries when marking all entries as read</Trans>}
|
label={<Trans>Navigate to the next category/feed with unread entries when marking all entries as read</Trans>}
|
||||||
checked={markAllAsReadNavigateToNextUnread}
|
checked={settings.markAllAsReadNavigateToNextUnread}
|
||||||
onChange={async e => await dispatch(changeMarkAllAsReadNavigateToUnread(e.currentTarget.checked))}
|
onChange={e => dispatch(changeSettings({ markAllAsReadNavigateToNextUnread: e.currentTarget.checked }))}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
label={<Trans>On mobile, show action buttons at the bottom of the screen</Trans>}
|
label={<Trans>On mobile, show action buttons at the bottom of the screen</Trans>}
|
||||||
checked={mobileFooter}
|
checked={settings.mobileFooter}
|
||||||
onChange={async e => await dispatch(changeMobileFooter(e.currentTarget.checked))}
|
onChange={e => dispatch(changeSettings({ mobileFooter: e.currentTarget.checked }))}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Divider label={<Trans>Scrolling</Trans>} labelPosition="center" />
|
<Divider label={<Trans>Scrolling</Trans>} labelPosition="center" />
|
||||||
@@ -159,14 +127,14 @@ export function DisplaySettings() {
|
|||||||
<Switch
|
<Switch
|
||||||
label={<Trans>Disable "Pull to refresh" browser behavior</Trans>}
|
label={<Trans>Disable "Pull to refresh" browser behavior</Trans>}
|
||||||
description={<Trans>This setting can cause scrolling issues on some browsers (e.g. Safari)</Trans>}
|
description={<Trans>This setting can cause scrolling issues on some browsers (e.g. Safari)</Trans>}
|
||||||
checked={disablePullToRefresh}
|
checked={settings.disablePullToRefresh}
|
||||||
onChange={async e => await dispatch(changeDisablePullToRefresh(e.currentTarget.checked))}
|
onChange={e => dispatch(changeSettings({ disablePullToRefresh: e.currentTarget.checked }))}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Radio.Group
|
<Radio.Group
|
||||||
label={<Trans>Scroll selected entry to the top of the page</Trans>}
|
label={<Trans>Scroll selected entry to the top of the page</Trans>}
|
||||||
value={scrollMode}
|
value={settings.scrollMode}
|
||||||
onChange={async value => await dispatch(changeScrollMode(value as ScrollMode))}
|
onChange={value => dispatch(changeSettings({ scrollMode: value }))}
|
||||||
>
|
>
|
||||||
<Group mt="xs">
|
<Group mt="xs">
|
||||||
{Object.entries(scrollModeOptions).map(e => (
|
{Object.entries(scrollModeOptions).map(e => (
|
||||||
@@ -179,56 +147,56 @@ export function DisplaySettings() {
|
|||||||
label={<Trans>Entries to keep above the selected entry when scrolling</Trans>}
|
label={<Trans>Entries to keep above the selected entry when scrolling</Trans>}
|
||||||
description={<Trans>Only applies to compact, cozy and detailed modes</Trans>}
|
description={<Trans>Only applies to compact, cozy and detailed modes</Trans>}
|
||||||
min={0}
|
min={0}
|
||||||
value={entriesToKeepOnTop}
|
value={settings.entriesToKeepOnTopWhenScrolling}
|
||||||
onChange={async value => await dispatch(changeEntriesToKeepOnTopWhenScrolling(+value))}
|
onChange={value => dispatch(changeSettings({ entriesToKeepOnTopWhenScrolling: +value }))}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
label={<Trans>Scroll smoothly when navigating between entries</Trans>}
|
label={<Trans>Scroll smoothly when navigating between entries</Trans>}
|
||||||
checked={scrollSpeed ? scrollSpeed > 0 : false}
|
checked={settings.scrollSpeed ? settings.scrollSpeed > 0 : false}
|
||||||
onChange={async e => await dispatch(changeScrollSpeed(e.currentTarget.checked))}
|
onChange={e => dispatch(changeSettings({ scrollSpeed: e.currentTarget.checked ? 400 : 0 }))}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
label={<Trans>In expanded view, scrolling through entries mark them as read</Trans>}
|
label={<Trans>In expanded view, scrolling through entries mark them as read</Trans>}
|
||||||
checked={scrollMarks}
|
checked={settings.scrollMarks}
|
||||||
onChange={async e => await dispatch(changeScrollMarks(e.currentTarget.checked))}
|
onChange={e => dispatch(changeSettings({ scrollMarks: e.currentTarget.checked }))}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Divider label={<Trans>Browser tab</Trans>} labelPosition="center" />
|
<Divider label={<Trans>Browser tab</Trans>} labelPosition="center" />
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
label={<Trans>Show unread count in tab title</Trans>}
|
label={<Trans>Show unread count in tab title</Trans>}
|
||||||
checked={unreadCountTitle}
|
checked={settings.unreadCountTitle}
|
||||||
onChange={async e => await dispatch(changeUnreadCountTitle(e.currentTarget.checked))}
|
onChange={e => dispatch(changeSettings({ unreadCountTitle: e.currentTarget.checked }))}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
label={<Trans>Show unread count in tab favicon</Trans>}
|
label={<Trans>Show unread count in tab favicon</Trans>}
|
||||||
checked={unreadCountFavicon}
|
checked={settings.unreadCountFavicon}
|
||||||
onChange={async e => await dispatch(changeUnreadCountFavicon(e.currentTarget.checked))}
|
onChange={e => dispatch(changeSettings({ unreadCountFavicon: e.currentTarget.checked }))}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Divider label={<Trans>Entry headers</Trans>} labelPosition="center" />
|
<Divider label={<Trans>Entry headers</Trans>} labelPosition="center" />
|
||||||
|
|
||||||
<Select
|
<Select
|
||||||
label={<Trans>Show star icon</Trans>}
|
label={<Trans>Show star icon</Trans>}
|
||||||
value={starIconDisplayMode}
|
value={settings.starIconDisplayMode}
|
||||||
data={displayModeData}
|
data={displayModeData}
|
||||||
onChange={async s => await dispatch(changeStarIconDisplayMode(s as IconDisplayMode))}
|
onChange={value => dispatch(changeSettings({ starIconDisplayMode: value as IconDisplayMode }))}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Select
|
<Select
|
||||||
label={<Trans>Show external link icon</Trans>}
|
label={<Trans>Show external link icon</Trans>}
|
||||||
value={externalLinkIconDisplayMode}
|
value={settings.externalLinkIconDisplayMode}
|
||||||
data={displayModeData}
|
data={displayModeData}
|
||||||
onChange={async s => await dispatch(changeExternalLinkIconDisplayMode(s as IconDisplayMode))}
|
onChange={value => dispatch(changeSettings({ externalLinkIconDisplayMode: value as IconDisplayMode }))}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
label={<Trans>Show CommaFeed's own context menu on right click</Trans>}
|
label={<Trans>Show CommaFeed's own context menu on right click</Trans>}
|
||||||
checked={customContextMenu}
|
checked={settings.customContextMenu}
|
||||||
onChange={async e => await dispatch(changeCustomContextMenu(e.currentTarget.checked))}
|
onChange={e => dispatch(changeSettings({ customContextMenu: e.currentTarget.checked }))}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Divider label={<Trans>Sharing sites</Trans>} labelPosition="center" />
|
<Divider label={<Trans>Sharing sites</Trans>} labelPosition="center" />
|
||||||
@@ -238,12 +206,14 @@ export function DisplaySettings() {
|
|||||||
<Switch
|
<Switch
|
||||||
key={site}
|
key={site}
|
||||||
label={Constants.sharing[site].label}
|
label={Constants.sharing[site].label}
|
||||||
checked={sharingSettings?.[site]}
|
checked={settings.sharingSettings[site]}
|
||||||
onChange={async e =>
|
onChange={e =>
|
||||||
await dispatch(
|
dispatch(
|
||||||
changeSharingSetting({
|
changeSettings({
|
||||||
site,
|
sharingSettings: {
|
||||||
value: e.currentTarget.checked,
|
...settings.sharingSettings,
|
||||||
|
[site]: e.currentTarget.checked,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { client, errorToStrings } from "@/app/client"
|
|||||||
import { redirectToSelectedSource } from "@/app/redirect/thunks"
|
import { redirectToSelectedSource } from "@/app/redirect/thunks"
|
||||||
import { useAppDispatch, useAppSelector } from "@/app/store"
|
import { useAppDispatch, useAppSelector } from "@/app/store"
|
||||||
import type { PushNotificationSettings as PushNotificationSettingsModel } from "@/app/types"
|
import type { PushNotificationSettings as PushNotificationSettingsModel } from "@/app/types"
|
||||||
import { changePushNotificationSettings } from "@/app/user/thunks"
|
import { changeSettings } from "@/app/user/thunks"
|
||||||
import { Alert } from "@/components/Alert"
|
import { Alert } from "@/components/Alert"
|
||||||
|
|
||||||
export function PushNotificationSettings() {
|
export function PushNotificationSettings() {
|
||||||
@@ -25,7 +25,7 @@ export function PushNotificationSettings() {
|
|||||||
}, [form.initialize, notificationSettings])
|
}, [form.initialize, notificationSettings])
|
||||||
|
|
||||||
const handleSubmit = (values: PushNotificationSettingsModel) => {
|
const handleSubmit = (values: PushNotificationSettingsModel) => {
|
||||||
dispatch(changePushNotificationSettings(values))
|
dispatch(changeSettings({ pushNotificationSettings: values }))
|
||||||
}
|
}
|
||||||
|
|
||||||
const sendTestPushNotification = useAsyncCallback(client.user.sendTestPushNotification)
|
const sendTestPushNotification = useAsyncCallback(client.user.sendTestPushNotification)
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ msgstr "إضافة مستخدم"
|
|||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "إداري"
|
msgstr "إداري"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr "اسم مستخدم المسؤول"
|
msgstr "اسم مستخدم المسؤول"
|
||||||
@@ -73,7 +72,6 @@ msgstr "اسم مستخدم المسؤول"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "الكل"
|
msgstr "الكل"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Always"
|
msgid "Always"
|
||||||
msgstr "دائمًا"
|
msgstr "دائمًا"
|
||||||
@@ -173,18 +171,14 @@ msgstr "قم ببناء تعبير تصفية لتحديد ما تريد قرا
|
|||||||
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
#: src/pages/app/TagDetailsPage.tsx
|
#: src/pages/app/TagDetailsPage.tsx
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "إلغاء"
|
msgstr "إلغاء"
|
||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -240,7 +234,6 @@ msgstr "تأكيد"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "تأكيد كلمة المرور"
|
msgstr "تأكيد كلمة المرور"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "تأكيد كلمة المرور"
|
msgstr "تأكيد كلمة المرور"
|
||||||
@@ -294,7 +287,6 @@ msgstr "أيام"
|
|||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "حذف"
|
msgstr "حذف"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Delete account"
|
msgid "Delete account"
|
||||||
msgstr "حذف الحساب"
|
msgstr "حذف الحساب"
|
||||||
@@ -342,13 +334,10 @@ msgstr "اسحب الرابط إلى شريط الإشارات"
|
|||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "البريد الإلكتروني"
|
msgstr "البريد الإلكتروني"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "E-mail address"
|
msgid "E-mail address"
|
||||||
msgstr "عنوان البريد الإلكتروني"
|
msgstr "عنوان البريد الإلكتروني"
|
||||||
@@ -399,7 +388,6 @@ msgstr "خيارات الإضافة"
|
|||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
msgstr "اسم الخلاصة"
|
msgstr "اسم الخلاصة"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
@@ -570,7 +558,6 @@ msgstr "تحميل الاشتراكات ..."
|
|||||||
msgid "Loading tags..."
|
msgid "Loading tags..."
|
||||||
msgstr "تحميل العلامات ..."
|
msgstr "تحميل العلامات ..."
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
@@ -648,7 +635,6 @@ msgstr "انتقل إلى اشتراك بإدخال اسمه"
|
|||||||
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
msgstr "انتقل إلى الفئة/الخلاصة التالية التي تحتوي على إدخالات غير مقروءة عند تمييز الكل كمقروء"
|
msgstr "انتقل إلى الفئة/الخلاصة التالية التي تحتوي على إدخالات غير مقروءة عند تمييز الكل كمقروء"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "أبدا"
|
msgstr "أبدا"
|
||||||
@@ -657,7 +643,6 @@ msgstr "أبدا"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "كلمة مرور جديدة"
|
msgstr "كلمة مرور جديدة"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "كلمة مرور جديدة"
|
msgstr "كلمة مرور جديدة"
|
||||||
@@ -764,7 +749,6 @@ msgstr "OPML"
|
|||||||
msgid "OPML export"
|
msgid "OPML export"
|
||||||
msgstr "تصدير OPML"
|
msgstr "تصدير OPML"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "OPML file"
|
msgid "OPML file"
|
||||||
msgstr "ملف OPML"
|
msgstr "ملف OPML"
|
||||||
@@ -791,10 +775,7 @@ msgstr "الفئة الأصل"
|
|||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "كلمة المرور"
|
msgstr "كلمة المرور"
|
||||||
@@ -874,7 +855,6 @@ msgstr "تحديث"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "تم إغلاق التسجيلات في مثيل CommaFeed هذا"
|
msgstr "تم إغلاق التسجيلات في مثيل CommaFeed هذا"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "إعادة تعيين كلمة المرور"
|
msgstr "إعادة تعيين كلمة المرور"
|
||||||
@@ -883,7 +863,6 @@ msgstr "إعادة تعيين كلمة المرور"
|
|||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REST API"
|
msgstr "REST API"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr "نقرة بالزر الأيمن"
|
msgstr "نقرة بالزر الأيمن"
|
||||||
@@ -910,8 +889,6 @@ msgid "Scrolling"
|
|||||||
msgstr "التمرير"
|
msgstr "التمرير"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
#: src/components/sidebar/TreeSearch.tsx
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "بحث"
|
msgstr "بحث"
|
||||||
@@ -924,7 +901,6 @@ msgstr "تحديد الخلاصة/الفئة التالية غير المقرو
|
|||||||
msgid "Select previous unread feed/category"
|
msgid "Select previous unread feed/category"
|
||||||
msgstr "تحديد الخلاصة/الفئة السابقة غير المقروءة"
|
msgstr "تحديد الخلاصة/الفئة السابقة غير المقروءة"
|
||||||
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
msgid "Server URL"
|
msgid "Server URL"
|
||||||
msgstr "رابط الخادم"
|
msgstr "رابط الخادم"
|
||||||
@@ -953,8 +929,6 @@ msgstr "مشاركة"
|
|||||||
msgid "Sharing sites"
|
msgid "Sharing sites"
|
||||||
msgstr "مشاركة المواقع"
|
msgstr "مشاركة المواقع"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Shift"
|
msgid "Shift"
|
||||||
msgstr "الحلقة"
|
msgstr "الحلقة"
|
||||||
@@ -1003,7 +977,6 @@ msgstr "إظهار عدد غير المقروء في أيقونة التبويب
|
|||||||
msgid "Show unread count in tab title"
|
msgid "Show unread count in tab title"
|
||||||
msgstr "إظهار عدد غير المقروء في عنوان التبويب"
|
msgstr "إظهار عدد غير المقروء في عنوان التبويب"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
@@ -1013,7 +986,6 @@ msgstr "قم بالتسجيل"
|
|||||||
msgid "Something bad just happened..."
|
msgid "Something bad just happened..."
|
||||||
msgstr "شيء سيء حدث للتو ..."
|
msgstr "شيء سيء حدث للتو ..."
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Space"
|
msgid "Space"
|
||||||
msgstr "فضاء"
|
msgstr "فضاء"
|
||||||
@@ -1030,7 +1002,6 @@ msgstr "النجم"
|
|||||||
msgid "Starred"
|
msgid "Starred"
|
||||||
msgstr "مميز بنجمة"
|
msgstr "مميز بنجمة"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AddPage.tsx
|
#: src/pages/app/AddPage.tsx
|
||||||
msgid "Subscribe"
|
msgid "Subscribe"
|
||||||
@@ -1064,7 +1035,6 @@ msgstr "قم بالتبديل إلى النسق الفاتح"
|
|||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "النظام"
|
msgstr "النظام"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "الكلمات"
|
msgstr "الكلمات"
|
||||||
@@ -1136,7 +1106,6 @@ msgstr "غير مقروءة"
|
|||||||
msgid "Unstar"
|
msgid "Unstar"
|
||||||
msgstr "إلغاء النجم"
|
msgstr "إلغاء النجم"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "إلغاء الاشتراك"
|
msgstr "إلغاء الاشتراك"
|
||||||
@@ -1149,7 +1118,6 @@ msgstr "مفتاح المستخدم"
|
|||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "اسم المستخدم"
|
msgstr "اسم المستخدم"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "User Name or E-mail"
|
msgid "User Name or E-mail"
|
||||||
msgstr "اسم المستخدم أو البريد الإلكتروني"
|
msgstr "اسم المستخدم أو البريد الإلكتروني"
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ msgstr "Afegeix usuari"
|
|||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "Administrador"
|
msgstr "Administrador"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr "Nom d'usuari de l'administrador"
|
msgstr "Nom d'usuari de l'administrador"
|
||||||
@@ -73,7 +72,6 @@ msgstr "Nom d'usuari de l'administrador"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Tot"
|
msgstr "Tot"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Always"
|
msgid "Always"
|
||||||
msgstr "Sempre"
|
msgstr "Sempre"
|
||||||
@@ -173,18 +171,14 @@ msgstr "Creeu una expressió de filtratge per indicar què voleu llegir. Les ent
|
|||||||
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
#: src/pages/app/TagDetailsPage.tsx
|
#: src/pages/app/TagDetailsPage.tsx
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Cancel·la"
|
msgstr "Cancel·la"
|
||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -240,7 +234,6 @@ msgstr "Confirma"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Confirmeu la contrasenya"
|
msgstr "Confirmeu la contrasenya"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "Confirma la contrasenya"
|
msgstr "Confirma la contrasenya"
|
||||||
@@ -294,7 +287,6 @@ msgstr "dies"
|
|||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Eliminar"
|
msgstr "Eliminar"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Delete account"
|
msgid "Delete account"
|
||||||
msgstr "Suprimeix el compte"
|
msgstr "Suprimeix el compte"
|
||||||
@@ -342,13 +334,10 @@ msgstr "Arrossegueu l'enllaç a la barra d'adreces d'interès"
|
|||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "Correu electrònic"
|
msgstr "Correu electrònic"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "E-mail address"
|
msgid "E-mail address"
|
||||||
msgstr "Adreça de correu electrònic"
|
msgstr "Adreça de correu electrònic"
|
||||||
@@ -399,7 +388,6 @@ msgstr "Opcions de l'extensió"
|
|||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
msgstr "Nom del canal"
|
msgstr "Nom del canal"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
@@ -570,7 +558,6 @@ msgstr "S'estan carregant les subscripcions..."
|
|||||||
msgid "Loading tags..."
|
msgid "Loading tags..."
|
||||||
msgstr "Carregant les etiquetes..."
|
msgstr "Carregant les etiquetes..."
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
@@ -648,7 +635,6 @@ msgstr "Navegueu a una subscripció introduint-ne el nom"
|
|||||||
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
msgstr "Navega a la següent categoria/canal amb entrades no llegides quan es marquen totes les entrades com a llegides"
|
msgstr "Navega a la següent categoria/canal amb entrades no llegides quan es marquen totes les entrades com a llegides"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "Mai"
|
msgstr "Mai"
|
||||||
@@ -657,7 +643,6 @@ msgstr "Mai"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Contrasenya nova"
|
msgstr "Contrasenya nova"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "Contrasenya nova"
|
msgstr "Contrasenya nova"
|
||||||
@@ -764,7 +749,6 @@ msgstr "OPML"
|
|||||||
msgid "OPML export"
|
msgid "OPML export"
|
||||||
msgstr "Exportació OPML"
|
msgstr "Exportació OPML"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "OPML file"
|
msgid "OPML file"
|
||||||
msgstr "Fitxer OPML"
|
msgstr "Fitxer OPML"
|
||||||
@@ -791,10 +775,7 @@ msgstr "Categoria pare"
|
|||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Contrasenya"
|
msgstr "Contrasenya"
|
||||||
@@ -874,7 +855,6 @@ msgstr "Actualitzar"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Els registres estan tancats en aquesta instància de CommaFeed"
|
msgstr "Els registres estan tancats en aquesta instància de CommaFeed"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "Restableix la contrasenya"
|
msgstr "Restableix la contrasenya"
|
||||||
@@ -883,7 +863,6 @@ msgstr "Restableix la contrasenya"
|
|||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "API REST"
|
msgstr "API REST"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr "Clic dret"
|
msgstr "Clic dret"
|
||||||
@@ -910,8 +889,6 @@ msgid "Scrolling"
|
|||||||
msgstr "Desplaçament"
|
msgstr "Desplaçament"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
#: src/components/sidebar/TreeSearch.tsx
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Cerca"
|
msgstr "Cerca"
|
||||||
@@ -924,7 +901,6 @@ msgstr "Selecciona el següent canal/categoria no llegit"
|
|||||||
msgid "Select previous unread feed/category"
|
msgid "Select previous unread feed/category"
|
||||||
msgstr "Selecciona el canal/categoria anterior sense llegir"
|
msgstr "Selecciona el canal/categoria anterior sense llegir"
|
||||||
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
msgid "Server URL"
|
msgid "Server URL"
|
||||||
msgstr "URL del servidor"
|
msgstr "URL del servidor"
|
||||||
@@ -953,8 +929,6 @@ msgstr "Comparteix"
|
|||||||
msgid "Sharing sites"
|
msgid "Sharing sites"
|
||||||
msgstr "Compartir a altres llocs web"
|
msgstr "Compartir a altres llocs web"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Shift"
|
msgid "Shift"
|
||||||
msgstr "canvi"
|
msgstr "canvi"
|
||||||
@@ -1003,7 +977,6 @@ msgstr "Mostra el recompte de no llegits a la icona de favorits de la pestanya"
|
|||||||
msgid "Show unread count in tab title"
|
msgid "Show unread count in tab title"
|
||||||
msgstr "Mostra el recompte de no llegits al títol de la pestanya"
|
msgstr "Mostra el recompte de no llegits al títol de la pestanya"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
@@ -1013,7 +986,6 @@ msgstr "Registra't"
|
|||||||
msgid "Something bad just happened..."
|
msgid "Something bad just happened..."
|
||||||
msgstr "Acaba de passar una cosa dolenta..."
|
msgstr "Acaba de passar una cosa dolenta..."
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Space"
|
msgid "Space"
|
||||||
msgstr "Espai"
|
msgstr "Espai"
|
||||||
@@ -1030,7 +1002,6 @@ msgstr "Estrella"
|
|||||||
msgid "Starred"
|
msgid "Starred"
|
||||||
msgstr "Estrellat"
|
msgstr "Estrellat"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AddPage.tsx
|
#: src/pages/app/AddPage.tsx
|
||||||
msgid "Subscribe"
|
msgid "Subscribe"
|
||||||
@@ -1064,7 +1035,6 @@ msgstr "Canvia al tema clar"
|
|||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "Sistema"
|
msgstr "Sistema"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Etiquetes"
|
msgstr "Etiquetes"
|
||||||
@@ -1136,7 +1106,6 @@ msgstr "Sense llegir"
|
|||||||
msgid "Unstar"
|
msgid "Unstar"
|
||||||
msgstr "Desestrellar"
|
msgstr "Desestrellar"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Donar-se de baixa"
|
msgstr "Donar-se de baixa"
|
||||||
@@ -1149,7 +1118,6 @@ msgstr "Clau d'usuari"
|
|||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Nom d'usuari"
|
msgstr "Nom d'usuari"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "User Name or E-mail"
|
msgid "User Name or E-mail"
|
||||||
msgstr "Nom d'usuari o correu electrònic"
|
msgstr "Nom d'usuari o correu electrònic"
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ msgstr "Přidat uživatele"
|
|||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "Správce"
|
msgstr "Správce"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr "Uživatelské jméno správce"
|
msgstr "Uživatelské jméno správce"
|
||||||
@@ -73,7 +72,6 @@ msgstr "Uživatelské jméno správce"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Všechny"
|
msgstr "Všechny"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Always"
|
msgid "Always"
|
||||||
msgstr "Vždy"
|
msgstr "Vždy"
|
||||||
@@ -173,18 +171,14 @@ msgstr "Vytvořte výraz filtru pro určení toho, co chcete číst. Položky, k
|
|||||||
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
#: src/pages/app/TagDetailsPage.tsx
|
#: src/pages/app/TagDetailsPage.tsx
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Zrušit"
|
msgstr "Zrušit"
|
||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -240,7 +234,6 @@ msgstr "Potvrdit"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Potvrďte heslo"
|
msgstr "Potvrďte heslo"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "Potvrdit heslo"
|
msgstr "Potvrdit heslo"
|
||||||
@@ -294,7 +287,6 @@ msgstr "dní"
|
|||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Smazat"
|
msgstr "Smazat"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Delete account"
|
msgid "Delete account"
|
||||||
msgstr "Smazat účet"
|
msgstr "Smazat účet"
|
||||||
@@ -342,13 +334,10 @@ msgstr "Přetáhněte odkaz na lištu záložek"
|
|||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "E-mail"
|
msgstr "E-mail"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "E-mail address"
|
msgid "E-mail address"
|
||||||
msgstr "E-mailová adresa"
|
msgstr "E-mailová adresa"
|
||||||
@@ -399,7 +388,6 @@ msgstr "Možnosti rozšíření"
|
|||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
msgstr "Název zdroje"
|
msgstr "Název zdroje"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
@@ -570,7 +558,6 @@ msgstr "Načítání odběrů..."
|
|||||||
msgid "Loading tags..."
|
msgid "Loading tags..."
|
||||||
msgstr "Načítání značek..."
|
msgstr "Načítání značek..."
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
@@ -648,7 +635,6 @@ msgstr "Přejděte na předplatné zadáním jeho názvu"
|
|||||||
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
msgstr "Po označení všech položek jako přečtených přejít na další kategorii/zdroj s nepřečtenými položkami"
|
msgstr "Po označení všech položek jako přečtených přejít na další kategorii/zdroj s nepřečtenými položkami"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "Nikdy"
|
msgstr "Nikdy"
|
||||||
@@ -657,7 +643,6 @@ msgstr "Nikdy"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Nové heslo"
|
msgstr "Nové heslo"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "Nové heslo"
|
msgstr "Nové heslo"
|
||||||
@@ -764,7 +749,6 @@ msgstr "OPML"
|
|||||||
msgid "OPML export"
|
msgid "OPML export"
|
||||||
msgstr "Export OPML"
|
msgstr "Export OPML"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "OPML file"
|
msgid "OPML file"
|
||||||
msgstr "soubor OPML"
|
msgstr "soubor OPML"
|
||||||
@@ -791,10 +775,7 @@ msgstr "Rodičovská kategorie"
|
|||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Heslo"
|
msgstr "Heslo"
|
||||||
@@ -874,7 +855,6 @@ msgstr "Obnovit"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "V této instanci CommaFeed jsou registrace uzavřeny"
|
msgstr "V této instanci CommaFeed jsou registrace uzavřeny"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "Obnovit heslo"
|
msgstr "Obnovit heslo"
|
||||||
@@ -883,7 +863,6 @@ msgstr "Obnovit heslo"
|
|||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REST API"
|
msgstr "REST API"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr "Kliknutí pravým tlačítkem"
|
msgstr "Kliknutí pravým tlačítkem"
|
||||||
@@ -910,8 +889,6 @@ msgid "Scrolling"
|
|||||||
msgstr "Posouvání"
|
msgstr "Posouvání"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
#: src/components/sidebar/TreeSearch.tsx
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Hledej"
|
msgstr "Hledej"
|
||||||
@@ -924,7 +901,6 @@ msgstr "Vybrat další nepřečtený zdroj/kategorii"
|
|||||||
msgid "Select previous unread feed/category"
|
msgid "Select previous unread feed/category"
|
||||||
msgstr "Vybrat předchozí nepřečtený zdroj/kategorii"
|
msgstr "Vybrat předchozí nepřečtený zdroj/kategorii"
|
||||||
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
msgid "Server URL"
|
msgid "Server URL"
|
||||||
msgstr "URL serveru"
|
msgstr "URL serveru"
|
||||||
@@ -953,8 +929,6 @@ msgstr "Sdílejte"
|
|||||||
msgid "Sharing sites"
|
msgid "Sharing sites"
|
||||||
msgstr "Stránky pro sdílení"
|
msgstr "Stránky pro sdílení"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Shift"
|
msgid "Shift"
|
||||||
msgstr "Směna"
|
msgstr "Směna"
|
||||||
@@ -1003,7 +977,6 @@ msgstr "Zobrazovat počet nepřečtených v ikoně karty"
|
|||||||
msgid "Show unread count in tab title"
|
msgid "Show unread count in tab title"
|
||||||
msgstr "Zobrazovat počet nepřečtených v názvu karty"
|
msgstr "Zobrazovat počet nepřečtených v názvu karty"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
@@ -1013,7 +986,6 @@ msgstr "Zaregistrovat se"
|
|||||||
msgid "Something bad just happened..."
|
msgid "Something bad just happened..."
|
||||||
msgstr "Právě se stalo něco špatného..."
|
msgstr "Právě se stalo něco špatného..."
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Space"
|
msgid "Space"
|
||||||
msgstr "Vesmír"
|
msgstr "Vesmír"
|
||||||
@@ -1030,7 +1002,6 @@ msgstr "Hvězda"
|
|||||||
msgid "Starred"
|
msgid "Starred"
|
||||||
msgstr "S hvězdičkou"
|
msgstr "S hvězdičkou"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AddPage.tsx
|
#: src/pages/app/AddPage.tsx
|
||||||
msgid "Subscribe"
|
msgid "Subscribe"
|
||||||
@@ -1064,7 +1035,6 @@ msgstr "Přepnout na světlý motiv"
|
|||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "Systémový"
|
msgstr "Systémový"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Štítky"
|
msgstr "Štítky"
|
||||||
@@ -1136,7 +1106,6 @@ msgstr "Nepřečteno"
|
|||||||
msgid "Unstar"
|
msgid "Unstar"
|
||||||
msgstr "Odstranit hvězdu"
|
msgstr "Odstranit hvězdu"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Odhlásit odběr"
|
msgstr "Odhlásit odběr"
|
||||||
@@ -1149,7 +1118,6 @@ msgstr "Uživatelský klíč"
|
|||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Uživatelské jméno"
|
msgstr "Uživatelské jméno"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "User Name or E-mail"
|
msgid "User Name or E-mail"
|
||||||
msgstr "Uživatelské jméno nebo e-mail"
|
msgstr "Uživatelské jméno nebo e-mail"
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ msgstr "Ychwanegu defnyddiwr"
|
|||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "Gweinyddol"
|
msgstr "Gweinyddol"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr "Enw defnyddiwr gweinyddwr"
|
msgstr "Enw defnyddiwr gweinyddwr"
|
||||||
@@ -73,7 +72,6 @@ msgstr "Enw defnyddiwr gweinyddwr"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Pawb"
|
msgstr "Pawb"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Always"
|
msgid "Always"
|
||||||
msgstr "Bob amser"
|
msgstr "Bob amser"
|
||||||
@@ -173,18 +171,14 @@ msgstr "Adeiladwch fynegiant hidlo i nodi'r hyn rydych chi am ei ddarllen. Bydd
|
|||||||
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
#: src/pages/app/TagDetailsPage.tsx
|
#: src/pages/app/TagDetailsPage.tsx
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Diddymu"
|
msgstr "Diddymu"
|
||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -240,7 +234,6 @@ msgstr "Cadarnhau"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Cadarnhau'r cyfrinair"
|
msgstr "Cadarnhau'r cyfrinair"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "Cadarnhau Cyfrinair"
|
msgstr "Cadarnhau Cyfrinair"
|
||||||
@@ -294,7 +287,6 @@ msgstr "diwrnodau"
|
|||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Dileu"
|
msgstr "Dileu"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Delete account"
|
msgid "Delete account"
|
||||||
msgstr "Dileu cyfrif"
|
msgstr "Dileu cyfrif"
|
||||||
@@ -342,13 +334,10 @@ msgstr "Llusgwch y ddolen i'r bar nod tudalen"
|
|||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "E-bost"
|
msgstr "E-bost"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "E-mail address"
|
msgid "E-mail address"
|
||||||
msgstr "cyfeiriad e-bost"
|
msgstr "cyfeiriad e-bost"
|
||||||
@@ -399,7 +388,6 @@ msgstr "Opsiynau estyniad"
|
|||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
msgstr "Enw porthiant"
|
msgstr "Enw porthiant"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
@@ -570,7 +558,6 @@ msgstr "Yn llwytho tanysgrifiadau..."
|
|||||||
msgid "Loading tags..."
|
msgid "Loading tags..."
|
||||||
msgstr "Wrthi'n llwytho tagiau..."
|
msgstr "Wrthi'n llwytho tagiau..."
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
@@ -648,7 +635,6 @@ msgstr "Llywiwch i danysgrifiad trwy nodi ei enw"
|
|||||||
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
msgstr "Llywiwch i'r categori/porthiant nesaf gyda chofnodion heb eu darllen wrth farcio pob cofnod fel un wedi'i ddarllen"
|
msgstr "Llywiwch i'r categori/porthiant nesaf gyda chofnodion heb eu darllen wrth farcio pob cofnod fel un wedi'i ddarllen"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "Byth"
|
msgstr "Byth"
|
||||||
@@ -657,7 +643,6 @@ msgstr "Byth"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Cyfrinair newydd"
|
msgstr "Cyfrinair newydd"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "Cyfrinair Newydd"
|
msgstr "Cyfrinair Newydd"
|
||||||
@@ -764,7 +749,6 @@ msgstr "OPML"
|
|||||||
msgid "OPML export"
|
msgid "OPML export"
|
||||||
msgstr "Allforio OPML"
|
msgstr "Allforio OPML"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "OPML file"
|
msgid "OPML file"
|
||||||
msgstr "Ffeil OPML"
|
msgstr "Ffeil OPML"
|
||||||
@@ -791,10 +775,7 @@ msgstr "Categori Rhiant"
|
|||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "cyfrinair"
|
msgstr "cyfrinair"
|
||||||
@@ -874,7 +855,6 @@ msgstr "Adnewyddu"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Mae cofrestriadau ar gau ar yr achos CommaFeed hwn"
|
msgstr "Mae cofrestriadau ar gau ar yr achos CommaFeed hwn"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "Ailosod Cyfrinair"
|
msgstr "Ailosod Cyfrinair"
|
||||||
@@ -883,7 +863,6 @@ msgstr "Ailosod Cyfrinair"
|
|||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REST API"
|
msgstr "REST API"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr "Clic dde"
|
msgstr "Clic dde"
|
||||||
@@ -910,8 +889,6 @@ msgid "Scrolling"
|
|||||||
msgstr "Sgrolio"
|
msgstr "Sgrolio"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
#: src/components/sidebar/TreeSearch.tsx
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Chwilio"
|
msgstr "Chwilio"
|
||||||
@@ -924,7 +901,6 @@ msgstr "Dewiswch y porthiant/categori nesaf heb ei ddarllen"
|
|||||||
msgid "Select previous unread feed/category"
|
msgid "Select previous unread feed/category"
|
||||||
msgstr "Dewiswch y porthiant/categori blaenorol heb ei ddarllen"
|
msgstr "Dewiswch y porthiant/categori blaenorol heb ei ddarllen"
|
||||||
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
msgid "Server URL"
|
msgid "Server URL"
|
||||||
msgstr "URL y gweinydd"
|
msgstr "URL y gweinydd"
|
||||||
@@ -953,8 +929,6 @@ msgstr "Rhannu"
|
|||||||
msgid "Sharing sites"
|
msgid "Sharing sites"
|
||||||
msgstr "Rhannu gwefannau"
|
msgstr "Rhannu gwefannau"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Shift"
|
msgid "Shift"
|
||||||
msgstr "shifft"
|
msgstr "shifft"
|
||||||
@@ -1003,7 +977,6 @@ msgstr "Dangos nifer heb ei ddarllen yn ffaficon y tab"
|
|||||||
msgid "Show unread count in tab title"
|
msgid "Show unread count in tab title"
|
||||||
msgstr "Dangos nifer heb ei ddarllen yn nheitl y tab"
|
msgstr "Dangos nifer heb ei ddarllen yn nheitl y tab"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
@@ -1013,7 +986,6 @@ msgstr "Cofrestrwch"
|
|||||||
msgid "Something bad just happened..."
|
msgid "Something bad just happened..."
|
||||||
msgstr "Mae rhywbeth drwg newydd ddigwydd ..."
|
msgstr "Mae rhywbeth drwg newydd ddigwydd ..."
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Space"
|
msgid "Space"
|
||||||
msgstr "Gofod"
|
msgstr "Gofod"
|
||||||
@@ -1030,7 +1002,6 @@ msgstr "seren"
|
|||||||
msgid "Starred"
|
msgid "Starred"
|
||||||
msgstr "serennog"
|
msgstr "serennog"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AddPage.tsx
|
#: src/pages/app/AddPage.tsx
|
||||||
msgid "Subscribe"
|
msgid "Subscribe"
|
||||||
@@ -1064,7 +1035,6 @@ msgstr "Newid i thema golau"
|
|||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "System"
|
msgstr "System"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Tagiau"
|
msgstr "Tagiau"
|
||||||
@@ -1136,7 +1106,6 @@ msgstr "Heb ei ddarllen"
|
|||||||
msgid "Unstar"
|
msgid "Unstar"
|
||||||
msgstr "dad-seren"
|
msgstr "dad-seren"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Dad-danysgrifio"
|
msgstr "Dad-danysgrifio"
|
||||||
@@ -1149,7 +1118,6 @@ msgstr "Allwedd defnyddiwr"
|
|||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Enw defnyddiwr"
|
msgstr "Enw defnyddiwr"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "User Name or E-mail"
|
msgid "User Name or E-mail"
|
||||||
msgstr "Enw Defnyddiwr neu E-bost"
|
msgstr "Enw Defnyddiwr neu E-bost"
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ msgstr "Tilføj bruger"
|
|||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "Administrator"
|
msgstr "Administrator"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr "Administrator brugernavn"
|
msgstr "Administrator brugernavn"
|
||||||
@@ -73,7 +72,6 @@ msgstr "Administrator brugernavn"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Alle"
|
msgstr "Alle"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Always"
|
msgid "Always"
|
||||||
msgstr "Altid"
|
msgstr "Altid"
|
||||||
@@ -173,18 +171,14 @@ msgstr "Byg et filterudtryk for at angive, hvad du vil læse. Indlæg, der ikke
|
|||||||
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
#: src/pages/app/TagDetailsPage.tsx
|
#: src/pages/app/TagDetailsPage.tsx
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Annuller"
|
msgstr "Annuller"
|
||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -240,7 +234,6 @@ msgstr "Bekræft"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Bekræft adgangskode"
|
msgstr "Bekræft adgangskode"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "Bekræft adgangskode"
|
msgstr "Bekræft adgangskode"
|
||||||
@@ -294,7 +287,6 @@ msgstr "dage"
|
|||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Slet"
|
msgstr "Slet"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Delete account"
|
msgid "Delete account"
|
||||||
msgstr "Slet konto"
|
msgstr "Slet konto"
|
||||||
@@ -342,13 +334,10 @@ msgstr "Træk linket til bogmærkelinjen"
|
|||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "E-mail"
|
msgstr "E-mail"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "E-mail address"
|
msgid "E-mail address"
|
||||||
msgstr "E-mailadresse"
|
msgstr "E-mailadresse"
|
||||||
@@ -399,7 +388,6 @@ msgstr "Indstillinger for udvidelse"
|
|||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
msgstr "Feednavn"
|
msgstr "Feednavn"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
@@ -570,7 +558,6 @@ msgstr "Indlæser abonnementer..."
|
|||||||
msgid "Loading tags..."
|
msgid "Loading tags..."
|
||||||
msgstr "Indlæser tags..."
|
msgstr "Indlæser tags..."
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
@@ -648,7 +635,6 @@ msgstr "Naviger til et abonnement ved at indtaste dets navn"
|
|||||||
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
msgstr "Naviger til næste kategori/feed med ulæste indlæg, når alle indlæg markeres som læst"
|
msgstr "Naviger til næste kategori/feed med ulæste indlæg, når alle indlæg markeres som læst"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "Aldrig"
|
msgstr "Aldrig"
|
||||||
@@ -657,7 +643,6 @@ msgstr "Aldrig"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Ny adgangskode"
|
msgstr "Ny adgangskode"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "Ny adgangskode"
|
msgstr "Ny adgangskode"
|
||||||
@@ -764,7 +749,6 @@ msgstr "OPML"
|
|||||||
msgid "OPML export"
|
msgid "OPML export"
|
||||||
msgstr "OPML eksport"
|
msgstr "OPML eksport"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "OPML file"
|
msgid "OPML file"
|
||||||
msgstr "OPML fil"
|
msgstr "OPML fil"
|
||||||
@@ -791,10 +775,7 @@ msgstr "Forældrekategori"
|
|||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Adgangskode"
|
msgstr "Adgangskode"
|
||||||
@@ -874,7 +855,6 @@ msgstr "Opdater"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Registreringer er lukket på denne CommaFeed-instans"
|
msgstr "Registreringer er lukket på denne CommaFeed-instans"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "Nulstil adgangskode"
|
msgstr "Nulstil adgangskode"
|
||||||
@@ -883,7 +863,6 @@ msgstr "Nulstil adgangskode"
|
|||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REST API"
|
msgstr "REST API"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr "Højreklik"
|
msgstr "Højreklik"
|
||||||
@@ -910,8 +889,6 @@ msgid "Scrolling"
|
|||||||
msgstr "Rulning"
|
msgstr "Rulning"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
#: src/components/sidebar/TreeSearch.tsx
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Søg"
|
msgstr "Søg"
|
||||||
@@ -924,7 +901,6 @@ msgstr "Vælg næste ulæste feed/kategori"
|
|||||||
msgid "Select previous unread feed/category"
|
msgid "Select previous unread feed/category"
|
||||||
msgstr "Vælg forrige ulæste feed/kategori"
|
msgstr "Vælg forrige ulæste feed/kategori"
|
||||||
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
msgid "Server URL"
|
msgid "Server URL"
|
||||||
msgstr "Server-URL"
|
msgstr "Server-URL"
|
||||||
@@ -953,8 +929,6 @@ msgstr "Del"
|
|||||||
msgid "Sharing sites"
|
msgid "Sharing sites"
|
||||||
msgstr "Delingssider"
|
msgstr "Delingssider"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Shift"
|
msgid "Shift"
|
||||||
msgstr "Skift"
|
msgstr "Skift"
|
||||||
@@ -1003,7 +977,6 @@ msgstr "Vis ulæst antal i fanens favicon"
|
|||||||
msgid "Show unread count in tab title"
|
msgid "Show unread count in tab title"
|
||||||
msgstr "Vis ulæst antal i fanens titel"
|
msgstr "Vis ulæst antal i fanens titel"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
@@ -1013,7 +986,6 @@ msgstr "Tilmeld dig"
|
|||||||
msgid "Something bad just happened..."
|
msgid "Something bad just happened..."
|
||||||
msgstr "Der er lige sket noget slemt..."
|
msgstr "Der er lige sket noget slemt..."
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Space"
|
msgid "Space"
|
||||||
msgstr "Rum"
|
msgstr "Rum"
|
||||||
@@ -1030,7 +1002,6 @@ msgstr "Stjerne"
|
|||||||
msgid "Starred"
|
msgid "Starred"
|
||||||
msgstr "Medvirkende"
|
msgstr "Medvirkende"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AddPage.tsx
|
#: src/pages/app/AddPage.tsx
|
||||||
msgid "Subscribe"
|
msgid "Subscribe"
|
||||||
@@ -1064,7 +1035,6 @@ msgstr "Skift til lystema"
|
|||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "System"
|
msgstr "System"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Tags"
|
msgstr "Tags"
|
||||||
@@ -1136,7 +1106,6 @@ msgstr "Ulæst"
|
|||||||
msgid "Unstar"
|
msgid "Unstar"
|
||||||
msgstr "Fjern stjerne"
|
msgstr "Fjern stjerne"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Afmeld"
|
msgstr "Afmeld"
|
||||||
@@ -1149,7 +1118,6 @@ msgstr "Brugernøgle"
|
|||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Brugernavn"
|
msgstr "Brugernavn"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "User Name or E-mail"
|
msgid "User Name or E-mail"
|
||||||
msgstr "Brugernavn eller e-mail"
|
msgstr "Brugernavn eller e-mail"
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ msgstr "Benutzer hinzufügen"
|
|||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "Verwaltung"
|
msgstr "Verwaltung"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr "Administrator-Benutzername"
|
msgstr "Administrator-Benutzername"
|
||||||
@@ -73,7 +72,6 @@ msgstr "Administrator-Benutzername"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Alle"
|
msgstr "Alle"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Always"
|
msgid "Always"
|
||||||
msgstr "Immer"
|
msgstr "Immer"
|
||||||
@@ -173,18 +171,14 @@ msgstr "Erstellen Sie einen Filterausdruck, um anzugeben, was Sie lesen möchten
|
|||||||
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
#: src/pages/app/TagDetailsPage.tsx
|
#: src/pages/app/TagDetailsPage.tsx
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Abbrechen"
|
msgstr "Abbrechen"
|
||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -240,7 +234,6 @@ msgstr "Bestätigen"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Passwort bestätigen"
|
msgstr "Passwort bestätigen"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "Passwort bestätigen"
|
msgstr "Passwort bestätigen"
|
||||||
@@ -294,7 +287,6 @@ msgstr "Tage"
|
|||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Löschen"
|
msgstr "Löschen"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Delete account"
|
msgid "Delete account"
|
||||||
msgstr "Konto löschen"
|
msgstr "Konto löschen"
|
||||||
@@ -342,13 +334,10 @@ msgstr "Link in Lesezeichenleiste ziehen"
|
|||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "E-Mail"
|
msgstr "E-Mail"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "E-mail address"
|
msgid "E-mail address"
|
||||||
msgstr "E-Mail-Adresse"
|
msgstr "E-Mail-Adresse"
|
||||||
@@ -399,7 +388,6 @@ msgstr "Erweiterungsoptionen"
|
|||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
msgstr "Feedname"
|
msgstr "Feedname"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
@@ -570,7 +558,6 @@ msgstr "Abonnements werden geladen..."
|
|||||||
msgid "Loading tags..."
|
msgid "Loading tags..."
|
||||||
msgstr "Tags werden geladen..."
|
msgstr "Tags werden geladen..."
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
@@ -648,7 +635,6 @@ msgstr "Navigieren Sie zu einem Abonnement, indem Sie seinen Namen eingeben"
|
|||||||
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
msgstr "Navigieren Sie zum nächsten Feed/Kategorie mit ungelesenen Einträgen, wenn Sie alle Einträge als gelesen markieren"
|
msgstr "Navigieren Sie zum nächsten Feed/Kategorie mit ungelesenen Einträgen, wenn Sie alle Einträge als gelesen markieren"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "Niemals"
|
msgstr "Niemals"
|
||||||
@@ -657,7 +643,6 @@ msgstr "Niemals"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Neues Passwort"
|
msgstr "Neues Passwort"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "Neues Passwort"
|
msgstr "Neues Passwort"
|
||||||
@@ -764,7 +749,6 @@ msgstr "OPML"
|
|||||||
msgid "OPML export"
|
msgid "OPML export"
|
||||||
msgstr "OPML-Export"
|
msgstr "OPML-Export"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "OPML file"
|
msgid "OPML file"
|
||||||
msgstr "OPML-Datei"
|
msgstr "OPML-Datei"
|
||||||
@@ -791,10 +775,7 @@ msgstr "Übergeordnete Kategorie"
|
|||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Passwort"
|
msgstr "Passwort"
|
||||||
@@ -874,7 +855,6 @@ msgstr "Aktualisieren"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Registrierungen sind für diese CommaFeed-Instanz geschlossen"
|
msgstr "Registrierungen sind für diese CommaFeed-Instanz geschlossen"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "Passwort zurücksetzen"
|
msgstr "Passwort zurücksetzen"
|
||||||
@@ -883,7 +863,6 @@ msgstr "Passwort zurücksetzen"
|
|||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REST-API"
|
msgstr "REST-API"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr "Rechtsklick"
|
msgstr "Rechtsklick"
|
||||||
@@ -910,8 +889,6 @@ msgid "Scrolling"
|
|||||||
msgstr "Scrollen"
|
msgstr "Scrollen"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
#: src/components/sidebar/TreeSearch.tsx
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Suche"
|
msgstr "Suche"
|
||||||
@@ -924,7 +901,6 @@ msgstr "Nächsten ungelesenen Feed/Kategorie auswählen"
|
|||||||
msgid "Select previous unread feed/category"
|
msgid "Select previous unread feed/category"
|
||||||
msgstr "Vorherigen ungelesenen Feed/Kategorie auswählen"
|
msgstr "Vorherigen ungelesenen Feed/Kategorie auswählen"
|
||||||
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
msgid "Server URL"
|
msgid "Server URL"
|
||||||
msgstr "Server-URL"
|
msgstr "Server-URL"
|
||||||
@@ -953,8 +929,6 @@ msgstr "Teilen"
|
|||||||
msgid "Sharing sites"
|
msgid "Sharing sites"
|
||||||
msgstr "Seiten teilen"
|
msgstr "Seiten teilen"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Shift"
|
msgid "Shift"
|
||||||
msgstr "Verschiebung"
|
msgstr "Verschiebung"
|
||||||
@@ -1003,7 +977,6 @@ msgstr "Anzahl ungelesener Nachrichten im Tab-Favicon anzeigen"
|
|||||||
msgid "Show unread count in tab title"
|
msgid "Show unread count in tab title"
|
||||||
msgstr "Anzahl ungelesener Nachrichten im Tab-Titel anzeigen"
|
msgstr "Anzahl ungelesener Nachrichten im Tab-Titel anzeigen"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
@@ -1013,7 +986,6 @@ msgstr "Melden Sie sich an"
|
|||||||
msgid "Something bad just happened..."
|
msgid "Something bad just happened..."
|
||||||
msgstr "Etwas Schlimmes ist gerade passiert..."
|
msgstr "Etwas Schlimmes ist gerade passiert..."
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Space"
|
msgid "Space"
|
||||||
msgstr "Raum"
|
msgstr "Raum"
|
||||||
@@ -1030,7 +1002,6 @@ msgstr "Stern"
|
|||||||
msgid "Starred"
|
msgid "Starred"
|
||||||
msgstr "Markiert"
|
msgstr "Markiert"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AddPage.tsx
|
#: src/pages/app/AddPage.tsx
|
||||||
msgid "Subscribe"
|
msgid "Subscribe"
|
||||||
@@ -1064,7 +1035,6 @@ msgstr "Zum Lightmode wechseln"
|
|||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "System"
|
msgstr "System"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Tags"
|
msgstr "Tags"
|
||||||
@@ -1136,7 +1106,6 @@ msgstr "Ungelesen"
|
|||||||
msgid "Unstar"
|
msgid "Unstar"
|
||||||
msgstr "Stern entfernen"
|
msgstr "Stern entfernen"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Abbestellen"
|
msgstr "Abbestellen"
|
||||||
@@ -1149,7 +1118,6 @@ msgstr "Benutzerschlüssel"
|
|||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Benutzername"
|
msgstr "Benutzername"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "User Name or E-mail"
|
msgid "User Name or E-mail"
|
||||||
msgstr "Benutzername oder E-Mail"
|
msgstr "Benutzername oder E-Mail"
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ msgstr "Add user"
|
|||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "Admin"
|
msgstr "Admin"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr "Admin user name"
|
msgstr "Admin user name"
|
||||||
@@ -73,7 +72,6 @@ msgstr "Admin user name"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "All"
|
msgstr "All"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Always"
|
msgid "Always"
|
||||||
msgstr "Always"
|
msgstr "Always"
|
||||||
@@ -173,18 +171,14 @@ msgstr "Build a filter expression to indicate what you want to read. Entries tha
|
|||||||
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
#: src/pages/app/TagDetailsPage.tsx
|
#: src/pages/app/TagDetailsPage.tsx
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Cancel"
|
msgstr "Cancel"
|
||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -240,7 +234,6 @@ msgstr "Confirm"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Confirm password"
|
msgstr "Confirm password"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "Confirm Password"
|
msgstr "Confirm Password"
|
||||||
@@ -294,7 +287,6 @@ msgstr "days"
|
|||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Delete"
|
msgstr "Delete"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Delete account"
|
msgid "Delete account"
|
||||||
msgstr "Delete account"
|
msgstr "Delete account"
|
||||||
@@ -342,13 +334,10 @@ msgstr "Drag link to bookmark bar"
|
|||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "E-mail"
|
msgstr "E-mail"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "E-mail address"
|
msgid "E-mail address"
|
||||||
msgstr "E-mail address"
|
msgstr "E-mail address"
|
||||||
@@ -399,7 +388,6 @@ msgstr "Extension options"
|
|||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
msgstr "Feed name"
|
msgstr "Feed name"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
@@ -570,7 +558,6 @@ msgstr "Loading subscriptions..."
|
|||||||
msgid "Loading tags..."
|
msgid "Loading tags..."
|
||||||
msgstr "Loading tags..."
|
msgstr "Loading tags..."
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
@@ -648,7 +635,6 @@ msgstr "Navigate to a subscription by entering its name"
|
|||||||
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
msgstr "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgstr "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "Never"
|
msgstr "Never"
|
||||||
@@ -657,7 +643,6 @@ msgstr "Never"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "New password"
|
msgstr "New password"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "New Password"
|
msgstr "New Password"
|
||||||
@@ -764,7 +749,6 @@ msgstr "OPML"
|
|||||||
msgid "OPML export"
|
msgid "OPML export"
|
||||||
msgstr "OPML export"
|
msgstr "OPML export"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "OPML file"
|
msgid "OPML file"
|
||||||
msgstr "OPML file"
|
msgstr "OPML file"
|
||||||
@@ -791,10 +775,7 @@ msgstr "Parent Category"
|
|||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Password"
|
msgstr "Password"
|
||||||
@@ -874,7 +855,6 @@ msgstr "Refresh"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Registrations are closed on this CommaFeed instance"
|
msgstr "Registrations are closed on this CommaFeed instance"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "Reset Password"
|
msgstr "Reset Password"
|
||||||
@@ -883,7 +863,6 @@ msgstr "Reset Password"
|
|||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REST API"
|
msgstr "REST API"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr "Right click"
|
msgstr "Right click"
|
||||||
@@ -910,8 +889,6 @@ msgid "Scrolling"
|
|||||||
msgstr "Scrolling"
|
msgstr "Scrolling"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
#: src/components/sidebar/TreeSearch.tsx
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Search"
|
msgstr "Search"
|
||||||
@@ -924,7 +901,6 @@ msgstr "Select next unread feed/category"
|
|||||||
msgid "Select previous unread feed/category"
|
msgid "Select previous unread feed/category"
|
||||||
msgstr "Select previous unread feed/category"
|
msgstr "Select previous unread feed/category"
|
||||||
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
msgid "Server URL"
|
msgid "Server URL"
|
||||||
msgstr "Server URL"
|
msgstr "Server URL"
|
||||||
@@ -953,8 +929,6 @@ msgstr "Share"
|
|||||||
msgid "Sharing sites"
|
msgid "Sharing sites"
|
||||||
msgstr "Sharing sites"
|
msgstr "Sharing sites"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Shift"
|
msgid "Shift"
|
||||||
msgstr "Shift"
|
msgstr "Shift"
|
||||||
@@ -1003,7 +977,6 @@ msgstr "Show unread count in tab favicon"
|
|||||||
msgid "Show unread count in tab title"
|
msgid "Show unread count in tab title"
|
||||||
msgstr "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/auth/RegistrationPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
@@ -1013,7 +986,6 @@ msgstr "Sign up"
|
|||||||
msgid "Something bad just happened..."
|
msgid "Something bad just happened..."
|
||||||
msgstr "Something bad just happened..."
|
msgstr "Something bad just happened..."
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Space"
|
msgid "Space"
|
||||||
msgstr "Space"
|
msgstr "Space"
|
||||||
@@ -1030,7 +1002,6 @@ msgstr "Star"
|
|||||||
msgid "Starred"
|
msgid "Starred"
|
||||||
msgstr "Starred"
|
msgstr "Starred"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AddPage.tsx
|
#: src/pages/app/AddPage.tsx
|
||||||
msgid "Subscribe"
|
msgid "Subscribe"
|
||||||
@@ -1064,7 +1035,6 @@ msgstr "Switch to light theme"
|
|||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "System"
|
msgstr "System"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Tags"
|
msgstr "Tags"
|
||||||
@@ -1136,7 +1106,6 @@ msgstr "Unread"
|
|||||||
msgid "Unstar"
|
msgid "Unstar"
|
||||||
msgstr "Unstar"
|
msgstr "Unstar"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Unsubscribe"
|
msgstr "Unsubscribe"
|
||||||
@@ -1149,7 +1118,6 @@ msgstr "User key"
|
|||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "User name"
|
msgstr "User name"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "User Name or E-mail"
|
msgid "User Name or E-mail"
|
||||||
msgstr "User Name or E-mail"
|
msgstr "User Name or E-mail"
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ msgstr "Añadir usuario"
|
|||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "Administrador"
|
msgstr "Administrador"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr "Nombre de usuario administrador"
|
msgstr "Nombre de usuario administrador"
|
||||||
@@ -74,7 +73,6 @@ msgstr "Nombre de usuario administrador"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Todo"
|
msgstr "Todo"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Always"
|
msgid "Always"
|
||||||
msgstr "Siempre"
|
msgstr "Siempre"
|
||||||
@@ -174,18 +172,14 @@ msgstr "Crea una expresión de filtrado para indicar lo que quieres leer. Las en
|
|||||||
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
#: src/pages/app/TagDetailsPage.tsx
|
#: src/pages/app/TagDetailsPage.tsx
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Cancelar"
|
msgstr "Cancelar"
|
||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -241,7 +235,6 @@ msgstr "Confirmar"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Confirmar contraseña"
|
msgstr "Confirmar contraseña"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "Confirmar contraseña"
|
msgstr "Confirmar contraseña"
|
||||||
@@ -295,7 +288,6 @@ msgstr "días"
|
|||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Borrar"
|
msgstr "Borrar"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Delete account"
|
msgid "Delete account"
|
||||||
msgstr "Borrar cuenta"
|
msgstr "Borrar cuenta"
|
||||||
@@ -343,13 +335,10 @@ msgstr "Arrastra el enlace a la barra de marcadores"
|
|||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "Correo electrónico"
|
msgstr "Correo electrónico"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "E-mail address"
|
msgid "E-mail address"
|
||||||
msgstr "Dirección de correo electrónico"
|
msgstr "Dirección de correo electrónico"
|
||||||
@@ -400,7 +389,6 @@ msgstr "Opciones de la extensión"
|
|||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
msgstr "Nombre del feed"
|
msgstr "Nombre del feed"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
@@ -571,7 +559,6 @@ msgstr "Cargando suscripciones..."
|
|||||||
msgid "Loading tags..."
|
msgid "Loading tags..."
|
||||||
msgstr "Cargando etiquetas..."
|
msgstr "Cargando etiquetas..."
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
@@ -649,7 +636,6 @@ msgstr "Navegar a una suscripción introduciendo su nombre"
|
|||||||
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
msgstr "Navegar a la siguiente categoría/feed con entradas no leídas al marcar todas como leídas"
|
msgstr "Navegar a la siguiente categoría/feed con entradas no leídas al marcar todas como leídas"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "Nunca"
|
msgstr "Nunca"
|
||||||
@@ -658,7 +644,6 @@ msgstr "Nunca"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Nueva contraseña"
|
msgstr "Nueva contraseña"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "Nueva contraseña"
|
msgstr "Nueva contraseña"
|
||||||
@@ -765,7 +750,6 @@ msgstr "OPML"
|
|||||||
msgid "OPML export"
|
msgid "OPML export"
|
||||||
msgstr "Exportar OPML"
|
msgstr "Exportar OPML"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "OPML file"
|
msgid "OPML file"
|
||||||
msgstr "Archivo OPML"
|
msgstr "Archivo OPML"
|
||||||
@@ -792,10 +776,7 @@ msgstr "Categoría principal"
|
|||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Contraseña"
|
msgstr "Contraseña"
|
||||||
@@ -875,7 +856,6 @@ msgstr "Actualizar"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Los registros están cerrados en esta instancia de CommaFeed"
|
msgstr "Los registros están cerrados en esta instancia de CommaFeed"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "Restablecer contraseña"
|
msgstr "Restablecer contraseña"
|
||||||
@@ -884,7 +864,6 @@ msgstr "Restablecer contraseña"
|
|||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "API REST"
|
msgstr "API REST"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr "Clic derecho"
|
msgstr "Clic derecho"
|
||||||
@@ -911,8 +890,6 @@ msgid "Scrolling"
|
|||||||
msgstr "Desplazarse"
|
msgstr "Desplazarse"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
#: src/components/sidebar/TreeSearch.tsx
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Buscar"
|
msgstr "Buscar"
|
||||||
@@ -925,7 +902,6 @@ msgstr "Seleccionar el siguiente feed/categoría no leído"
|
|||||||
msgid "Select previous unread feed/category"
|
msgid "Select previous unread feed/category"
|
||||||
msgstr "Seleccionar el anterior feed/categoría no leído"
|
msgstr "Seleccionar el anterior feed/categoría no leído"
|
||||||
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
msgid "Server URL"
|
msgid "Server URL"
|
||||||
msgstr "URL del servidor"
|
msgstr "URL del servidor"
|
||||||
@@ -954,8 +930,6 @@ msgstr "Compartir"
|
|||||||
msgid "Sharing sites"
|
msgid "Sharing sites"
|
||||||
msgstr "Compartir sitios"
|
msgstr "Compartir sitios"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Shift"
|
msgid "Shift"
|
||||||
msgstr "Shift"
|
msgstr "Shift"
|
||||||
@@ -1004,7 +978,6 @@ msgstr "Mostrar recuento de no leídos en la pestaña favicon"
|
|||||||
msgid "Show unread count in tab title"
|
msgid "Show unread count in tab title"
|
||||||
msgstr "Mostrar recuento de no leídos en el título de la pestaña"
|
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
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
@@ -1014,7 +987,6 @@ msgstr "Registrarse"
|
|||||||
msgid "Something bad just happened..."
|
msgid "Something bad just happened..."
|
||||||
msgstr "Algo malo acaba de pasar..."
|
msgstr "Algo malo acaba de pasar..."
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Space"
|
msgid "Space"
|
||||||
msgstr "Espacio"
|
msgstr "Espacio"
|
||||||
@@ -1031,7 +1003,6 @@ msgstr "Estrella"
|
|||||||
msgid "Starred"
|
msgid "Starred"
|
||||||
msgstr "Destacado"
|
msgstr "Destacado"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AddPage.tsx
|
#: src/pages/app/AddPage.tsx
|
||||||
msgid "Subscribe"
|
msgid "Subscribe"
|
||||||
@@ -1065,7 +1036,6 @@ msgstr "Cambiar a tema claro"
|
|||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "Sistema"
|
msgstr "Sistema"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Etiquetas"
|
msgstr "Etiquetas"
|
||||||
@@ -1137,7 +1107,6 @@ msgstr "No leído"
|
|||||||
msgid "Unstar"
|
msgid "Unstar"
|
||||||
msgstr "Desmarcar"
|
msgstr "Desmarcar"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Cancelar suscripción"
|
msgstr "Cancelar suscripción"
|
||||||
@@ -1150,7 +1119,6 @@ msgstr "Clave de usuario"
|
|||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Nombre de usuario"
|
msgstr "Nombre de usuario"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "User Name or E-mail"
|
msgid "User Name or E-mail"
|
||||||
msgstr "Nombre de usuario o correo electrónico"
|
msgstr "Nombre de usuario o correo electrónico"
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ msgstr "افزودن کاربر"
|
|||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "مدیر"
|
msgstr "مدیر"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr "نام کاربری مدیر"
|
msgstr "نام کاربری مدیر"
|
||||||
@@ -73,7 +72,6 @@ msgstr "نام کاربری مدیر"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "همه"
|
msgstr "همه"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Always"
|
msgid "Always"
|
||||||
msgstr "همیشه"
|
msgstr "همیشه"
|
||||||
@@ -173,18 +171,14 @@ msgstr "یک عبارت فیلتر بسازید تا نشان دهید چه چی
|
|||||||
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
#: src/pages/app/TagDetailsPage.tsx
|
#: src/pages/app/TagDetailsPage.tsx
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "لغو"
|
msgstr "لغو"
|
||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -240,7 +234,6 @@ msgstr "تأیید کنید"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "رمز عبور را تأیید کنید"
|
msgstr "رمز عبور را تأیید کنید"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "تأیید رمز عبور"
|
msgstr "تأیید رمز عبور"
|
||||||
@@ -294,7 +287,6 @@ msgstr "روز"
|
|||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "حذف کنید"
|
msgstr "حذف کنید"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Delete account"
|
msgid "Delete account"
|
||||||
msgstr "حذف حساب"
|
msgstr "حذف حساب"
|
||||||
@@ -342,13 +334,10 @@ msgstr "پیوند را به نوار نشانک بکشید"
|
|||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "ایمیل"
|
msgstr "ایمیل"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "E-mail address"
|
msgid "E-mail address"
|
||||||
msgstr "آدرس ایمیل"
|
msgstr "آدرس ایمیل"
|
||||||
@@ -399,7 +388,6 @@ msgstr "گزینه های افزونه"
|
|||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
msgstr "نام فید"
|
msgstr "نام فید"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
@@ -570,7 +558,6 @@ msgstr "بارگیری اشتراک ها..."
|
|||||||
msgid "Loading tags..."
|
msgid "Loading tags..."
|
||||||
msgstr "بارگیری برچسب ها..."
|
msgstr "بارگیری برچسب ها..."
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
@@ -648,7 +635,6 @@ msgstr "با وارد کردن نام اشتراک، به آن بروید"
|
|||||||
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
msgstr "هنگام علامتگذاری همه ورودیها بهعنوان خواندهشده، به دستهبندی/فید بعدی با ورودیهای خواندهنشده بروید"
|
msgstr "هنگام علامتگذاری همه ورودیها بهعنوان خواندهشده، به دستهبندی/فید بعدی با ورودیهای خواندهنشده بروید"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "هرگز"
|
msgstr "هرگز"
|
||||||
@@ -657,7 +643,6 @@ msgstr "هرگز"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "رمز عبور جدید"
|
msgstr "رمز عبور جدید"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "رمز عبور جدید"
|
msgstr "رمز عبور جدید"
|
||||||
@@ -764,7 +749,6 @@ msgstr "OPML"
|
|||||||
msgid "OPML export"
|
msgid "OPML export"
|
||||||
msgstr "خروجی OPML"
|
msgstr "خروجی OPML"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "OPML file"
|
msgid "OPML file"
|
||||||
msgstr "فایل OPML"
|
msgstr "فایل OPML"
|
||||||
@@ -791,10 +775,7 @@ msgstr "دسته والد"
|
|||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "رمز عبور"
|
msgstr "رمز عبور"
|
||||||
@@ -874,7 +855,6 @@ msgstr "تازه کردن"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "ثبت نام در این نمونه CommaFeed بسته شده است"
|
msgstr "ثبت نام در این نمونه CommaFeed بسته شده است"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "بازنشانی رمز عبور"
|
msgstr "بازنشانی رمز عبور"
|
||||||
@@ -883,7 +863,6 @@ msgstr "بازنشانی رمز عبور"
|
|||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REST API"
|
msgstr "REST API"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr "راست کلیک"
|
msgstr "راست کلیک"
|
||||||
@@ -910,8 +889,6 @@ msgid "Scrolling"
|
|||||||
msgstr "پیمایش"
|
msgstr "پیمایش"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
#: src/components/sidebar/TreeSearch.tsx
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "جستجو"
|
msgstr "جستجو"
|
||||||
@@ -924,7 +901,6 @@ msgstr "انتخاب فید/دسته بعدی خوانده نشده"
|
|||||||
msgid "Select previous unread feed/category"
|
msgid "Select previous unread feed/category"
|
||||||
msgstr "انتخاب فید/دسته قبلی خوانده نشده"
|
msgstr "انتخاب فید/دسته قبلی خوانده نشده"
|
||||||
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
msgid "Server URL"
|
msgid "Server URL"
|
||||||
msgstr "آدرس سرور"
|
msgstr "آدرس سرور"
|
||||||
@@ -953,8 +929,6 @@ msgstr "به اشتراک بگذارید"
|
|||||||
msgid "Sharing sites"
|
msgid "Sharing sites"
|
||||||
msgstr "اشتراک گذاری سایت ها"
|
msgstr "اشتراک گذاری سایت ها"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Shift"
|
msgid "Shift"
|
||||||
msgstr "شیفت"
|
msgstr "شیفت"
|
||||||
@@ -1003,7 +977,6 @@ msgstr "نمایش تعداد خوانده نشده در فاویکون زبان
|
|||||||
msgid "Show unread count in tab title"
|
msgid "Show unread count in tab title"
|
||||||
msgstr "نمایش تعداد خوانده نشده در عنوان زبانه"
|
msgstr "نمایش تعداد خوانده نشده در عنوان زبانه"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
@@ -1013,7 +986,6 @@ msgstr "ثبت نام کنید"
|
|||||||
msgid "Something bad just happened..."
|
msgid "Something bad just happened..."
|
||||||
msgstr "اتفاق بدی افتاد..."
|
msgstr "اتفاق بدی افتاد..."
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Space"
|
msgid "Space"
|
||||||
msgstr "فضا"
|
msgstr "فضا"
|
||||||
@@ -1030,7 +1002,6 @@ msgstr "ستاره"
|
|||||||
msgid "Starred"
|
msgid "Starred"
|
||||||
msgstr "ستاره دار"
|
msgstr "ستاره دار"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AddPage.tsx
|
#: src/pages/app/AddPage.tsx
|
||||||
msgid "Subscribe"
|
msgid "Subscribe"
|
||||||
@@ -1064,7 +1035,6 @@ msgstr "تغییر به تم روشن"
|
|||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "سیستم"
|
msgstr "سیستم"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "برچسبها"
|
msgstr "برچسبها"
|
||||||
@@ -1136,7 +1106,6 @@ msgstr "خوانده نشده"
|
|||||||
msgid "Unstar"
|
msgid "Unstar"
|
||||||
msgstr "برداشتن ستاره"
|
msgstr "برداشتن ستاره"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "لغو اشتراک"
|
msgstr "لغو اشتراک"
|
||||||
@@ -1149,7 +1118,6 @@ msgstr "کلید کاربر"
|
|||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "نام کاربری"
|
msgstr "نام کاربری"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "User Name or E-mail"
|
msgid "User Name or E-mail"
|
||||||
msgstr "نام کاربری یا ایمیل"
|
msgstr "نام کاربری یا ایمیل"
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ msgstr "Lisää käyttäjä"
|
|||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "Järjestelmänvalvoja"
|
msgstr "Järjestelmänvalvoja"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr "Järjestelmänvalvojan käyttäjänimi"
|
msgstr "Järjestelmänvalvojan käyttäjänimi"
|
||||||
@@ -73,7 +72,6 @@ msgstr "Järjestelmänvalvojan käyttäjänimi"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Kaikki"
|
msgstr "Kaikki"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Always"
|
msgid "Always"
|
||||||
msgstr "Aina"
|
msgstr "Aina"
|
||||||
@@ -173,18 +171,14 @@ msgstr "Rakenna suodatinlauseke määrittääksesi, mitä haluat lukea. Merkinn
|
|||||||
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
#: src/pages/app/TagDetailsPage.tsx
|
#: src/pages/app/TagDetailsPage.tsx
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Peruuta"
|
msgstr "Peruuta"
|
||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -240,7 +234,6 @@ msgstr "Vahvista"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Vahvista salasana"
|
msgstr "Vahvista salasana"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "Vahvista salasana"
|
msgstr "Vahvista salasana"
|
||||||
@@ -294,7 +287,6 @@ msgstr "päivää"
|
|||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Poista"
|
msgstr "Poista"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Delete account"
|
msgid "Delete account"
|
||||||
msgstr "Poista tili"
|
msgstr "Poista tili"
|
||||||
@@ -342,13 +334,10 @@ msgstr "Vedä linkki kirjanmerkkipalkkiin"
|
|||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "Sähköposti"
|
msgstr "Sähköposti"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "E-mail address"
|
msgid "E-mail address"
|
||||||
msgstr "Sähköpostiosoite"
|
msgstr "Sähköpostiosoite"
|
||||||
@@ -399,7 +388,6 @@ msgstr "Laajennuksen asetukset"
|
|||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
msgstr "Syötteen nimi"
|
msgstr "Syötteen nimi"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
@@ -570,7 +558,6 @@ msgstr "Ladataan tilauksia..."
|
|||||||
msgid "Loading tags..."
|
msgid "Loading tags..."
|
||||||
msgstr "Ladataan tunnisteita..."
|
msgstr "Ladataan tunnisteita..."
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
@@ -648,7 +635,6 @@ msgstr "Siirry tilaukseen kirjoittamalla sen nimi"
|
|||||||
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
msgstr "Siirry seuraavaan luokkaan/syötteeseen, jossa on lukemattomia merkintöjä, kun kaikki merkinnät merkitään luetuiksi"
|
msgstr "Siirry seuraavaan luokkaan/syötteeseen, jossa on lukemattomia merkintöjä, kun kaikki merkinnät merkitään luetuiksi"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "Ei koskaan"
|
msgstr "Ei koskaan"
|
||||||
@@ -657,7 +643,6 @@ msgstr "Ei koskaan"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Uusi salasana"
|
msgstr "Uusi salasana"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "Uusi salasana"
|
msgstr "Uusi salasana"
|
||||||
@@ -764,7 +749,6 @@ msgstr "OPML"
|
|||||||
msgid "OPML export"
|
msgid "OPML export"
|
||||||
msgstr "OPML-vienti"
|
msgstr "OPML-vienti"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "OPML file"
|
msgid "OPML file"
|
||||||
msgstr "OPML-tiedosto"
|
msgstr "OPML-tiedosto"
|
||||||
@@ -791,10 +775,7 @@ msgstr "Pääluokka"
|
|||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Salasana"
|
msgstr "Salasana"
|
||||||
@@ -874,7 +855,6 @@ msgstr "Päivitä"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Tämän CommaFeed-esiintymän rekisteröinnit on suljettu"
|
msgstr "Tämän CommaFeed-esiintymän rekisteröinnit on suljettu"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "Nollaa salasana"
|
msgstr "Nollaa salasana"
|
||||||
@@ -883,7 +863,6 @@ msgstr "Nollaa salasana"
|
|||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REST-API"
|
msgstr "REST-API"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr "Oikea napsautus"
|
msgstr "Oikea napsautus"
|
||||||
@@ -910,8 +889,6 @@ msgid "Scrolling"
|
|||||||
msgstr "Vieritys"
|
msgstr "Vieritys"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
#: src/components/sidebar/TreeSearch.tsx
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Etsi"
|
msgstr "Etsi"
|
||||||
@@ -924,7 +901,6 @@ msgstr "Valitse seuraava lukematon syöte/luokka"
|
|||||||
msgid "Select previous unread feed/category"
|
msgid "Select previous unread feed/category"
|
||||||
msgstr "Valitse edellinen lukematon syöte/luokka"
|
msgstr "Valitse edellinen lukematon syöte/luokka"
|
||||||
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
msgid "Server URL"
|
msgid "Server URL"
|
||||||
msgstr "Palvelimen URL-osoite"
|
msgstr "Palvelimen URL-osoite"
|
||||||
@@ -953,8 +929,6 @@ msgstr "Jaa"
|
|||||||
msgid "Sharing sites"
|
msgid "Sharing sites"
|
||||||
msgstr "Sivustojen jakaminen"
|
msgstr "Sivustojen jakaminen"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Shift"
|
msgid "Shift"
|
||||||
msgstr "Vaihto"
|
msgstr "Vaihto"
|
||||||
@@ -1003,7 +977,6 @@ msgstr "Näytä lukemattomien määrä välilehden kuvakkeessa"
|
|||||||
msgid "Show unread count in tab title"
|
msgid "Show unread count in tab title"
|
||||||
msgstr "Näytä lukemattomien määrä välilehden otsikossa"
|
msgstr "Näytä lukemattomien määrä välilehden otsikossa"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
@@ -1013,7 +986,6 @@ msgstr "Rekisteröidy"
|
|||||||
msgid "Something bad just happened..."
|
msgid "Something bad just happened..."
|
||||||
msgstr "Jotain pahaa tapahtui juuri..."
|
msgstr "Jotain pahaa tapahtui juuri..."
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Space"
|
msgid "Space"
|
||||||
msgstr "Avaruus"
|
msgstr "Avaruus"
|
||||||
@@ -1030,7 +1002,6 @@ msgstr "Tähti"
|
|||||||
msgid "Starred"
|
msgid "Starred"
|
||||||
msgstr "Tähdellä merkitty"
|
msgstr "Tähdellä merkitty"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AddPage.tsx
|
#: src/pages/app/AddPage.tsx
|
||||||
msgid "Subscribe"
|
msgid "Subscribe"
|
||||||
@@ -1064,7 +1035,6 @@ msgstr "Vaihda vaaleaan teemaan"
|
|||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "Järjestelmä"
|
msgstr "Järjestelmä"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Tunnisteet"
|
msgstr "Tunnisteet"
|
||||||
@@ -1136,7 +1106,6 @@ msgstr "Lukematon"
|
|||||||
msgid "Unstar"
|
msgid "Unstar"
|
||||||
msgstr "Poista tähti"
|
msgstr "Poista tähti"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Peruuta tilaus"
|
msgstr "Peruuta tilaus"
|
||||||
@@ -1149,7 +1118,6 @@ msgstr "Käyttäjäavain"
|
|||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Käyttäjänimi"
|
msgstr "Käyttäjänimi"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "User Name or E-mail"
|
msgid "User Name or E-mail"
|
||||||
msgstr "Käyttäjänimi tai sähköpostiosoite"
|
msgstr "Käyttäjänimi tai sähköpostiosoite"
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ msgstr "Ajouter un utilisateur"
|
|||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "Administrateur"
|
msgstr "Administrateur"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr "Nom de l'administrateur"
|
msgstr "Nom de l'administrateur"
|
||||||
@@ -73,7 +72,6 @@ msgstr "Nom de l'administrateur"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Tout"
|
msgstr "Tout"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Always"
|
msgid "Always"
|
||||||
msgstr "Toujours"
|
msgstr "Toujours"
|
||||||
@@ -173,18 +171,14 @@ msgstr "Créez une expression régulière pour filtrer ce que vous voulez lire.
|
|||||||
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
#: src/pages/app/TagDetailsPage.tsx
|
#: src/pages/app/TagDetailsPage.tsx
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Annuler"
|
msgstr "Annuler"
|
||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -240,7 +234,6 @@ msgstr "Confirmer"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Confirmer le mot de passe"
|
msgstr "Confirmer le mot de passe"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "Confirmer le mot de passe"
|
msgstr "Confirmer le mot de passe"
|
||||||
@@ -294,7 +287,6 @@ msgstr "jours"
|
|||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Effacer"
|
msgstr "Effacer"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Delete account"
|
msgid "Delete account"
|
||||||
msgstr "Effacer le compte"
|
msgstr "Effacer le compte"
|
||||||
@@ -342,13 +334,10 @@ msgstr "Déplacez le lien vers la barre de favoris"
|
|||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "E-mail"
|
msgstr "E-mail"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "E-mail address"
|
msgid "E-mail address"
|
||||||
msgstr "Adresse e-mail"
|
msgstr "Adresse e-mail"
|
||||||
@@ -399,7 +388,6 @@ msgstr "Options de l'extension"
|
|||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
msgstr "Nom du flux"
|
msgstr "Nom du flux"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
@@ -570,7 +558,6 @@ msgstr "Chargement des abonnements..."
|
|||||||
msgid "Loading tags..."
|
msgid "Loading tags..."
|
||||||
msgstr "Chargement des marqueurs..."
|
msgstr "Chargement des marqueurs..."
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
@@ -648,7 +635,6 @@ msgstr "Naviguer vers un abonnement en entrant son nom"
|
|||||||
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
msgstr "Aller vers la catégorie/le flux comportant des entrées non lues suivant après avoir marqué toutes les entrées lues"
|
msgstr "Aller vers la catégorie/le flux comportant des entrées non lues suivant après avoir marqué toutes les entrées lues"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "Jamais"
|
msgstr "Jamais"
|
||||||
@@ -657,7 +643,6 @@ msgstr "Jamais"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Nouveau mot de passe"
|
msgstr "Nouveau mot de passe"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "Nouveau mot de passe"
|
msgstr "Nouveau mot de passe"
|
||||||
@@ -764,7 +749,6 @@ msgstr "OPML"
|
|||||||
msgid "OPML export"
|
msgid "OPML export"
|
||||||
msgstr "Export du fichier OPML"
|
msgstr "Export du fichier OPML"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "OPML file"
|
msgid "OPML file"
|
||||||
msgstr "Fichier OPML"
|
msgstr "Fichier OPML"
|
||||||
@@ -791,10 +775,7 @@ msgstr "Catégorie parente"
|
|||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Mot de passe"
|
msgstr "Mot de passe"
|
||||||
@@ -874,7 +855,6 @@ msgstr "Rafraîchir"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Les inscriptions sont fermées sur cette instance de CommaFeed"
|
msgstr "Les inscriptions sont fermées sur cette instance de CommaFeed"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "Réinitialiser le mot de passe"
|
msgstr "Réinitialiser le mot de passe"
|
||||||
@@ -883,7 +863,6 @@ msgstr "Réinitialiser le mot de passe"
|
|||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "API REST"
|
msgstr "API REST"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr "Clic droit"
|
msgstr "Clic droit"
|
||||||
@@ -910,8 +889,6 @@ msgid "Scrolling"
|
|||||||
msgstr "Défilement"
|
msgstr "Défilement"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
#: src/components/sidebar/TreeSearch.tsx
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Rechercher"
|
msgstr "Rechercher"
|
||||||
@@ -924,7 +901,6 @@ msgstr "Sélectionner l'article non lu suivant/la catégorie non lue suivante"
|
|||||||
msgid "Select previous unread feed/category"
|
msgid "Select previous unread feed/category"
|
||||||
msgstr "Sélectionner l'article non lu précédent/la catégorie non lue précédente"
|
msgstr "Sélectionner l'article non lu précédent/la catégorie non lue précédente"
|
||||||
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
msgid "Server URL"
|
msgid "Server URL"
|
||||||
msgstr "URL du serveur"
|
msgstr "URL du serveur"
|
||||||
@@ -953,8 +929,6 @@ msgstr "Partager"
|
|||||||
msgid "Sharing sites"
|
msgid "Sharing sites"
|
||||||
msgstr "Sites de partage"
|
msgstr "Sites de partage"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Shift"
|
msgid "Shift"
|
||||||
msgstr "Maj"
|
msgstr "Maj"
|
||||||
@@ -1003,7 +977,6 @@ msgstr "Afficher le nombre d'entrées non lues dans la favicône de l'onglet"
|
|||||||
msgid "Show unread count in tab title"
|
msgid "Show unread count in tab title"
|
||||||
msgstr "Afficher le nombre d'entrées non lues dans le titre de l'onglet"
|
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
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
@@ -1013,7 +986,6 @@ msgstr "Créer un compte"
|
|||||||
msgid "Something bad just happened..."
|
msgid "Something bad just happened..."
|
||||||
msgstr "Quelque chose s'est mal passé..."
|
msgstr "Quelque chose s'est mal passé..."
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Space"
|
msgid "Space"
|
||||||
msgstr "Espace"
|
msgstr "Espace"
|
||||||
@@ -1030,7 +1002,6 @@ msgstr "Ajouter aux favoris"
|
|||||||
msgid "Starred"
|
msgid "Starred"
|
||||||
msgstr "Favoris"
|
msgstr "Favoris"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AddPage.tsx
|
#: src/pages/app/AddPage.tsx
|
||||||
msgid "Subscribe"
|
msgid "Subscribe"
|
||||||
@@ -1064,7 +1035,6 @@ msgstr "Activer le mode clair"
|
|||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "Système"
|
msgstr "Système"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Marqueurs"
|
msgstr "Marqueurs"
|
||||||
@@ -1136,7 +1106,6 @@ msgstr "Non lu"
|
|||||||
msgid "Unstar"
|
msgid "Unstar"
|
||||||
msgstr "Retirer des favoris"
|
msgstr "Retirer des favoris"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Se désabonner"
|
msgstr "Se désabonner"
|
||||||
@@ -1149,7 +1118,6 @@ msgstr "Clé utilisateur"
|
|||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Nom"
|
msgstr "Nom"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "User Name or E-mail"
|
msgid "User Name or E-mail"
|
||||||
msgstr "Nom d'utilisateur ou e-mail"
|
msgstr "Nom d'utilisateur ou e-mail"
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ msgstr "Engadir persoa usuaria"
|
|||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "Administración"
|
msgstr "Administración"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr "Identificador de admin"
|
msgstr "Identificador de admin"
|
||||||
@@ -74,7 +73,6 @@ msgstr "Identificador de admin"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Todos"
|
msgstr "Todos"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Always"
|
msgid "Always"
|
||||||
msgstr "Sempre"
|
msgstr "Sempre"
|
||||||
@@ -174,18 +172,14 @@ msgstr "Crea unha expresión de filtrado para indicar o que queres ler. Os artig
|
|||||||
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
#: src/pages/app/TagDetailsPage.tsx
|
#: src/pages/app/TagDetailsPage.tsx
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Cancelar"
|
msgstr "Cancelar"
|
||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -241,7 +235,6 @@ msgstr "Confirmar"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Confirmar contrasinal"
|
msgstr "Confirmar contrasinal"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "Confirmar contrasinal"
|
msgstr "Confirmar contrasinal"
|
||||||
@@ -295,7 +288,6 @@ msgstr "días"
|
|||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Eliminar"
|
msgstr "Eliminar"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Delete account"
|
msgid "Delete account"
|
||||||
msgstr "Eliminar conta"
|
msgstr "Eliminar conta"
|
||||||
@@ -343,13 +335,10 @@ msgstr "Arrastra a ligazón á barra de marcadores"
|
|||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "Correo electrónico"
|
msgstr "Correo electrónico"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "E-mail address"
|
msgid "E-mail address"
|
||||||
msgstr "Enderezo de correo electrónico"
|
msgstr "Enderezo de correo electrónico"
|
||||||
@@ -400,7 +389,6 @@ msgstr "Opcións do complemento"
|
|||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
msgstr "Nome da canle"
|
msgstr "Nome da canle"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
@@ -571,7 +559,6 @@ msgstr "Cargando subscricións..."
|
|||||||
msgid "Loading tags..."
|
msgid "Loading tags..."
|
||||||
msgstr "Cargando etiquetas..."
|
msgstr "Cargando etiquetas..."
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
@@ -649,7 +636,6 @@ msgstr "Vai a unha subscrición ao escribir o seu nome"
|
|||||||
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
msgstr "Vai á seguinte categoría/canle con artigos sen ler cando marques todos artigos como lidos"
|
msgstr "Vai á seguinte categoría/canle con artigos sen ler cando marques todos artigos como lidos"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "Nunca"
|
msgstr "Nunca"
|
||||||
@@ -658,7 +644,6 @@ msgstr "Nunca"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Novo contrasinal"
|
msgstr "Novo contrasinal"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "Novo contrasinal"
|
msgstr "Novo contrasinal"
|
||||||
@@ -765,7 +750,6 @@ msgstr "OPML"
|
|||||||
msgid "OPML export"
|
msgid "OPML export"
|
||||||
msgstr "Exportación OPML"
|
msgstr "Exportación OPML"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "OPML file"
|
msgid "OPML file"
|
||||||
msgstr "Ficheiro OPML"
|
msgstr "Ficheiro OPML"
|
||||||
@@ -792,10 +776,7 @@ msgstr "Categoría superior"
|
|||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Contrasinal"
|
msgstr "Contrasinal"
|
||||||
@@ -875,7 +856,6 @@ msgstr "Actualizar"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Non se admiten novas contas nesta instancia de CommaFeed"
|
msgstr "Non se admiten novas contas nesta instancia de CommaFeed"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "Restablecer contrasinal"
|
msgstr "Restablecer contrasinal"
|
||||||
@@ -884,7 +864,6 @@ msgstr "Restablecer contrasinal"
|
|||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "API REST"
|
msgstr "API REST"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr "Botón dereito"
|
msgstr "Botón dereito"
|
||||||
@@ -911,8 +890,6 @@ msgid "Scrolling"
|
|||||||
msgstr "Desprazamento"
|
msgstr "Desprazamento"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
#: src/components/sidebar/TreeSearch.tsx
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Busca"
|
msgstr "Busca"
|
||||||
@@ -925,7 +902,6 @@ msgstr "Seleccionar a seguinte canle/categoría sen ler"
|
|||||||
msgid "Select previous unread feed/category"
|
msgid "Select previous unread feed/category"
|
||||||
msgstr "Seleccionar a canle/categoría anterior sen ler"
|
msgstr "Seleccionar a canle/categoría anterior sen ler"
|
||||||
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
msgid "Server URL"
|
msgid "Server URL"
|
||||||
msgstr "URL do servidor"
|
msgstr "URL do servidor"
|
||||||
@@ -954,8 +930,6 @@ msgstr "Compartir"
|
|||||||
msgid "Sharing sites"
|
msgid "Sharing sites"
|
||||||
msgstr "Servizos para compartir"
|
msgstr "Servizos para compartir"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Shift"
|
msgid "Shift"
|
||||||
msgstr "Maiúsculas"
|
msgstr "Maiúsculas"
|
||||||
@@ -1004,7 +978,6 @@ msgstr "Mostrar a conta de artigos sen ler na icona da pestana"
|
|||||||
msgid "Show unread count in tab title"
|
msgid "Show unread count in tab title"
|
||||||
msgstr "Mostar a conta de artigos sen ler no título da pestana"
|
msgstr "Mostar a conta de artigos sen ler no título da pestana"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
@@ -1014,7 +987,6 @@ msgstr "Crear conta"
|
|||||||
msgid "Something bad just happened..."
|
msgid "Something bad just happened..."
|
||||||
msgstr "Algo malo pasou..."
|
msgstr "Algo malo pasou..."
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Space"
|
msgid "Space"
|
||||||
msgstr "Espazo"
|
msgstr "Espazo"
|
||||||
@@ -1031,7 +1003,6 @@ msgstr "Pór estrela"
|
|||||||
msgid "Starred"
|
msgid "Starred"
|
||||||
msgstr "Con estrela"
|
msgstr "Con estrela"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AddPage.tsx
|
#: src/pages/app/AddPage.tsx
|
||||||
msgid "Subscribe"
|
msgid "Subscribe"
|
||||||
@@ -1065,7 +1036,6 @@ msgstr "Cambiar ao decorado claro"
|
|||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "Sistema"
|
msgstr "Sistema"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Etiquetas"
|
msgstr "Etiquetas"
|
||||||
@@ -1137,7 +1107,6 @@ msgstr "Sen ler"
|
|||||||
msgid "Unstar"
|
msgid "Unstar"
|
||||||
msgstr "Retirar estrela"
|
msgstr "Retirar estrela"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Cancelar a subscrición"
|
msgstr "Cancelar a subscrición"
|
||||||
@@ -1150,7 +1119,6 @@ msgstr "Clave de usuario"
|
|||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Identificador"
|
msgstr "Identificador"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "User Name or E-mail"
|
msgid "User Name or E-mail"
|
||||||
msgstr "Identificador ou correo electrónico"
|
msgstr "Identificador ou correo electrónico"
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ msgstr "Felhasználó hozzáadása"
|
|||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "Adminisztráció"
|
msgstr "Adminisztráció"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr "Adminisztrátor felhasználóneve"
|
msgstr "Adminisztrátor felhasználóneve"
|
||||||
@@ -73,7 +72,6 @@ msgstr "Adminisztrátor felhasználóneve"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Mind"
|
msgstr "Mind"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Always"
|
msgid "Always"
|
||||||
msgstr "Mindig"
|
msgstr "Mindig"
|
||||||
@@ -173,18 +171,14 @@ msgstr "Hozzon létre egy szűrőkifejezést annak megjelölésére, hogy mit sz
|
|||||||
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
#: src/pages/app/TagDetailsPage.tsx
|
#: src/pages/app/TagDetailsPage.tsx
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Mégse"
|
msgstr "Mégse"
|
||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -240,7 +234,6 @@ msgstr "Erősítse meg"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Erősítse meg a jelszót"
|
msgstr "Erősítse meg a jelszót"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "Jelszó megerősítése"
|
msgstr "Jelszó megerősítése"
|
||||||
@@ -294,7 +287,6 @@ msgstr "nap"
|
|||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Törlés"
|
msgstr "Törlés"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Delete account"
|
msgid "Delete account"
|
||||||
msgstr "Fiók törlése"
|
msgstr "Fiók törlése"
|
||||||
@@ -342,13 +334,10 @@ msgstr "Húzza a hivatkozást a könyvjelzősávra"
|
|||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "E-mail"
|
msgstr "E-mail"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "E-mail address"
|
msgid "E-mail address"
|
||||||
msgstr "E-mail cím"
|
msgstr "E-mail cím"
|
||||||
@@ -399,7 +388,6 @@ msgstr "Bővítmény beállításai"
|
|||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
msgstr "Hírcsatorna neve"
|
msgstr "Hírcsatorna neve"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
@@ -570,7 +558,6 @@ msgstr "Előfizetések betöltése..."
|
|||||||
msgid "Loading tags..."
|
msgid "Loading tags..."
|
||||||
msgstr "Címkék betöltése..."
|
msgstr "Címkék betöltése..."
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
@@ -648,7 +635,6 @@ msgstr "Navigáljon egy előfizetéshez a nevének megadásával"
|
|||||||
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
msgstr "Navigálás a következő olvasatlan bejegyzéseket tartalmazó kategóriára/hírcsatornára, ha minden bejegyzést olvasottnak jelöl"
|
msgstr "Navigálás a következő olvasatlan bejegyzéseket tartalmazó kategóriára/hírcsatornára, ha minden bejegyzést olvasottnak jelöl"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "Soha"
|
msgstr "Soha"
|
||||||
@@ -657,7 +643,6 @@ msgstr "Soha"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Új jelszó"
|
msgstr "Új jelszó"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "Új jelszó"
|
msgstr "Új jelszó"
|
||||||
@@ -764,7 +749,6 @@ msgstr "OPML"
|
|||||||
msgid "OPML export"
|
msgid "OPML export"
|
||||||
msgstr "OPML exportálás"
|
msgstr "OPML exportálás"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "OPML file"
|
msgid "OPML file"
|
||||||
msgstr "OPML fájl"
|
msgstr "OPML fájl"
|
||||||
@@ -791,10 +775,7 @@ msgstr "Szülő kategória"
|
|||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Jelszó"
|
msgstr "Jelszó"
|
||||||
@@ -874,7 +855,6 @@ msgstr "Frissítés"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "A regisztrációk le vannak zárva ezen a CommaFeed példányon"
|
msgstr "A regisztrációk le vannak zárva ezen a CommaFeed példányon"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "Jelszó visszaállítása"
|
msgstr "Jelszó visszaállítása"
|
||||||
@@ -883,7 +863,6 @@ msgstr "Jelszó visszaállítása"
|
|||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REST API"
|
msgstr "REST API"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr "Jobb klikk"
|
msgstr "Jobb klikk"
|
||||||
@@ -910,8 +889,6 @@ msgid "Scrolling"
|
|||||||
msgstr "Görgetés"
|
msgstr "Görgetés"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
#: src/components/sidebar/TreeSearch.tsx
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Keresés"
|
msgstr "Keresés"
|
||||||
@@ -924,7 +901,6 @@ msgstr "Következő olvasatlan feed/kategória kiválasztása"
|
|||||||
msgid "Select previous unread feed/category"
|
msgid "Select previous unread feed/category"
|
||||||
msgstr "Előző olvasatlan feed/kategória kiválasztása"
|
msgstr "Előző olvasatlan feed/kategória kiválasztása"
|
||||||
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
msgid "Server URL"
|
msgid "Server URL"
|
||||||
msgstr "Szerver URL"
|
msgstr "Szerver URL"
|
||||||
@@ -953,8 +929,6 @@ msgstr "Oszd meg"
|
|||||||
msgid "Sharing sites"
|
msgid "Sharing sites"
|
||||||
msgstr "Webhelyek megosztása"
|
msgstr "Webhelyek megosztása"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Shift"
|
msgid "Shift"
|
||||||
msgstr "Shift"
|
msgstr "Shift"
|
||||||
@@ -1003,7 +977,6 @@ msgstr "Olvasatlan darabszám megjelenítése a tab faviconján"
|
|||||||
msgid "Show unread count in tab title"
|
msgid "Show unread count in tab title"
|
||||||
msgstr "Olvasatlan darabszám megjelenítése a tab címében"
|
msgstr "Olvasatlan darabszám megjelenítése a tab címében"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
@@ -1013,7 +986,6 @@ msgstr "Regisztráció"
|
|||||||
msgid "Something bad just happened..."
|
msgid "Something bad just happened..."
|
||||||
msgstr "Valami rossz történt..."
|
msgstr "Valami rossz történt..."
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Space"
|
msgid "Space"
|
||||||
msgstr "Szóköz"
|
msgstr "Szóköz"
|
||||||
@@ -1030,7 +1002,6 @@ msgstr "Csillag"
|
|||||||
msgid "Starred"
|
msgid "Starred"
|
||||||
msgstr "Csillaggal megjelölve"
|
msgstr "Csillaggal megjelölve"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AddPage.tsx
|
#: src/pages/app/AddPage.tsx
|
||||||
msgid "Subscribe"
|
msgid "Subscribe"
|
||||||
@@ -1064,7 +1035,6 @@ msgstr "Váltás világos témára"
|
|||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "Rendszer"
|
msgstr "Rendszer"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Címkék"
|
msgstr "Címkék"
|
||||||
@@ -1136,7 +1106,6 @@ msgstr "Olvasatlan"
|
|||||||
msgid "Unstar"
|
msgid "Unstar"
|
||||||
msgstr "Csillag eltávolítása"
|
msgstr "Csillag eltávolítása"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Leiratkozás"
|
msgstr "Leiratkozás"
|
||||||
@@ -1149,7 +1118,6 @@ msgstr "Felhasználói kulcs"
|
|||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Felhasználónév"
|
msgstr "Felhasználónév"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "User Name or E-mail"
|
msgid "User Name or E-mail"
|
||||||
msgstr "Felhasználói név vagy e-mail cím"
|
msgstr "Felhasználói név vagy e-mail cím"
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ msgstr "Tambahkan pengguna"
|
|||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "Admin"
|
msgstr "Admin"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr "Nama pengguna admin"
|
msgstr "Nama pengguna admin"
|
||||||
@@ -73,7 +72,6 @@ msgstr "Nama pengguna admin"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Semua"
|
msgstr "Semua"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Always"
|
msgid "Always"
|
||||||
msgstr "Selalu"
|
msgstr "Selalu"
|
||||||
@@ -173,18 +171,14 @@ msgstr "Bangun ekspresi filter untuk menunjukkan apa yang ingin Anda baca. Entri
|
|||||||
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
#: src/pages/app/TagDetailsPage.tsx
|
#: src/pages/app/TagDetailsPage.tsx
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Batal"
|
msgstr "Batal"
|
||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -240,7 +234,6 @@ msgstr "Konfirmasi"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Konfirmasi kata sandi"
|
msgstr "Konfirmasi kata sandi"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "Konfirmasi Kata Sandi"
|
msgstr "Konfirmasi Kata Sandi"
|
||||||
@@ -294,7 +287,6 @@ msgstr "hari"
|
|||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Hapus"
|
msgstr "Hapus"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Delete account"
|
msgid "Delete account"
|
||||||
msgstr "Hapus akun"
|
msgstr "Hapus akun"
|
||||||
@@ -342,13 +334,10 @@ msgstr "Seret tautan ke bilah bookmark"
|
|||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "Email"
|
msgstr "Email"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "E-mail address"
|
msgid "E-mail address"
|
||||||
msgstr "Alamat email"
|
msgstr "Alamat email"
|
||||||
@@ -399,7 +388,6 @@ msgstr "Opsi ekstensi"
|
|||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
msgstr "Nama umpan"
|
msgstr "Nama umpan"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
@@ -570,7 +558,6 @@ msgstr "Memuat langganan..."
|
|||||||
msgid "Loading tags..."
|
msgid "Loading tags..."
|
||||||
msgstr "Memuat tag..."
|
msgstr "Memuat tag..."
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
@@ -648,7 +635,6 @@ msgstr "Navigasikan ke langganan dengan memasukkan namanya"
|
|||||||
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
msgstr "Navigasikan ke kategori/umpan berikutnya dengan entri yang belum dibaca saat menandai semua entri sebagai telah dibaca"
|
msgstr "Navigasikan ke kategori/umpan berikutnya dengan entri yang belum dibaca saat menandai semua entri sebagai telah dibaca"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "Tidak pernah"
|
msgstr "Tidak pernah"
|
||||||
@@ -657,7 +643,6 @@ msgstr "Tidak pernah"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Kata sandi baru"
|
msgstr "Kata sandi baru"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "Kata Sandi Baru"
|
msgstr "Kata Sandi Baru"
|
||||||
@@ -764,7 +749,6 @@ msgstr "OPML"
|
|||||||
msgid "OPML export"
|
msgid "OPML export"
|
||||||
msgstr "ekspor OPML"
|
msgstr "ekspor OPML"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "OPML file"
|
msgid "OPML file"
|
||||||
msgstr "file OPML"
|
msgstr "file OPML"
|
||||||
@@ -791,10 +775,7 @@ msgstr "Kategori Induk"
|
|||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Kata Sandi"
|
msgstr "Kata Sandi"
|
||||||
@@ -874,7 +855,6 @@ msgstr "Segarkan"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Pendaftaran ditutup pada instans CommaFeed ini"
|
msgstr "Pendaftaran ditutup pada instans CommaFeed ini"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "Atur Ulang Kata Sandi"
|
msgstr "Atur Ulang Kata Sandi"
|
||||||
@@ -883,7 +863,6 @@ msgstr "Atur Ulang Kata Sandi"
|
|||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REST API"
|
msgstr "REST API"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr "Klik kanan"
|
msgstr "Klik kanan"
|
||||||
@@ -910,8 +889,6 @@ msgid "Scrolling"
|
|||||||
msgstr "Menggulir"
|
msgstr "Menggulir"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
#: src/components/sidebar/TreeSearch.tsx
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Pencarian"
|
msgstr "Pencarian"
|
||||||
@@ -924,7 +901,6 @@ msgstr "Pilih umpan/kategori belum dibaca berikutnya"
|
|||||||
msgid "Select previous unread feed/category"
|
msgid "Select previous unread feed/category"
|
||||||
msgstr "Pilih umpan/kategori belum dibaca sebelumnya"
|
msgstr "Pilih umpan/kategori belum dibaca sebelumnya"
|
||||||
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
msgid "Server URL"
|
msgid "Server URL"
|
||||||
msgstr "URL Server"
|
msgstr "URL Server"
|
||||||
@@ -953,8 +929,6 @@ msgstr "Bagikan"
|
|||||||
msgid "Sharing sites"
|
msgid "Sharing sites"
|
||||||
msgstr "Berbagi situs"
|
msgstr "Berbagi situs"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Shift"
|
msgid "Shift"
|
||||||
msgstr "Pergeseran"
|
msgstr "Pergeseran"
|
||||||
@@ -1003,7 +977,6 @@ msgstr "Tampilkan jumlah yang belum dibaca di favicon tab"
|
|||||||
msgid "Show unread count in tab title"
|
msgid "Show unread count in tab title"
|
||||||
msgstr "Tampilkan jumlah yang belum dibaca di judul tab"
|
msgstr "Tampilkan jumlah yang belum dibaca di judul tab"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
@@ -1013,7 +986,6 @@ msgstr "Daftar"
|
|||||||
msgid "Something bad just happened..."
|
msgid "Something bad just happened..."
|
||||||
msgstr "Sesuatu yang buruk baru saja terjadi..."
|
msgstr "Sesuatu yang buruk baru saja terjadi..."
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Space"
|
msgid "Space"
|
||||||
msgstr "Spasi"
|
msgstr "Spasi"
|
||||||
@@ -1030,7 +1002,6 @@ msgstr "Bintang"
|
|||||||
msgid "Starred"
|
msgid "Starred"
|
||||||
msgstr "Berbintang"
|
msgstr "Berbintang"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AddPage.tsx
|
#: src/pages/app/AddPage.tsx
|
||||||
msgid "Subscribe"
|
msgid "Subscribe"
|
||||||
@@ -1064,7 +1035,6 @@ msgstr "Beralih ke tema terang"
|
|||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "Sistem"
|
msgstr "Sistem"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Tag"
|
msgstr "Tag"
|
||||||
@@ -1136,7 +1106,6 @@ msgstr "Belum Dibaca"
|
|||||||
msgid "Unstar"
|
msgid "Unstar"
|
||||||
msgstr "Hapus bintang"
|
msgstr "Hapus bintang"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Berhenti berlangganan"
|
msgstr "Berhenti berlangganan"
|
||||||
@@ -1149,7 +1118,6 @@ msgstr "Kunci pengguna"
|
|||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Nama pengguna"
|
msgstr "Nama pengguna"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "User Name or E-mail"
|
msgid "User Name or E-mail"
|
||||||
msgstr "Nama Pengguna atau Email"
|
msgstr "Nama Pengguna atau Email"
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ msgstr "Aggiungi utente"
|
|||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "Ammin"
|
msgstr "Ammin"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr "Nome utente amministratore"
|
msgstr "Nome utente amministratore"
|
||||||
@@ -73,7 +72,6 @@ msgstr "Nome utente amministratore"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Tutto"
|
msgstr "Tutto"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Always"
|
msgid "Always"
|
||||||
msgstr "Sempre"
|
msgstr "Sempre"
|
||||||
@@ -173,18 +171,14 @@ msgstr "Crea un'espressione di filtro per indicare cosa vuoi leggere. Le voci ch
|
|||||||
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
#: src/pages/app/TagDetailsPage.tsx
|
#: src/pages/app/TagDetailsPage.tsx
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Annulla"
|
msgstr "Annulla"
|
||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -240,7 +234,6 @@ msgstr "Conferma"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Conferma password"
|
msgstr "Conferma password"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "Conferma password"
|
msgstr "Conferma password"
|
||||||
@@ -294,7 +287,6 @@ msgstr "giorni"
|
|||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Elimina"
|
msgstr "Elimina"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Delete account"
|
msgid "Delete account"
|
||||||
msgstr "Elimina account"
|
msgstr "Elimina account"
|
||||||
@@ -342,13 +334,10 @@ msgstr "Trascina il collegamento sulla barra dei preferiti"
|
|||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "E-mail"
|
msgstr "E-mail"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "E-mail address"
|
msgid "E-mail address"
|
||||||
msgstr "Indirizzo e-mail"
|
msgstr "Indirizzo e-mail"
|
||||||
@@ -399,7 +388,6 @@ msgstr "Opzioni estensione"
|
|||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
msgstr "Nome del feed"
|
msgstr "Nome del feed"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
@@ -570,7 +558,6 @@ msgstr "Caricamento abbonamenti..."
|
|||||||
msgid "Loading tags..."
|
msgid "Loading tags..."
|
||||||
msgstr "Caricamento tag..."
|
msgstr "Caricamento tag..."
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
@@ -648,7 +635,6 @@ msgstr "Navigare verso un abbonamento inserendo il suo nome"
|
|||||||
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
msgstr "Passa alla categoria/feed successivo con voci non lette quando contrassegni tutte le voci come lette"
|
msgstr "Passa alla categoria/feed successivo con voci non lette quando contrassegni tutte le voci come lette"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "Mai"
|
msgstr "Mai"
|
||||||
@@ -657,7 +643,6 @@ msgstr "Mai"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Nuova password"
|
msgstr "Nuova password"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "Nuova password"
|
msgstr "Nuova password"
|
||||||
@@ -764,7 +749,6 @@ msgstr "OPML"
|
|||||||
msgid "OPML export"
|
msgid "OPML export"
|
||||||
msgstr "Esportazione OPML"
|
msgstr "Esportazione OPML"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "OPML file"
|
msgid "OPML file"
|
||||||
msgstr "File OPML"
|
msgstr "File OPML"
|
||||||
@@ -791,10 +775,7 @@ msgstr "Categoria padre"
|
|||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Password"
|
msgstr "Password"
|
||||||
@@ -874,7 +855,6 @@ msgstr "Aggiorna"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Le registrazioni sono chiuse su questa istanza CommaFeed"
|
msgstr "Le registrazioni sono chiuse su questa istanza CommaFeed"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "Reimposta password"
|
msgstr "Reimposta password"
|
||||||
@@ -883,7 +863,6 @@ msgstr "Reimposta password"
|
|||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "API REST"
|
msgstr "API REST"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr "Clic destro"
|
msgstr "Clic destro"
|
||||||
@@ -910,8 +889,6 @@ msgid "Scrolling"
|
|||||||
msgstr "Scorrimento"
|
msgstr "Scorrimento"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
#: src/components/sidebar/TreeSearch.tsx
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Cerca"
|
msgstr "Cerca"
|
||||||
@@ -924,7 +901,6 @@ msgstr "Seleziona il feed/categoria non letto successivo"
|
|||||||
msgid "Select previous unread feed/category"
|
msgid "Select previous unread feed/category"
|
||||||
msgstr "Seleziona il feed/categoria non letto precedente"
|
msgstr "Seleziona il feed/categoria non letto precedente"
|
||||||
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
msgid "Server URL"
|
msgid "Server URL"
|
||||||
msgstr "URL del server"
|
msgstr "URL del server"
|
||||||
@@ -953,8 +929,6 @@ msgstr "Condividi"
|
|||||||
msgid "Sharing sites"
|
msgid "Sharing sites"
|
||||||
msgstr "Condivisione di siti"
|
msgstr "Condivisione di siti"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Shift"
|
msgid "Shift"
|
||||||
msgstr "Cambio"
|
msgstr "Cambio"
|
||||||
@@ -1003,7 +977,6 @@ msgstr "Mostra il numero di non letti nella favicon della scheda"
|
|||||||
msgid "Show unread count in tab title"
|
msgid "Show unread count in tab title"
|
||||||
msgstr "Mostra il numero di non letti nel titolo della scheda"
|
msgstr "Mostra il numero di non letti nel titolo della scheda"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
@@ -1013,7 +986,6 @@ msgstr "Iscriviti"
|
|||||||
msgid "Something bad just happened..."
|
msgid "Something bad just happened..."
|
||||||
msgstr "È appena successo qualcosa di brutto..."
|
msgstr "È appena successo qualcosa di brutto..."
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Space"
|
msgid "Space"
|
||||||
msgstr "Spazio"
|
msgstr "Spazio"
|
||||||
@@ -1030,7 +1002,6 @@ msgstr "Stella"
|
|||||||
msgid "Starred"
|
msgid "Starred"
|
||||||
msgstr "Speciali"
|
msgstr "Speciali"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AddPage.tsx
|
#: src/pages/app/AddPage.tsx
|
||||||
msgid "Subscribe"
|
msgid "Subscribe"
|
||||||
@@ -1064,7 +1035,6 @@ msgstr "Passa al tema chiaro"
|
|||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "Sistema"
|
msgstr "Sistema"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Tag"
|
msgstr "Tag"
|
||||||
@@ -1136,7 +1106,6 @@ msgstr "Non letto"
|
|||||||
msgid "Unstar"
|
msgid "Unstar"
|
||||||
msgstr "Elimina le stelle"
|
msgstr "Elimina le stelle"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Annulla iscrizione"
|
msgstr "Annulla iscrizione"
|
||||||
@@ -1149,7 +1118,6 @@ msgstr "Chiave utente"
|
|||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Nome utente"
|
msgstr "Nome utente"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "User Name or E-mail"
|
msgid "User Name or E-mail"
|
||||||
msgstr "Nome utente o e-mail"
|
msgstr "Nome utente o e-mail"
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ msgstr "ユーザー追加"
|
|||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "管理者"
|
msgstr "管理者"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr "管理者ユーザー名"
|
msgstr "管理者ユーザー名"
|
||||||
@@ -73,7 +72,6 @@ msgstr "管理者ユーザー名"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "すべて"
|
msgstr "すべて"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Always"
|
msgid "Always"
|
||||||
msgstr "常に"
|
msgstr "常に"
|
||||||
@@ -173,18 +171,14 @@ msgstr "読みたい内容を指定するためのフィルタ式を作成しま
|
|||||||
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
#: src/pages/app/TagDetailsPage.tsx
|
#: src/pages/app/TagDetailsPage.tsx
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "キャンセル"
|
msgstr "キャンセル"
|
||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -240,7 +234,6 @@ msgstr "確認"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "パスワード確認"
|
msgstr "パスワード確認"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "パスワードの確認"
|
msgstr "パスワードの確認"
|
||||||
@@ -294,7 +287,6 @@ msgstr "日"
|
|||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "削除"
|
msgstr "削除"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Delete account"
|
msgid "Delete account"
|
||||||
msgstr "アカウント削除"
|
msgstr "アカウント削除"
|
||||||
@@ -342,13 +334,10 @@ msgstr "リンクをブックマークバーにドラッグ"
|
|||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "メール"
|
msgstr "メール"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "E-mail address"
|
msgid "E-mail address"
|
||||||
msgstr "メールアドレス"
|
msgstr "メールアドレス"
|
||||||
@@ -399,7 +388,6 @@ msgstr "拡張機能オプション"
|
|||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
msgstr "フィード名"
|
msgstr "フィード名"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
@@ -570,7 +558,6 @@ msgstr "サブスクリプションを読み込んでいます..."
|
|||||||
msgid "Loading tags..."
|
msgid "Loading tags..."
|
||||||
msgstr "タグを読み込んでいます..."
|
msgstr "タグを読み込んでいます..."
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
@@ -648,7 +635,6 @@ msgstr "名前を入力してサブスクリプションに移動します"
|
|||||||
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
msgstr "すべてのエントリーを既読にするとき、未読エントリーのある次のカテゴリ/フィードに移動する"
|
msgstr "すべてのエントリーを既読にするとき、未読エントリーのある次のカテゴリ/フィードに移動する"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "しない"
|
msgstr "しない"
|
||||||
@@ -657,7 +643,6 @@ msgstr "しない"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "新しいパスワード"
|
msgstr "新しいパスワード"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "新しいパスワード"
|
msgstr "新しいパスワード"
|
||||||
@@ -764,7 +749,6 @@ msgstr "OPML"
|
|||||||
msgid "OPML export"
|
msgid "OPML export"
|
||||||
msgstr "OPML エクスポート"
|
msgstr "OPML エクスポート"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "OPML file"
|
msgid "OPML file"
|
||||||
msgstr "OPMLファイル"
|
msgstr "OPMLファイル"
|
||||||
@@ -791,10 +775,7 @@ msgstr "親カテゴリ"
|
|||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "パスワード"
|
msgstr "パスワード"
|
||||||
@@ -874,7 +855,6 @@ msgstr "リフレッシュ"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "このCommaFeedインスタンスの登録は終了しています"
|
msgstr "このCommaFeedインスタンスの登録は終了しています"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "パスワードをリセット"
|
msgstr "パスワードをリセット"
|
||||||
@@ -883,7 +863,6 @@ msgstr "パスワードをリセット"
|
|||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REST API"
|
msgstr "REST API"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr "右クリック"
|
msgstr "右クリック"
|
||||||
@@ -910,8 +889,6 @@ msgid "Scrolling"
|
|||||||
msgstr "スクロール"
|
msgstr "スクロール"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
#: src/components/sidebar/TreeSearch.tsx
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "検索"
|
msgstr "検索"
|
||||||
@@ -924,7 +901,6 @@ msgstr "次の未読フィード/カテゴリを選択"
|
|||||||
msgid "Select previous unread feed/category"
|
msgid "Select previous unread feed/category"
|
||||||
msgstr "前の未読フィード/カテゴリを選択"
|
msgstr "前の未読フィード/カテゴリを選択"
|
||||||
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
msgid "Server URL"
|
msgid "Server URL"
|
||||||
msgstr "サーバーURL"
|
msgstr "サーバーURL"
|
||||||
@@ -953,8 +929,6 @@ msgstr "シェア"
|
|||||||
msgid "Sharing sites"
|
msgid "Sharing sites"
|
||||||
msgstr "共有サイト"
|
msgstr "共有サイト"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Shift"
|
msgid "Shift"
|
||||||
msgstr "Shift"
|
msgstr "Shift"
|
||||||
@@ -1003,7 +977,6 @@ msgstr "未読数をタブのアイコンに表示する"
|
|||||||
msgid "Show unread count in tab title"
|
msgid "Show unread count in tab title"
|
||||||
msgstr "未読数をタブのタイトルに表示する"
|
msgstr "未読数をタブのタイトルに表示する"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
@@ -1013,7 +986,6 @@ msgstr "サインアップ"
|
|||||||
msgid "Something bad just happened..."
|
msgid "Something bad just happened..."
|
||||||
msgstr "何か悪いことが起きました..."
|
msgstr "何か悪いことが起きました..."
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Space"
|
msgid "Space"
|
||||||
msgstr "Space"
|
msgstr "Space"
|
||||||
@@ -1030,7 +1002,6 @@ msgstr "スター"
|
|||||||
msgid "Starred"
|
msgid "Starred"
|
||||||
msgstr "スター付き"
|
msgstr "スター付き"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AddPage.tsx
|
#: src/pages/app/AddPage.tsx
|
||||||
msgid "Subscribe"
|
msgid "Subscribe"
|
||||||
@@ -1064,7 +1035,6 @@ msgstr "ライトテーマに切り替え"
|
|||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "システム"
|
msgstr "システム"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "タグ"
|
msgstr "タグ"
|
||||||
@@ -1136,7 +1106,6 @@ msgstr "未読"
|
|||||||
msgid "Unstar"
|
msgid "Unstar"
|
||||||
msgstr "スターを外す"
|
msgstr "スターを外す"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "退会"
|
msgstr "退会"
|
||||||
@@ -1149,7 +1118,6 @@ msgstr "ユーザーキー"
|
|||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "ユーザー名"
|
msgstr "ユーザー名"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "User Name or E-mail"
|
msgid "User Name or E-mail"
|
||||||
msgstr "ユーザー名またはメールアドレス"
|
msgstr "ユーザー名またはメールアドレス"
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ msgstr "사용자 추가"
|
|||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "관리자"
|
msgstr "관리자"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr "관리자 사용자 이름"
|
msgstr "관리자 사용자 이름"
|
||||||
@@ -73,7 +72,6 @@ msgstr "관리자 사용자 이름"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "전체"
|
msgstr "전체"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Always"
|
msgid "Always"
|
||||||
msgstr "항상"
|
msgstr "항상"
|
||||||
@@ -173,18 +171,14 @@ msgstr "읽고 싶은 항목을 지정하기 위한 필터 표현식을 작성
|
|||||||
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
#: src/pages/app/TagDetailsPage.tsx
|
#: src/pages/app/TagDetailsPage.tsx
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "취소"
|
msgstr "취소"
|
||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -240,7 +234,6 @@ msgstr "확인"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "비밀번호 확인"
|
msgstr "비밀번호 확인"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "비밀번호 확인"
|
msgstr "비밀번호 확인"
|
||||||
@@ -294,7 +287,6 @@ msgstr "일"
|
|||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "삭제"
|
msgstr "삭제"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Delete account"
|
msgid "Delete account"
|
||||||
msgstr "계정 삭제"
|
msgstr "계정 삭제"
|
||||||
@@ -342,13 +334,10 @@ msgstr "링크를 북마크바로 드래그"
|
|||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "이메일"
|
msgstr "이메일"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "E-mail address"
|
msgid "E-mail address"
|
||||||
msgstr "이메일 주소"
|
msgstr "이메일 주소"
|
||||||
@@ -399,7 +388,6 @@ msgstr "확장 프로그램 옵션"
|
|||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
msgstr "피드 이름"
|
msgstr "피드 이름"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
@@ -570,7 +558,6 @@ msgstr "구독 로드 중..."
|
|||||||
msgid "Loading tags..."
|
msgid "Loading tags..."
|
||||||
msgstr "태그 로드 중..."
|
msgstr "태그 로드 중..."
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
@@ -648,7 +635,6 @@ msgstr "이름을 입력하여 구독으로 이동"
|
|||||||
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
msgstr "모든 항목을 읽음으로 표시할 때 읽지 않은 항목이 있는 다음 카테고리/피드로 이동"
|
msgstr "모든 항목을 읽음으로 표시할 때 읽지 않은 항목이 있는 다음 카테고리/피드로 이동"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "안 함"
|
msgstr "안 함"
|
||||||
@@ -657,7 +643,6 @@ msgstr "안 함"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "새 비밀번호"
|
msgstr "새 비밀번호"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "새 비밀번호"
|
msgstr "새 비밀번호"
|
||||||
@@ -764,7 +749,6 @@ msgstr "OPML"
|
|||||||
msgid "OPML export"
|
msgid "OPML export"
|
||||||
msgstr "OPML 내보내기"
|
msgstr "OPML 내보내기"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "OPML file"
|
msgid "OPML file"
|
||||||
msgstr "OPML 파일"
|
msgstr "OPML 파일"
|
||||||
@@ -791,10 +775,7 @@ msgstr "부모 카테고리"
|
|||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "비밀번호"
|
msgstr "비밀번호"
|
||||||
@@ -874,7 +855,6 @@ msgstr "새로 고침"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "이 CommaFeed 인스턴스에 대한 등록이 마감되었습니다."
|
msgstr "이 CommaFeed 인스턴스에 대한 등록이 마감되었습니다."
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "비밀번호 재설정"
|
msgstr "비밀번호 재설정"
|
||||||
@@ -883,7 +863,6 @@ msgstr "비밀번호 재설정"
|
|||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REST API"
|
msgstr "REST API"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr "오른쪽 클릭"
|
msgstr "오른쪽 클릭"
|
||||||
@@ -910,8 +889,6 @@ msgid "Scrolling"
|
|||||||
msgstr "스크롤"
|
msgstr "스크롤"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
#: src/components/sidebar/TreeSearch.tsx
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "검색"
|
msgstr "검색"
|
||||||
@@ -924,7 +901,6 @@ msgstr "다음 읽지 않은 피드/카테고리 선택"
|
|||||||
msgid "Select previous unread feed/category"
|
msgid "Select previous unread feed/category"
|
||||||
msgstr "이전 읽지 않은 피드/카테고리 선택"
|
msgstr "이전 읽지 않은 피드/카테고리 선택"
|
||||||
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
msgid "Server URL"
|
msgid "Server URL"
|
||||||
msgstr "서버 URL"
|
msgstr "서버 URL"
|
||||||
@@ -953,8 +929,6 @@ msgstr "공유"
|
|||||||
msgid "Sharing sites"
|
msgid "Sharing sites"
|
||||||
msgstr "사이트 공유"
|
msgstr "사이트 공유"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Shift"
|
msgid "Shift"
|
||||||
msgstr "시프트"
|
msgstr "시프트"
|
||||||
@@ -1003,7 +977,6 @@ msgstr "탭 파비콘에 읽지 않은 개수 표시"
|
|||||||
msgid "Show unread count in tab title"
|
msgid "Show unread count in tab title"
|
||||||
msgstr "탭 제목에 읽지 않은 개수 표시"
|
msgstr "탭 제목에 읽지 않은 개수 표시"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
@@ -1013,7 +986,6 @@ msgstr "가입"
|
|||||||
msgid "Something bad just happened..."
|
msgid "Something bad just happened..."
|
||||||
msgstr "뭔가 안 좋은 일이 일어났어..."
|
msgstr "뭔가 안 좋은 일이 일어났어..."
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Space"
|
msgid "Space"
|
||||||
msgstr "우주"
|
msgstr "우주"
|
||||||
@@ -1030,7 +1002,6 @@ msgstr "스타"
|
|||||||
msgid "Starred"
|
msgid "Starred"
|
||||||
msgstr "별표"
|
msgstr "별표"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AddPage.tsx
|
#: src/pages/app/AddPage.tsx
|
||||||
msgid "Subscribe"
|
msgid "Subscribe"
|
||||||
@@ -1064,7 +1035,6 @@ msgstr "밝은 테마로 전환"
|
|||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "시스템"
|
msgstr "시스템"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "태그"
|
msgstr "태그"
|
||||||
@@ -1136,7 +1106,6 @@ msgstr "읽지 않음"
|
|||||||
msgid "Unstar"
|
msgid "Unstar"
|
||||||
msgstr "별표 제거"
|
msgstr "별표 제거"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "구독 취소"
|
msgstr "구독 취소"
|
||||||
@@ -1149,7 +1118,6 @@ msgstr "사용자 키"
|
|||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "사용자 이름"
|
msgstr "사용자 이름"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "User Name or E-mail"
|
msgid "User Name or E-mail"
|
||||||
msgstr "사용자 이름 또는 이메일"
|
msgstr "사용자 이름 또는 이메일"
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ msgstr "Tambah pengguna"
|
|||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "Pentadbir"
|
msgstr "Pentadbir"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr "Nama pengguna pentadbir"
|
msgstr "Nama pengguna pentadbir"
|
||||||
@@ -73,7 +72,6 @@ msgstr "Nama pengguna pentadbir"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Semua"
|
msgstr "Semua"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Always"
|
msgid "Always"
|
||||||
msgstr "Sentiasa"
|
msgstr "Sentiasa"
|
||||||
@@ -173,18 +171,14 @@ msgstr "Bina ungkapan penapis untuk menunjukkan perkara yang anda mahu baca. Ent
|
|||||||
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
#: src/pages/app/TagDetailsPage.tsx
|
#: src/pages/app/TagDetailsPage.tsx
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Batal"
|
msgstr "Batal"
|
||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -240,7 +234,6 @@ msgstr "Sahkan"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Sahkan kata laluan"
|
msgstr "Sahkan kata laluan"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "Sahkan Kata Laluan"
|
msgstr "Sahkan Kata Laluan"
|
||||||
@@ -294,7 +287,6 @@ msgstr "hari"
|
|||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Padam"
|
msgstr "Padam"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Delete account"
|
msgid "Delete account"
|
||||||
msgstr "Padam akaun"
|
msgstr "Padam akaun"
|
||||||
@@ -342,13 +334,10 @@ msgstr "Seret pautan ke bar penanda halaman"
|
|||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "E-mel"
|
msgstr "E-mel"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "E-mail address"
|
msgid "E-mail address"
|
||||||
msgstr "Alamat e-mel"
|
msgstr "Alamat e-mel"
|
||||||
@@ -399,7 +388,6 @@ msgstr "Pilihan ekstensi"
|
|||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
msgstr "Nama suapan"
|
msgstr "Nama suapan"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
@@ -570,7 +558,6 @@ msgstr "Memuatkan langganan..."
|
|||||||
msgid "Loading tags..."
|
msgid "Loading tags..."
|
||||||
msgstr "Memuatkan tag..."
|
msgstr "Memuatkan tag..."
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
@@ -648,7 +635,6 @@ msgstr "Navigasi ke langganan dengan memasukkan namanya"
|
|||||||
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
msgstr "Navigasi ke kategori/suapan seterusnya dengan entri yang belum dibaca apabila menandakan semua entri sebagai dibaca"
|
msgstr "Navigasi ke kategori/suapan seterusnya dengan entri yang belum dibaca apabila menandakan semua entri sebagai dibaca"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "Tidak pernah"
|
msgstr "Tidak pernah"
|
||||||
@@ -657,7 +643,6 @@ msgstr "Tidak pernah"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Kata laluan baharu"
|
msgstr "Kata laluan baharu"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "Kata Laluan Baharu"
|
msgstr "Kata Laluan Baharu"
|
||||||
@@ -764,7 +749,6 @@ msgstr "OPML"
|
|||||||
msgid "OPML export"
|
msgid "OPML export"
|
||||||
msgstr "OPML eksport"
|
msgstr "OPML eksport"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "OPML file"
|
msgid "OPML file"
|
||||||
msgstr "Fail OPML"
|
msgstr "Fail OPML"
|
||||||
@@ -791,10 +775,7 @@ msgstr "Kategori Induk"
|
|||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Kata Laluan"
|
msgstr "Kata Laluan"
|
||||||
@@ -874,7 +855,6 @@ msgstr "Muat semula"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Pendaftaran ditutup pada contoh CommaFeed ini"
|
msgstr "Pendaftaran ditutup pada contoh CommaFeed ini"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "Tetap Semula Kata Laluan"
|
msgstr "Tetap Semula Kata Laluan"
|
||||||
@@ -883,7 +863,6 @@ msgstr "Tetap Semula Kata Laluan"
|
|||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REHAT API"
|
msgstr "REHAT API"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr "Klik kanan"
|
msgstr "Klik kanan"
|
||||||
@@ -910,8 +889,6 @@ msgid "Scrolling"
|
|||||||
msgstr "Menatal"
|
msgstr "Menatal"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
#: src/components/sidebar/TreeSearch.tsx
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Cari"
|
msgstr "Cari"
|
||||||
@@ -924,7 +901,6 @@ msgstr "Pilih suapan/kategori belum dibaca seterusnya"
|
|||||||
msgid "Select previous unread feed/category"
|
msgid "Select previous unread feed/category"
|
||||||
msgstr "Pilih suapan/kategori belum dibaca sebelumnya"
|
msgstr "Pilih suapan/kategori belum dibaca sebelumnya"
|
||||||
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
msgid "Server URL"
|
msgid "Server URL"
|
||||||
msgstr "URL Pelayan"
|
msgstr "URL Pelayan"
|
||||||
@@ -953,8 +929,6 @@ msgstr "Kongsi"
|
|||||||
msgid "Sharing sites"
|
msgid "Sharing sites"
|
||||||
msgstr "Berkongsi tapak"
|
msgstr "Berkongsi tapak"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Shift"
|
msgid "Shift"
|
||||||
msgstr "Anjakan"
|
msgstr "Anjakan"
|
||||||
@@ -1003,7 +977,6 @@ msgstr "Tunjukkan kiraan belum dibaca dalam favicon tab"
|
|||||||
msgid "Show unread count in tab title"
|
msgid "Show unread count in tab title"
|
||||||
msgstr "Tunjukkan kiraan belum dibaca dalam tajuk tab"
|
msgstr "Tunjukkan kiraan belum dibaca dalam tajuk tab"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
@@ -1013,7 +986,6 @@ msgstr "Daftar"
|
|||||||
msgid "Something bad just happened..."
|
msgid "Something bad just happened..."
|
||||||
msgstr "Sesuatu yang buruk baru saja berlaku..."
|
msgstr "Sesuatu yang buruk baru saja berlaku..."
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Space"
|
msgid "Space"
|
||||||
msgstr "Angkasa"
|
msgstr "Angkasa"
|
||||||
@@ -1030,7 +1002,6 @@ msgstr "Bintang"
|
|||||||
msgid "Starred"
|
msgid "Starred"
|
||||||
msgstr "Dibintangi"
|
msgstr "Dibintangi"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AddPage.tsx
|
#: src/pages/app/AddPage.tsx
|
||||||
msgid "Subscribe"
|
msgid "Subscribe"
|
||||||
@@ -1064,7 +1035,6 @@ msgstr "Tukar kepada tema cahaya"
|
|||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "Sistem"
|
msgstr "Sistem"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Tag"
|
msgstr "Tag"
|
||||||
@@ -1136,7 +1106,6 @@ msgstr "Belum dibaca"
|
|||||||
msgid "Unstar"
|
msgid "Unstar"
|
||||||
msgstr "Nyahbintang"
|
msgstr "Nyahbintang"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Nyahlanggan"
|
msgstr "Nyahlanggan"
|
||||||
@@ -1149,7 +1118,6 @@ msgstr "Kunci pengguna"
|
|||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Nama pengguna"
|
msgstr "Nama pengguna"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "User Name or E-mail"
|
msgid "User Name or E-mail"
|
||||||
msgstr "Nama Pengguna atau E-mel"
|
msgstr "Nama Pengguna atau E-mel"
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ msgstr "Legg til bruker"
|
|||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "Administrator"
|
msgstr "Administrator"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr "Administrator brukernavn"
|
msgstr "Administrator brukernavn"
|
||||||
@@ -73,7 +72,6 @@ msgstr "Administrator brukernavn"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Alle"
|
msgstr "Alle"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Always"
|
msgid "Always"
|
||||||
msgstr "Alltid"
|
msgstr "Alltid"
|
||||||
@@ -173,18 +171,14 @@ msgstr "Bygg et filteruttrykk for å angi hva du vil lese. Oppføringer som ikke
|
|||||||
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
#: src/pages/app/TagDetailsPage.tsx
|
#: src/pages/app/TagDetailsPage.tsx
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Avbryt"
|
msgstr "Avbryt"
|
||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -240,7 +234,6 @@ msgstr "Bekreft"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Bekreft passord"
|
msgstr "Bekreft passord"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "Bekreft passord"
|
msgstr "Bekreft passord"
|
||||||
@@ -294,7 +287,6 @@ msgstr "dager"
|
|||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Slett"
|
msgstr "Slett"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Delete account"
|
msgid "Delete account"
|
||||||
msgstr "Slett konto"
|
msgstr "Slett konto"
|
||||||
@@ -342,13 +334,10 @@ msgstr "Dra lenken til bokmerkelinjen"
|
|||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "E-post"
|
msgstr "E-post"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "E-mail address"
|
msgid "E-mail address"
|
||||||
msgstr "E-postadresse"
|
msgstr "E-postadresse"
|
||||||
@@ -399,7 +388,6 @@ msgstr "Utvidelsesvalg"
|
|||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
msgstr "Feednavn"
|
msgstr "Feednavn"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
@@ -570,7 +558,6 @@ msgstr "Laster abonnementer..."
|
|||||||
msgid "Loading tags..."
|
msgid "Loading tags..."
|
||||||
msgstr "Laster tagger..."
|
msgstr "Laster tagger..."
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
@@ -648,7 +635,6 @@ msgstr "Naviger til et abonnement ved å skrive inn navnet"
|
|||||||
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
msgstr "Naviger til neste kategori/feed med uleste oppføringer når du markerer alle oppføringer som lest"
|
msgstr "Naviger til neste kategori/feed med uleste oppføringer når du markerer alle oppføringer som lest"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "Aldri"
|
msgstr "Aldri"
|
||||||
@@ -657,7 +643,6 @@ msgstr "Aldri"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Nytt passord"
|
msgstr "Nytt passord"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "Nytt passord"
|
msgstr "Nytt passord"
|
||||||
@@ -764,7 +749,6 @@ msgstr "OPML"
|
|||||||
msgid "OPML export"
|
msgid "OPML export"
|
||||||
msgstr "OPML-eksport"
|
msgstr "OPML-eksport"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "OPML file"
|
msgid "OPML file"
|
||||||
msgstr "OPML-fil"
|
msgstr "OPML-fil"
|
||||||
@@ -791,10 +775,7 @@ msgstr "Overordnet kategori"
|
|||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Passord"
|
msgstr "Passord"
|
||||||
@@ -874,7 +855,6 @@ msgstr "Oppdater"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Registreringer er stengt på denne CommaFeed-forekomsten"
|
msgstr "Registreringer er stengt på denne CommaFeed-forekomsten"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "Tilbakestill passord"
|
msgstr "Tilbakestill passord"
|
||||||
@@ -883,7 +863,6 @@ msgstr "Tilbakestill passord"
|
|||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REST API"
|
msgstr "REST API"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr "Høyreklikk"
|
msgstr "Høyreklikk"
|
||||||
@@ -910,8 +889,6 @@ msgid "Scrolling"
|
|||||||
msgstr "Rulling"
|
msgstr "Rulling"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
#: src/components/sidebar/TreeSearch.tsx
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Søk"
|
msgstr "Søk"
|
||||||
@@ -924,7 +901,6 @@ msgstr "Velg neste uleste feed/kategori"
|
|||||||
msgid "Select previous unread feed/category"
|
msgid "Select previous unread feed/category"
|
||||||
msgstr "Velg forrige uleste feed/kategori"
|
msgstr "Velg forrige uleste feed/kategori"
|
||||||
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
msgid "Server URL"
|
msgid "Server URL"
|
||||||
msgstr "Server-URL"
|
msgstr "Server-URL"
|
||||||
@@ -953,8 +929,6 @@ msgstr "Del"
|
|||||||
msgid "Sharing sites"
|
msgid "Sharing sites"
|
||||||
msgstr "Delingssider"
|
msgstr "Delingssider"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Shift"
|
msgid "Shift"
|
||||||
msgstr "Skift"
|
msgstr "Skift"
|
||||||
@@ -1003,7 +977,6 @@ msgstr "Vis antall uleste i fanens favicon"
|
|||||||
msgid "Show unread count in tab title"
|
msgid "Show unread count in tab title"
|
||||||
msgstr "Vis antall uleste i fanetittelen"
|
msgstr "Vis antall uleste i fanetittelen"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
@@ -1013,7 +986,6 @@ msgstr "Meld deg på"
|
|||||||
msgid "Something bad just happened..."
|
msgid "Something bad just happened..."
|
||||||
msgstr "Noe ille skjedde akkurat..."
|
msgstr "Noe ille skjedde akkurat..."
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Space"
|
msgid "Space"
|
||||||
msgstr "Mellomrom"
|
msgstr "Mellomrom"
|
||||||
@@ -1030,7 +1002,6 @@ msgstr "Stjerne"
|
|||||||
msgid "Starred"
|
msgid "Starred"
|
||||||
msgstr "Stjerne"
|
msgstr "Stjerne"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AddPage.tsx
|
#: src/pages/app/AddPage.tsx
|
||||||
msgid "Subscribe"
|
msgid "Subscribe"
|
||||||
@@ -1064,7 +1035,6 @@ msgstr "Bytt til lystema"
|
|||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "System"
|
msgstr "System"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Tagger"
|
msgstr "Tagger"
|
||||||
@@ -1136,7 +1106,6 @@ msgstr "Ulest"
|
|||||||
msgid "Unstar"
|
msgid "Unstar"
|
||||||
msgstr "Fjern stjerne"
|
msgstr "Fjern stjerne"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Avslutt abonnement"
|
msgstr "Avslutt abonnement"
|
||||||
@@ -1149,7 +1118,6 @@ msgstr "Brukernøkkel"
|
|||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Brukernavn"
|
msgstr "Brukernavn"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "User Name or E-mail"
|
msgid "User Name or E-mail"
|
||||||
msgstr "Brukernavn eller e-post"
|
msgstr "Brukernavn eller e-post"
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ msgstr "Gebruiker toevoegen"
|
|||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "Beheerder"
|
msgstr "Beheerder"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr "Gebruikersnaam beheerder"
|
msgstr "Gebruikersnaam beheerder"
|
||||||
@@ -73,7 +72,6 @@ msgstr "Gebruikersnaam beheerder"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Alles"
|
msgstr "Alles"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Always"
|
msgid "Always"
|
||||||
msgstr "Altijd"
|
msgstr "Altijd"
|
||||||
@@ -173,18 +171,14 @@ msgstr "Maak een filterexpressie om aan te geven wat u wilt lezen. Items die nie
|
|||||||
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
#: src/pages/app/TagDetailsPage.tsx
|
#: src/pages/app/TagDetailsPage.tsx
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Annuleren"
|
msgstr "Annuleren"
|
||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -240,7 +234,6 @@ msgstr "Bevestigen"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Bevestig wachtwoord"
|
msgstr "Bevestig wachtwoord"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "Bevestig wachtwoord"
|
msgstr "Bevestig wachtwoord"
|
||||||
@@ -294,7 +287,6 @@ msgstr "dagen"
|
|||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Verwijderen"
|
msgstr "Verwijderen"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Delete account"
|
msgid "Delete account"
|
||||||
msgstr "Account verwijderen"
|
msgstr "Account verwijderen"
|
||||||
@@ -342,13 +334,10 @@ msgstr "Link naar bladwijzerbalk slepen"
|
|||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "E-mail"
|
msgstr "E-mail"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "E-mail address"
|
msgid "E-mail address"
|
||||||
msgstr "E-mailadres"
|
msgstr "E-mailadres"
|
||||||
@@ -399,7 +388,6 @@ msgstr "Extensie opties"
|
|||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
msgstr "Feednaam"
|
msgstr "Feednaam"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
@@ -570,7 +558,6 @@ msgstr "Abonnementen laden..."
|
|||||||
msgid "Loading tags..."
|
msgid "Loading tags..."
|
||||||
msgstr "Tags laden..."
|
msgstr "Tags laden..."
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
@@ -648,7 +635,6 @@ msgstr "Navigeer naar een abonnement door de naam in te voeren"
|
|||||||
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
msgstr "Navigeer naar de volgende categorie/feed met ongelezen items wanneer alle items als gelezen worden gemarkeerd"
|
msgstr "Navigeer naar de volgende categorie/feed met ongelezen items wanneer alle items als gelezen worden gemarkeerd"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "Nooit"
|
msgstr "Nooit"
|
||||||
@@ -657,7 +643,6 @@ msgstr "Nooit"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Nieuw wachtwoord"
|
msgstr "Nieuw wachtwoord"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "Nieuw wachtwoord"
|
msgstr "Nieuw wachtwoord"
|
||||||
@@ -764,7 +749,6 @@ msgstr "OPML"
|
|||||||
msgid "OPML export"
|
msgid "OPML export"
|
||||||
msgstr "OPML-export"
|
msgstr "OPML-export"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "OPML file"
|
msgid "OPML file"
|
||||||
msgstr "OPML-bestand"
|
msgstr "OPML-bestand"
|
||||||
@@ -791,10 +775,7 @@ msgstr "Oudercategorie"
|
|||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Wachtwoord"
|
msgstr "Wachtwoord"
|
||||||
@@ -874,7 +855,6 @@ msgstr "Vernieuwen"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Registraties zijn gesloten op deze CommaFeed-instantie"
|
msgstr "Registraties zijn gesloten op deze CommaFeed-instantie"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "Wachtwoord herstellen"
|
msgstr "Wachtwoord herstellen"
|
||||||
@@ -883,7 +863,6 @@ msgstr "Wachtwoord herstellen"
|
|||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REST-API"
|
msgstr "REST-API"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr "Rechtermuisklik"
|
msgstr "Rechtermuisklik"
|
||||||
@@ -910,8 +889,6 @@ msgid "Scrolling"
|
|||||||
msgstr "Scrollen"
|
msgstr "Scrollen"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
#: src/components/sidebar/TreeSearch.tsx
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Zoeken"
|
msgstr "Zoeken"
|
||||||
@@ -924,7 +901,6 @@ msgstr "Selecteer volgende ongelezen feed/categorie"
|
|||||||
msgid "Select previous unread feed/category"
|
msgid "Select previous unread feed/category"
|
||||||
msgstr "Selecteer vorige ongelezen feed/categorie"
|
msgstr "Selecteer vorige ongelezen feed/categorie"
|
||||||
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
msgid "Server URL"
|
msgid "Server URL"
|
||||||
msgstr "Server-URL"
|
msgstr "Server-URL"
|
||||||
@@ -953,8 +929,6 @@ msgstr "Delen"
|
|||||||
msgid "Sharing sites"
|
msgid "Sharing sites"
|
||||||
msgstr "Sites delen"
|
msgstr "Sites delen"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Shift"
|
msgid "Shift"
|
||||||
msgstr "Shift"
|
msgstr "Shift"
|
||||||
@@ -1003,7 +977,6 @@ msgstr "Toon aantal ongelezen in tabblad-favicon"
|
|||||||
msgid "Show unread count in tab title"
|
msgid "Show unread count in tab title"
|
||||||
msgstr "Toon aantal ongelezen in tabbladtitel"
|
msgstr "Toon aantal ongelezen in tabbladtitel"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
@@ -1013,7 +986,6 @@ msgstr "Aanmelden"
|
|||||||
msgid "Something bad just happened..."
|
msgid "Something bad just happened..."
|
||||||
msgstr "Er is net iets ergs gebeurd..."
|
msgstr "Er is net iets ergs gebeurd..."
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Space"
|
msgid "Space"
|
||||||
msgstr "Ruimte"
|
msgstr "Ruimte"
|
||||||
@@ -1030,7 +1002,6 @@ msgstr "Ster"
|
|||||||
msgid "Starred"
|
msgid "Starred"
|
||||||
msgstr "Met ster"
|
msgstr "Met ster"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AddPage.tsx
|
#: src/pages/app/AddPage.tsx
|
||||||
msgid "Subscribe"
|
msgid "Subscribe"
|
||||||
@@ -1064,7 +1035,6 @@ msgstr "Schakel over naar licht thema"
|
|||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "Systeem"
|
msgstr "Systeem"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Tags"
|
msgstr "Tags"
|
||||||
@@ -1136,7 +1106,6 @@ msgstr "Ongelezen"
|
|||||||
msgid "Unstar"
|
msgid "Unstar"
|
||||||
msgstr "Sterren uit"
|
msgstr "Sterren uit"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Afmelden"
|
msgstr "Afmelden"
|
||||||
@@ -1149,7 +1118,6 @@ msgstr "Gebruikerssleutel"
|
|||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Gebruikersnaam"
|
msgstr "Gebruikersnaam"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "User Name or E-mail"
|
msgid "User Name or E-mail"
|
||||||
msgstr "Gebruikersnaam of e-mail"
|
msgstr "Gebruikersnaam of e-mail"
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ msgstr "Legg til brukar"
|
|||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "Administrator"
|
msgstr "Administrator"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr "Brukarnamn for administrator"
|
msgstr "Brukarnamn for administrator"
|
||||||
@@ -73,7 +72,6 @@ msgstr "Brukarnamn for administrator"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Alle"
|
msgstr "Alle"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Always"
|
msgid "Always"
|
||||||
msgstr "Alltid"
|
msgstr "Alltid"
|
||||||
@@ -173,18 +171,14 @@ msgstr "Bygg eit filteruttrykk for å angis kva du vil lesa. Innlegg som ikkje s
|
|||||||
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
#: src/pages/app/TagDetailsPage.tsx
|
#: src/pages/app/TagDetailsPage.tsx
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Avbryt"
|
msgstr "Avbryt"
|
||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -240,7 +234,6 @@ msgstr "Bekreft"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Bekreft passord"
|
msgstr "Bekreft passord"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "Stadfest passord"
|
msgstr "Stadfest passord"
|
||||||
@@ -294,7 +287,6 @@ msgstr "dagar"
|
|||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Slett"
|
msgstr "Slett"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Delete account"
|
msgid "Delete account"
|
||||||
msgstr "Slett konto"
|
msgstr "Slett konto"
|
||||||
@@ -342,13 +334,10 @@ msgstr "Dra lenken til bokmerkelinjen"
|
|||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "E-post"
|
msgstr "E-post"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "E-mail address"
|
msgid "E-mail address"
|
||||||
msgstr "E-postadresse"
|
msgstr "E-postadresse"
|
||||||
@@ -399,7 +388,6 @@ msgstr "Val for utviding"
|
|||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
msgstr "Feednavn"
|
msgstr "Feednavn"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
@@ -570,7 +558,6 @@ msgstr "Laster abonnementer..."
|
|||||||
msgid "Loading tags..."
|
msgid "Loading tags..."
|
||||||
msgstr "Laster tagger..."
|
msgstr "Laster tagger..."
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
@@ -648,7 +635,6 @@ msgstr "Naviger til et abonnement ved å skrive inn navnet"
|
|||||||
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
msgstr "Naviger til neste kategori/suap med ulesne innlegg når du markerer alle innlegg som lesne"
|
msgstr "Naviger til neste kategori/suap med ulesne innlegg når du markerer alle innlegg som lesne"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "Aldri"
|
msgstr "Aldri"
|
||||||
@@ -657,7 +643,6 @@ msgstr "Aldri"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Nytt passord"
|
msgstr "Nytt passord"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "Nytt passord"
|
msgstr "Nytt passord"
|
||||||
@@ -764,7 +749,6 @@ msgstr "OPML"
|
|||||||
msgid "OPML export"
|
msgid "OPML export"
|
||||||
msgstr "OPML-eksport"
|
msgstr "OPML-eksport"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "OPML file"
|
msgid "OPML file"
|
||||||
msgstr "OPML-fil"
|
msgstr "OPML-fil"
|
||||||
@@ -791,10 +775,7 @@ msgstr "Overordnet kategori"
|
|||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Passord"
|
msgstr "Passord"
|
||||||
@@ -874,7 +855,6 @@ msgstr "Oppdater"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Registreringer er stengt på denne CommaFeed-forekomsten"
|
msgstr "Registreringer er stengt på denne CommaFeed-forekomsten"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "Tilbakestill passord"
|
msgstr "Tilbakestill passord"
|
||||||
@@ -883,7 +863,6 @@ msgstr "Tilbakestill passord"
|
|||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REST API"
|
msgstr "REST API"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr "Høgreklikk"
|
msgstr "Høgreklikk"
|
||||||
@@ -910,8 +889,6 @@ msgid "Scrolling"
|
|||||||
msgstr "Rulling"
|
msgstr "Rulling"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
#: src/components/sidebar/TreeSearch.tsx
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Søk"
|
msgstr "Søk"
|
||||||
@@ -924,7 +901,6 @@ msgstr "Vel neste ulesne suap/kategori"
|
|||||||
msgid "Select previous unread feed/category"
|
msgid "Select previous unread feed/category"
|
||||||
msgstr "Vel førre ulesne suap/kategori"
|
msgstr "Vel førre ulesne suap/kategori"
|
||||||
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
msgid "Server URL"
|
msgid "Server URL"
|
||||||
msgstr "Server-URL"
|
msgstr "Server-URL"
|
||||||
@@ -953,8 +929,6 @@ msgstr "Del"
|
|||||||
msgid "Sharing sites"
|
msgid "Sharing sites"
|
||||||
msgstr "Delingssider"
|
msgstr "Delingssider"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Shift"
|
msgid "Shift"
|
||||||
msgstr "Skift"
|
msgstr "Skift"
|
||||||
@@ -1003,7 +977,6 @@ msgstr "Vis talet på ulesne i favicon for fana"
|
|||||||
msgid "Show unread count in tab title"
|
msgid "Show unread count in tab title"
|
||||||
msgstr "Vis talet på ulesne i tittelen på fana"
|
msgstr "Vis talet på ulesne i tittelen på fana"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
@@ -1013,7 +986,6 @@ msgstr "Meld deg på"
|
|||||||
msgid "Something bad just happened..."
|
msgid "Something bad just happened..."
|
||||||
msgstr "Noe ille skjedde akkurat..."
|
msgstr "Noe ille skjedde akkurat..."
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Space"
|
msgid "Space"
|
||||||
msgstr "Mellomrom"
|
msgstr "Mellomrom"
|
||||||
@@ -1030,7 +1002,6 @@ msgstr "Stjerne"
|
|||||||
msgid "Starred"
|
msgid "Starred"
|
||||||
msgstr "Stjernemerka"
|
msgstr "Stjernemerka"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AddPage.tsx
|
#: src/pages/app/AddPage.tsx
|
||||||
msgid "Subscribe"
|
msgid "Subscribe"
|
||||||
@@ -1064,7 +1035,6 @@ msgstr "Bytt til lyst tema"
|
|||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "System"
|
msgstr "System"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Tagger"
|
msgstr "Tagger"
|
||||||
@@ -1136,7 +1106,6 @@ msgstr "Ulesen"
|
|||||||
msgid "Unstar"
|
msgid "Unstar"
|
||||||
msgstr "Fjern stjerne"
|
msgstr "Fjern stjerne"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Avslutt abonnement"
|
msgstr "Avslutt abonnement"
|
||||||
@@ -1149,7 +1118,6 @@ msgstr "Brukarnøkkel"
|
|||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Brukarnamn"
|
msgstr "Brukarnamn"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "User Name or E-mail"
|
msgid "User Name or E-mail"
|
||||||
msgstr "Brukarnamn eller e-post"
|
msgstr "Brukarnamn eller e-post"
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ msgstr "Dodaj użytkownika"
|
|||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "Administracja"
|
msgstr "Administracja"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr "Nazwa użytkownika administratora"
|
msgstr "Nazwa użytkownika administratora"
|
||||||
@@ -73,7 +72,6 @@ msgstr "Nazwa użytkownika administratora"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Wszystkie"
|
msgstr "Wszystkie"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Always"
|
msgid "Always"
|
||||||
msgstr "Zawsze"
|
msgstr "Zawsze"
|
||||||
@@ -173,18 +171,14 @@ msgstr "Zbuduj wyrażenie filtrujące, aby wskazać, co chcesz czytać. Wpisy, k
|
|||||||
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
#: src/pages/app/TagDetailsPage.tsx
|
#: src/pages/app/TagDetailsPage.tsx
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Anuluj"
|
msgstr "Anuluj"
|
||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -240,7 +234,6 @@ msgstr "Potwierdź"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Potwierdź hasło"
|
msgstr "Potwierdź hasło"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "Potwierdź hasło"
|
msgstr "Potwierdź hasło"
|
||||||
@@ -294,7 +287,6 @@ msgstr "dni"
|
|||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Usuń"
|
msgstr "Usuń"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Delete account"
|
msgid "Delete account"
|
||||||
msgstr "Usuń konto"
|
msgstr "Usuń konto"
|
||||||
@@ -342,13 +334,10 @@ msgstr "Przeciągnij link do paska zakładek"
|
|||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "E-mail"
|
msgstr "E-mail"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "E-mail address"
|
msgid "E-mail address"
|
||||||
msgstr "Adres e-mail"
|
msgstr "Adres e-mail"
|
||||||
@@ -399,7 +388,6 @@ msgstr "Opcje rozszerzenia"
|
|||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
msgstr "nazwa kanału"
|
msgstr "nazwa kanału"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
@@ -570,7 +558,6 @@ msgstr "Ładowanie subskrypcji..."
|
|||||||
msgid "Loading tags..."
|
msgid "Loading tags..."
|
||||||
msgstr "Ładowanie tagów..."
|
msgstr "Ładowanie tagów..."
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
@@ -648,7 +635,6 @@ msgstr "Przejdź do subskrypcji, wpisując jej nazwę"
|
|||||||
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
msgstr "Przejdź do następnej kategorii/kanału z nieprzeczytanymi wpisami po oznaczeniu wszystkich wpisów jako przeczytane"
|
msgstr "Przejdź do następnej kategorii/kanału z nieprzeczytanymi wpisami po oznaczeniu wszystkich wpisów jako przeczytane"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "Nigdy"
|
msgstr "Nigdy"
|
||||||
@@ -657,7 +643,6 @@ msgstr "Nigdy"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Nowe hasło"
|
msgstr "Nowe hasło"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "Nowe hasło"
|
msgstr "Nowe hasło"
|
||||||
@@ -764,7 +749,6 @@ msgstr "OPML"
|
|||||||
msgid "OPML export"
|
msgid "OPML export"
|
||||||
msgstr "Eksport OPML"
|
msgstr "Eksport OPML"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "OPML file"
|
msgid "OPML file"
|
||||||
msgstr "Plik OPML"
|
msgstr "Plik OPML"
|
||||||
@@ -791,10 +775,7 @@ msgstr "Kategoria nadrzędna"
|
|||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Hasło"
|
msgstr "Hasło"
|
||||||
@@ -874,7 +855,6 @@ msgstr "Odśwież"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Rejestracje są zamknięte w tej instancji CommaFeed"
|
msgstr "Rejestracje są zamknięte w tej instancji CommaFeed"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "Zresetuj hasło"
|
msgstr "Zresetuj hasło"
|
||||||
@@ -883,7 +863,6 @@ msgstr "Zresetuj hasło"
|
|||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REST API"
|
msgstr "REST API"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr "Prawe kliknięcie"
|
msgstr "Prawe kliknięcie"
|
||||||
@@ -910,8 +889,6 @@ msgid "Scrolling"
|
|||||||
msgstr "Przewijanie"
|
msgstr "Przewijanie"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
#: src/components/sidebar/TreeSearch.tsx
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Szukaj"
|
msgstr "Szukaj"
|
||||||
@@ -924,7 +901,6 @@ msgstr "Wybierz następny nieprzeczytany kanał/kategorię"
|
|||||||
msgid "Select previous unread feed/category"
|
msgid "Select previous unread feed/category"
|
||||||
msgstr "Wybierz poprzedni nieprzeczytany kanał/kategorię"
|
msgstr "Wybierz poprzedni nieprzeczytany kanał/kategorię"
|
||||||
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
msgid "Server URL"
|
msgid "Server URL"
|
||||||
msgstr "URL serwera"
|
msgstr "URL serwera"
|
||||||
@@ -953,8 +929,6 @@ msgstr "Udostępnij"
|
|||||||
msgid "Sharing sites"
|
msgid "Sharing sites"
|
||||||
msgstr "Udostępnianie witryn"
|
msgstr "Udostępnianie witryn"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Shift"
|
msgid "Shift"
|
||||||
msgstr "zmiana"
|
msgstr "zmiana"
|
||||||
@@ -1003,7 +977,6 @@ msgstr "Pokazuj liczbę nieprzeczytanych na ikonie karty"
|
|||||||
msgid "Show unread count in tab title"
|
msgid "Show unread count in tab title"
|
||||||
msgstr "Pokazuj liczbę nieprzeczytanych w tytule karty"
|
msgstr "Pokazuj liczbę nieprzeczytanych w tytule karty"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
@@ -1013,7 +986,6 @@ msgstr "Zarejestruj się"
|
|||||||
msgid "Something bad just happened..."
|
msgid "Something bad just happened..."
|
||||||
msgstr "Coś złego właśnie się stało..."
|
msgstr "Coś złego właśnie się stało..."
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Space"
|
msgid "Space"
|
||||||
msgstr "Przestrzeń"
|
msgstr "Przestrzeń"
|
||||||
@@ -1030,7 +1002,6 @@ msgstr "Gwiazda"
|
|||||||
msgid "Starred"
|
msgid "Starred"
|
||||||
msgstr "Oznaczone gwiazdką"
|
msgstr "Oznaczone gwiazdką"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AddPage.tsx
|
#: src/pages/app/AddPage.tsx
|
||||||
msgid "Subscribe"
|
msgid "Subscribe"
|
||||||
@@ -1064,7 +1035,6 @@ msgstr "Przełącz na jasny motyw"
|
|||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "Systemowy"
|
msgstr "Systemowy"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Tagi"
|
msgstr "Tagi"
|
||||||
@@ -1136,7 +1106,6 @@ msgstr "Nieprzeczytane"
|
|||||||
msgid "Unstar"
|
msgid "Unstar"
|
||||||
msgstr "Usuń gwiazdkę"
|
msgstr "Usuń gwiazdkę"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Anuluj subskrypcję"
|
msgstr "Anuluj subskrypcję"
|
||||||
@@ -1149,7 +1118,6 @@ msgstr "Klucz użytkownika"
|
|||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Nazwa użytkownika"
|
msgstr "Nazwa użytkownika"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "User Name or E-mail"
|
msgid "User Name or E-mail"
|
||||||
msgstr "Nazwa użytkownika lub e-mail"
|
msgstr "Nazwa użytkownika lub e-mail"
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ msgstr "Adicionar usuário"
|
|||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "Administrador"
|
msgstr "Administrador"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr "Nome de usuário do administrador"
|
msgstr "Nome de usuário do administrador"
|
||||||
@@ -73,7 +72,6 @@ msgstr "Nome de usuário do administrador"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Todos"
|
msgstr "Todos"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Always"
|
msgid "Always"
|
||||||
msgstr "Sempre"
|
msgstr "Sempre"
|
||||||
@@ -173,18 +171,14 @@ msgstr "Crie uma expressão de filtro para indicar o que você deseja ler. As en
|
|||||||
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
#: src/pages/app/TagDetailsPage.tsx
|
#: src/pages/app/TagDetailsPage.tsx
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Cancelar"
|
msgstr "Cancelar"
|
||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -240,7 +234,6 @@ msgstr "Confirmar"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Confirmar senha"
|
msgstr "Confirmar senha"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "Confirmar senha"
|
msgstr "Confirmar senha"
|
||||||
@@ -294,7 +287,6 @@ msgstr "dias"
|
|||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Excluir"
|
msgstr "Excluir"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Delete account"
|
msgid "Delete account"
|
||||||
msgstr "Excluir conta"
|
msgstr "Excluir conta"
|
||||||
@@ -342,13 +334,10 @@ msgstr "Arraste o link para a barra de favoritos"
|
|||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "E-mail"
|
msgstr "E-mail"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "E-mail address"
|
msgid "E-mail address"
|
||||||
msgstr "Endereço de e-mail"
|
msgstr "Endereço de e-mail"
|
||||||
@@ -399,7 +388,6 @@ msgstr "Opções da extensão"
|
|||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
msgstr "Nome do feed"
|
msgstr "Nome do feed"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
@@ -570,7 +558,6 @@ msgstr "Carregando assinaturas..."
|
|||||||
msgid "Loading tags..."
|
msgid "Loading tags..."
|
||||||
msgstr "Carregando tags..."
|
msgstr "Carregando tags..."
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
@@ -648,7 +635,6 @@ msgstr "Navegue até uma assinatura digitando seu nome"
|
|||||||
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
msgstr "Navegar para a próxima categoria/feed com entradas não lidas quando todas as entrafas forem lidas"
|
msgstr "Navegar para a próxima categoria/feed com entradas não lidas quando todas as entrafas forem lidas"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "Nunca"
|
msgstr "Nunca"
|
||||||
@@ -657,7 +643,6 @@ msgstr "Nunca"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Nova senha"
|
msgstr "Nova senha"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "Nova senha"
|
msgstr "Nova senha"
|
||||||
@@ -764,7 +749,6 @@ msgstr "OPML"
|
|||||||
msgid "OPML export"
|
msgid "OPML export"
|
||||||
msgstr "Exportação OPML"
|
msgstr "Exportação OPML"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "OPML file"
|
msgid "OPML file"
|
||||||
msgstr "Arquivo OPML"
|
msgstr "Arquivo OPML"
|
||||||
@@ -791,10 +775,7 @@ msgstr "Categoria Pai"
|
|||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Senha"
|
msgstr "Senha"
|
||||||
@@ -874,7 +855,6 @@ msgstr "Atualizar"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Os registros estão fechados nesta instância do CommaFeed"
|
msgstr "Os registros estão fechados nesta instância do CommaFeed"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "Redefinir senha"
|
msgstr "Redefinir senha"
|
||||||
@@ -883,7 +863,6 @@ msgstr "Redefinir senha"
|
|||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "API REST"
|
msgstr "API REST"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr "Clique com o botão direito"
|
msgstr "Clique com o botão direito"
|
||||||
@@ -910,8 +889,6 @@ msgid "Scrolling"
|
|||||||
msgstr "Deslizar"
|
msgstr "Deslizar"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
#: src/components/sidebar/TreeSearch.tsx
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Pesquisar"
|
msgstr "Pesquisar"
|
||||||
@@ -924,7 +901,6 @@ msgstr "Selecionar próximo feed/categoria não lido"
|
|||||||
msgid "Select previous unread feed/category"
|
msgid "Select previous unread feed/category"
|
||||||
msgstr "Selecionar feed/categoria não lido anterior"
|
msgstr "Selecionar feed/categoria não lido anterior"
|
||||||
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
msgid "Server URL"
|
msgid "Server URL"
|
||||||
msgstr "URL do servidor"
|
msgstr "URL do servidor"
|
||||||
@@ -953,8 +929,6 @@ msgstr "Compartilhar"
|
|||||||
msgid "Sharing sites"
|
msgid "Sharing sites"
|
||||||
msgstr "Compartilhando sites"
|
msgstr "Compartilhando sites"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Shift"
|
msgid "Shift"
|
||||||
msgstr "Shift"
|
msgstr "Shift"
|
||||||
@@ -1003,7 +977,6 @@ msgstr "Mostrar contagem de não lidos no favion da aba"
|
|||||||
msgid "Show unread count in tab title"
|
msgid "Show unread count in tab title"
|
||||||
msgstr "Mostrar contagem de não lidos no título da aba"
|
msgstr "Mostrar contagem de não lidos no título da aba"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
@@ -1013,7 +986,6 @@ msgstr "Inscreva-se"
|
|||||||
msgid "Something bad just happened..."
|
msgid "Something bad just happened..."
|
||||||
msgstr "Algo ruim acabou de acontecer..."
|
msgstr "Algo ruim acabou de acontecer..."
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Space"
|
msgid "Space"
|
||||||
msgstr "Espaço"
|
msgstr "Espaço"
|
||||||
@@ -1030,7 +1002,6 @@ msgstr "Estrela"
|
|||||||
msgid "Starred"
|
msgid "Starred"
|
||||||
msgstr "Com estrela"
|
msgstr "Com estrela"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AddPage.tsx
|
#: src/pages/app/AddPage.tsx
|
||||||
msgid "Subscribe"
|
msgid "Subscribe"
|
||||||
@@ -1064,7 +1035,6 @@ msgstr "Mudar para tema claro"
|
|||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "Sistema"
|
msgstr "Sistema"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Etiquetas"
|
msgstr "Etiquetas"
|
||||||
@@ -1136,7 +1106,6 @@ msgstr "Não lido"
|
|||||||
msgid "Unstar"
|
msgid "Unstar"
|
||||||
msgstr "Desestrelar"
|
msgstr "Desestrelar"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Cancelar inscrição"
|
msgstr "Cancelar inscrição"
|
||||||
@@ -1149,7 +1118,6 @@ msgstr "Chave do usuário"
|
|||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Nome de usuário"
|
msgstr "Nome de usuário"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "User Name or E-mail"
|
msgid "User Name or E-mail"
|
||||||
msgstr "Nome de usuário ou e-mail"
|
msgstr "Nome de usuário ou e-mail"
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ msgstr "Добавить пользователя"
|
|||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "Админ"
|
msgstr "Админ"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr "Имя администратора"
|
msgstr "Имя администратора"
|
||||||
@@ -73,7 +72,6 @@ msgstr "Имя администратора"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Все"
|
msgstr "Все"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Always"
|
msgid "Always"
|
||||||
msgstr "Всегда"
|
msgstr "Всегда"
|
||||||
@@ -173,18 +171,14 @@ msgstr "Создайте выражение фильтра, чтобы указ
|
|||||||
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
#: src/pages/app/TagDetailsPage.tsx
|
#: src/pages/app/TagDetailsPage.tsx
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Отмена"
|
msgstr "Отмена"
|
||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -240,7 +234,6 @@ msgstr "Подтвердить"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Подтвердить пароль"
|
msgstr "Подтвердить пароль"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "Подтвердите пароль"
|
msgstr "Подтвердите пароль"
|
||||||
@@ -294,7 +287,6 @@ msgstr "дней"
|
|||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Удалить"
|
msgstr "Удалить"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Delete account"
|
msgid "Delete account"
|
||||||
msgstr "Удалить учетную запись"
|
msgstr "Удалить учетную запись"
|
||||||
@@ -342,13 +334,10 @@ msgstr "Перетащите ссылку на панель закладок"
|
|||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "Электронная почта"
|
msgstr "Электронная почта"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "E-mail address"
|
msgid "E-mail address"
|
||||||
msgstr "Адрес электронной почты"
|
msgstr "Адрес электронной почты"
|
||||||
@@ -399,7 +388,6 @@ msgstr "Параметры расширения"
|
|||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
msgstr "Имя фида"
|
msgstr "Имя фида"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
@@ -570,7 +558,6 @@ msgstr "Загрузка подписок..."
|
|||||||
msgid "Loading tags..."
|
msgid "Loading tags..."
|
||||||
msgstr "Загрузка тегов..."
|
msgstr "Загрузка тегов..."
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
@@ -648,7 +635,6 @@ msgstr "Перейдите к подписке, введя ее имя."
|
|||||||
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
msgstr "Переходить к следующей категории/фиду с непрочитанными записями при пометке всех записей как прочитанных"
|
msgstr "Переходить к следующей категории/фиду с непрочитанными записями при пометке всех записей как прочитанных"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "Никогда"
|
msgstr "Никогда"
|
||||||
@@ -657,7 +643,6 @@ msgstr "Никогда"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Новый пароль"
|
msgstr "Новый пароль"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "Новый пароль"
|
msgstr "Новый пароль"
|
||||||
@@ -764,7 +749,6 @@ msgstr "OPML"
|
|||||||
msgid "OPML export"
|
msgid "OPML export"
|
||||||
msgstr "Экспорт OPML"
|
msgstr "Экспорт OPML"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "OPML file"
|
msgid "OPML file"
|
||||||
msgstr "OPML файл"
|
msgstr "OPML файл"
|
||||||
@@ -791,10 +775,7 @@ msgstr "Родительская категория"
|
|||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Пароль"
|
msgstr "Пароль"
|
||||||
@@ -874,7 +855,6 @@ msgstr "Обновить"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Регистрация закрыта для этого экземпляра CommaFeed."
|
msgstr "Регистрация закрыта для этого экземпляра CommaFeed."
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "Сброс пароля"
|
msgstr "Сброс пароля"
|
||||||
@@ -883,7 +863,6 @@ msgstr "Сброс пароля"
|
|||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REST API"
|
msgstr "REST API"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr "Правый клик"
|
msgstr "Правый клик"
|
||||||
@@ -910,8 +889,6 @@ msgid "Scrolling"
|
|||||||
msgstr "Прокрутка"
|
msgstr "Прокрутка"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
#: src/components/sidebar/TreeSearch.tsx
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Поиск"
|
msgstr "Поиск"
|
||||||
@@ -924,7 +901,6 @@ msgstr "Выбрать следующий непрочитанный фид/ка
|
|||||||
msgid "Select previous unread feed/category"
|
msgid "Select previous unread feed/category"
|
||||||
msgstr "Выбрать предыдущий непрочитанный фид/категорию"
|
msgstr "Выбрать предыдущий непрочитанный фид/категорию"
|
||||||
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
msgid "Server URL"
|
msgid "Server URL"
|
||||||
msgstr "URL сервера"
|
msgstr "URL сервера"
|
||||||
@@ -953,8 +929,6 @@ msgstr "Поделиться"
|
|||||||
msgid "Sharing sites"
|
msgid "Sharing sites"
|
||||||
msgstr "Обмен сайтами"
|
msgstr "Обмен сайтами"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Shift"
|
msgid "Shift"
|
||||||
msgstr "Shift"
|
msgstr "Shift"
|
||||||
@@ -1003,7 +977,6 @@ msgstr "Показывать количество непрочитанных в
|
|||||||
msgid "Show unread count in tab title"
|
msgid "Show unread count in tab title"
|
||||||
msgstr "Показывать количество непрочитанных в заголовке вкладки"
|
msgstr "Показывать количество непрочитанных в заголовке вкладки"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
@@ -1013,7 +986,6 @@ msgstr "Зарегистрироваться"
|
|||||||
msgid "Something bad just happened..."
|
msgid "Something bad just happened..."
|
||||||
msgstr "Только что случилось что-то плохое..."
|
msgstr "Только что случилось что-то плохое..."
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Space"
|
msgid "Space"
|
||||||
msgstr "Пробел"
|
msgstr "Пробел"
|
||||||
@@ -1030,7 +1002,6 @@ msgstr "В избранное"
|
|||||||
msgid "Starred"
|
msgid "Starred"
|
||||||
msgstr "Избранное"
|
msgstr "Избранное"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AddPage.tsx
|
#: src/pages/app/AddPage.tsx
|
||||||
msgid "Subscribe"
|
msgid "Subscribe"
|
||||||
@@ -1064,7 +1035,6 @@ msgstr "Переключиться на светлую тему"
|
|||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "Системная"
|
msgstr "Системная"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Теги"
|
msgstr "Теги"
|
||||||
@@ -1136,7 +1106,6 @@ msgstr "Не прочитано"
|
|||||||
msgid "Unstar"
|
msgid "Unstar"
|
||||||
msgstr "Удалить из избранного"
|
msgstr "Удалить из избранного"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Отписаться"
|
msgstr "Отписаться"
|
||||||
@@ -1149,7 +1118,6 @@ msgstr "Ключ пользователя"
|
|||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Имя пользователя"
|
msgstr "Имя пользователя"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "User Name or E-mail"
|
msgid "User Name or E-mail"
|
||||||
msgstr "Имя пользователя или адрес электронной почты"
|
msgstr "Имя пользователя или адрес электронной почты"
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ msgstr "Pridať užívateľa"
|
|||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "Správca"
|
msgstr "Správca"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr "Meno správcu"
|
msgstr "Meno správcu"
|
||||||
@@ -73,7 +72,6 @@ msgstr "Meno správcu"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Všetky"
|
msgstr "Všetky"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Always"
|
msgid "Always"
|
||||||
msgstr "Vždy"
|
msgstr "Vždy"
|
||||||
@@ -173,18 +171,14 @@ msgstr "Vytvorte výraz filtra na určenie toho, čo chcete čítať. Záznamy,
|
|||||||
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
#: src/pages/app/TagDetailsPage.tsx
|
#: src/pages/app/TagDetailsPage.tsx
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Zrušiť"
|
msgstr "Zrušiť"
|
||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -240,7 +234,6 @@ msgstr "Potvrdiť"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Potvrďte heslo"
|
msgstr "Potvrďte heslo"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "Potvrdiť heslo"
|
msgstr "Potvrdiť heslo"
|
||||||
@@ -294,7 +287,6 @@ msgstr "dni"
|
|||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Vymazať"
|
msgstr "Vymazať"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Delete account"
|
msgid "Delete account"
|
||||||
msgstr "Vymažte účet"
|
msgstr "Vymažte účet"
|
||||||
@@ -342,13 +334,10 @@ msgstr "Presuňte odkaz na lištu so záložkami"
|
|||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "E-mail"
|
msgstr "E-mail"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "E-mail address"
|
msgid "E-mail address"
|
||||||
msgstr "E-mailová adresa"
|
msgstr "E-mailová adresa"
|
||||||
@@ -399,7 +388,6 @@ msgstr "Možnosti rozšírenia"
|
|||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
msgstr "Názov informačného kanála"
|
msgstr "Názov informačného kanála"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
@@ -570,7 +558,6 @@ msgstr "Načítavam odbery..."
|
|||||||
msgid "Loading tags..."
|
msgid "Loading tags..."
|
||||||
msgstr "Načítavam značky..."
|
msgstr "Načítavam značky..."
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
@@ -648,7 +635,6 @@ msgstr "Prejdite na predplatné zadaním jeho názvu"
|
|||||||
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
msgstr "Pri označovaní všetkých položiek ako prečítaných prejdite na ďalšiu kategóriu/kanál s neprečítanými položkami"
|
msgstr "Pri označovaní všetkých položiek ako prečítaných prejdite na ďalšiu kategóriu/kanál s neprečítanými položkami"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "Nikdy"
|
msgstr "Nikdy"
|
||||||
@@ -657,7 +643,6 @@ msgstr "Nikdy"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Nové heslo"
|
msgstr "Nové heslo"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "Nové heslo"
|
msgstr "Nové heslo"
|
||||||
@@ -764,7 +749,6 @@ msgstr "OPML"
|
|||||||
msgid "OPML export"
|
msgid "OPML export"
|
||||||
msgstr "Export OPML"
|
msgstr "Export OPML"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "OPML file"
|
msgid "OPML file"
|
||||||
msgstr "Súbor OPML"
|
msgstr "Súbor OPML"
|
||||||
@@ -791,10 +775,7 @@ msgstr "Rodičovská kategória"
|
|||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Heslo"
|
msgstr "Heslo"
|
||||||
@@ -874,7 +855,6 @@ msgstr "Obnoviť"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "V tejto inštancii CommaFeed sú registrácie uzavreté"
|
msgstr "V tejto inštancii CommaFeed sú registrácie uzavreté"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "Obnoviť heslo"
|
msgstr "Obnoviť heslo"
|
||||||
@@ -883,7 +863,6 @@ msgstr "Obnoviť heslo"
|
|||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REST API"
|
msgstr "REST API"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr "Kliknutie pravým tlačidlom"
|
msgstr "Kliknutie pravým tlačidlom"
|
||||||
@@ -910,8 +889,6 @@ msgid "Scrolling"
|
|||||||
msgstr "Rolovanie"
|
msgstr "Rolovanie"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
#: src/components/sidebar/TreeSearch.tsx
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Hľadaj"
|
msgstr "Hľadaj"
|
||||||
@@ -924,7 +901,6 @@ msgstr "Vybrať ďalší neprečítaný kanál/kategóriu"
|
|||||||
msgid "Select previous unread feed/category"
|
msgid "Select previous unread feed/category"
|
||||||
msgstr "Vybrať predchádzajúci neprečítaný kanál/kategóriu"
|
msgstr "Vybrať predchádzajúci neprečítaný kanál/kategóriu"
|
||||||
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
msgid "Server URL"
|
msgid "Server URL"
|
||||||
msgstr "URL servera"
|
msgstr "URL servera"
|
||||||
@@ -953,8 +929,6 @@ msgstr "Zdieľať"
|
|||||||
msgid "Sharing sites"
|
msgid "Sharing sites"
|
||||||
msgstr "Zdieľanie stránok"
|
msgstr "Zdieľanie stránok"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Shift"
|
msgid "Shift"
|
||||||
msgstr "Smena"
|
msgstr "Smena"
|
||||||
@@ -1003,7 +977,6 @@ msgstr "Zobraziť počet neprečítaných v ikone karty"
|
|||||||
msgid "Show unread count in tab title"
|
msgid "Show unread count in tab title"
|
||||||
msgstr "Zobraziť počet neprečítaných v názve karty"
|
msgstr "Zobraziť počet neprečítaných v názve karty"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
@@ -1013,7 +986,6 @@ msgstr "Zaregistrujte sa"
|
|||||||
msgid "Something bad just happened..."
|
msgid "Something bad just happened..."
|
||||||
msgstr "Práve sa stalo niečo zlé..."
|
msgstr "Práve sa stalo niečo zlé..."
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Space"
|
msgid "Space"
|
||||||
msgstr "Medzera"
|
msgstr "Medzera"
|
||||||
@@ -1030,7 +1002,6 @@ msgstr "Hviezda"
|
|||||||
msgid "Starred"
|
msgid "Starred"
|
||||||
msgstr "S hviezdičkou"
|
msgstr "S hviezdičkou"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AddPage.tsx
|
#: src/pages/app/AddPage.tsx
|
||||||
msgid "Subscribe"
|
msgid "Subscribe"
|
||||||
@@ -1064,7 +1035,6 @@ msgstr "Prepnite na svetlú tému"
|
|||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "Systém"
|
msgstr "Systém"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Značky"
|
msgstr "Značky"
|
||||||
@@ -1136,7 +1106,6 @@ msgstr "Neprečítané"
|
|||||||
msgid "Unstar"
|
msgid "Unstar"
|
||||||
msgstr "Odobrať hviezdičku"
|
msgstr "Odobrať hviezdičku"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Zrušte odber"
|
msgstr "Zrušte odber"
|
||||||
@@ -1149,7 +1118,6 @@ msgstr "Používateľský kľúč"
|
|||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Meno používateľa"
|
msgstr "Meno používateľa"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "User Name or E-mail"
|
msgid "User Name or E-mail"
|
||||||
msgstr "Meno používateľa alebo e-mail"
|
msgstr "Meno používateľa alebo e-mail"
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ msgstr "Lägg till användare"
|
|||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "Admin"
|
msgstr "Admin"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr "Administratörsanvändarnamn"
|
msgstr "Administratörsanvändarnamn"
|
||||||
@@ -73,7 +72,6 @@ msgstr "Administratörsanvändarnamn"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Alla"
|
msgstr "Alla"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Always"
|
msgid "Always"
|
||||||
msgstr "Alltid"
|
msgstr "Alltid"
|
||||||
@@ -173,18 +171,14 @@ msgstr "Skapa ett filteruttryck för att ange vad du vill läsa. Poster som inte
|
|||||||
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
#: src/pages/app/TagDetailsPage.tsx
|
#: src/pages/app/TagDetailsPage.tsx
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Avbryt"
|
msgstr "Avbryt"
|
||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -240,7 +234,6 @@ msgstr "Bekräfta"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Bekräfta lösenord"
|
msgstr "Bekräfta lösenord"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "Bekräfta lösenord"
|
msgstr "Bekräfta lösenord"
|
||||||
@@ -294,7 +287,6 @@ msgstr "dagar"
|
|||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Ta bort"
|
msgstr "Ta bort"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Delete account"
|
msgid "Delete account"
|
||||||
msgstr "Radera konto"
|
msgstr "Radera konto"
|
||||||
@@ -342,13 +334,10 @@ msgstr "Dra länken till bokmärkesfältet"
|
|||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "E-post"
|
msgstr "E-post"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "E-mail address"
|
msgid "E-mail address"
|
||||||
msgstr "E-postadress"
|
msgstr "E-postadress"
|
||||||
@@ -399,7 +388,6 @@ msgstr "Tilläggsalternativ"
|
|||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
msgstr "Flödesnamn"
|
msgstr "Flödesnamn"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
@@ -570,7 +558,6 @@ msgstr "Laddar prenumerationer..."
|
|||||||
msgid "Loading tags..."
|
msgid "Loading tags..."
|
||||||
msgstr "Laddar taggar..."
|
msgstr "Laddar taggar..."
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
@@ -648,7 +635,6 @@ msgstr "Navigera till ett abonnemang genom att ange dess namn"
|
|||||||
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
msgstr "Navigera till nästa kategori/flöde med olästa poster när alla poster markeras som lästa"
|
msgstr "Navigera till nästa kategori/flöde med olästa poster när alla poster markeras som lästa"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "Aldrig"
|
msgstr "Aldrig"
|
||||||
@@ -657,7 +643,6 @@ msgstr "Aldrig"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Nytt lösenord"
|
msgstr "Nytt lösenord"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "Nytt lösenord"
|
msgstr "Nytt lösenord"
|
||||||
@@ -764,7 +749,6 @@ msgstr "OPML"
|
|||||||
msgid "OPML export"
|
msgid "OPML export"
|
||||||
msgstr "OPML-export"
|
msgstr "OPML-export"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "OPML file"
|
msgid "OPML file"
|
||||||
msgstr "OPML-fil"
|
msgstr "OPML-fil"
|
||||||
@@ -791,10 +775,7 @@ msgstr "Föräldrakategori"
|
|||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Lösenord"
|
msgstr "Lösenord"
|
||||||
@@ -874,7 +855,6 @@ msgstr "Uppdatera"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Registreringar är stängda på denna CommaFeed-instans"
|
msgstr "Registreringar är stängda på denna CommaFeed-instans"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "Återställ lösenord"
|
msgstr "Återställ lösenord"
|
||||||
@@ -883,7 +863,6 @@ msgstr "Återställ lösenord"
|
|||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REST API"
|
msgstr "REST API"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr "Högerklick"
|
msgstr "Högerklick"
|
||||||
@@ -910,8 +889,6 @@ msgid "Scrolling"
|
|||||||
msgstr "Rullning"
|
msgstr "Rullning"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
#: src/components/sidebar/TreeSearch.tsx
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Sök"
|
msgstr "Sök"
|
||||||
@@ -924,7 +901,6 @@ msgstr "Välj nästa olästa flöde/kategori"
|
|||||||
msgid "Select previous unread feed/category"
|
msgid "Select previous unread feed/category"
|
||||||
msgstr "Välj föregående olästa flöde/kategori"
|
msgstr "Välj föregående olästa flöde/kategori"
|
||||||
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
msgid "Server URL"
|
msgid "Server URL"
|
||||||
msgstr "Server-URL"
|
msgstr "Server-URL"
|
||||||
@@ -953,8 +929,6 @@ msgstr "Dela"
|
|||||||
msgid "Sharing sites"
|
msgid "Sharing sites"
|
||||||
msgstr "Delningssajter"
|
msgstr "Delningssajter"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Shift"
|
msgid "Shift"
|
||||||
msgstr "Skift"
|
msgstr "Skift"
|
||||||
@@ -1003,7 +977,6 @@ msgstr "Visa antal olästa i flikikonen"
|
|||||||
msgid "Show unread count in tab title"
|
msgid "Show unread count in tab title"
|
||||||
msgstr "Visa antal olästa i fliktiteln"
|
msgstr "Visa antal olästa i fliktiteln"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
@@ -1013,7 +986,6 @@ msgstr "Anmäl dig"
|
|||||||
msgid "Something bad just happened..."
|
msgid "Something bad just happened..."
|
||||||
msgstr "Något dåligt hände precis..."
|
msgstr "Något dåligt hände precis..."
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Space"
|
msgid "Space"
|
||||||
msgstr "Rymden"
|
msgstr "Rymden"
|
||||||
@@ -1030,7 +1002,6 @@ msgstr "Stjärna"
|
|||||||
msgid "Starred"
|
msgid "Starred"
|
||||||
msgstr "Starmed"
|
msgstr "Starmed"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AddPage.tsx
|
#: src/pages/app/AddPage.tsx
|
||||||
msgid "Subscribe"
|
msgid "Subscribe"
|
||||||
@@ -1064,7 +1035,6 @@ msgstr "Byt till ljustema"
|
|||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "System"
|
msgstr "System"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Taggar"
|
msgstr "Taggar"
|
||||||
@@ -1136,7 +1106,6 @@ msgstr "Oläst"
|
|||||||
msgid "Unstar"
|
msgid "Unstar"
|
||||||
msgstr "Ta bort stjärna"
|
msgstr "Ta bort stjärna"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Avsluta prenumeration"
|
msgstr "Avsluta prenumeration"
|
||||||
@@ -1149,7 +1118,6 @@ msgstr "Användarnyckel"
|
|||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Användarnamn"
|
msgstr "Användarnamn"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "User Name or E-mail"
|
msgid "User Name or E-mail"
|
||||||
msgstr "Användarnamn eller e-post"
|
msgstr "Användarnamn eller e-post"
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ msgstr "Kullanıcı ekle"
|
|||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "Yönetici"
|
msgstr "Yönetici"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr "Yönetici kullanıcı adı"
|
msgstr "Yönetici kullanıcı adı"
|
||||||
@@ -73,7 +72,6 @@ msgstr "Yönetici kullanıcı adı"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Tümü"
|
msgstr "Tümü"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Always"
|
msgid "Always"
|
||||||
msgstr "Her zaman"
|
msgstr "Her zaman"
|
||||||
@@ -173,18 +171,14 @@ msgstr "Ne okumak istediğinizi belirtmek için bir filtre ifadesi oluşturun. E
|
|||||||
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
#: src/pages/app/TagDetailsPage.tsx
|
#: src/pages/app/TagDetailsPage.tsx
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "İptal"
|
msgstr "İptal"
|
||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -240,7 +234,6 @@ msgstr "Onayla"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "Şifreyi onayla"
|
msgstr "Şifreyi onayla"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "Şifreyi Onayla"
|
msgstr "Şifreyi Onayla"
|
||||||
@@ -294,7 +287,6 @@ msgstr "gün"
|
|||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Sil"
|
msgstr "Sil"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Delete account"
|
msgid "Delete account"
|
||||||
msgstr "Hesabı sil"
|
msgstr "Hesabı sil"
|
||||||
@@ -342,13 +334,10 @@ msgstr "Bağlantıyı yer işareti çubuğuna sürükleyin"
|
|||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "E-posta"
|
msgstr "E-posta"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "E-mail address"
|
msgid "E-mail address"
|
||||||
msgstr "E-posta adresi"
|
msgstr "E-posta adresi"
|
||||||
@@ -399,7 +388,6 @@ msgstr "Eklenti ayarları"
|
|||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
msgstr "Yayın adı"
|
msgstr "Yayın adı"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
@@ -570,7 +558,6 @@ msgstr "Abonelikler yükleniyor..."
|
|||||||
msgid "Loading tags..."
|
msgid "Loading tags..."
|
||||||
msgstr "Etiketler yükleniyor..."
|
msgstr "Etiketler yükleniyor..."
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
@@ -648,7 +635,6 @@ msgstr "Adını girerek bir aboneliğe gidin"
|
|||||||
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
msgstr "Tüm girişleri okundu olarak işaretlerken okunmamış girişleri olan bir sonraki kategoriye/beslemeye git"
|
msgstr "Tüm girişleri okundu olarak işaretlerken okunmamış girişleri olan bir sonraki kategoriye/beslemeye git"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "Asla"
|
msgstr "Asla"
|
||||||
@@ -657,7 +643,6 @@ msgstr "Asla"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "Yeni şifre"
|
msgstr "Yeni şifre"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "Yeni Şifre"
|
msgstr "Yeni Şifre"
|
||||||
@@ -764,7 +749,6 @@ msgstr "OPML"
|
|||||||
msgid "OPML export"
|
msgid "OPML export"
|
||||||
msgstr "OPML dışa aktarma"
|
msgstr "OPML dışa aktarma"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "OPML file"
|
msgid "OPML file"
|
||||||
msgstr "OPML dosyası"
|
msgstr "OPML dosyası"
|
||||||
@@ -791,10 +775,7 @@ msgstr "Üst Kategori"
|
|||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Şifre"
|
msgstr "Şifre"
|
||||||
@@ -874,7 +855,6 @@ msgstr "Yenile"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "Bu CommaFeed örneğinde kayıtlar kapalı"
|
msgstr "Bu CommaFeed örneğinde kayıtlar kapalı"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "Şifreyi Sıfırla"
|
msgstr "Şifreyi Sıfırla"
|
||||||
@@ -883,7 +863,6 @@ msgstr "Şifreyi Sıfırla"
|
|||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REST API"
|
msgstr "REST API"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr "Sağ tık"
|
msgstr "Sağ tık"
|
||||||
@@ -910,8 +889,6 @@ msgid "Scrolling"
|
|||||||
msgstr "Kaydırma"
|
msgstr "Kaydırma"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
#: src/components/sidebar/TreeSearch.tsx
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Ara"
|
msgstr "Ara"
|
||||||
@@ -924,7 +901,6 @@ msgstr "Sonraki okunmamış beslemeyi/kategoriyi seç"
|
|||||||
msgid "Select previous unread feed/category"
|
msgid "Select previous unread feed/category"
|
||||||
msgstr "Önceki okunmamış beslemeyi/kategoriyi seç"
|
msgstr "Önceki okunmamış beslemeyi/kategoriyi seç"
|
||||||
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
msgid "Server URL"
|
msgid "Server URL"
|
||||||
msgstr "Sunucu URL'si"
|
msgstr "Sunucu URL'si"
|
||||||
@@ -953,8 +929,6 @@ msgstr "Paylaş"
|
|||||||
msgid "Sharing sites"
|
msgid "Sharing sites"
|
||||||
msgstr "Siteleri paylaşma"
|
msgstr "Siteleri paylaşma"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Shift"
|
msgid "Shift"
|
||||||
msgstr "Vardiya"
|
msgstr "Vardiya"
|
||||||
@@ -1003,7 +977,6 @@ msgstr "Sekme simgesinde okunmamış sayısını göster"
|
|||||||
msgid "Show unread count in tab title"
|
msgid "Show unread count in tab title"
|
||||||
msgstr "Sekme başlığında okunmamış sayısını göster"
|
msgstr "Sekme başlığında okunmamış sayısını göster"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
@@ -1013,7 +986,6 @@ msgstr "Kaydolun"
|
|||||||
msgid "Something bad just happened..."
|
msgid "Something bad just happened..."
|
||||||
msgstr "Az önce kötü bir şey oldu..."
|
msgstr "Az önce kötü bir şey oldu..."
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Space"
|
msgid "Space"
|
||||||
msgstr "Uzay"
|
msgstr "Uzay"
|
||||||
@@ -1030,7 +1002,6 @@ msgstr "Yıldız"
|
|||||||
msgid "Starred"
|
msgid "Starred"
|
||||||
msgstr "Yıldızlı"
|
msgstr "Yıldızlı"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AddPage.tsx
|
#: src/pages/app/AddPage.tsx
|
||||||
msgid "Subscribe"
|
msgid "Subscribe"
|
||||||
@@ -1064,7 +1035,6 @@ msgstr "Aydınlık temaya geç"
|
|||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "Sistem"
|
msgstr "Sistem"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "Etiketler"
|
msgstr "Etiketler"
|
||||||
@@ -1136,7 +1106,6 @@ msgstr "Okunmamış"
|
|||||||
msgid "Unstar"
|
msgid "Unstar"
|
||||||
msgstr "Yıldızı kaldır"
|
msgstr "Yıldızı kaldır"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "Aboneliği iptal et"
|
msgstr "Aboneliği iptal et"
|
||||||
@@ -1149,7 +1118,6 @@ msgstr "Kullanıcı anahtarı"
|
|||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "Kullanıcı adı"
|
msgstr "Kullanıcı adı"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "User Name or E-mail"
|
msgid "User Name or E-mail"
|
||||||
msgstr "Kullanıcı Adı veya E-posta"
|
msgstr "Kullanıcı Adı veya E-posta"
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ msgstr "添加用户"
|
|||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "管理员"
|
msgstr "管理员"
|
||||||
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
msgid "Admin user name"
|
msgid "Admin user name"
|
||||||
msgstr "管理员用户名"
|
msgstr "管理员用户名"
|
||||||
@@ -73,7 +72,6 @@ msgstr "管理员用户名"
|
|||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "全部"
|
msgstr "全部"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Always"
|
msgid "Always"
|
||||||
msgstr "总是"
|
msgstr "总是"
|
||||||
@@ -173,18 +171,14 @@ msgstr "构建过滤表达式以指示您想阅读的内容。不匹配的条目
|
|||||||
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
#: src/components/MarkAllAsReadConfirmationDialog.tsx
|
||||||
#: src/components/settings/CustomCodeSettings.tsx
|
#: src/components/settings/CustomCodeSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
#: src/pages/app/CategoryDetailsPage.tsx
|
||||||
#: src/pages/app/CategoryDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
#: src/pages/app/TagDetailsPage.tsx
|
#: src/pages/app/TagDetailsPage.tsx
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "取消"
|
msgstr "取消"
|
||||||
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
|
||||||
#: src/components/content/add/AddCategory.tsx
|
#: src/components/content/add/AddCategory.tsx
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
@@ -240,7 +234,6 @@ msgstr "确认"
|
|||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr "确认密码"
|
msgstr "确认密码"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Confirm Password"
|
msgid "Confirm Password"
|
||||||
msgstr "确认密码"
|
msgstr "确认密码"
|
||||||
@@ -294,7 +287,6 @@ msgstr "天"
|
|||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "删除"
|
msgstr "删除"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "Delete account"
|
msgid "Delete account"
|
||||||
msgstr "删除帐号"
|
msgstr "删除帐号"
|
||||||
@@ -342,13 +334,10 @@ msgstr "拖动链接到书签栏"
|
|||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
#: src/pages/admin/AdminUsersPage.tsx
|
#: src/pages/admin/AdminUsersPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
|
||||||
#: src/pages/auth/PasswordRecoveryPage.tsx
|
#: src/pages/auth/PasswordRecoveryPage.tsx
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "电子邮件"
|
msgstr "电子邮件"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "E-mail address"
|
msgid "E-mail address"
|
||||||
msgstr "电子邮件地址"
|
msgstr "电子邮件地址"
|
||||||
@@ -399,7 +388,6 @@ msgstr "扩展选项"
|
|||||||
msgid "Feed name"
|
msgid "Feed name"
|
||||||
msgstr "信息流名称"
|
msgstr "信息流名称"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
@@ -570,7 +558,6 @@ msgstr "正在加载订阅..."
|
|||||||
msgid "Loading tags..."
|
msgid "Loading tags..."
|
||||||
msgstr "正在加载标签..."
|
msgstr "正在加载标签..."
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
@@ -648,7 +635,6 @@ msgstr "通过输入订阅名称导航到订阅"
|
|||||||
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
msgid "Navigate to the next category/feed with unread entries when marking all entries as read"
|
||||||
msgstr "将所有条目标记为已读时导航到下一个包含未读条目的类别/信息流"
|
msgstr "将所有条目标记为已读时导航到下一个包含未读条目的类别/信息流"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Never"
|
msgid "Never"
|
||||||
msgstr "从不"
|
msgstr "从不"
|
||||||
@@ -657,7 +643,6 @@ msgstr "从不"
|
|||||||
msgid "New password"
|
msgid "New password"
|
||||||
msgstr "新密码"
|
msgstr "新密码"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "New Password"
|
msgid "New Password"
|
||||||
msgstr "新密码"
|
msgstr "新密码"
|
||||||
@@ -764,7 +749,6 @@ msgstr "OPML"
|
|||||||
msgid "OPML export"
|
msgid "OPML export"
|
||||||
msgstr "OPML 导出"
|
msgstr "OPML 导出"
|
||||||
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
|
||||||
#: src/components/content/add/ImportOpml.tsx
|
#: src/components/content/add/ImportOpml.tsx
|
||||||
msgid "OPML file"
|
msgid "OPML file"
|
||||||
msgstr "OPML 文件"
|
msgstr "OPML 文件"
|
||||||
@@ -791,10 +775,7 @@ msgstr "父类别"
|
|||||||
|
|
||||||
#: src/components/admin/UserEdit.tsx
|
#: src/components/admin/UserEdit.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
#: src/pages/auth/InitialSetupPage.tsx
|
||||||
#: src/pages/auth/InitialSetupPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "密码"
|
msgstr "密码"
|
||||||
@@ -874,7 +855,6 @@ msgstr "刷新"
|
|||||||
msgid "Registrations are closed on this CommaFeed instance"
|
msgid "Registrations are closed on this CommaFeed instance"
|
||||||
msgstr "此 CommaFeed 实例上的注册已关闭"
|
msgstr "此 CommaFeed 实例上的注册已关闭"
|
||||||
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
|
||||||
#: src/pages/auth/PasswordResetPage.tsx
|
#: src/pages/auth/PasswordResetPage.tsx
|
||||||
msgid "Reset Password"
|
msgid "Reset Password"
|
||||||
msgstr "重置密码"
|
msgstr "重置密码"
|
||||||
@@ -883,7 +863,6 @@ msgstr "重置密码"
|
|||||||
msgid "REST API"
|
msgid "REST API"
|
||||||
msgstr "REST API"
|
msgstr "REST API"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Right click"
|
msgid "Right click"
|
||||||
msgstr "右键单击"
|
msgstr "右键单击"
|
||||||
@@ -910,8 +889,6 @@ msgid "Scrolling"
|
|||||||
msgstr "滚动"
|
msgstr "滚动"
|
||||||
|
|
||||||
#: src/components/header/Header.tsx
|
#: src/components/header/Header.tsx
|
||||||
#: src/components/header/Header.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
|
||||||
#: src/components/sidebar/TreeSearch.tsx
|
#: src/components/sidebar/TreeSearch.tsx
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "搜索"
|
msgstr "搜索"
|
||||||
@@ -924,7 +901,6 @@ msgstr "选择下一个未读信息流/类别"
|
|||||||
msgid "Select previous unread feed/category"
|
msgid "Select previous unread feed/category"
|
||||||
msgstr "选择上一个未读信息流/类别"
|
msgstr "选择上一个未读信息流/类别"
|
||||||
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
|
||||||
#: src/components/settings/PushNotificationSettings.tsx
|
#: src/components/settings/PushNotificationSettings.tsx
|
||||||
msgid "Server URL"
|
msgid "Server URL"
|
||||||
msgstr "服务器网址"
|
msgstr "服务器网址"
|
||||||
@@ -953,8 +929,6 @@ msgstr "分享"
|
|||||||
msgid "Sharing sites"
|
msgid "Sharing sites"
|
||||||
msgstr "共享站点"
|
msgstr "共享站点"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Shift"
|
msgid "Shift"
|
||||||
msgstr "Shift"
|
msgstr "Shift"
|
||||||
@@ -1003,7 +977,6 @@ msgstr "在标签页图标上显示未读数量"
|
|||||||
msgid "Show unread count in tab title"
|
msgid "Show unread count in tab title"
|
||||||
msgstr "在标签页标题中显示未读数量"
|
msgstr "在标签页标题中显示未读数量"
|
||||||
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
|
||||||
#: src/pages/auth/RegistrationPage.tsx
|
#: src/pages/auth/RegistrationPage.tsx
|
||||||
#: src/pages/WelcomePage.tsx
|
#: src/pages/WelcomePage.tsx
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
@@ -1013,7 +986,6 @@ msgstr "注册"
|
|||||||
msgid "Something bad just happened..."
|
msgid "Something bad just happened..."
|
||||||
msgstr "刚刚发生了不好的事情……"
|
msgstr "刚刚发生了不好的事情……"
|
||||||
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
|
||||||
#: src/components/KeyboardShortcutsHelp.tsx
|
#: src/components/KeyboardShortcutsHelp.tsx
|
||||||
msgid "Space"
|
msgid "Space"
|
||||||
msgstr "空格"
|
msgstr "空格"
|
||||||
@@ -1030,7 +1002,6 @@ msgstr "星标"
|
|||||||
msgid "Starred"
|
msgid "Starred"
|
||||||
msgstr "已加星标"
|
msgstr "已加星标"
|
||||||
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
|
||||||
#: src/components/content/add/Subscribe.tsx
|
#: src/components/content/add/Subscribe.tsx
|
||||||
#: src/pages/app/AddPage.tsx
|
#: src/pages/app/AddPage.tsx
|
||||||
msgid "Subscribe"
|
msgid "Subscribe"
|
||||||
@@ -1064,7 +1035,6 @@ msgstr "切换到浅色主题"
|
|||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "跟随系统"
|
msgstr "跟随系统"
|
||||||
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
|
||||||
#: src/components/content/FeedEntryFooter.tsx
|
#: src/components/content/FeedEntryFooter.tsx
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr "标签"
|
msgstr "标签"
|
||||||
@@ -1136,7 +1106,6 @@ msgstr "未读"
|
|||||||
msgid "Unstar"
|
msgid "Unstar"
|
||||||
msgstr "取消星标"
|
msgstr "取消星标"
|
||||||
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
|
||||||
#: src/pages/app/FeedDetailsPage.tsx
|
#: src/pages/app/FeedDetailsPage.tsx
|
||||||
msgid "Unsubscribe"
|
msgid "Unsubscribe"
|
||||||
msgstr "取消订阅"
|
msgstr "取消订阅"
|
||||||
@@ -1149,7 +1118,6 @@ msgstr "用户密钥"
|
|||||||
msgid "User name"
|
msgid "User name"
|
||||||
msgstr "用户名"
|
msgstr "用户名"
|
||||||
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
|
||||||
#: src/pages/auth/LoginPage.tsx
|
#: src/pages/auth/LoginPage.tsx
|
||||||
msgid "User Name or E-mail"
|
msgid "User Name or E-mail"
|
||||||
msgstr "用户名或电子邮件"
|
msgstr "用户名或电子邮件"
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import { msg } from "@lingui/core/macro"
|
import { msg } from "@lingui/core/macro"
|
||||||
import { ActionIcon, AppShell, Box, Center, Group, ScrollArea, Title, useMantineTheme } from "@mantine/core"
|
import { ActionIcon, AppShell, Box, Center, Group, ScrollArea, Title, useMantineTheme } from "@mantine/core"
|
||||||
import { type ReactNode, type RefObject, Suspense, useEffect, useRef } from "react"
|
import { type ReactNode, type RefObject, Suspense, useEffect, useRef, useState } from "react"
|
||||||
import Draggable from "react-draggable"
|
import Draggable from "react-draggable"
|
||||||
import { TbMenu2, TbPlus, TbX } from "react-icons/tb"
|
import { TbMenu2, TbPlus, TbX } from "react-icons/tb"
|
||||||
import { Outlet } from "react-router-dom"
|
import { Outlet } from "react-router-dom"
|
||||||
import { useSwipeable } from "react-swipeable"
|
import { useSwipeable } from "react-swipeable"
|
||||||
|
import Tinycon from "tinycon"
|
||||||
import { Constants } from "@/app/constants"
|
import { Constants } from "@/app/constants"
|
||||||
import { redirectToAdd, redirectToRootCategory } from "@/app/redirect/thunks"
|
import { redirectToAdd, redirectToRootCategory } from "@/app/redirect/thunks"
|
||||||
import { useAppDispatch, useAppSelector } from "@/app/store"
|
import { useAppDispatch, useAppSelector } from "@/app/store"
|
||||||
@@ -12,8 +13,10 @@ import { setMobileMenuOpen } from "@/app/tree/slice"
|
|||||||
import { reloadTree } from "@/app/tree/thunks"
|
import { reloadTree } from "@/app/tree/thunks"
|
||||||
import { setSidebarWidth } from "@/app/user/slice"
|
import { setSidebarWidth } from "@/app/user/slice"
|
||||||
import { reloadProfile, reloadSettings, reloadTags } from "@/app/user/thunks"
|
import { reloadProfile, reloadSettings, reloadTags } from "@/app/user/thunks"
|
||||||
|
import { categoryUnreadCount } from "@/app/utils"
|
||||||
import { ActionButton } from "@/components/ActionButton"
|
import { ActionButton } from "@/components/ActionButton"
|
||||||
import { AnnouncementDialog } from "@/components/AnnouncementDialog"
|
import { AnnouncementDialog } from "@/components/AnnouncementDialog"
|
||||||
|
import { DisablePullToRefresh } from "@/components/DisablePullToRefresh"
|
||||||
import { Loader } from "@/components/Loader"
|
import { Loader } from "@/components/Loader"
|
||||||
import { Logo } from "@/components/Logo"
|
import { Logo } from "@/components/Logo"
|
||||||
import { MarkAllAsReadConfirmationDialog } from "@/components/MarkAllAsReadConfirmationDialog"
|
import { MarkAllAsReadConfirmationDialog } from "@/components/MarkAllAsReadConfirmationDialog"
|
||||||
@@ -51,6 +54,78 @@ function LogoAndTitle() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function UnreadCountTitleHandler({
|
||||||
|
enabled,
|
||||||
|
}: Readonly<{
|
||||||
|
enabled?: boolean
|
||||||
|
}>) {
|
||||||
|
const root = useAppSelector(state => state.tree.rootCategory)
|
||||||
|
const unreadCount = categoryUnreadCount(root)
|
||||||
|
return <title>{enabled && unreadCount > 0 ? `(${unreadCount}) CommaFeed` : "CommaFeed"}</title>
|
||||||
|
}
|
||||||
|
|
||||||
|
function UnreadCountFaviconHandler({ enabled }: { enabled?: boolean }) {
|
||||||
|
const root = useAppSelector(state => state.tree.rootCategory)
|
||||||
|
const unreadCount = categoryUnreadCount(root)
|
||||||
|
useEffect(() => {
|
||||||
|
if (enabled && unreadCount > 0) {
|
||||||
|
Tinycon.setBubble(unreadCount)
|
||||||
|
} else {
|
||||||
|
Tinycon.reset()
|
||||||
|
}
|
||||||
|
}, [unreadCount, enabled])
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
function BrowserExtensionBadgeUnreadCountHandler() {
|
||||||
|
const root = useAppSelector(state => state.tree.rootCategory)
|
||||||
|
const { setBadgeUnreadCount } = useBrowserExtension()
|
||||||
|
useEffect(() => {
|
||||||
|
if (!root) return
|
||||||
|
const unreadCount = categoryUnreadCount(root)
|
||||||
|
setBadgeUnreadCount(unreadCount)
|
||||||
|
}, [root, setBadgeUnreadCount])
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
function CustomJsHandler() {
|
||||||
|
const [scriptLoaded, setScriptLoaded] = useState(false)
|
||||||
|
const { loading } = useAppLoading()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (scriptLoaded || loading) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const script = document.createElement("script")
|
||||||
|
script.src = "custom_js.js"
|
||||||
|
script.async = true
|
||||||
|
document.body.appendChild(script)
|
||||||
|
|
||||||
|
setScriptLoaded(true)
|
||||||
|
|
||||||
|
return () => script.remove()
|
||||||
|
}, [scriptLoaded, loading])
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
function CustomCssHandler() {
|
||||||
|
useEffect(() => {
|
||||||
|
const link = document.createElement("link")
|
||||||
|
link.rel = "stylesheet"
|
||||||
|
link.type = "text/css"
|
||||||
|
link.href = "custom_css.css"
|
||||||
|
document.head.appendChild(link)
|
||||||
|
|
||||||
|
return () => link.remove()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
const useStyles = tss
|
const useStyles = tss
|
||||||
.withParams<{
|
.withParams<{
|
||||||
sidebarWidth: number
|
sidebarWidth: number
|
||||||
@@ -75,6 +150,9 @@ export default function Layout(props: Readonly<LayoutProps>) {
|
|||||||
const draggableSeparator = useRef<HTMLDivElement>(null)
|
const draggableSeparator = useRef<HTMLDivElement>(null)
|
||||||
|
|
||||||
const { loading } = useAppLoading()
|
const { loading } = useAppLoading()
|
||||||
|
const unreadCountTitle = useAppSelector(state => state.user.settings?.unreadCountTitle)
|
||||||
|
const unreadCountFavicon = useAppSelector(state => state.user.settings?.unreadCountFavicon)
|
||||||
|
const disablePullToRefresh = useAppSelector(state => state.user.settings?.disablePullToRefresh)
|
||||||
const mobileMenuOpen = useAppSelector(state => state.tree.mobileMenuOpen)
|
const mobileMenuOpen = useAppSelector(state => state.tree.mobileMenuOpen)
|
||||||
const webSocketConnected = useAppSelector(state => state.server.webSocketConnected)
|
const webSocketConnected = useAppSelector(state => state.server.webSocketConnected)
|
||||||
const treeReloadInterval = useAppSelector(state => state.server.serverInfos?.treeReloadInterval)
|
const treeReloadInterval = useAppSelector(state => state.server.serverInfos?.treeReloadInterval)
|
||||||
@@ -173,6 +251,13 @@ export default function Layout(props: Readonly<LayoutProps>) {
|
|||||||
|
|
||||||
if (loading) return <LoadingPage />
|
if (loading) return <LoadingPage />
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
<UnreadCountTitleHandler enabled={unreadCountTitle} />
|
||||||
|
<UnreadCountFaviconHandler enabled={unreadCountFavicon} />
|
||||||
|
<BrowserExtensionBadgeUnreadCountHandler />
|
||||||
|
<CustomJsHandler />
|
||||||
|
<CustomCssHandler />
|
||||||
|
<DisablePullToRefresh enabled={disablePullToRefresh} />
|
||||||
<Box {...swipeHandlers}>
|
<Box {...swipeHandlers}>
|
||||||
<AppShell
|
<AppShell
|
||||||
header={{ height: Constants.layout.headerHeight, collapsed: headerInFooter }}
|
header={{ height: Constants.layout.headerHeight, collapsed: headerInFooter }}
|
||||||
@@ -229,5 +314,6 @@ export default function Layout(props: Readonly<LayoutProps>) {
|
|||||||
</AppShell.Main>
|
</AppShell.Main>
|
||||||
</AppShell>
|
</AppShell>
|
||||||
</Box>
|
</Box>
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ export default defineConfig(() => ({
|
|||||||
}),
|
}),
|
||||||
lingui(),
|
lingui(),
|
||||||
checker({
|
checker({
|
||||||
typescript: true,
|
// temporary disabled until TypeScript 7 exposes a stable api
|
||||||
|
// typescript: true,
|
||||||
biome: {
|
biome: {
|
||||||
command: "check",
|
command: "check",
|
||||||
flags: "--error-on-warnings",
|
flags: "--error-on-warnings",
|
||||||
|
|||||||
@@ -1,401 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<profiles version="23">
|
|
||||||
<profile kind="CodeFormatterProfile" name="CommaFeed" version="23">
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.align_with_spaces" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_before_code_block" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="48"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_record_components" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_logical_operator" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line" value="one_line_never"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_record_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line" value="one_line_never"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line" value="one_line_never"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_shift_operator" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_loops" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_switch_case_arrow_operator" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_enum_constant" value="49"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.text_block_indentation" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_module_statements" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line" value="one_line_never"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_permitted_types" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_annotations" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assertion_message_operator" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines" value="2147483647"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="80"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_not_operator" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="48"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package" value="49"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_record_header" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.javadoc_do_not_separate_block_tags" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_tag_description" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_constructor" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_string_concatenation" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_shift_operator" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_shift_operator" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_record_components" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_additive_operator" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_record_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_relational_operator" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_logical_operator" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_record_declaration" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="48"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_switch_body_block_on_one_line" value="one_line_never"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_arrow" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="140"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_method_body_on_one_line" value="one_line_never"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line" value="one_line_never"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line" value="one_line_never"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_additive_operator" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_constructor" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_relational_operator" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_record_declaration_on_one_line" value="one_line_never"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_relational_operator" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_additive_operator" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.align_selector_in_method_invocation_on_expression_first_line" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_declaration" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_switch_case_with_arrow_on_one_line" value="one_line_never"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_colon" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type" value="49"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable" value="49"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_additive_operator" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field" value="49"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_shift_operator" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_code_block_on_one_line" value="one_line_never"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_record_components" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_record_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="48"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_switch_case_with_arrow" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line" value="one_line_never"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method" value="49"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_record_constructor_on_one_line" value="one_line_never"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assertion_message" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_logical_operator" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_record_declaration" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_relational_operator" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_logical_operator" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_permitted_types" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line" value="one_line_never"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="tab"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_string_concatenation" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="140"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
|
|
||||||
</profile>
|
|
||||||
</profiles>
|
|
||||||
@@ -40,11 +40,6 @@
|
|||||||
<module name="AvoidStarImport" />
|
<module name="AvoidStarImport" />
|
||||||
<module name="AvoidStaticImport" />
|
<module name="AvoidStaticImport" />
|
||||||
<module name="IllegalImport" />
|
<module name="IllegalImport" />
|
||||||
<module name="ImportOrder">
|
|
||||||
<property name="groups" value="/^java\./,javax,jakarta,org,com" />
|
|
||||||
<property name="ordered" value="true" />
|
|
||||||
<property name="separated" value="true" />
|
|
||||||
</module>
|
|
||||||
<module name="RedundantImport" />
|
<module name="RedundantImport" />
|
||||||
<module name="UnusedImports" />
|
<module name="UnusedImports" />
|
||||||
|
|
||||||
@@ -113,12 +108,6 @@
|
|||||||
<module name="NoLineWrap" />
|
<module name="NoLineWrap" />
|
||||||
<module name="NoWhitespaceBefore" />
|
<module name="NoWhitespaceBefore" />
|
||||||
<module name="ParenPad" />
|
<module name="ParenPad" />
|
||||||
<module name="RegexpSinglelineJava">
|
|
||||||
<property name="format" value="^\t* +\t*\S" />
|
|
||||||
<property name="message" value="Line has leading space characters; indentation should be performed with tabs only." />
|
|
||||||
<property name="ignoreComments" value="true" />
|
|
||||||
</module>
|
|
||||||
<module name="WhitespaceAround" />
|
|
||||||
|
|
||||||
</module>
|
</module>
|
||||||
</module>
|
</module>
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
#Organize Import Order
|
|
||||||
#Wed Jan 29 15:15:04 CET 2025
|
|
||||||
0=java
|
|
||||||
1=javax
|
|
||||||
2=jakarta
|
|
||||||
3=org
|
|
||||||
4=com
|
|
||||||
@@ -6,16 +6,18 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.commafeed</groupId>
|
<groupId>com.commafeed</groupId>
|
||||||
<artifactId>commafeed</artifactId>
|
<artifactId>commafeed</artifactId>
|
||||||
<version>7.1.0</version>
|
<version>7.2.1</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>commafeed-server</artifactId>
|
<artifactId>commafeed-server</artifactId>
|
||||||
<name>CommaFeed Server</name>
|
<name>CommaFeed Server</name>
|
||||||
<packaging>quarkus</packaging>
|
<packaging>quarkus</packaging>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<quarkus.version>3.34.3</quarkus.version>
|
<quarkus.version>3.38.0</quarkus.version>
|
||||||
<querydsl.version>7.1</querydsl.version>
|
<querydsl.version>7.5</querydsl.version>
|
||||||
<rome.version>2.1.0</rome.version>
|
<rome.version>2.1.0</rome.version>
|
||||||
|
<!-- renovate: depName=com.google.googlejavaformat:google-java-format -->
|
||||||
|
<google-java-format.version>1.36.1</google-java-format.version>
|
||||||
|
|
||||||
<build.database>h2</build.database>
|
<build.database>h2</build.database>
|
||||||
</properties>
|
</properties>
|
||||||
@@ -33,7 +35,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.protobuf</groupId>
|
<groupId>com.google.protobuf</groupId>
|
||||||
<artifactId>protobuf-java</artifactId>
|
<artifactId>protobuf-java</artifactId>
|
||||||
<version>4.34.1</version>
|
<version>4.35.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
@@ -49,7 +51,7 @@
|
|||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-help-plugin</artifactId>
|
<artifactId>maven-help-plugin</artifactId>
|
||||||
<version>3.5.1</version>
|
<version>3.5.2</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<phase>initialize</phase>
|
<phase>initialize</phase>
|
||||||
@@ -162,7 +164,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>3.5.5</version>
|
<version>3.5.6</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<argLine>@{argLine}</argLine>
|
<argLine>@{argLine}</argLine>
|
||||||
<systemPropertyVariables>
|
<systemPropertyVariables>
|
||||||
@@ -174,7 +176,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-failsafe-plugin</artifactId>
|
<artifactId>maven-failsafe-plugin</artifactId>
|
||||||
<version>3.5.5</version>
|
<version>3.5.6</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<goals>
|
<goals>
|
||||||
@@ -243,7 +245,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.puppycrawl.tools</groupId>
|
<groupId>com.puppycrawl.tools</groupId>
|
||||||
<artifactId>checkstyle</artifactId>
|
<artifactId>checkstyle</artifactId>
|
||||||
<version>13.4.0</version>
|
<version>13.9.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<executions>
|
<executions>
|
||||||
@@ -272,7 +274,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>com.diffplug.spotless</groupId>
|
<groupId>com.diffplug.spotless</groupId>
|
||||||
<artifactId>spotless-maven-plugin</artifactId>
|
<artifactId>spotless-maven-plugin</artifactId>
|
||||||
<version>3.4.0</version>
|
<version>3.9.0</version>
|
||||||
<?m2e ignore?>
|
<?m2e ignore?>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
@@ -285,12 +287,11 @@
|
|||||||
<configuration>
|
<configuration>
|
||||||
<encoding>UTF-8</encoding>
|
<encoding>UTF-8</encoding>
|
||||||
<java>
|
<java>
|
||||||
<eclipse>
|
<googleJavaFormat>
|
||||||
<file>${project.basedir}/dev/EclipseCodeFormatter.xml</file>
|
<version>${google-java-format.version}</version>
|
||||||
</eclipse>
|
<style>AOSP</style>
|
||||||
<importOrder>
|
<reorderImports>true</reorderImports>
|
||||||
<file>${project.basedir}/dev/eclipse.importorder</file>
|
</googleJavaFormat>
|
||||||
</importOrder>
|
|
||||||
</java>
|
</java>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
@@ -301,15 +302,14 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.commafeed</groupId>
|
<groupId>com.commafeed</groupId>
|
||||||
<artifactId>commafeed-client</artifactId>
|
<artifactId>commafeed-client</artifactId>
|
||||||
<version>7.1.0</version>
|
<version>7.2.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- compile-time processors -->
|
<!-- compile-time processors -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
<version>1.18.44</version>
|
<version>1.18.46</version>
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.kohsuke.metainf-services</groupId>
|
<groupId>org.kohsuke.metainf-services</groupId>
|
||||||
@@ -368,7 +368,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.dropwizard.metrics</groupId>
|
<groupId>io.dropwizard.metrics</groupId>
|
||||||
<artifactId>metrics-json</artifactId>
|
<artifactId>metrics-json</artifactId>
|
||||||
<version>4.2.38</version>
|
<version>4.2.39</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.github.openfeign.querydsl</groupId>
|
<groupId>io.github.openfeign.querydsl</groupId>
|
||||||
@@ -399,7 +399,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>dev.cel</groupId>
|
<groupId>dev.cel</groupId>
|
||||||
<artifactId>cel</artifactId>
|
<artifactId>cel</artifactId>
|
||||||
<version>0.12.0</version>
|
<version>0.13.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.passay</groupId>
|
<groupId>org.passay</groupId>
|
||||||
@@ -429,7 +429,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jsoup</groupId>
|
<groupId>org.jsoup</groupId>
|
||||||
<artifactId>jsoup</artifactId>
|
<artifactId>jsoup</artifactId>
|
||||||
<version>1.22.1</version>
|
<version>1.23.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.ibm.icu</groupId>
|
<groupId>com.ibm.icu</groupId>
|
||||||
@@ -449,18 +449,23 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.httpcomponents.client5</groupId>
|
<groupId>org.apache.httpcomponents.client5</groupId>
|
||||||
<artifactId>httpclient5</artifactId>
|
<artifactId>httpclient5</artifactId>
|
||||||
<version>5.6</version>
|
<version>5.6.3</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.github.hakky54</groupId>
|
<groupId>io.github.hakky54</groupId>
|
||||||
<artifactId>ayza-for-apache5</artifactId>
|
<artifactId>ayza-for-apache5</artifactId>
|
||||||
<version>10.0.4</version>
|
<version>10.0.6</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.brotli</groupId>
|
<groupId>org.brotli</groupId>
|
||||||
<artifactId>dec</artifactId>
|
<artifactId>dec</artifactId>
|
||||||
<version>0.1.2</version>
|
<version>0.1.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.seancfoley</groupId>
|
||||||
|
<artifactId>ipaddress</artifactId>
|
||||||
|
<version>5.6.2</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- test dependencies -->
|
<!-- test dependencies -->
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -471,13 +476,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.quarkiverse.playwright</groupId>
|
<groupId>io.quarkiverse.playwright</groupId>
|
||||||
<artifactId>quarkus-playwright</artifactId>
|
<artifactId>quarkus-playwright</artifactId>
|
||||||
<version>2.3.3</version>
|
<version>2.3.8</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mock-server</groupId>
|
<groupId>org.mock-server</groupId>
|
||||||
<artifactId>mockserver-junit-jupiter</artifactId>
|
<artifactId>mockserver-junit-jupiter</artifactId>
|
||||||
<version>5.15.0</version>
|
<version>7.5.0</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM ibm-semeru-runtimes:open-jdk-25.0.2_10-jre@sha256:b02e4cd184d9ece59b01129af1d0a069fa01e4f0f798f0bc4f3ff1a8391ba694
|
FROM ibm-semeru-runtimes:open-jdk-25.0.3.0-jre@sha256:43ec947fee9c4c2ed880620ae9e78911ac5eef66391e5a2c43f956dcc9000491
|
||||||
EXPOSE 8082
|
EXPOSE 8082
|
||||||
|
|
||||||
RUN mkdir -p /commafeed/data
|
RUN mkdir -p /commafeed/data
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM debian:13.4@sha256:3352c2e13876c8a5c5873ef20870e1939e73cb9a3c1aeba5e3e72172a85ce9ed
|
FROM debian:13.6@sha256:fac46bff2e02f51425b6e33b0e1169f55dfb053d83511ca28aa50c09fd5ed7a4
|
||||||
ARG TARGETARCH
|
ARG TARGETARCH
|
||||||
|
|
||||||
EXPOSE 8082
|
EXPOSE 8082
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
package com.commafeed;
|
package com.commafeed;
|
||||||
|
|
||||||
import jakarta.enterprise.event.Observes;
|
|
||||||
import jakarta.inject.Singleton;
|
|
||||||
|
|
||||||
import com.commafeed.backend.feed.FeedRefreshEngine;
|
import com.commafeed.backend.feed.FeedRefreshEngine;
|
||||||
|
import com.commafeed.backend.feed.ImageProxyUrl;
|
||||||
import com.commafeed.backend.task.TaskScheduler;
|
import com.commafeed.backend.task.TaskScheduler;
|
||||||
import com.commafeed.security.password.PasswordConstraintValidator;
|
import com.commafeed.security.password.PasswordConstraintValidator;
|
||||||
|
|
||||||
import io.quarkus.runtime.ShutdownEvent;
|
import io.quarkus.runtime.ShutdownEvent;
|
||||||
import io.quarkus.runtime.StartupEvent;
|
import io.quarkus.runtime.StartupEvent;
|
||||||
|
|
||||||
|
import jakarta.enterprise.event.Observes;
|
||||||
|
import jakarta.inject.Singleton;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@@ -24,7 +26,12 @@ public class CommaFeedApplication {
|
|||||||
public void start(@Observes StartupEvent ev) {
|
public void start(@Observes StartupEvent ev) {
|
||||||
log.info("starting up...");
|
log.info("starting up...");
|
||||||
|
|
||||||
PasswordConstraintValidator.setMinimumPasswordLength(config.users().minimumPasswordLength());
|
PasswordConstraintValidator.setMinimumPasswordLength(
|
||||||
|
config.users().minimumPasswordLength());
|
||||||
|
|
||||||
|
if (config.imageProxyEnabled()) {
|
||||||
|
ImageProxyUrl.generateKey();
|
||||||
|
}
|
||||||
|
|
||||||
feedRefreshEngine.start();
|
feedRefreshEngine.start();
|
||||||
taskScheduler.start();
|
taskScheduler.start();
|
||||||
@@ -36,5 +43,4 @@ public class CommaFeedApplication {
|
|||||||
feedRefreshEngine.stop();
|
feedRefreshEngine.stop();
|
||||||
taskScheduler.stop();
|
taskScheduler.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,5 @@
|
|||||||
package com.commafeed;
|
package com.commafeed;
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import jakarta.validation.constraints.Min;
|
|
||||||
import jakarta.validation.constraints.Positive;
|
|
||||||
|
|
||||||
import com.commafeed.backend.feed.FeedRefreshIntervalCalculator;
|
import com.commafeed.backend.feed.FeedRefreshIntervalCalculator;
|
||||||
|
|
||||||
import io.quarkus.runtime.annotations.ConfigDocSection;
|
import io.quarkus.runtime.annotations.ConfigDocSection;
|
||||||
@@ -16,10 +9,18 @@ import io.quarkus.runtime.configuration.MemorySize;
|
|||||||
import io.smallrye.config.ConfigMapping;
|
import io.smallrye.config.ConfigMapping;
|
||||||
import io.smallrye.config.WithDefault;
|
import io.smallrye.config.WithDefault;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.Min;
|
||||||
|
import jakarta.validation.constraints.Positive;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CommaFeed configuration
|
* CommaFeed configuration
|
||||||
*
|
*
|
||||||
* Default values are for production, they can be overridden in application.properties for other profiles
|
* <p>Default values are for production, they can be overridden in application.properties for other
|
||||||
|
* profiles
|
||||||
*/
|
*/
|
||||||
@ConfigMapping(prefix = "commafeed")
|
@ConfigMapping(prefix = "commafeed")
|
||||||
@ConfigRoot(phase = ConfigPhase.RUN_TIME)
|
@ConfigRoot(phase = ConfigPhase.RUN_TIME)
|
||||||
@@ -31,9 +32,11 @@ public interface CommaFeedConfiguration {
|
|||||||
boolean hideFromWebCrawlers();
|
boolean hideFromWebCrawlers();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If enabled, images in feed entries will be proxied through the server instead of accessed directly by the browser.
|
* 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.
|
* <p>This is useful if commafeed is accessed through a restricting proxy that blocks some feeds
|
||||||
|
* that are followed.
|
||||||
*/
|
*/
|
||||||
@WithDefault("false")
|
@WithDefault("false")
|
||||||
boolean imageProxyEnabled();
|
boolean imageProxyEnabled();
|
||||||
@@ -41,59 +44,44 @@ public interface CommaFeedConfiguration {
|
|||||||
/**
|
/**
|
||||||
* Enable password recovery via email.
|
* Enable password recovery via email.
|
||||||
*
|
*
|
||||||
* Quarkus mailer will need to be configured.
|
* <p>Quarkus mailer will need to be configured.
|
||||||
*/
|
*/
|
||||||
@WithDefault("false")
|
@WithDefault("false")
|
||||||
boolean passwordRecoveryEnabled();
|
boolean passwordRecoveryEnabled();
|
||||||
|
|
||||||
/**
|
/** Message displayed in a notification at the bottom of the page. */
|
||||||
* Message displayed in a notification at the bottom of the page.
|
|
||||||
*/
|
|
||||||
Optional<String> announcement();
|
Optional<String> announcement();
|
||||||
|
|
||||||
/**
|
/** Google Auth key for fetching Youtube channel favicons. */
|
||||||
* Google Auth key for fetching Youtube channel favicons.
|
|
||||||
*/
|
|
||||||
Optional<String> googleAuthKey();
|
Optional<String> googleAuthKey();
|
||||||
|
|
||||||
/**
|
/** HTTP client configuration */
|
||||||
* HTTP client configuration
|
|
||||||
*/
|
|
||||||
@ConfigDocSection
|
@ConfigDocSection
|
||||||
HttpClient httpClient();
|
HttpClient httpClient();
|
||||||
|
|
||||||
/**
|
/** Feed refresh engine settings. */
|
||||||
* Feed refresh engine settings.
|
|
||||||
*/
|
|
||||||
@ConfigDocSection
|
@ConfigDocSection
|
||||||
FeedRefresh feedRefresh();
|
FeedRefresh feedRefresh();
|
||||||
|
|
||||||
/**
|
/** Push notification settings. */
|
||||||
* Push notification settings.
|
|
||||||
*/
|
|
||||||
@ConfigDocSection
|
@ConfigDocSection
|
||||||
PushNotifications pushNotifications();
|
PushNotifications pushNotifications();
|
||||||
|
|
||||||
/**
|
/** Database settings. */
|
||||||
* Database settings.
|
|
||||||
*/
|
|
||||||
@ConfigDocSection
|
@ConfigDocSection
|
||||||
Database database();
|
Database database();
|
||||||
|
|
||||||
/**
|
/** Users settings. */
|
||||||
* Users settings.
|
|
||||||
*/
|
|
||||||
@ConfigDocSection
|
@ConfigDocSection
|
||||||
Users users();
|
Users users();
|
||||||
|
|
||||||
/**
|
/** Websocket settings. */
|
||||||
* Websocket settings.
|
|
||||||
*/
|
|
||||||
@ConfigDocSection
|
@ConfigDocSection
|
||||||
Websocket websocket();
|
Websocket websocket();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Duration to wait for the feed refresh engine and the task scheduler to stop when the application is shutting down.
|
* Duration to wait for the feed refresh engine and the task scheduler to stop when the
|
||||||
|
* application is shutting down.
|
||||||
*/
|
*/
|
||||||
@WithDefault("2s")
|
@WithDefault("2s")
|
||||||
Duration shutdownTimeout();
|
Duration shutdownTimeout();
|
||||||
@@ -104,171 +92,150 @@ public interface CommaFeedConfiguration {
|
|||||||
*/
|
*/
|
||||||
Optional<String> userAgent();
|
Optional<String> userAgent();
|
||||||
|
|
||||||
/**
|
/** Time to wait for a connection to be established. */
|
||||||
* Time to wait for a connection to be established.
|
|
||||||
*/
|
|
||||||
@WithDefault("5s")
|
@WithDefault("5s")
|
||||||
Duration connectTimeout();
|
Duration connectTimeout();
|
||||||
|
|
||||||
/**
|
/** Time to wait for SSL handshake to complete. */
|
||||||
* Time to wait for SSL handshake to complete.
|
|
||||||
*/
|
|
||||||
@WithDefault("5s")
|
@WithDefault("5s")
|
||||||
Duration sslHandshakeTimeout();
|
Duration sslHandshakeTimeout();
|
||||||
|
|
||||||
/**
|
/** Time to wait between two packets before timeout. */
|
||||||
* Time to wait between two packets before timeout.
|
|
||||||
*/
|
|
||||||
@WithDefault("10s")
|
@WithDefault("10s")
|
||||||
Duration socketTimeout();
|
Duration socketTimeout();
|
||||||
|
|
||||||
/**
|
/** Time to wait for the full response to be received. */
|
||||||
* Time to wait for the full response to be received.
|
|
||||||
*/
|
|
||||||
@WithDefault("10s")
|
@WithDefault("10s")
|
||||||
Duration responseTimeout();
|
Duration responseTimeout();
|
||||||
|
|
||||||
/**
|
/** Time to live for a connection in the pool. */
|
||||||
* Time to live for a connection in the pool.
|
|
||||||
*/
|
|
||||||
@WithDefault("30s")
|
@WithDefault("30s")
|
||||||
Duration connectionTimeToLive();
|
Duration connectionTimeToLive();
|
||||||
|
|
||||||
/**
|
/** Time between eviction runs for idle connections. */
|
||||||
* Time between eviction runs for idle connections.
|
|
||||||
*/
|
|
||||||
@WithDefault("1m")
|
@WithDefault("1m")
|
||||||
Duration idleConnectionsEvictionInterval();
|
Duration idleConnectionsEvictionInterval();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If a feed is larger than this, it will be discarded to prevent memory issues while parsing the feed.
|
* If a feed is larger than this, it will be discarded to prevent memory issues while
|
||||||
|
* parsing the feed.
|
||||||
*/
|
*/
|
||||||
@WithDefault("5M")
|
@WithDefault("5M")
|
||||||
MemorySize maxResponseSize();
|
MemorySize maxResponseSize();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prevent access to local addresses to mitigate server-side request forgery (SSRF) attacks, which could potentially expose internal
|
* Prevent access to local addresses to mitigate server-side request forgery (SSRF) attacks,
|
||||||
* resources.
|
* which could potentially expose internal resources.
|
||||||
*
|
*
|
||||||
* You may want to enable this if you host a public instance of CommaFeed with registrations open.
|
* <p>You may want to enable this if you host a public instance of CommaFeed with
|
||||||
|
* registrations open.
|
||||||
*/
|
*/
|
||||||
@WithDefault("false")
|
@WithDefault("false")
|
||||||
boolean blockLocalAddresses();
|
boolean blockLocalAddresses();
|
||||||
|
|
||||||
/**
|
/** HTTP client cache configuration */
|
||||||
* HTTP client cache configuration
|
|
||||||
*/
|
|
||||||
@ConfigDocSection
|
@ConfigDocSection
|
||||||
HttpClientCache cache();
|
HttpClientCache cache();
|
||||||
}
|
}
|
||||||
|
|
||||||
interface HttpClientCache {
|
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
|
* Whether to enable the cache. This cache is used to avoid spamming feeds in short bursts
|
||||||
* first time or when clicking "fetch all my feeds now").
|
* (e.g. when subscribing to a feed for the first time or when clicking "fetch all my feeds
|
||||||
|
* now").
|
||||||
*/
|
*/
|
||||||
@WithDefault("true")
|
@WithDefault("true")
|
||||||
boolean enabled();
|
boolean enabled();
|
||||||
|
|
||||||
/**
|
/** Maximum amount of memory the cache can use. */
|
||||||
* Maximum amount of memory the cache can use.
|
|
||||||
*/
|
|
||||||
@WithDefault("10M")
|
@WithDefault("10M")
|
||||||
MemorySize maximumMemorySize();
|
MemorySize maximumMemorySize();
|
||||||
|
|
||||||
/**
|
/** Duration after which an entry is removed from the cache. */
|
||||||
* Duration after which an entry is removed from the cache.
|
|
||||||
*/
|
|
||||||
@WithDefault("1m")
|
@WithDefault("1m")
|
||||||
Duration expiration();
|
Duration expiration();
|
||||||
}
|
}
|
||||||
|
|
||||||
interface FeedRefresh {
|
interface FeedRefresh {
|
||||||
/**
|
/** Default amount of time CommaFeed will wait before refreshing a feed. */
|
||||||
* Default amount of time CommaFeed will wait before refreshing a feed.
|
|
||||||
*/
|
|
||||||
@WithDefault("5m")
|
@WithDefault("5m")
|
||||||
Duration interval();
|
Duration interval();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum amount of time CommaFeed will wait before refreshing a feed. This is used as an upper bound when:
|
* Maximum amount of time CommaFeed will wait before refreshing a feed. This is used as an
|
||||||
|
* upper bound when:
|
||||||
*
|
*
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>an error occurs while refreshing a feed and we're backing off exponentially</li>
|
* <li>an error occurs while refreshing a feed and we're backing off exponentially
|
||||||
* <li>we receive a Cache-Control header from the feed</li>
|
* <li>we receive a Cache-Control header from the feed
|
||||||
* <li>we receive a Retry-After header from the feed</li>
|
* <li>we receive a Retry-After header from the feed
|
||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
@WithDefault("4h")
|
@WithDefault("4h")
|
||||||
Duration maxInterval();
|
Duration maxInterval();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If enabled, CommaFeed will calculate the next refresh time based on the feed's average time between entries and the time since
|
* If enabled, CommaFeed will calculate the next refresh time based on the feed's average
|
||||||
* the last entry was published. The interval will be sometimes between the default refresh interval
|
* time between entries and the time since the last entry was published. The interval will
|
||||||
* (`commafeed.feed-refresh.interval`) and the maximum refresh interval (`commafeed.feed-refresh.max-interval`).
|
* be sometimes between the default refresh interval (`commafeed.feed-refresh.interval`) and
|
||||||
|
* the maximum refresh interval (`commafeed.feed-refresh.max-interval`).
|
||||||
*
|
*
|
||||||
* See {@link FeedRefreshIntervalCalculator} for details.
|
* <p>See {@link FeedRefreshIntervalCalculator} for details.
|
||||||
*/
|
*/
|
||||||
@WithDefault("true")
|
@WithDefault("true")
|
||||||
boolean intervalEmpirical();
|
boolean intervalEmpirical();
|
||||||
|
|
||||||
/**
|
/** Feed refresh engine error handling settings. */
|
||||||
* Feed refresh engine error handling settings.
|
|
||||||
*/
|
|
||||||
@ConfigDocSection
|
@ConfigDocSection
|
||||||
FeedRefreshErrorHandling errors();
|
FeedRefreshErrorHandling errors();
|
||||||
|
|
||||||
/**
|
/** Amount of http threads used to fetch feeds. */
|
||||||
* Amount of http threads used to fetch feeds.
|
|
||||||
*/
|
|
||||||
@Min(1)
|
@Min(1)
|
||||||
@WithDefault("3")
|
@WithDefault("3")
|
||||||
int httpThreads();
|
int httpThreads();
|
||||||
|
|
||||||
/**
|
/** Amount of threads used to insert new entries in the database. */
|
||||||
* Amount of threads used to insert new entries in the database.
|
|
||||||
*/
|
|
||||||
@Min(1)
|
@Min(1)
|
||||||
@WithDefault("1")
|
@WithDefault("1")
|
||||||
int databaseThreads();
|
int databaseThreads();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Duration after which a user is considered inactive. Feeds for inactive users are not refreshed until they log in again.
|
* Duration after which a user is considered inactive. Feeds for inactive users are not
|
||||||
|
* refreshed until they log in again.
|
||||||
*
|
*
|
||||||
* 0 to disable.
|
* <p>0 to disable.
|
||||||
*/
|
*/
|
||||||
@WithDefault("0")
|
@WithDefault("0")
|
||||||
Duration userInactivityPeriod();
|
Duration userInactivityPeriod();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Duration after which the evaluation of a filtering expresion to mark an entry as read is considered to have timed out.
|
* Duration after which the evaluation of a filtering expresion to mark an entry as read is
|
||||||
|
* considered to have timed out.
|
||||||
*/
|
*/
|
||||||
@WithDefault("500ms")
|
@WithDefault("500ms")
|
||||||
Duration filteringExpressionEvaluationTimeout();
|
Duration filteringExpressionEvaluationTimeout();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Duration after which the "Fetch all my feeds now" action is available again after use to avoid spamming feeds.
|
* Duration after which the "Fetch all my feeds now" action is available again after use to
|
||||||
|
* avoid spamming feeds.
|
||||||
*/
|
*/
|
||||||
@WithDefault("0")
|
@WithDefault("0")
|
||||||
Duration forceRefreshCooldownDuration();
|
Duration forceRefreshCooldownDuration();
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PushNotifications {
|
interface PushNotifications {
|
||||||
/**
|
/** Whether to enable push notifications to notify users of new entries in their feeds. */
|
||||||
* Whether to enable push notifications to notify users of new entries in their feeds.
|
|
||||||
*/
|
|
||||||
@WithDefault("true")
|
@WithDefault("true")
|
||||||
boolean enabled();
|
boolean enabled();
|
||||||
|
|
||||||
/**
|
/** Amount of threads used to send external notifications about new entries. */
|
||||||
* Amount of threads used to send external notifications about new entries.
|
|
||||||
*/
|
|
||||||
@Min(1)
|
@Min(1)
|
||||||
@WithDefault("5")
|
@WithDefault("5")
|
||||||
int threads();
|
int threads();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum amount of notifications that can be queued before new notifications are discarded.
|
* Maximum amount of notifications that can be queued before new notifications are
|
||||||
|
* discarded.
|
||||||
*/
|
*/
|
||||||
@Min(1)
|
@Min(1)
|
||||||
@WithDefault("100")
|
@WithDefault("100")
|
||||||
@@ -276,15 +243,14 @@ public interface CommaFeedConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface FeedRefreshErrorHandling {
|
interface FeedRefreshErrorHandling {
|
||||||
/**
|
/** Number of retries before backoff is applied. */
|
||||||
* Number of retries before backoff is applied.
|
|
||||||
*/
|
|
||||||
@Min(0)
|
@Min(0)
|
||||||
@WithDefault("3")
|
@WithDefault("3")
|
||||||
int retriesBeforeBackoff();
|
int retriesBeforeBackoff();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Duration to wait before retrying after an error. Will be multiplied by the number of errors since the last successful fetch.
|
* Duration to wait before retrying after an error. Will be multiplied by the number of
|
||||||
|
* errors since the last successful fetch.
|
||||||
*/
|
*/
|
||||||
@WithDefault("1h")
|
@WithDefault("1h")
|
||||||
Duration backoffInterval();
|
Duration backoffInterval();
|
||||||
@@ -294,14 +260,12 @@ public interface CommaFeedConfiguration {
|
|||||||
/**
|
/**
|
||||||
* Timeout applied to all database queries.
|
* Timeout applied to all database queries.
|
||||||
*
|
*
|
||||||
* 0 to disable.
|
* <p>0 to disable.
|
||||||
*/
|
*/
|
||||||
@WithDefault("0")
|
@WithDefault("0")
|
||||||
Duration queryTimeout();
|
Duration queryTimeout();
|
||||||
|
|
||||||
/**
|
/** Database cleanup settings. */
|
||||||
* Database cleanup settings.
|
|
||||||
*/
|
|
||||||
@ConfigDocSection
|
@ConfigDocSection
|
||||||
Cleanup cleanup();
|
Cleanup cleanup();
|
||||||
|
|
||||||
@@ -309,15 +273,16 @@ public interface CommaFeedConfiguration {
|
|||||||
/**
|
/**
|
||||||
* Maximum age of feed entries in the database. Older entries will be deleted.
|
* Maximum age of feed entries in the database. Older entries will be deleted.
|
||||||
*
|
*
|
||||||
* 0 to disable.
|
* <p>0 to disable.
|
||||||
*/
|
*/
|
||||||
@WithDefault("365d")
|
@WithDefault("365d")
|
||||||
Duration entriesMaxAge();
|
Duration entriesMaxAge();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum age of feed entry statuses (read/unread) in the database. Older statuses will be deleted.
|
* Maximum age of feed entry statuses (read/unread) in the database. Older statuses will
|
||||||
|
* be deleted.
|
||||||
*
|
*
|
||||||
* 0 to disable.
|
* <p>0 to disable.
|
||||||
*/
|
*/
|
||||||
@WithDefault("0")
|
@WithDefault("0")
|
||||||
Duration statusesMaxAge();
|
Duration statusesMaxAge();
|
||||||
@@ -325,7 +290,7 @@ public interface CommaFeedConfiguration {
|
|||||||
/**
|
/**
|
||||||
* Maximum number of entries per feed to keep in the database.
|
* Maximum number of entries per feed to keep in the database.
|
||||||
*
|
*
|
||||||
* 0 to disable.
|
* <p>0 to disable.
|
||||||
*/
|
*/
|
||||||
@WithDefault("500")
|
@WithDefault("500")
|
||||||
int maxFeedCapacity();
|
int maxFeedCapacity();
|
||||||
@@ -333,74 +298,66 @@ public interface CommaFeedConfiguration {
|
|||||||
/**
|
/**
|
||||||
* Limit the number of feeds a user can subscribe to.
|
* Limit the number of feeds a user can subscribe to.
|
||||||
*
|
*
|
||||||
* 0 to disable.
|
* <p>0 to disable.
|
||||||
*/
|
*/
|
||||||
@WithDefault("0")
|
@WithDefault("0")
|
||||||
int maxFeedsPerUser();
|
int maxFeedsPerUser();
|
||||||
|
|
||||||
/**
|
/** Rows to delete per query while cleaning up old entries. */
|
||||||
* Rows to delete per query while cleaning up old entries.
|
|
||||||
*/
|
|
||||||
@Positive
|
@Positive
|
||||||
@WithDefault("100")
|
@WithDefault("100")
|
||||||
int batchSize();
|
int batchSize();
|
||||||
|
|
||||||
/**
|
/** Whether to keep starred entries when cleaning up old entries. */
|
||||||
* Whether to keep starred entries when cleaning up old entries.
|
|
||||||
*/
|
|
||||||
@WithDefault("true")
|
@WithDefault("true")
|
||||||
boolean keepStarredEntries();
|
boolean keepStarredEntries();
|
||||||
|
|
||||||
default Instant statusesInstantThreshold() {
|
default Instant statusesInstantThreshold() {
|
||||||
return statusesMaxAge().toMillis() > 0 ? Instant.now().minus(statusesMaxAge()) : null;
|
return statusesMaxAge().toMillis() > 0
|
||||||
|
? Instant.now().minus(statusesMaxAge())
|
||||||
|
: null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Users {
|
interface Users {
|
||||||
/**
|
/** Whether to let users create accounts for themselves. */
|
||||||
* Whether to let users create accounts for themselves.
|
|
||||||
*/
|
|
||||||
@WithDefault("false")
|
@WithDefault("false")
|
||||||
boolean allowRegistrations();
|
boolean allowRegistrations();
|
||||||
|
|
||||||
/**
|
/** Minimum password length for user accounts. */
|
||||||
* Minimum password length for user accounts.
|
|
||||||
*/
|
|
||||||
@WithDefault("4")
|
@WithDefault("4")
|
||||||
int minimumPasswordLength();
|
int minimumPasswordLength();
|
||||||
|
|
||||||
/**
|
/** Whether an email address is required when creating a user account. */
|
||||||
* Whether an email address is required when creating a user account.
|
|
||||||
*/
|
|
||||||
@WithDefault("false")
|
@WithDefault("false")
|
||||||
boolean emailAddressRequired();
|
boolean emailAddressRequired();
|
||||||
|
|
||||||
/**
|
/** Whether to create a demo account the first time the app starts. */
|
||||||
* Whether to create a demo account the first time the app starts.
|
|
||||||
*/
|
|
||||||
@WithDefault("false")
|
@WithDefault("false")
|
||||||
boolean createDemoAccount();
|
boolean createDemoAccount();
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Websocket {
|
interface Websocket {
|
||||||
/**
|
/**
|
||||||
* Enable websocket connection so the server can notify web clients that there are new entries for feeds.
|
* Enable websocket connection so the server can notify web clients that there are new
|
||||||
|
* entries for feeds.
|
||||||
*/
|
*/
|
||||||
@WithDefault("true")
|
@WithDefault("true")
|
||||||
boolean enabled();
|
boolean enabled();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interval at which the client will send a ping message on the websocket to keep the connection alive.
|
* Interval at which the client will send a ping message on the websocket to keep the
|
||||||
|
* connection alive.
|
||||||
*/
|
*/
|
||||||
@WithDefault("15m")
|
@WithDefault("15m")
|
||||||
Duration pingInterval();
|
Duration pingInterval();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the websocket connection is disabled or the connection is lost, the client will reload the feed tree at this interval.
|
* If the websocket connection is disabled or the connection is lost, the client will reload
|
||||||
|
* the feed tree at this interval.
|
||||||
*/
|
*/
|
||||||
@WithDefault("30s")
|
@WithDefault("30s")
|
||||||
Duration treeReloadInterval();
|
Duration treeReloadInterval();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.commafeed;
|
package com.commafeed;
|
||||||
|
|
||||||
import java.time.InstantSource;
|
import com.codahale.metrics.MetricRegistry;
|
||||||
|
|
||||||
import jakarta.enterprise.inject.Produces;
|
import jakarta.enterprise.inject.Produces;
|
||||||
import jakarta.inject.Singleton;
|
import jakarta.inject.Singleton;
|
||||||
|
|
||||||
import com.codahale.metrics.MetricRegistry;
|
import java.time.InstantSource;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class CommaFeedProducers {
|
public class CommaFeedProducers {
|
||||||
@@ -21,5 +21,4 @@ public class CommaFeedProducers {
|
|||||||
public MetricRegistry metricRegistry() {
|
public MetricRegistry metricRegistry() {
|
||||||
return new MetricRegistry();
|
return new MetricRegistry();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
package com.commafeed;
|
package com.commafeed;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import jakarta.inject.Singleton;
|
import jakarta.inject.Singleton;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@Getter
|
@Getter
|
||||||
public class CommaFeedVersion {
|
public class CommaFeedVersion {
|
||||||
@@ -26,5 +26,4 @@ public class CommaFeedVersion {
|
|||||||
this.version = properties.getProperty("git.build.version", "unknown");
|
this.version = properties.getProperty("git.build.version", "unknown");
|
||||||
this.gitCommit = properties.getProperty("git.commit.id.abbrev", "unknown");
|
this.gitCommit = properties.getProperty("git.commit.id.abbrev", "unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,23 @@
|
|||||||
package com.commafeed;
|
package com.commafeed;
|
||||||
|
|
||||||
import jakarta.annotation.Priority;
|
|
||||||
import jakarta.validation.ValidationException;
|
|
||||||
import jakarta.ws.rs.core.NewCookie;
|
|
||||||
import jakarta.ws.rs.ext.Provider;
|
|
||||||
|
|
||||||
import org.jboss.resteasy.reactive.RestResponse;
|
|
||||||
import org.jboss.resteasy.reactive.RestResponse.ResponseBuilder;
|
|
||||||
import org.jboss.resteasy.reactive.RestResponse.Status;
|
|
||||||
import org.jboss.resteasy.reactive.server.ServerExceptionMapper;
|
|
||||||
|
|
||||||
import com.commafeed.security.CookieService;
|
import com.commafeed.security.CookieService;
|
||||||
|
|
||||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
import io.quarkus.security.AuthenticationFailedException;
|
import io.quarkus.security.AuthenticationFailedException;
|
||||||
import io.quarkus.security.UnauthorizedException;
|
import io.quarkus.security.UnauthorizedException;
|
||||||
|
|
||||||
|
import jakarta.annotation.Priority;
|
||||||
|
import jakarta.validation.ValidationException;
|
||||||
|
import jakarta.ws.rs.core.NewCookie;
|
||||||
|
import jakarta.ws.rs.ext.Provider;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
import org.jboss.resteasy.reactive.RestResponse;
|
||||||
|
import org.jboss.resteasy.reactive.RestResponse.ResponseBuilder;
|
||||||
|
import org.jboss.resteasy.reactive.RestResponse.Status;
|
||||||
|
import org.jboss.resteasy.reactive.server.ServerExceptionMapper;
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Provider
|
@Provider
|
||||||
@Priority(1)
|
@Priority(1)
|
||||||
@@ -27,13 +28,18 @@ public class ExceptionMappers {
|
|||||||
|
|
||||||
@ServerExceptionMapper(UnauthorizedException.class)
|
@ServerExceptionMapper(UnauthorizedException.class)
|
||||||
public RestResponse<UnauthorizedResponse> unauthorized(UnauthorizedException e) {
|
public RestResponse<UnauthorizedResponse> unauthorized(UnauthorizedException e) {
|
||||||
return RestResponse.status(Status.UNAUTHORIZED, new UnauthorizedResponse(e.getMessage(), config.users().allowRegistrations()));
|
return RestResponse.status(
|
||||||
|
Status.UNAUTHORIZED,
|
||||||
|
new UnauthorizedResponse(e.getMessage(), config.users().allowRegistrations()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ServerExceptionMapper(AuthenticationFailedException.class)
|
@ServerExceptionMapper(AuthenticationFailedException.class)
|
||||||
public RestResponse<AuthenticationFailed> authenticationFailed(AuthenticationFailedException e) {
|
public RestResponse<AuthenticationFailed> authenticationFailed(
|
||||||
|
AuthenticationFailedException e) {
|
||||||
NewCookie logoutCookie = cookieService.buildLogoutCookie();
|
NewCookie logoutCookie = cookieService.buildLogoutCookie();
|
||||||
return ResponseBuilder.create(Status.UNAUTHORIZED, new AuthenticationFailed(e.getMessage())).cookie(logoutCookie).build();
|
return ResponseBuilder.create(Status.UNAUTHORIZED, new AuthenticationFailed(e.getMessage()))
|
||||||
|
.cookie(logoutCookie)
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ServerExceptionMapper(ValidationException.class)
|
@ServerExceptionMapper(ValidationException.class)
|
||||||
@@ -42,14 +48,11 @@ public class ExceptionMappers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@RegisterForReflection
|
@RegisterForReflection
|
||||||
public record UnauthorizedResponse(String message, boolean allowRegistrations) {
|
public record UnauthorizedResponse(String message, boolean allowRegistrations) {}
|
||||||
}
|
|
||||||
|
|
||||||
@RegisterForReflection
|
@RegisterForReflection
|
||||||
public record AuthenticationFailed(String message) {
|
public record AuthenticationFailed(String message) {}
|
||||||
}
|
|
||||||
|
|
||||||
@RegisterForReflection
|
@RegisterForReflection
|
||||||
public record ValidationFailed(String message) {
|
public record ValidationFailed(String message) {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
package com.commafeed;
|
package com.commafeed;
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import jakarta.inject.Singleton;
|
|
||||||
|
|
||||||
import com.codahale.metrics.json.MetricsModule;
|
import com.codahale.metrics.json.MetricsModule;
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
@@ -12,6 +8,10 @@ import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
|||||||
|
|
||||||
import io.quarkus.jackson.ObjectMapperCustomizer;
|
import io.quarkus.jackson.ObjectMapperCustomizer;
|
||||||
|
|
||||||
|
import jakarta.inject.Singleton;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class JacksonCustomizer implements ObjectMapperCustomizer {
|
public class JacksonCustomizer implements ObjectMapperCustomizer {
|
||||||
@Override
|
@Override
|
||||||
@@ -19,7 +19,8 @@ public class JacksonCustomizer implements ObjectMapperCustomizer {
|
|||||||
objectMapper.registerModule(new JavaTimeModule());
|
objectMapper.registerModule(new JavaTimeModule());
|
||||||
|
|
||||||
// read and write instants as milliseconds instead of nanoseconds
|
// read and write instants as milliseconds instead of nanoseconds
|
||||||
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true)
|
objectMapper
|
||||||
|
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true)
|
||||||
.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false)
|
.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false)
|
||||||
.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS, false);
|
.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS, false);
|
||||||
|
|
||||||
|
|||||||
@@ -12,215 +12,338 @@ import io.quarkus.runtime.annotations.RegisterForReflection;
|
|||||||
@RegisterForReflection(
|
@RegisterForReflection(
|
||||||
targets = {
|
targets = {
|
||||||
// metrics
|
// metrics
|
||||||
MetricRegistry.class, Meter.class, Gauge.class, Counter.class, Timer.class, Histogram.class,
|
MetricRegistry.class,
|
||||||
|
Meter.class,
|
||||||
|
Gauge.class,
|
||||||
|
Counter.class,
|
||||||
|
Timer.class,
|
||||||
|
Histogram.class,
|
||||||
|
|
||||||
// rome
|
// rome
|
||||||
java.util.Date.class, com.rometools.opml.feed.synd.impl.TreeCategoryImpl.class,
|
java.util.Date.class,
|
||||||
com.rometools.rome.feed.synd.SyndFeedImpl.class, com.rometools.rome.feed.module.DCSubjectImpl.class,
|
com.rometools.opml.feed.synd.impl.TreeCategoryImpl.class,
|
||||||
com.rometools.rome.feed.synd.SyndEntryImpl.class, com.rometools.modules.psc.types.SimpleChapter.class,
|
com.rometools.rome.feed.synd.SyndFeedImpl.class,
|
||||||
com.rometools.rome.feed.synd.SyndCategoryImpl.class, com.rometools.rome.feed.synd.SyndImageImpl.class,
|
com.rometools.rome.feed.module.DCSubjectImpl.class,
|
||||||
com.rometools.rome.feed.synd.SyndContentImpl.class, com.rometools.rome.feed.synd.SyndEnclosureImpl.class,
|
com.rometools.rome.feed.synd.SyndEntryImpl.class,
|
||||||
|
com.rometools.modules.psc.types.SimpleChapter.class,
|
||||||
|
com.rometools.rome.feed.synd.SyndCategoryImpl.class,
|
||||||
|
com.rometools.rome.feed.synd.SyndImageImpl.class,
|
||||||
|
com.rometools.rome.feed.synd.SyndContentImpl.class,
|
||||||
|
com.rometools.rome.feed.synd.SyndEnclosureImpl.class,
|
||||||
|
|
||||||
// rome cloneable
|
// rome cloneable
|
||||||
com.rometools.modules.activitystreams.types.Article.class, com.rometools.modules.activitystreams.types.Audio.class,
|
com.rometools.modules.activitystreams.types.Article.class,
|
||||||
com.rometools.modules.activitystreams.types.Bookmark.class, com.rometools.modules.activitystreams.types.Comment.class,
|
com.rometools.modules.activitystreams.types.Audio.class,
|
||||||
com.rometools.modules.activitystreams.types.Event.class, com.rometools.modules.activitystreams.types.File.class,
|
com.rometools.modules.activitystreams.types.Bookmark.class,
|
||||||
com.rometools.modules.activitystreams.types.Folder.class, com.rometools.modules.activitystreams.types.List.class,
|
com.rometools.modules.activitystreams.types.Comment.class,
|
||||||
com.rometools.modules.activitystreams.types.Note.class, com.rometools.modules.activitystreams.types.Person.class,
|
com.rometools.modules.activitystreams.types.Event.class,
|
||||||
com.rometools.modules.activitystreams.types.Photo.class, com.rometools.modules.activitystreams.types.PhotoAlbum.class,
|
com.rometools.modules.activitystreams.types.File.class,
|
||||||
com.rometools.modules.activitystreams.types.Place.class, com.rometools.modules.activitystreams.types.Playlist.class,
|
com.rometools.modules.activitystreams.types.Folder.class,
|
||||||
com.rometools.modules.activitystreams.types.Product.class, com.rometools.modules.activitystreams.types.Review.class,
|
com.rometools.modules.activitystreams.types.List.class,
|
||||||
com.rometools.modules.activitystreams.types.Service.class, com.rometools.modules.activitystreams.types.Song.class,
|
com.rometools.modules.activitystreams.types.Note.class,
|
||||||
com.rometools.modules.activitystreams.types.Status.class, com.rometools.modules.base.types.DateTimeRange.class,
|
com.rometools.modules.activitystreams.types.Person.class,
|
||||||
com.rometools.modules.base.types.FloatUnit.class, com.rometools.modules.base.types.GenderEnumeration.class,
|
com.rometools.modules.activitystreams.types.Photo.class,
|
||||||
com.rometools.modules.base.types.IntUnit.class, com.rometools.modules.base.types.PriceTypeEnumeration.class,
|
com.rometools.modules.activitystreams.types.PhotoAlbum.class,
|
||||||
com.rometools.modules.base.types.ShippingType.class, com.rometools.modules.base.types.ShortDate.class,
|
com.rometools.modules.activitystreams.types.Place.class,
|
||||||
com.rometools.modules.base.types.Size.class, com.rometools.modules.base.types.YearType.class,
|
com.rometools.modules.activitystreams.types.Playlist.class,
|
||||||
com.rometools.modules.content.ContentItem.class, com.rometools.modules.georss.GeoRSSPoint.class,
|
com.rometools.modules.activitystreams.types.Product.class,
|
||||||
com.rometools.modules.georss.geometries.Envelope.class, com.rometools.modules.georss.geometries.LineString.class,
|
com.rometools.modules.activitystreams.types.Review.class,
|
||||||
com.rometools.modules.georss.geometries.LinearRing.class, com.rometools.modules.georss.geometries.Point.class,
|
com.rometools.modules.activitystreams.types.Service.class,
|
||||||
com.rometools.modules.georss.geometries.Polygon.class, com.rometools.modules.georss.geometries.Position.class,
|
com.rometools.modules.activitystreams.types.Song.class,
|
||||||
com.rometools.modules.georss.geometries.PositionList.class, com.rometools.modules.mediarss.types.MediaGroup.class,
|
com.rometools.modules.activitystreams.types.Status.class,
|
||||||
com.rometools.modules.mediarss.types.Metadata.class, com.rometools.modules.mediarss.types.Thumbnail.class,
|
com.rometools.modules.base.types.DateTimeRange.class,
|
||||||
com.rometools.modules.opensearch.entity.OSQuery.class, com.rometools.modules.photocast.types.PhotoDate.class,
|
com.rometools.modules.base.types.FloatUnit.class,
|
||||||
com.rometools.modules.sle.types.DateValue.class, com.rometools.modules.sle.types.Group.class,
|
com.rometools.modules.base.types.GenderEnumeration.class,
|
||||||
com.rometools.modules.sle.types.NumberValue.class, com.rometools.modules.sle.types.Sort.class,
|
com.rometools.modules.base.types.IntUnit.class,
|
||||||
com.rometools.modules.sle.types.StringValue.class, com.rometools.modules.yahooweather.types.Astronomy.class,
|
com.rometools.modules.base.types.PriceTypeEnumeration.class,
|
||||||
com.rometools.modules.yahooweather.types.Atmosphere.class, com.rometools.modules.yahooweather.types.Condition.class,
|
com.rometools.modules.base.types.ShippingType.class,
|
||||||
com.rometools.modules.yahooweather.types.Forecast.class, com.rometools.modules.yahooweather.types.Location.class,
|
com.rometools.modules.base.types.ShortDate.class,
|
||||||
com.rometools.modules.yahooweather.types.Units.class, com.rometools.modules.yahooweather.types.Wind.class,
|
com.rometools.modules.base.types.Size.class,
|
||||||
com.rometools.opml.feed.opml.Attribute.class, com.rometools.opml.feed.opml.Opml.class,
|
com.rometools.modules.base.types.YearType.class,
|
||||||
com.rometools.opml.feed.opml.Outline.class, com.rometools.rome.feed.atom.Category.class,
|
com.rometools.modules.content.ContentItem.class,
|
||||||
com.rometools.rome.feed.atom.Content.class, com.rometools.rome.feed.atom.Entry.class,
|
com.rometools.modules.georss.GeoRSSPoint.class,
|
||||||
com.rometools.rome.feed.atom.Feed.class, com.rometools.rome.feed.atom.Generator.class,
|
com.rometools.modules.georss.geometries.Envelope.class,
|
||||||
com.rometools.rome.feed.atom.Link.class, com.rometools.rome.feed.atom.Person.class,
|
com.rometools.modules.georss.geometries.LineString.class,
|
||||||
com.rometools.rome.feed.rss.Category.class, com.rometools.rome.feed.rss.Channel.class,
|
com.rometools.modules.georss.geometries.LinearRing.class,
|
||||||
com.rometools.rome.feed.rss.Cloud.class, com.rometools.rome.feed.rss.Content.class,
|
com.rometools.modules.georss.geometries.Point.class,
|
||||||
com.rometools.rome.feed.rss.Description.class, com.rometools.rome.feed.rss.Enclosure.class,
|
com.rometools.modules.georss.geometries.Polygon.class,
|
||||||
com.rometools.rome.feed.rss.Guid.class, com.rometools.rome.feed.rss.Image.class, com.rometools.rome.feed.rss.Item.class,
|
com.rometools.modules.georss.geometries.Position.class,
|
||||||
com.rometools.rome.feed.rss.Source.class, com.rometools.rome.feed.rss.TextInput.class,
|
com.rometools.modules.georss.geometries.PositionList.class,
|
||||||
com.rometools.rome.feed.synd.SyndLinkImpl.class, com.rometools.rome.feed.synd.SyndPersonImpl.class,
|
com.rometools.modules.mediarss.types.MediaGroup.class,
|
||||||
|
com.rometools.modules.mediarss.types.Metadata.class,
|
||||||
|
com.rometools.modules.mediarss.types.Thumbnail.class,
|
||||||
|
com.rometools.modules.opensearch.entity.OSQuery.class,
|
||||||
|
com.rometools.modules.photocast.types.PhotoDate.class,
|
||||||
|
com.rometools.modules.sle.types.DateValue.class,
|
||||||
|
com.rometools.modules.sle.types.Group.class,
|
||||||
|
com.rometools.modules.sle.types.NumberValue.class,
|
||||||
|
com.rometools.modules.sle.types.Sort.class,
|
||||||
|
com.rometools.modules.sle.types.StringValue.class,
|
||||||
|
com.rometools.modules.yahooweather.types.Astronomy.class,
|
||||||
|
com.rometools.modules.yahooweather.types.Atmosphere.class,
|
||||||
|
com.rometools.modules.yahooweather.types.Condition.class,
|
||||||
|
com.rometools.modules.yahooweather.types.Forecast.class,
|
||||||
|
com.rometools.modules.yahooweather.types.Location.class,
|
||||||
|
com.rometools.modules.yahooweather.types.Units.class,
|
||||||
|
com.rometools.modules.yahooweather.types.Wind.class,
|
||||||
|
com.rometools.opml.feed.opml.Attribute.class,
|
||||||
|
com.rometools.opml.feed.opml.Opml.class,
|
||||||
|
com.rometools.opml.feed.opml.Outline.class,
|
||||||
|
com.rometools.rome.feed.atom.Category.class,
|
||||||
|
com.rometools.rome.feed.atom.Content.class,
|
||||||
|
com.rometools.rome.feed.atom.Entry.class,
|
||||||
|
com.rometools.rome.feed.atom.Feed.class,
|
||||||
|
com.rometools.rome.feed.atom.Generator.class,
|
||||||
|
com.rometools.rome.feed.atom.Link.class,
|
||||||
|
com.rometools.rome.feed.atom.Person.class,
|
||||||
|
com.rometools.rome.feed.rss.Category.class,
|
||||||
|
com.rometools.rome.feed.rss.Channel.class,
|
||||||
|
com.rometools.rome.feed.rss.Cloud.class,
|
||||||
|
com.rometools.rome.feed.rss.Content.class,
|
||||||
|
com.rometools.rome.feed.rss.Description.class,
|
||||||
|
com.rometools.rome.feed.rss.Enclosure.class,
|
||||||
|
com.rometools.rome.feed.rss.Guid.class,
|
||||||
|
com.rometools.rome.feed.rss.Image.class,
|
||||||
|
com.rometools.rome.feed.rss.Item.class,
|
||||||
|
com.rometools.rome.feed.rss.Source.class,
|
||||||
|
com.rometools.rome.feed.rss.TextInput.class,
|
||||||
|
com.rometools.rome.feed.synd.SyndLinkImpl.class,
|
||||||
|
com.rometools.rome.feed.synd.SyndPersonImpl.class,
|
||||||
java.util.ArrayList.class,
|
java.util.ArrayList.class,
|
||||||
|
|
||||||
// rome modules
|
// rome modules
|
||||||
com.rometools.modules.sse.modules.Conflict.class, com.rometools.modules.sse.modules.Conflicts.class,
|
com.rometools.modules.sse.modules.Conflict.class,
|
||||||
com.rometools.modules.cc.CreativeCommonsImpl.class, com.rometools.modules.feedpress.modules.FeedpressModuleImpl.class,
|
com.rometools.modules.sse.modules.Conflicts.class,
|
||||||
com.rometools.modules.opensearch.impl.OpenSearchModuleImpl.class, com.rometools.modules.sse.modules.Sharing.class,
|
com.rometools.modules.cc.CreativeCommonsImpl.class,
|
||||||
com.rometools.modules.georss.SimpleModuleImpl.class, com.rometools.modules.atom.modules.AtomLinkModuleImpl.class,
|
com.rometools.modules.feedpress.modules.FeedpressModuleImpl.class,
|
||||||
com.rometools.modules.itunes.EntryInformationImpl.class, com.rometools.modules.sse.modules.Update.class,
|
com.rometools.modules.opensearch.impl.OpenSearchModuleImpl.class,
|
||||||
com.rometools.modules.photocast.PhotocastModuleImpl.class, com.rometools.modules.itunes.FeedInformationImpl.class,
|
com.rometools.modules.sse.modules.Sharing.class,
|
||||||
com.rometools.modules.yahooweather.YWeatherModuleImpl.class, com.rometools.modules.feedburner.FeedBurnerImpl.class,
|
com.rometools.modules.georss.SimpleModuleImpl.class,
|
||||||
com.rometools.modules.sse.modules.Related.class, com.rometools.modules.fyyd.modules.FyydModuleImpl.class,
|
com.rometools.modules.atom.modules.AtomLinkModuleImpl.class,
|
||||||
com.rometools.modules.psc.modules.PodloveSimpleChapterModuleImpl.class, com.rometools.modules.thr.ThreadingModuleImpl.class,
|
com.rometools.modules.itunes.EntryInformationImpl.class,
|
||||||
com.rometools.modules.sse.modules.Sync.class, com.rometools.modules.sle.SimpleListExtensionImpl.class,
|
com.rometools.modules.sse.modules.Update.class,
|
||||||
com.rometools.modules.slash.SlashImpl.class, com.rometools.modules.sse.modules.History.class,
|
com.rometools.modules.photocast.PhotocastModuleImpl.class,
|
||||||
com.rometools.modules.georss.GMLModuleImpl.class, com.rometools.modules.base.CustomTagsImpl.class,
|
com.rometools.modules.itunes.FeedInformationImpl.class,
|
||||||
com.rometools.modules.base.GoogleBaseImpl.class, com.rometools.modules.sle.SleEntryImpl.class,
|
com.rometools.modules.yahooweather.YWeatherModuleImpl.class,
|
||||||
com.rometools.modules.mediarss.MediaEntryModuleImpl.class, com.rometools.modules.content.ContentModuleImpl.class,
|
com.rometools.modules.feedburner.FeedBurnerImpl.class,
|
||||||
com.rometools.modules.georss.W3CGeoModuleImpl.class, com.rometools.rome.feed.module.DCModuleImpl.class,
|
com.rometools.modules.sse.modules.Related.class,
|
||||||
com.rometools.modules.mediarss.MediaModuleImpl.class, com.rometools.rome.feed.module.SyModuleImpl.class,
|
com.rometools.modules.fyyd.modules.FyydModuleImpl.class,
|
||||||
|
com.rometools.modules.psc.modules.PodloveSimpleChapterModuleImpl.class,
|
||||||
|
com.rometools.modules.thr.ThreadingModuleImpl.class,
|
||||||
|
com.rometools.modules.sse.modules.Sync.class,
|
||||||
|
com.rometools.modules.sle.SimpleListExtensionImpl.class,
|
||||||
|
com.rometools.modules.slash.SlashImpl.class,
|
||||||
|
com.rometools.modules.sse.modules.History.class,
|
||||||
|
com.rometools.modules.georss.GMLModuleImpl.class,
|
||||||
|
com.rometools.modules.base.CustomTagsImpl.class,
|
||||||
|
com.rometools.modules.base.GoogleBaseImpl.class,
|
||||||
|
com.rometools.modules.sle.SleEntryImpl.class,
|
||||||
|
com.rometools.modules.mediarss.MediaEntryModuleImpl.class,
|
||||||
|
com.rometools.modules.content.ContentModuleImpl.class,
|
||||||
|
com.rometools.modules.georss.W3CGeoModuleImpl.class,
|
||||||
|
com.rometools.rome.feed.module.DCModuleImpl.class,
|
||||||
|
com.rometools.modules.mediarss.MediaModuleImpl.class,
|
||||||
|
com.rometools.rome.feed.module.SyModuleImpl.class,
|
||||||
|
|
||||||
// extracted from all 3 rome.properties files of rome library
|
// extracted from all 3 rome.properties files of rome library
|
||||||
com.rometools.rome.io.impl.RSS090Parser.class, com.rometools.rome.io.impl.RSS091NetscapeParser.class,
|
com.rometools.rome.io.impl.RSS090Parser.class,
|
||||||
com.rometools.rome.io.impl.RSS091UserlandParser.class, com.rometools.rome.io.impl.RSS092Parser.class,
|
com.rometools.rome.io.impl.RSS091NetscapeParser.class,
|
||||||
com.rometools.rome.io.impl.RSS093Parser.class, com.rometools.rome.io.impl.RSS094Parser.class,
|
com.rometools.rome.io.impl.RSS091UserlandParser.class,
|
||||||
com.rometools.rome.io.impl.RSS10Parser.class, com.rometools.rome.io.impl.RSS20wNSParser.class,
|
com.rometools.rome.io.impl.RSS092Parser.class,
|
||||||
com.rometools.rome.io.impl.RSS20Parser.class, com.rometools.rome.io.impl.Atom10Parser.class,
|
com.rometools.rome.io.impl.RSS093Parser.class,
|
||||||
|
com.rometools.rome.io.impl.RSS094Parser.class,
|
||||||
|
com.rometools.rome.io.impl.RSS10Parser.class,
|
||||||
|
com.rometools.rome.io.impl.RSS20wNSParser.class,
|
||||||
|
com.rometools.rome.io.impl.RSS20Parser.class,
|
||||||
|
com.rometools.rome.io.impl.Atom10Parser.class,
|
||||||
com.rometools.rome.io.impl.Atom03Parser.class,
|
com.rometools.rome.io.impl.Atom03Parser.class,
|
||||||
|
com.rometools.rome.io.impl.SyModuleParser.class,
|
||||||
com.rometools.rome.io.impl.SyModuleParser.class, com.rometools.rome.io.impl.DCModuleParser.class,
|
com.rometools.rome.io.impl.DCModuleParser.class,
|
||||||
|
com.rometools.rome.io.impl.RSS090Generator.class,
|
||||||
com.rometools.rome.io.impl.RSS090Generator.class, com.rometools.rome.io.impl.RSS091NetscapeGenerator.class,
|
com.rometools.rome.io.impl.RSS091NetscapeGenerator.class,
|
||||||
com.rometools.rome.io.impl.RSS091UserlandGenerator.class, com.rometools.rome.io.impl.RSS092Generator.class,
|
com.rometools.rome.io.impl.RSS091UserlandGenerator.class,
|
||||||
com.rometools.rome.io.impl.RSS093Generator.class, com.rometools.rome.io.impl.RSS094Generator.class,
|
com.rometools.rome.io.impl.RSS092Generator.class,
|
||||||
com.rometools.rome.io.impl.RSS10Generator.class, com.rometools.rome.io.impl.RSS20Generator.class,
|
com.rometools.rome.io.impl.RSS093Generator.class,
|
||||||
com.rometools.rome.io.impl.Atom10Generator.class, com.rometools.rome.io.impl.Atom03Generator.class,
|
com.rometools.rome.io.impl.RSS094Generator.class,
|
||||||
|
com.rometools.rome.io.impl.RSS10Generator.class,
|
||||||
com.rometools.rome.feed.synd.impl.ConverterForAtom10.class, com.rometools.rome.feed.synd.impl.ConverterForAtom03.class,
|
com.rometools.rome.io.impl.RSS20Generator.class,
|
||||||
|
com.rometools.rome.io.impl.Atom10Generator.class,
|
||||||
|
com.rometools.rome.io.impl.Atom03Generator.class,
|
||||||
|
com.rometools.rome.feed.synd.impl.ConverterForAtom10.class,
|
||||||
|
com.rometools.rome.feed.synd.impl.ConverterForAtom03.class,
|
||||||
com.rometools.rome.feed.synd.impl.ConverterForRSS090.class,
|
com.rometools.rome.feed.synd.impl.ConverterForRSS090.class,
|
||||||
com.rometools.rome.feed.synd.impl.ConverterForRSS091Netscape.class,
|
com.rometools.rome.feed.synd.impl.ConverterForRSS091Netscape.class,
|
||||||
com.rometools.rome.feed.synd.impl.ConverterForRSS091Userland.class,
|
com.rometools.rome.feed.synd.impl.ConverterForRSS091Userland.class,
|
||||||
com.rometools.rome.feed.synd.impl.ConverterForRSS092.class, com.rometools.rome.feed.synd.impl.ConverterForRSS093.class,
|
com.rometools.rome.feed.synd.impl.ConverterForRSS092.class,
|
||||||
com.rometools.rome.feed.synd.impl.ConverterForRSS094.class, com.rometools.rome.feed.synd.impl.ConverterForRSS10.class,
|
com.rometools.rome.feed.synd.impl.ConverterForRSS093.class,
|
||||||
|
com.rometools.rome.feed.synd.impl.ConverterForRSS094.class,
|
||||||
|
com.rometools.rome.feed.synd.impl.ConverterForRSS10.class,
|
||||||
com.rometools.rome.feed.synd.impl.ConverterForRSS20.class,
|
com.rometools.rome.feed.synd.impl.ConverterForRSS20.class,
|
||||||
|
|
||||||
com.rometools.modules.mediarss.io.RSS20YahooParser.class,
|
com.rometools.modules.mediarss.io.RSS20YahooParser.class,
|
||||||
|
com.rometools.modules.cc.io.ModuleParserRSS2.class,
|
||||||
com.rometools.modules.cc.io.ModuleParserRSS2.class, com.rometools.modules.content.io.ContentModuleParser.class,
|
com.rometools.modules.content.io.ContentModuleParser.class,
|
||||||
com.rometools.modules.itunes.io.ITunesParser.class, com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
com.rometools.modules.itunes.io.ITunesParser.class,
|
||||||
com.rometools.modules.opensearch.impl.OpenSearchModuleParser.class, com.rometools.modules.georss.SimpleParser.class,
|
com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
||||||
com.rometools.modules.georss.W3CGeoParser.class, com.rometools.modules.photocast.io.Parser.class,
|
com.rometools.modules.opensearch.impl.OpenSearchModuleParser.class,
|
||||||
com.rometools.modules.mediarss.io.MediaModuleParser.class, com.rometools.modules.atom.io.AtomModuleParser.class,
|
com.rometools.modules.georss.SimpleParser.class,
|
||||||
|
com.rometools.modules.georss.W3CGeoParser.class,
|
||||||
|
com.rometools.modules.photocast.io.Parser.class,
|
||||||
|
com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
||||||
|
com.rometools.modules.atom.io.AtomModuleParser.class,
|
||||||
com.rometools.modules.itunes.io.ITunesParserOldNamespace.class,
|
com.rometools.modules.itunes.io.ITunesParserOldNamespace.class,
|
||||||
com.rometools.modules.mediarss.io.AlternateMediaModuleParser.class, com.rometools.modules.sle.io.ModuleParser.class,
|
com.rometools.modules.mediarss.io.AlternateMediaModuleParser.class,
|
||||||
com.rometools.modules.yahooweather.io.WeatherModuleParser.class, com.rometools.modules.feedpress.io.FeedpressParser.class,
|
com.rometools.modules.sle.io.ModuleParser.class,
|
||||||
|
com.rometools.modules.yahooweather.io.WeatherModuleParser.class,
|
||||||
|
com.rometools.modules.feedpress.io.FeedpressParser.class,
|
||||||
com.rometools.modules.fyyd.io.FyydParser.class,
|
com.rometools.modules.fyyd.io.FyydParser.class,
|
||||||
|
com.rometools.modules.cc.io.ModuleParserRSS2.class,
|
||||||
com.rometools.modules.cc.io.ModuleParserRSS2.class, com.rometools.modules.content.io.ContentModuleParser.class,
|
com.rometools.modules.content.io.ContentModuleParser.class,
|
||||||
com.rometools.modules.itunes.io.ITunesParser.class, com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
com.rometools.modules.itunes.io.ITunesParser.class,
|
||||||
com.rometools.modules.opensearch.impl.OpenSearchModuleParser.class, com.rometools.modules.georss.SimpleParser.class,
|
com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
||||||
com.rometools.modules.georss.W3CGeoParser.class, com.rometools.modules.photocast.io.Parser.class,
|
com.rometools.modules.opensearch.impl.OpenSearchModuleParser.class,
|
||||||
com.rometools.modules.mediarss.io.MediaModuleParser.class, com.rometools.modules.atom.io.AtomModuleParser.class,
|
com.rometools.modules.georss.SimpleParser.class,
|
||||||
|
com.rometools.modules.georss.W3CGeoParser.class,
|
||||||
|
com.rometools.modules.photocast.io.Parser.class,
|
||||||
|
com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
||||||
|
com.rometools.modules.atom.io.AtomModuleParser.class,
|
||||||
com.rometools.modules.itunes.io.ITunesParserOldNamespace.class,
|
com.rometools.modules.itunes.io.ITunesParserOldNamespace.class,
|
||||||
com.rometools.modules.mediarss.io.AlternateMediaModuleParser.class, com.rometools.modules.sle.io.ModuleParser.class,
|
com.rometools.modules.mediarss.io.AlternateMediaModuleParser.class,
|
||||||
com.rometools.modules.yahooweather.io.WeatherModuleParser.class, com.rometools.modules.feedpress.io.FeedpressParser.class,
|
com.rometools.modules.sle.io.ModuleParser.class,
|
||||||
|
com.rometools.modules.yahooweather.io.WeatherModuleParser.class,
|
||||||
|
com.rometools.modules.feedpress.io.FeedpressParser.class,
|
||||||
com.rometools.modules.fyyd.io.FyydParser.class,
|
com.rometools.modules.fyyd.io.FyydParser.class,
|
||||||
|
com.rometools.modules.cc.io.ModuleParserRSS1.class,
|
||||||
com.rometools.modules.cc.io.ModuleParserRSS1.class, com.rometools.modules.content.io.ContentModuleParser.class,
|
com.rometools.modules.content.io.ContentModuleParser.class,
|
||||||
|
com.rometools.modules.cc.io.ModuleParserRSS2.class,
|
||||||
com.rometools.modules.cc.io.ModuleParserRSS2.class, com.rometools.modules.opensearch.impl.OpenSearchModuleParser.class,
|
com.rometools.modules.opensearch.impl.OpenSearchModuleParser.class,
|
||||||
com.rometools.modules.georss.SimpleParser.class, com.rometools.modules.georss.W3CGeoParser.class,
|
com.rometools.modules.georss.SimpleParser.class,
|
||||||
com.rometools.modules.photocast.io.Parser.class, com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
com.rometools.modules.georss.W3CGeoParser.class,
|
||||||
|
com.rometools.modules.photocast.io.Parser.class,
|
||||||
|
com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
||||||
com.rometools.modules.mediarss.io.AlternateMediaModuleParser.class,
|
com.rometools.modules.mediarss.io.AlternateMediaModuleParser.class,
|
||||||
|
com.rometools.modules.cc.io.ModuleParserRSS2.class,
|
||||||
com.rometools.modules.cc.io.ModuleParserRSS2.class, com.rometools.modules.opensearch.impl.OpenSearchModuleParser.class,
|
com.rometools.modules.opensearch.impl.OpenSearchModuleParser.class,
|
||||||
com.rometools.modules.georss.SimpleParser.class, com.rometools.modules.georss.W3CGeoParser.class,
|
com.rometools.modules.georss.SimpleParser.class,
|
||||||
com.rometools.modules.photocast.io.Parser.class, com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
com.rometools.modules.georss.W3CGeoParser.class,
|
||||||
|
com.rometools.modules.photocast.io.Parser.class,
|
||||||
|
com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
||||||
com.rometools.modules.mediarss.io.AlternateMediaModuleParser.class,
|
com.rometools.modules.mediarss.io.AlternateMediaModuleParser.class,
|
||||||
com.rometools.modules.feedpress.io.FeedpressParser.class, com.rometools.modules.fyyd.io.FyydParser.class,
|
com.rometools.modules.feedpress.io.FeedpressParser.class,
|
||||||
|
com.rometools.modules.fyyd.io.FyydParser.class,
|
||||||
com.rometools.modules.cc.io.ModuleParserRSS2.class, com.rometools.modules.base.io.GoogleBaseParser.class,
|
com.rometools.modules.cc.io.ModuleParserRSS2.class,
|
||||||
com.rometools.modules.content.io.ContentModuleParser.class, com.rometools.modules.slash.io.SlashModuleParser.class,
|
com.rometools.modules.base.io.GoogleBaseParser.class,
|
||||||
com.rometools.modules.itunes.io.ITunesParser.class, com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
com.rometools.modules.content.io.ContentModuleParser.class,
|
||||||
com.rometools.modules.atom.io.AtomModuleParser.class, com.rometools.modules.opensearch.impl.OpenSearchModuleParser.class,
|
com.rometools.modules.slash.io.SlashModuleParser.class,
|
||||||
com.rometools.modules.georss.SimpleParser.class, com.rometools.modules.georss.W3CGeoParser.class,
|
com.rometools.modules.itunes.io.ITunesParser.class,
|
||||||
com.rometools.modules.photocast.io.Parser.class, com.rometools.modules.itunes.io.ITunesParserOldNamespace.class,
|
com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
||||||
com.rometools.modules.mediarss.io.AlternateMediaModuleParser.class, com.rometools.modules.sle.io.ItemParser.class,
|
com.rometools.modules.atom.io.AtomModuleParser.class,
|
||||||
|
com.rometools.modules.opensearch.impl.OpenSearchModuleParser.class,
|
||||||
|
com.rometools.modules.georss.SimpleParser.class,
|
||||||
|
com.rometools.modules.georss.W3CGeoParser.class,
|
||||||
|
com.rometools.modules.photocast.io.Parser.class,
|
||||||
|
com.rometools.modules.itunes.io.ITunesParserOldNamespace.class,
|
||||||
|
com.rometools.modules.mediarss.io.AlternateMediaModuleParser.class,
|
||||||
|
com.rometools.modules.sle.io.ItemParser.class,
|
||||||
com.rometools.modules.yahooweather.io.WeatherModuleParser.class,
|
com.rometools.modules.yahooweather.io.WeatherModuleParser.class,
|
||||||
com.rometools.modules.psc.io.PodloveSimpleChapterParser.class,
|
com.rometools.modules.psc.io.PodloveSimpleChapterParser.class,
|
||||||
|
com.rometools.modules.cc.io.ModuleParserRSS1.class,
|
||||||
com.rometools.modules.cc.io.ModuleParserRSS1.class, com.rometools.modules.base.io.GoogleBaseParser.class,
|
com.rometools.modules.base.io.GoogleBaseParser.class,
|
||||||
com.rometools.modules.base.io.CustomTagParser.class, com.rometools.modules.content.io.ContentModuleParser.class,
|
com.rometools.modules.base.io.CustomTagParser.class,
|
||||||
|
com.rometools.modules.content.io.ContentModuleParser.class,
|
||||||
com.rometools.modules.slash.io.SlashModuleParser.class,
|
com.rometools.modules.slash.io.SlashModuleParser.class,
|
||||||
|
com.rometools.modules.cc.io.ModuleParserRSS2.class,
|
||||||
com.rometools.modules.cc.io.ModuleParserRSS2.class, com.rometools.modules.base.io.GoogleBaseParser.class,
|
com.rometools.modules.base.io.GoogleBaseParser.class,
|
||||||
com.rometools.modules.base.io.CustomTagParser.class, com.rometools.modules.slash.io.SlashModuleParser.class,
|
com.rometools.modules.base.io.CustomTagParser.class,
|
||||||
com.rometools.modules.opensearch.impl.OpenSearchModuleParser.class, com.rometools.modules.georss.SimpleParser.class,
|
com.rometools.modules.slash.io.SlashModuleParser.class,
|
||||||
com.rometools.modules.georss.W3CGeoParser.class, com.rometools.modules.photocast.io.Parser.class,
|
com.rometools.modules.opensearch.impl.OpenSearchModuleParser.class,
|
||||||
|
com.rometools.modules.georss.SimpleParser.class,
|
||||||
|
com.rometools.modules.georss.W3CGeoParser.class,
|
||||||
|
com.rometools.modules.photocast.io.Parser.class,
|
||||||
com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
||||||
com.rometools.modules.mediarss.io.AlternateMediaModuleParser.class,
|
com.rometools.modules.mediarss.io.AlternateMediaModuleParser.class,
|
||||||
|
com.rometools.modules.cc.io.ModuleParserRSS2.class,
|
||||||
com.rometools.modules.cc.io.ModuleParserRSS2.class, com.rometools.modules.base.io.GoogleBaseParser.class,
|
com.rometools.modules.base.io.GoogleBaseParser.class,
|
||||||
com.rometools.modules.base.io.CustomTagParser.class, com.rometools.modules.slash.io.SlashModuleParser.class,
|
com.rometools.modules.base.io.CustomTagParser.class,
|
||||||
com.rometools.modules.opensearch.impl.OpenSearchModuleParser.class, com.rometools.modules.georss.SimpleParser.class,
|
com.rometools.modules.slash.io.SlashModuleParser.class,
|
||||||
com.rometools.modules.georss.W3CGeoParser.class, com.rometools.modules.photocast.io.Parser.class,
|
com.rometools.modules.opensearch.impl.OpenSearchModuleParser.class,
|
||||||
|
com.rometools.modules.georss.SimpleParser.class,
|
||||||
|
com.rometools.modules.georss.W3CGeoParser.class,
|
||||||
|
com.rometools.modules.photocast.io.Parser.class,
|
||||||
com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
||||||
com.rometools.modules.mediarss.io.AlternateMediaModuleParser.class,
|
com.rometools.modules.mediarss.io.AlternateMediaModuleParser.class,
|
||||||
com.rometools.modules.thr.io.ThreadingModuleParser.class, com.rometools.modules.psc.io.PodloveSimpleChapterParser.class,
|
com.rometools.modules.thr.io.ThreadingModuleParser.class,
|
||||||
|
com.rometools.modules.psc.io.PodloveSimpleChapterParser.class,
|
||||||
com.rometools.modules.cc.io.CCModuleGenerator.class, com.rometools.modules.content.io.ContentModuleGenerator.class,
|
com.rometools.modules.cc.io.CCModuleGenerator.class,
|
||||||
com.rometools.modules.itunes.io.ITunesGenerator.class,
|
|
||||||
com.rometools.modules.opensearch.impl.OpenSearchModuleGenerator.class, com.rometools.modules.georss.SimpleGenerator.class,
|
|
||||||
com.rometools.modules.georss.W3CGeoGenerator.class, com.rometools.modules.photocast.io.Generator.class,
|
|
||||||
com.rometools.modules.mediarss.io.MediaModuleGenerator.class, com.rometools.modules.atom.io.AtomModuleGenerator.class,
|
|
||||||
com.rometools.modules.sle.io.ModuleGenerator.class, com.rometools.modules.yahooweather.io.WeatherModuleGenerator.class,
|
|
||||||
com.rometools.modules.feedpress.io.FeedpressGenerator.class, com.rometools.modules.fyyd.io.FyydGenerator.class,
|
|
||||||
|
|
||||||
com.rometools.modules.content.io.ContentModuleGenerator.class,
|
com.rometools.modules.content.io.ContentModuleGenerator.class,
|
||||||
|
com.rometools.modules.itunes.io.ITunesGenerator.class,
|
||||||
com.rometools.modules.cc.io.CCModuleGenerator.class, com.rometools.modules.opensearch.impl.OpenSearchModuleGenerator.class,
|
com.rometools.modules.opensearch.impl.OpenSearchModuleGenerator.class,
|
||||||
com.rometools.modules.georss.SimpleGenerator.class, com.rometools.modules.georss.W3CGeoGenerator.class,
|
com.rometools.modules.georss.SimpleGenerator.class,
|
||||||
com.rometools.modules.photocast.io.Generator.class, com.rometools.modules.mediarss.io.MediaModuleGenerator.class,
|
com.rometools.modules.georss.W3CGeoGenerator.class,
|
||||||
|
com.rometools.modules.photocast.io.Generator.class,
|
||||||
com.rometools.modules.cc.io.CCModuleGenerator.class, com.rometools.modules.opensearch.impl.OpenSearchModuleGenerator.class,
|
com.rometools.modules.mediarss.io.MediaModuleGenerator.class,
|
||||||
com.rometools.modules.georss.SimpleGenerator.class, com.rometools.modules.georss.W3CGeoGenerator.class,
|
com.rometools.modules.atom.io.AtomModuleGenerator.class,
|
||||||
com.rometools.modules.photocast.io.Generator.class, com.rometools.modules.mediarss.io.MediaModuleGenerator.class,
|
com.rometools.modules.sle.io.ModuleGenerator.class,
|
||||||
com.rometools.modules.feedpress.io.FeedpressGenerator.class, com.rometools.modules.fyyd.io.FyydGenerator.class,
|
com.rometools.modules.yahooweather.io.WeatherModuleGenerator.class,
|
||||||
|
com.rometools.modules.feedpress.io.FeedpressGenerator.class,
|
||||||
com.rometools.modules.cc.io.CCModuleGenerator.class, com.rometools.modules.base.io.GoogleBaseGenerator.class,
|
com.rometools.modules.fyyd.io.FyydGenerator.class,
|
||||||
com.rometools.modules.base.io.CustomTagGenerator.class, com.rometools.modules.content.io.ContentModuleGenerator.class,
|
com.rometools.modules.content.io.ContentModuleGenerator.class,
|
||||||
com.rometools.modules.slash.io.SlashModuleGenerator.class, com.rometools.modules.itunes.io.ITunesGenerator.class,
|
com.rometools.modules.cc.io.CCModuleGenerator.class,
|
||||||
com.rometools.modules.opensearch.impl.OpenSearchModuleGenerator.class, com.rometools.modules.georss.SimpleGenerator.class,
|
com.rometools.modules.opensearch.impl.OpenSearchModuleGenerator.class,
|
||||||
com.rometools.modules.georss.W3CGeoGenerator.class, com.rometools.modules.photocast.io.Generator.class,
|
com.rometools.modules.georss.SimpleGenerator.class,
|
||||||
com.rometools.modules.mediarss.io.MediaModuleGenerator.class, com.rometools.modules.atom.io.AtomModuleGenerator.class,
|
com.rometools.modules.georss.W3CGeoGenerator.class,
|
||||||
|
com.rometools.modules.photocast.io.Generator.class,
|
||||||
|
com.rometools.modules.mediarss.io.MediaModuleGenerator.class,
|
||||||
|
com.rometools.modules.cc.io.CCModuleGenerator.class,
|
||||||
|
com.rometools.modules.opensearch.impl.OpenSearchModuleGenerator.class,
|
||||||
|
com.rometools.modules.georss.SimpleGenerator.class,
|
||||||
|
com.rometools.modules.georss.W3CGeoGenerator.class,
|
||||||
|
com.rometools.modules.photocast.io.Generator.class,
|
||||||
|
com.rometools.modules.mediarss.io.MediaModuleGenerator.class,
|
||||||
|
com.rometools.modules.feedpress.io.FeedpressGenerator.class,
|
||||||
|
com.rometools.modules.fyyd.io.FyydGenerator.class,
|
||||||
|
com.rometools.modules.cc.io.CCModuleGenerator.class,
|
||||||
|
com.rometools.modules.base.io.GoogleBaseGenerator.class,
|
||||||
|
com.rometools.modules.base.io.CustomTagGenerator.class,
|
||||||
|
com.rometools.modules.content.io.ContentModuleGenerator.class,
|
||||||
|
com.rometools.modules.slash.io.SlashModuleGenerator.class,
|
||||||
|
com.rometools.modules.itunes.io.ITunesGenerator.class,
|
||||||
|
com.rometools.modules.opensearch.impl.OpenSearchModuleGenerator.class,
|
||||||
|
com.rometools.modules.georss.SimpleGenerator.class,
|
||||||
|
com.rometools.modules.georss.W3CGeoGenerator.class,
|
||||||
|
com.rometools.modules.photocast.io.Generator.class,
|
||||||
|
com.rometools.modules.mediarss.io.MediaModuleGenerator.class,
|
||||||
|
com.rometools.modules.atom.io.AtomModuleGenerator.class,
|
||||||
com.rometools.modules.yahooweather.io.WeatherModuleGenerator.class,
|
com.rometools.modules.yahooweather.io.WeatherModuleGenerator.class,
|
||||||
com.rometools.modules.psc.io.PodloveSimpleChapterGenerator.class,
|
com.rometools.modules.psc.io.PodloveSimpleChapterGenerator.class,
|
||||||
|
com.rometools.modules.base.io.GoogleBaseGenerator.class,
|
||||||
com.rometools.modules.base.io.GoogleBaseGenerator.class, com.rometools.modules.content.io.ContentModuleGenerator.class,
|
com.rometools.modules.content.io.ContentModuleGenerator.class,
|
||||||
com.rometools.modules.slash.io.SlashModuleGenerator.class,
|
com.rometools.modules.slash.io.SlashModuleGenerator.class,
|
||||||
|
com.rometools.modules.cc.io.CCModuleGenerator.class,
|
||||||
com.rometools.modules.cc.io.CCModuleGenerator.class, com.rometools.modules.base.io.GoogleBaseGenerator.class,
|
com.rometools.modules.base.io.GoogleBaseGenerator.class,
|
||||||
com.rometools.modules.base.io.CustomTagGenerator.class, com.rometools.modules.slash.io.SlashModuleGenerator.class,
|
com.rometools.modules.base.io.CustomTagGenerator.class,
|
||||||
com.rometools.modules.opensearch.impl.OpenSearchModuleGenerator.class, com.rometools.modules.georss.SimpleGenerator.class,
|
com.rometools.modules.slash.io.SlashModuleGenerator.class,
|
||||||
com.rometools.modules.georss.W3CGeoGenerator.class, com.rometools.modules.photocast.io.Generator.class,
|
com.rometools.modules.opensearch.impl.OpenSearchModuleGenerator.class,
|
||||||
|
com.rometools.modules.georss.SimpleGenerator.class,
|
||||||
|
com.rometools.modules.georss.W3CGeoGenerator.class,
|
||||||
|
com.rometools.modules.photocast.io.Generator.class,
|
||||||
com.rometools.modules.mediarss.io.MediaModuleGenerator.class,
|
com.rometools.modules.mediarss.io.MediaModuleGenerator.class,
|
||||||
|
com.rometools.modules.cc.io.CCModuleGenerator.class,
|
||||||
com.rometools.modules.cc.io.CCModuleGenerator.class, com.rometools.modules.base.io.CustomTagGenerator.class,
|
com.rometools.modules.base.io.CustomTagGenerator.class,
|
||||||
com.rometools.modules.slash.io.SlashModuleGenerator.class,
|
com.rometools.modules.slash.io.SlashModuleGenerator.class,
|
||||||
com.rometools.modules.opensearch.impl.OpenSearchModuleGenerator.class, com.rometools.modules.georss.SimpleGenerator.class,
|
com.rometools.modules.opensearch.impl.OpenSearchModuleGenerator.class,
|
||||||
com.rometools.modules.georss.W3CGeoGenerator.class, com.rometools.modules.photocast.io.Generator.class,
|
com.rometools.modules.georss.SimpleGenerator.class,
|
||||||
com.rometools.modules.mediarss.io.MediaModuleGenerator.class, com.rometools.modules.thr.io.ThreadingModuleGenerator.class,
|
com.rometools.modules.georss.W3CGeoGenerator.class,
|
||||||
|
com.rometools.modules.photocast.io.Generator.class,
|
||||||
|
com.rometools.modules.mediarss.io.MediaModuleGenerator.class,
|
||||||
|
com.rometools.modules.thr.io.ThreadingModuleGenerator.class,
|
||||||
com.rometools.modules.psc.io.PodloveSimpleChapterGenerator.class,
|
com.rometools.modules.psc.io.PodloveSimpleChapterGenerator.class,
|
||||||
|
|
||||||
com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
||||||
|
|
||||||
com.rometools.modules.mediarss.io.MediaModuleGenerator.class,
|
com.rometools.modules.mediarss.io.MediaModuleGenerator.class,
|
||||||
|
com.rometools.opml.io.impl.OPML10Generator.class,
|
||||||
com.rometools.opml.io.impl.OPML10Generator.class, com.rometools.opml.io.impl.OPML20Generator.class,
|
com.rometools.opml.io.impl.OPML20Generator.class,
|
||||||
|
com.rometools.opml.io.impl.OPML10Parser.class,
|
||||||
com.rometools.opml.io.impl.OPML10Parser.class, com.rometools.opml.io.impl.OPML20Parser.class,
|
com.rometools.opml.io.impl.OPML20Parser.class,
|
||||||
|
com.rometools.opml.feed.synd.impl.ConverterForOPML10.class,
|
||||||
com.rometools.opml.feed.synd.impl.ConverterForOPML10.class, com.rometools.opml.feed.synd.impl.ConverterForOPML20.class, })
|
com.rometools.opml.feed.synd.impl.ConverterForOPML20.class,
|
||||||
|
})
|
||||||
public class NativeImageClasses {
|
public class NativeImageClasses {}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package com.commafeed.backend;
|
package com.commafeed.backend;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
|
|
||||||
import com.google.common.hash.HashFunction;
|
import com.google.common.hash.HashFunction;
|
||||||
import com.google.common.hash.Hashing;
|
import com.google.common.hash.Hashing;
|
||||||
|
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
@UtilityClass
|
@UtilityClass
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public class Digests {
|
public class Digests {
|
||||||
|
|||||||
@@ -1,16 +1,20 @@
|
|||||||
package com.commafeed.backend;
|
package com.commafeed.backend;
|
||||||
|
|
||||||
import java.net.InetAddress;
|
import com.commafeed.CommaFeedConfiguration;
|
||||||
import java.net.URI;
|
import com.commafeed.CommaFeedVersion;
|
||||||
import java.net.UnknownHostException;
|
import com.google.common.net.HttpHeaders;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
import inet.ipaddr.IPAddress;
|
||||||
import java.util.List;
|
import inet.ipaddr.IPAddressNetwork;
|
||||||
import java.util.SequencedMap;
|
import inet.ipaddr.IPAddressString;
|
||||||
import java.util.zip.GZIPInputStream;
|
|
||||||
|
|
||||||
import jakarta.inject.Singleton;
|
import jakarta.inject.Singleton;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
import nl.altindag.ssl.SSLFactory;
|
||||||
|
import nl.altindag.ssl.apache5.util.Apache5SslUtils;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.DnsResolver;
|
import org.apache.hc.client5.http.DnsResolver;
|
||||||
import org.apache.hc.client5.http.SystemDefaultDnsResolver;
|
import org.apache.hc.client5.http.SystemDefaultDnsResolver;
|
||||||
import org.apache.hc.client5.http.config.ConnectionConfig;
|
import org.apache.hc.client5.http.config.ConnectionConfig;
|
||||||
@@ -35,32 +39,43 @@ import org.apache.hc.core5.util.TimeValue;
|
|||||||
import org.apache.hc.core5.util.Timeout;
|
import org.apache.hc.core5.util.Timeout;
|
||||||
import org.brotli.dec.BrotliInputStream;
|
import org.brotli.dec.BrotliInputStream;
|
||||||
|
|
||||||
import com.commafeed.CommaFeedConfiguration;
|
import java.net.InetAddress;
|
||||||
import com.commafeed.CommaFeedVersion;
|
import java.net.URI;
|
||||||
import com.google.common.net.HttpHeaders;
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import lombok.RequiredArgsConstructor;
|
import java.util.LinkedHashMap;
|
||||||
import nl.altindag.ssl.SSLFactory;
|
import java.util.List;
|
||||||
import nl.altindag.ssl.apache5.util.Apache5SslUtils;
|
import java.util.SequencedMap;
|
||||||
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class HttpClientFactory {
|
public class HttpClientFactory {
|
||||||
|
|
||||||
private static final DnsResolver DNS_RESOLVER = SystemDefaultDnsResolver.INSTANCE;
|
private static final DnsResolver DNS_RESOLVER = SystemDefaultDnsResolver.INSTANCE;
|
||||||
|
private static final IPAddress CGNAT_RANGE = new IPAddressString("100.64.0.0/10").getAddress();
|
||||||
|
|
||||||
private final CommaFeedConfiguration config;
|
private final CommaFeedConfiguration config;
|
||||||
private final CommaFeedVersion version;
|
private final CommaFeedVersion version;
|
||||||
|
|
||||||
public CloseableHttpClient newClient(int poolSize) {
|
public CloseableHttpClient newClient(int poolSize) {
|
||||||
PoolingHttpClientConnectionManager connectionManager = newConnectionManager(config, poolSize);
|
PoolingHttpClientConnectionManager connectionManager =
|
||||||
String userAgent = config.httpClient()
|
newConnectionManager(config, poolSize);
|
||||||
|
String userAgent =
|
||||||
|
config.httpClient()
|
||||||
.userAgent()
|
.userAgent()
|
||||||
.orElseGet(() -> String.format("CommaFeed/%s (https://github.com/Athou/commafeed)", version.getVersion()));
|
.orElseGet(
|
||||||
|
() ->
|
||||||
|
String.format(
|
||||||
|
"CommaFeed/%s (https://github.com/Athou/commafeed)",
|
||||||
|
version.getVersion()));
|
||||||
return newClient(config, connectionManager, userAgent);
|
return newClient(config, connectionManager, userAgent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CloseableHttpClient newClient(CommaFeedConfiguration config, HttpClientConnectionManager connectionManager, String userAgent) {
|
private CloseableHttpClient newClient(
|
||||||
|
CommaFeedConfiguration config,
|
||||||
|
HttpClientConnectionManager connectionManager,
|
||||||
|
String userAgent) {
|
||||||
List<Header> headers = new ArrayList<>();
|
List<Header> headers = new ArrayList<>();
|
||||||
headers.add(new BasicHeader(HttpHeaders.ACCEPT_LANGUAGE, "en"));
|
headers.add(new BasicHeader(HttpHeaders.ACCEPT_LANGUAGE, "en"));
|
||||||
headers.add(new BasicHeader(HttpHeaders.PRAGMA, "No-cache"));
|
headers.add(new BasicHeader(HttpHeaders.PRAGMA, "No-cache"));
|
||||||
@@ -71,11 +86,13 @@ public class HttpClientFactory {
|
|||||||
contentDecoderMap.put(ContentCoding.DEFLATE.token(), DeflateInputStream::new);
|
contentDecoderMap.put(ContentCoding.DEFLATE.token(), DeflateInputStream::new);
|
||||||
contentDecoderMap.put(ContentCoding.BROTLI.token(), BrotliInputStream::new);
|
contentDecoderMap.put(ContentCoding.BROTLI.token(), BrotliInputStream::new);
|
||||||
|
|
||||||
RedirectStrategy redirectStrategy = config.httpClient().blockLocalAddresses()
|
RedirectStrategy redirectStrategy =
|
||||||
|
config.httpClient().blockLocalAddresses()
|
||||||
? new BlockLocalAddressesRedirectStrategy(DNS_RESOLVER)
|
? new BlockLocalAddressesRedirectStrategy(DNS_RESOLVER)
|
||||||
: new DefaultRedirectStrategy();
|
: new DefaultRedirectStrategy();
|
||||||
|
|
||||||
return HttpClientBuilder.create()
|
return HttpClientBuilder.create()
|
||||||
|
.disableConnectionState()
|
||||||
.useSystemProperties()
|
.useSystemProperties()
|
||||||
.disableAutomaticRetries()
|
.disableAutomaticRetries()
|
||||||
.disableCookieManagement()
|
.disableCookieManagement()
|
||||||
@@ -83,35 +100,45 @@ public class HttpClientFactory {
|
|||||||
.setDefaultHeaders(headers)
|
.setDefaultHeaders(headers)
|
||||||
.setConnectionManager(connectionManager)
|
.setConnectionManager(connectionManager)
|
||||||
.evictExpiredConnections()
|
.evictExpiredConnections()
|
||||||
.evictIdleConnections(TimeValue.of(config.httpClient().idleConnectionsEvictionInterval()))
|
.evictIdleConnections(
|
||||||
|
TimeValue.of(config.httpClient().idleConnectionsEvictionInterval()))
|
||||||
.setContentDecoderRegistry(new LinkedHashMap<>(contentDecoderMap))
|
.setContentDecoderRegistry(new LinkedHashMap<>(contentDecoderMap))
|
||||||
.setRedirectStrategy(redirectStrategy)
|
.setRedirectStrategy(redirectStrategy)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private PoolingHttpClientConnectionManager newConnectionManager(CommaFeedConfiguration config, int poolSize) {
|
private PoolingHttpClientConnectionManager newConnectionManager(
|
||||||
SSLFactory sslFactory = SSLFactory.builder().withUnsafeTrustMaterial().withUnsafeHostnameVerifier().build();
|
CommaFeedConfiguration config, int poolSize) {
|
||||||
DnsResolver dnsResolver = config.httpClient().blockLocalAddresses() ? new BlockLocalAddressesDnsResolver(DNS_RESOLVER)
|
SSLFactory sslFactory =
|
||||||
|
SSLFactory.builder().withUnsafeTrustMaterial().withUnsafeHostnameVerifier().build();
|
||||||
|
DnsResolver dnsResolver =
|
||||||
|
config.httpClient().blockLocalAddresses()
|
||||||
|
? new BlockLocalAddressesDnsResolver(DNS_RESOLVER)
|
||||||
: DNS_RESOLVER;
|
: DNS_RESOLVER;
|
||||||
|
|
||||||
return PoolingHttpClientConnectionManagerBuilder.create()
|
return PoolingHttpClientConnectionManagerBuilder.create()
|
||||||
.setTlsSocketStrategy(Apache5SslUtils.toTlsSocketStrategy(sslFactory))
|
.setTlsSocketStrategy(Apache5SslUtils.toTlsSocketStrategy(sslFactory))
|
||||||
.setDefaultConnectionConfig(ConnectionConfig.custom()
|
.setDefaultConnectionConfig(
|
||||||
|
ConnectionConfig.custom()
|
||||||
.setConnectTimeout(Timeout.of(config.httpClient().connectTimeout()))
|
.setConnectTimeout(Timeout.of(config.httpClient().connectTimeout()))
|
||||||
.setSocketTimeout(Timeout.of(config.httpClient().socketTimeout()))
|
.setSocketTimeout(Timeout.of(config.httpClient().socketTimeout()))
|
||||||
.setTimeToLive(Timeout.of(config.httpClient().connectionTimeToLive()))
|
.setTimeToLive(
|
||||||
|
Timeout.of(config.httpClient().connectionTimeToLive()))
|
||||||
|
.build())
|
||||||
|
.setDefaultTlsConfig(
|
||||||
|
TlsConfig.custom()
|
||||||
|
.setHandshakeTimeout(
|
||||||
|
Timeout.of(config.httpClient().sslHandshakeTimeout()))
|
||||||
.build())
|
.build())
|
||||||
.setDefaultTlsConfig(TlsConfig.custom().setHandshakeTimeout(Timeout.of(config.httpClient().sslHandshakeTimeout())).build())
|
|
||||||
.setMaxConnPerRoute(poolSize)
|
.setMaxConnPerRoute(poolSize)
|
||||||
.setMaxConnTotal(poolSize)
|
.setMaxConnTotal(poolSize)
|
||||||
.setDnsResolver(dnsResolver)
|
.setDnsResolver(dnsResolver)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isLocalAddress(InetAddress address) {
|
private static boolean isLocalAddress(InetAddress address) {
|
||||||
return address.isSiteLocalAddress() || address.isAnyLocalAddress() || address.isLinkLocalAddress() || address.isLoopbackAddress()
|
IPAddress ip = new IPAddressNetwork.IPAddressGenerator().from(address);
|
||||||
|| address.isMulticastAddress();
|
return ip.isLocal() || ip.isLoopback() || ip.isMulticast() || CGNAT_RANGE.contains(ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
private record BlockLocalAddressesDnsResolver(DnsResolver delegate) implements DnsResolver {
|
private record BlockLocalAddressesDnsResolver(DnsResolver delegate) implements DnsResolver {
|
||||||
@@ -120,7 +147,8 @@ public class HttpClientFactory {
|
|||||||
InetAddress[] addresses = delegate.resolve(host);
|
InetAddress[] addresses = delegate.resolve(host);
|
||||||
for (InetAddress addr : addresses) {
|
for (InetAddress addr : addresses) {
|
||||||
if (isLocalAddress(addr)) {
|
if (isLocalAddress(addr)) {
|
||||||
throw new UnknownHostException("Access to local address blocked: " + addr.getHostAddress());
|
throw new UnknownHostException(
|
||||||
|
"Access to local address blocked: " + addr.getHostAddress());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return addresses;
|
return addresses;
|
||||||
@@ -138,7 +166,8 @@ public class HttpClientFactory {
|
|||||||
private final DnsResolver delegate;
|
private final DnsResolver delegate;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public URI getLocationURI(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException {
|
public URI getLocationURI(HttpRequest request, HttpResponse response, HttpContext context)
|
||||||
|
throws HttpException {
|
||||||
URI redirectUri = super.getLocationURI(request, response, context);
|
URI redirectUri = super.getLocationURI(request, response, context);
|
||||||
|
|
||||||
String host = redirectUri.getHost();
|
String host = redirectUri.getHost();
|
||||||
@@ -155,12 +184,12 @@ public class HttpClientFactory {
|
|||||||
|
|
||||||
for (InetAddress addr : addresses) {
|
for (InetAddress addr : addresses) {
|
||||||
if (isLocalAddress(addr)) {
|
if (isLocalAddress(addr)) {
|
||||||
throw new HttpException("Access to local address blocked: " + addr.getHostAddress());
|
throw new HttpException(
|
||||||
|
"Access to local address blocked: " + addr.getHostAddress());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirectUri;
|
return redirectUri;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,24 @@
|
|||||||
package com.commafeed.backend;
|
package com.commafeed.backend;
|
||||||
|
|
||||||
import java.io.IOException;
|
import com.codahale.metrics.MetricRegistry;
|
||||||
import java.io.InputStream;
|
import com.commafeed.CommaFeedConfiguration;
|
||||||
import java.net.URI;
|
import com.commafeed.CommaFeedConfiguration.HttpClientCache;
|
||||||
import java.time.Duration;
|
import com.google.common.cache.Cache;
|
||||||
import java.time.Instant;
|
import com.google.common.cache.CacheBuilder;
|
||||||
import java.time.InstantSource;
|
import com.google.common.collect.Iterables;
|
||||||
import java.util.Optional;
|
import com.google.common.io.ByteStreams;
|
||||||
import java.util.concurrent.ExecutionException;
|
import com.google.common.net.HttpHeaders;
|
||||||
|
|
||||||
import jakarta.inject.Singleton;
|
import jakarta.inject.Singleton;
|
||||||
import jakarta.ws.rs.core.CacheControl;
|
import jakarta.ws.rs.core.CacheControl;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Lombok;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.hc.client5.http.config.RequestConfig;
|
import org.apache.hc.client5.http.config.RequestConfig;
|
||||||
@@ -27,25 +34,16 @@ import org.apache.hc.core5.http.io.support.ClassicRequestBuilder;
|
|||||||
import org.apache.hc.core5.util.Timeout;
|
import org.apache.hc.core5.util.Timeout;
|
||||||
import org.jboss.resteasy.reactive.common.headers.CacheControlDelegate;
|
import org.jboss.resteasy.reactive.common.headers.CacheControlDelegate;
|
||||||
|
|
||||||
import com.codahale.metrics.MetricRegistry;
|
import java.io.IOException;
|
||||||
import com.commafeed.CommaFeedConfiguration;
|
import java.io.InputStream;
|
||||||
import com.commafeed.CommaFeedConfiguration.HttpClientCache;
|
import java.net.URI;
|
||||||
import com.google.common.cache.Cache;
|
import java.time.Duration;
|
||||||
import com.google.common.cache.CacheBuilder;
|
import java.time.Instant;
|
||||||
import com.google.common.collect.Iterables;
|
import java.time.InstantSource;
|
||||||
import com.google.common.io.ByteStreams;
|
import java.util.Optional;
|
||||||
import com.google.common.net.HttpHeaders;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
import lombok.Builder;
|
/** Smart HTTP getter: handles gzip, ssl, last modified and etag headers */
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Lombok;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Smart HTTP getter: handles gzip, ssl, last modified and etag headers
|
|
||||||
*/
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class HttpGetter {
|
public class HttpGetter {
|
||||||
@@ -54,24 +52,42 @@ public class HttpGetter {
|
|||||||
private final CloseableHttpClient client;
|
private final CloseableHttpClient client;
|
||||||
private final Cache<HttpRequest, HttpResponse> cache;
|
private final Cache<HttpRequest, HttpResponse> cache;
|
||||||
|
|
||||||
public HttpGetter(CommaFeedConfiguration config, InstantSource instantSource, HttpClientFactory httpClientFactory,
|
public HttpGetter(
|
||||||
|
CommaFeedConfiguration config,
|
||||||
|
InstantSource instantSource,
|
||||||
|
HttpClientFactory httpClientFactory,
|
||||||
MetricRegistry metrics) {
|
MetricRegistry metrics) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.instantSource = instantSource;
|
this.instantSource = instantSource;
|
||||||
this.client = httpClientFactory.newClient(config.feedRefresh().httpThreads());
|
this.client = httpClientFactory.newClient(config.feedRefresh().httpThreads());
|
||||||
this.cache = newCache(config);
|
this.cache = newCache(config);
|
||||||
|
|
||||||
metrics.registerGauge(MetricRegistry.name(getClass(), "cache", "size"), () -> cache == null ? 0 : cache.size());
|
metrics.registerGauge(
|
||||||
metrics.registerGauge(MetricRegistry.name(getClass(), "cache", "memoryUsage"),
|
MetricRegistry.name(getClass(), "cache", "size"),
|
||||||
() -> cache == null ? 0 : cache.asMap().values().stream().mapToInt(e -> ArrayUtils.getLength(e.content)).sum());
|
() -> cache == null ? 0 : cache.size());
|
||||||
|
metrics.registerGauge(
|
||||||
|
MetricRegistry.name(getClass(), "cache", "memoryUsage"),
|
||||||
|
() ->
|
||||||
|
cache == null
|
||||||
|
? 0
|
||||||
|
: cache.asMap().values().stream()
|
||||||
|
.mapToInt(e -> ArrayUtils.getLength(e.content))
|
||||||
|
.sum());
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpResult get(String url) throws IOException, NotModifiedException, TooManyRequestsException, SchemeNotAllowedException {
|
public HttpResult get(String url)
|
||||||
|
throws IOException,
|
||||||
|
NotModifiedException,
|
||||||
|
TooManyRequestsException,
|
||||||
|
SchemeNotAllowedException {
|
||||||
return get(HttpRequest.builder(url).build());
|
return get(HttpRequest.builder(url).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpResult get(HttpRequest request)
|
public HttpResult get(HttpRequest request)
|
||||||
throws IOException, NotModifiedException, TooManyRequestsException, SchemeNotAllowedException {
|
throws IOException,
|
||||||
|
NotModifiedException,
|
||||||
|
TooManyRequestsException,
|
||||||
|
SchemeNotAllowedException {
|
||||||
URI uri = URI.create(request.getUrl());
|
URI uri = URI.create(request.getUrl());
|
||||||
ensureHttpScheme(uri.getScheme());
|
ensureHttpScheme(uri.getScheme());
|
||||||
|
|
||||||
@@ -91,7 +107,8 @@ public class HttpGetter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int code = response.code();
|
int code = response.code();
|
||||||
if (code == HttpStatus.SC_TOO_MANY_REQUESTS || code == HttpStatus.SC_SERVICE_UNAVAILABLE && response.retryAfter() != null) {
|
if (code == HttpStatus.SC_TOO_MANY_REQUESTS
|
||||||
|
|| code == HttpStatus.SC_SERVICE_UNAVAILABLE && response.retryAfter() != null) {
|
||||||
throw new TooManyRequestsException(response.retryAfter());
|
throw new TooManyRequestsException(response.retryAfter());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,12 +123,18 @@ public class HttpGetter {
|
|||||||
String lastModifiedHeader = response.lastModifiedHeader();
|
String lastModifiedHeader = response.lastModifiedHeader();
|
||||||
String eTagHeader = response.eTagHeader();
|
String eTagHeader = response.eTagHeader();
|
||||||
|
|
||||||
Duration validFor = Optional.ofNullable(response.cacheControl())
|
Duration validFor =
|
||||||
|
Optional.ofNullable(response.cacheControl())
|
||||||
.filter(cc -> cc.getMaxAge() >= 0)
|
.filter(cc -> cc.getMaxAge() >= 0)
|
||||||
.map(cc -> Duration.ofSeconds(cc.getMaxAge()))
|
.map(cc -> Duration.ofSeconds(cc.getMaxAge()))
|
||||||
.orElse(Duration.ZERO);
|
.orElse(Duration.ZERO);
|
||||||
|
|
||||||
return new HttpResult(response.content(), response.contentType(), lastModifiedHeader, eTagHeader, response.urlAfterRedirect(),
|
return new HttpResult(
|
||||||
|
response.content(),
|
||||||
|
response.contentType(),
|
||||||
|
lastModifiedHeader,
|
||||||
|
eTagHeader,
|
||||||
|
response.urlAfterRedirect(),
|
||||||
validFor);
|
validFor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +148,8 @@ public class HttpGetter {
|
|||||||
log.debug("fetching {}", request.getUrl());
|
log.debug("fetching {}", request.getUrl());
|
||||||
|
|
||||||
HttpClientContext context = HttpClientContext.create();
|
HttpClientContext context = HttpClientContext.create();
|
||||||
context.setRequestConfig(RequestConfig.custom()
|
context.setRequestConfig(
|
||||||
|
RequestConfig.custom()
|
||||||
.setResponseTimeout(Timeout.of(config.httpClient().responseTimeout()))
|
.setResponseTimeout(Timeout.of(config.httpClient().responseTimeout()))
|
||||||
// causes issues with some feeds
|
// causes issues with some feeds
|
||||||
// see https://github.com/Athou/commafeed/issues/1572
|
// see https://github.com/Athou/commafeed/issues/1572
|
||||||
@@ -133,39 +157,62 @@ public class HttpGetter {
|
|||||||
.setProtocolUpgradeEnabled(false)
|
.setProtocolUpgradeEnabled(false)
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
return client.execute(request.toClassicHttpRequest(), context, resp -> {
|
return client.execute(
|
||||||
byte[] content = resp.getEntity() == null ? null
|
request.toClassicHttpRequest(),
|
||||||
: toByteArray(resp.getEntity(), config.httpClient().maxResponseSize().asLongValue());
|
context,
|
||||||
|
resp -> {
|
||||||
|
byte[] content =
|
||||||
|
resp.getEntity() == null
|
||||||
|
? null
|
||||||
|
: toByteArray(
|
||||||
|
resp.getEntity(),
|
||||||
|
config.httpClient().maxResponseSize().asLongValue());
|
||||||
int code = resp.getCode();
|
int code = resp.getCode();
|
||||||
String lastModifiedHeader = Optional.ofNullable(resp.getFirstHeader(HttpHeaders.LAST_MODIFIED))
|
String lastModifiedHeader =
|
||||||
|
Optional.ofNullable(resp.getFirstHeader(HttpHeaders.LAST_MODIFIED))
|
||||||
.map(NameValuePair::getValue)
|
.map(NameValuePair::getValue)
|
||||||
.map(StringUtils::trimToNull)
|
.map(StringUtils::trimToNull)
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
String eTagHeader = Optional.ofNullable(resp.getFirstHeader(HttpHeaders.ETAG))
|
String eTagHeader =
|
||||||
|
Optional.ofNullable(resp.getFirstHeader(HttpHeaders.ETAG))
|
||||||
.map(NameValuePair::getValue)
|
.map(NameValuePair::getValue)
|
||||||
.map(StringUtils::trimToNull)
|
.map(StringUtils::trimToNull)
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
|
|
||||||
CacheControl cacheControl = Optional.ofNullable(resp.getFirstHeader(HttpHeaders.CACHE_CONTROL))
|
CacheControl cacheControl =
|
||||||
|
Optional.ofNullable(resp.getFirstHeader(HttpHeaders.CACHE_CONTROL))
|
||||||
.map(NameValuePair::getValue)
|
.map(NameValuePair::getValue)
|
||||||
.map(StringUtils::trimToNull)
|
.map(StringUtils::trimToNull)
|
||||||
.map(HttpGetter::toCacheControl)
|
.map(HttpGetter::toCacheControl)
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
|
|
||||||
Instant retryAfter = Optional.ofNullable(resp.getFirstHeader(HttpHeaders.RETRY_AFTER))
|
Instant retryAfter =
|
||||||
|
Optional.ofNullable(resp.getFirstHeader(HttpHeaders.RETRY_AFTER))
|
||||||
.map(NameValuePair::getValue)
|
.map(NameValuePair::getValue)
|
||||||
.map(StringUtils::trimToNull)
|
.map(StringUtils::trimToNull)
|
||||||
.map(this::toInstant)
|
.map(this::toInstant)
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
|
|
||||||
String contentType = Optional.ofNullable(resp.getEntity()).map(HttpEntity::getContentType).orElse(null);
|
String contentType =
|
||||||
String urlAfterRedirect = Optional.ofNullable(context.getRedirectLocations())
|
Optional.ofNullable(resp.getEntity())
|
||||||
|
.map(HttpEntity::getContentType)
|
||||||
|
.orElse(null);
|
||||||
|
String urlAfterRedirect =
|
||||||
|
Optional.ofNullable(context.getRedirectLocations())
|
||||||
.map(RedirectLocations::getAll)
|
.map(RedirectLocations::getAll)
|
||||||
.map(l -> Iterables.getLast(l, null))
|
.map(l -> Iterables.getLast(l, null))
|
||||||
.map(URI::toString)
|
.map(URI::toString)
|
||||||
.orElse(request.getUrl());
|
.orElse(request.getUrl());
|
||||||
|
|
||||||
return new HttpResponse(code, lastModifiedHeader, eTagHeader, cacheControl, retryAfter, content, contentType, urlAfterRedirect);
|
return new HttpResponse(
|
||||||
|
code,
|
||||||
|
lastModifiedHeader,
|
||||||
|
eTagHeader,
|
||||||
|
cacheControl,
|
||||||
|
retryAfter,
|
||||||
|
content,
|
||||||
|
contentType,
|
||||||
|
urlAfterRedirect);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,7 +240,8 @@ public class HttpGetter {
|
|||||||
private static byte[] toByteArray(HttpEntity entity, long maxBytes) throws IOException {
|
private static byte[] toByteArray(HttpEntity entity, long maxBytes) throws IOException {
|
||||||
if (entity.getContentLength() > maxBytes) {
|
if (entity.getContentLength() > maxBytes) {
|
||||||
throw new IOException(
|
throw new IOException(
|
||||||
"Response size (%s bytes) exceeds the maximum allowed size (%s bytes)".formatted(entity.getContentLength(), maxBytes));
|
"Response size (%s bytes) exceeds the maximum allowed size (%s bytes)"
|
||||||
|
.formatted(entity.getContentLength(), maxBytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
try (InputStream input = entity.getContent()) {
|
try (InputStream input = entity.getContent()) {
|
||||||
@@ -203,7 +251,9 @@ public class HttpGetter {
|
|||||||
|
|
||||||
byte[] bytes = ByteStreams.limit(input, maxBytes + 1).readAllBytes();
|
byte[] bytes = ByteStreams.limit(input, maxBytes + 1).readAllBytes();
|
||||||
if (bytes.length > maxBytes) {
|
if (bytes.length > maxBytes) {
|
||||||
throw new IOException("Response size exceeds the maximum allowed size (%s bytes)".formatted(maxBytes));
|
throw new IOException(
|
||||||
|
"Response size exceeds the maximum allowed size (%s bytes)"
|
||||||
|
.formatted(maxBytes));
|
||||||
}
|
}
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
@@ -216,7 +266,9 @@ public class HttpGetter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return CacheBuilder.newBuilder()
|
return CacheBuilder.newBuilder()
|
||||||
.weigher((HttpRequest key, HttpResponse value) -> value.content() != null ? value.content().length : 0)
|
.weigher(
|
||||||
|
(HttpRequest key, HttpResponse value) ->
|
||||||
|
value.content() != null ? value.content().length : 0)
|
||||||
.maximumWeight(cacheConfig.maximumMemorySize().asLongValue())
|
.maximumWeight(cacheConfig.maximumMemorySize().asLongValue())
|
||||||
.expireAfterWrite(cacheConfig.expiration())
|
.expireAfterWrite(cacheConfig.expiration())
|
||||||
.build();
|
.build();
|
||||||
@@ -234,21 +286,18 @@ public class HttpGetter {
|
|||||||
public static class NotModifiedException extends Exception {
|
public static class NotModifiedException extends Exception {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/** if the value of this header changed, this is its new value */
|
||||||
* if the value of this header changed, this is its new value
|
|
||||||
*/
|
|
||||||
private final String newLastModifiedHeader;
|
private final String newLastModifiedHeader;
|
||||||
|
|
||||||
/**
|
/** if the value of this header changed, this is its new value */
|
||||||
* if the value of this header changed, this is its new value
|
|
||||||
*/
|
|
||||||
private final String newEtagHeader;
|
private final String newEtagHeader;
|
||||||
|
|
||||||
public NotModifiedException(String message) {
|
public NotModifiedException(String message) {
|
||||||
this(message, null, null);
|
this(message, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NotModifiedException(String message, String newLastModifiedHeader, String newEtagHeader) {
|
public NotModifiedException(
|
||||||
|
String message, String newLastModifiedHeader, String newEtagHeader) {
|
||||||
super(message);
|
super(message);
|
||||||
this.newLastModifiedHeader = newLastModifiedHeader;
|
this.newLastModifiedHeader = newLastModifiedHeader;
|
||||||
this.newEtagHeader = newEtagHeader;
|
this.newEtagHeader = newEtagHeader;
|
||||||
@@ -299,12 +348,21 @@ public class HttpGetter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private record HttpResponse(int code, String lastModifiedHeader, String eTagHeader, CacheControl cacheControl, Instant retryAfter,
|
private record HttpResponse(
|
||||||
byte[] content, String contentType, String urlAfterRedirect) {
|
int code,
|
||||||
}
|
String lastModifiedHeader,
|
||||||
|
String eTagHeader,
|
||||||
public record HttpResult(byte[] content, String contentType, String lastModifiedSince, String eTag, String urlAfterRedirect,
|
CacheControl cacheControl,
|
||||||
Duration validFor) {
|
Instant retryAfter,
|
||||||
}
|
byte[] content,
|
||||||
|
String contentType,
|
||||||
|
String urlAfterRedirect) {}
|
||||||
|
|
||||||
|
public record HttpResult(
|
||||||
|
byte[] content,
|
||||||
|
String contentType,
|
||||||
|
String lastModifiedSince,
|
||||||
|
String eTag,
|
||||||
|
String urlAfterRedirect,
|
||||||
|
Duration validFor) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,41 +1,59 @@
|
|||||||
package com.commafeed.backend;
|
package com.commafeed.backend;
|
||||||
|
|
||||||
import java.net.URI;
|
import lombok.experimental.UtilityClass;
|
||||||
import java.util.regex.Pattern;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import org.apache.commons.lang3.Strings;
|
import org.apache.commons.lang3.Strings;
|
||||||
import org.netpreserve.urlcanon.Canonicalizer;
|
import org.netpreserve.urlcanon.Canonicalizer;
|
||||||
import org.netpreserve.urlcanon.ParsedUrl;
|
import org.netpreserve.urlcanon.ParsedUrl;
|
||||||
|
|
||||||
import lombok.experimental.UtilityClass;
|
import java.net.URI;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import java.util.Locale;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@UtilityClass
|
@UtilityClass
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class Urls {
|
public class Urls {
|
||||||
|
|
||||||
private static final String ESCAPED_QUESTION_MARK = Pattern.quote("?");
|
private static final Pattern QUESTION_MARK = Pattern.compile(Pattern.quote("?"));
|
||||||
|
|
||||||
public static boolean isHttp(String url) {
|
public static boolean isHttp(String url) {
|
||||||
return url.startsWith("http://");
|
if (url == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return url.toLowerCase(Locale.ROOT).startsWith("http://");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isHttps(String url) {
|
public static boolean isHttps(String url) {
|
||||||
return url.startsWith("https://");
|
if (url == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return url.toLowerCase(Locale.ROOT).startsWith("https://");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isAbsolute(String url) {
|
public static boolean isAbsolute(String url) {
|
||||||
return isHttp(url) || isHttps(url);
|
return isHttp(url) || isHttps(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** remove malicious 'javascript: 'URLs * */
|
||||||
|
public static String sanitize(String url) {
|
||||||
|
if (url == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isHttp(url) && !isHttps(url)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @param relativeUrl the url of the entry
|
||||||
* @param relativeUrl
|
* @param feedLink the url of the feed as described in the feed
|
||||||
* the url of the entry
|
* @param feedUrl the url of the feed that we used to fetch the feed
|
||||||
* @param feedLink
|
|
||||||
* the url of the feed as described in the feed
|
|
||||||
* @param feedUrl
|
|
||||||
* the url of the feed that we used to fetch the feed
|
|
||||||
* @return an absolute url pointing to the entry
|
* @return an absolute url pointing to the entry
|
||||||
*/
|
*/
|
||||||
public static String toAbsolute(String relativeUrl, String feedLink, String feedUrl) {
|
public static String toAbsolute(String relativeUrl, String feedLink, String feedUrl) {
|
||||||
@@ -47,7 +65,11 @@ public class Urls {
|
|||||||
try {
|
try {
|
||||||
return URI.create(baseUrl).resolve(relativeUrl).toString();
|
return URI.create(baseUrl).resolve(relativeUrl).toString();
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
log.debug("Unable to create absolute url from relative url: {} base: {}", relativeUrl, baseUrl, e);
|
log.debug(
|
||||||
|
"Unable to create absolute url from relative url: {} base: {}",
|
||||||
|
relativeUrl,
|
||||||
|
baseUrl,
|
||||||
|
e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,7 +86,8 @@ public class Urls {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Normalize the url. The resulting url is not meant to be fetched but rather used as a mean to identify a feed and avoid duplicates
|
* Normalize the url. The resulting url is not meant to be fetched but rather used as a mean to
|
||||||
|
* identify a feed and avoid duplicates
|
||||||
*/
|
*/
|
||||||
public static String normalize(String url) {
|
public static String normalize(String url) {
|
||||||
if (url == null) {
|
if (url == null) {
|
||||||
@@ -95,9 +118,9 @@ public class Urls {
|
|||||||
normalized = normalized.replace("feedproxy.google.com", "feeds.feedburner.com");
|
normalized = normalized.replace("feedproxy.google.com", "feeds.feedburner.com");
|
||||||
|
|
||||||
// feedburner feeds have a special treatment
|
// feedburner feeds have a special treatment
|
||||||
if (normalized.split(ESCAPED_QUESTION_MARK)[0].contains("feedburner.com")) {
|
if (QUESTION_MARK.split(normalized)[0].contains("feedburner.com")) {
|
||||||
normalized = normalized.replace("feeds2.feedburner.com", "feeds.feedburner.com");
|
normalized = normalized.replace("feeds2.feedburner.com", "feeds.feedburner.com");
|
||||||
normalized = normalized.split(ESCAPED_QUESTION_MARK)[0];
|
normalized = QUESTION_MARK.split(normalized)[0];
|
||||||
normalized = Strings.CS.removeEnd(normalized, "/");
|
normalized = Strings.CS.removeEnd(normalized, "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
package com.commafeed.backend.dao;
|
package com.commafeed.backend.dao;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import jakarta.inject.Singleton;
|
|
||||||
import jakarta.persistence.EntityManager;
|
|
||||||
|
|
||||||
import com.commafeed.backend.model.FeedCategory;
|
import com.commafeed.backend.model.FeedCategory;
|
||||||
import com.commafeed.backend.model.QFeedCategory;
|
import com.commafeed.backend.model.QFeedCategory;
|
||||||
import com.commafeed.backend.model.QUser;
|
import com.commafeed.backend.model.QUser;
|
||||||
import com.commafeed.backend.model.User;
|
import com.commafeed.backend.model.User;
|
||||||
import com.querydsl.core.types.Predicate;
|
import com.querydsl.core.types.Predicate;
|
||||||
|
|
||||||
|
import jakarta.inject.Singleton;
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class FeedCategoryDAO extends GenericDAO<FeedCategory> {
|
public class FeedCategoryDAO extends GenericDAO<FeedCategory> {
|
||||||
|
|
||||||
@@ -22,11 +22,17 @@ public class FeedCategoryDAO extends GenericDAO<FeedCategory> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<FeedCategory> findAll(User user) {
|
public List<FeedCategory> findAll(User user) {
|
||||||
return query().selectFrom(CATEGORY).where(CATEGORY.user.eq(user)).join(CATEGORY.user, QUser.user).fetchJoin().fetch();
|
return query().selectFrom(CATEGORY)
|
||||||
|
.where(CATEGORY.user.eq(user))
|
||||||
|
.join(CATEGORY.user, QUser.user)
|
||||||
|
.fetchJoin()
|
||||||
|
.fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
public FeedCategory findById(User user, Long id) {
|
public FeedCategory findById(User user, Long id) {
|
||||||
return query().selectFrom(CATEGORY).where(CATEGORY.user.eq(user), CATEGORY.id.eq(id)).fetchOne();
|
return query().selectFrom(CATEGORY)
|
||||||
|
.where(CATEGORY.user.eq(user), CATEGORY.id.eq(id))
|
||||||
|
.fetchOne();
|
||||||
}
|
}
|
||||||
|
|
||||||
public FeedCategory findByName(User user, String name, FeedCategory parent) {
|
public FeedCategory findByName(User user, String name, FeedCategory parent) {
|
||||||
@@ -36,7 +42,9 @@ public class FeedCategoryDAO extends GenericDAO<FeedCategory> {
|
|||||||
} else {
|
} else {
|
||||||
parentPredicate = CATEGORY.parent.eq(parent);
|
parentPredicate = CATEGORY.parent.eq(parent);
|
||||||
}
|
}
|
||||||
return query().selectFrom(CATEGORY).where(CATEGORY.user.eq(user), CATEGORY.name.eq(name), parentPredicate).fetchOne();
|
return query().selectFrom(CATEGORY)
|
||||||
|
.where(CATEGORY.user.eq(user), CATEGORY.name.eq(name), parentPredicate)
|
||||||
|
.fetchOne();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<FeedCategory> findByParent(User user, FeedCategory parent) {
|
public List<FeedCategory> findByParent(User user, FeedCategory parent) {
|
||||||
@@ -67,5 +75,4 @@ public class FeedCategoryDAO extends GenericDAO<FeedCategory> {
|
|||||||
}
|
}
|
||||||
return isChild;
|
return isChild;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
package com.commafeed.backend.dao;
|
package com.commafeed.backend.dao;
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import jakarta.inject.Singleton;
|
|
||||||
import jakarta.persistence.EntityManager;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.Strings;
|
|
||||||
|
|
||||||
import com.commafeed.backend.model.Feed;
|
import com.commafeed.backend.model.Feed;
|
||||||
import com.commafeed.backend.model.QFeed;
|
import com.commafeed.backend.model.QFeed;
|
||||||
import com.commafeed.backend.model.QFeedSubscription;
|
import com.commafeed.backend.model.QFeedSubscription;
|
||||||
import com.querydsl.jpa.JPAExpressions;
|
import com.querydsl.jpa.JPAExpressions;
|
||||||
import com.querydsl.jpa.impl.JPAQuery;
|
import com.querydsl.jpa.impl.JPAQuery;
|
||||||
|
|
||||||
|
import jakarta.inject.Singleton;
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.Strings;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class FeedDAO extends GenericDAO<Feed> {
|
public class FeedDAO extends GenericDAO<Feed> {
|
||||||
|
|
||||||
@@ -29,12 +29,16 @@ public class FeedDAO extends GenericDAO<Feed> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<Feed> findNextUpdatable(int count, Instant lastLoginThreshold) {
|
public List<Feed> findNextUpdatable(int count, Instant lastLoginThreshold) {
|
||||||
JPAQuery<Feed> query = query().selectFrom(FEED)
|
JPAQuery<Feed> query =
|
||||||
|
query().selectFrom(FEED)
|
||||||
.distinct()
|
.distinct()
|
||||||
// join on subscriptions to only refresh feeds that have subscribers
|
// join on subscriptions to only refresh feeds that have subscribers
|
||||||
.join(SUBSCRIPTION)
|
.join(SUBSCRIPTION)
|
||||||
.on(SUBSCRIPTION.feed.eq(FEED))
|
.on(SUBSCRIPTION.feed.eq(FEED))
|
||||||
.where(FEED.disabledUntil.isNull().or(FEED.disabledUntil.lt(Instant.now())));
|
.where(
|
||||||
|
FEED.disabledUntil
|
||||||
|
.isNull()
|
||||||
|
.or(FEED.disabledUntil.lt(Instant.now())));
|
||||||
|
|
||||||
if (lastLoginThreshold != null) {
|
if (lastLoginThreshold != null) {
|
||||||
query.join(SUBSCRIPTION.user).where(SUBSCRIPTION.user.lastLogin.gt(lastLoginThreshold));
|
query.join(SUBSCRIPTION.user).where(SUBSCRIPTION.user.lastLogin.gt(lastLoginThreshold));
|
||||||
@@ -48,7 +52,8 @@ public class FeedDAO extends GenericDAO<Feed> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Feed findByUrl(String normalizedUrl, String normalizedUrlHash) {
|
public Feed findByUrl(String normalizedUrl, String normalizedUrlHash) {
|
||||||
return query().selectFrom(FEED)
|
return query()
|
||||||
|
.selectFrom(FEED)
|
||||||
.where(FEED.normalizedUrlHash.eq(normalizedUrlHash))
|
.where(FEED.normalizedUrlHash.eq(normalizedUrlHash))
|
||||||
.fetch()
|
.fetch()
|
||||||
.stream()
|
.stream()
|
||||||
@@ -59,6 +64,9 @@ public class FeedDAO extends GenericDAO<Feed> {
|
|||||||
|
|
||||||
public List<Feed> findWithoutSubscriptions(int max) {
|
public List<Feed> findWithoutSubscriptions(int max) {
|
||||||
QFeedSubscription sub = QFeedSubscription.feedSubscription;
|
QFeedSubscription sub = QFeedSubscription.feedSubscription;
|
||||||
return query().selectFrom(FEED).where(JPAExpressions.selectOne().from(sub).where(sub.feed.eq(FEED)).notExists()).limit(max).fetch();
|
return query().selectFrom(FEED)
|
||||||
|
.where(JPAExpressions.selectOne().from(sub).where(sub.feed.eq(FEED)).notExists())
|
||||||
|
.limit(max)
|
||||||
|
.fetch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
package com.commafeed.backend.dao;
|
package com.commafeed.backend.dao;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import jakarta.inject.Singleton;
|
|
||||||
import jakarta.persistence.EntityManager;
|
|
||||||
|
|
||||||
import com.commafeed.backend.model.FeedEntryContent;
|
import com.commafeed.backend.model.FeedEntryContent;
|
||||||
import com.commafeed.backend.model.QFeedEntry;
|
import com.commafeed.backend.model.QFeedEntry;
|
||||||
import com.commafeed.backend.model.QFeedEntryContent;
|
import com.commafeed.backend.model.QFeedEntryContent;
|
||||||
|
|
||||||
|
import jakarta.inject.Singleton;
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class FeedEntryContentDAO extends GenericDAO<FeedEntryContent> {
|
public class FeedEntryContentDAO extends GenericDAO<FeedEntryContent> {
|
||||||
|
|
||||||
@@ -20,11 +20,15 @@ public class FeedEntryContentDAO extends GenericDAO<FeedEntryContent> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<FeedEntryContent> findExisting(String contentHash, String titleHash) {
|
public List<FeedEntryContent> findExisting(String contentHash, String titleHash) {
|
||||||
return query().select(CONTENT).from(CONTENT).where(CONTENT.contentHash.eq(contentHash), CONTENT.titleHash.eq(titleHash)).fetch();
|
return query().select(CONTENT)
|
||||||
|
.from(CONTENT)
|
||||||
|
.where(CONTENT.contentHash.eq(contentHash), CONTENT.titleHash.eq(titleHash))
|
||||||
|
.fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long deleteWithoutEntries(int max) {
|
public long deleteWithoutEntries(int max) {
|
||||||
List<Long> ids = query().select(CONTENT.id)
|
List<Long> ids =
|
||||||
|
query().select(CONTENT.id)
|
||||||
.from(CONTENT)
|
.from(CONTENT)
|
||||||
.leftJoin(ENTRY)
|
.leftJoin(ENTRY)
|
||||||
.on(ENTRY.content.id.eq(CONTENT.id))
|
.on(ENTRY.content.id.eq(CONTENT.id))
|
||||||
|
|||||||
@@ -1,14 +1,5 @@
|
|||||||
package com.commafeed.backend.dao;
|
package com.commafeed.backend.dao;
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import jakarta.inject.Singleton;
|
|
||||||
import jakarta.persistence.EntityManager;
|
|
||||||
|
|
||||||
import com.commafeed.backend.model.Feed;
|
import com.commafeed.backend.model.Feed;
|
||||||
import com.commafeed.backend.model.FeedEntry;
|
import com.commafeed.backend.model.FeedEntry;
|
||||||
import com.commafeed.backend.model.QFeedEntry;
|
import com.commafeed.backend.model.QFeedEntry;
|
||||||
@@ -17,6 +8,15 @@ import com.querydsl.core.Tuple;
|
|||||||
import com.querydsl.core.types.dsl.NumberExpression;
|
import com.querydsl.core.types.dsl.NumberExpression;
|
||||||
import com.querydsl.jpa.impl.JPAQuery;
|
import com.querydsl.jpa.impl.JPAQuery;
|
||||||
|
|
||||||
|
import jakarta.inject.Singleton;
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class FeedEntryDAO extends GenericDAO<FeedEntry> {
|
public class FeedEntryDAO extends GenericDAO<FeedEntry> {
|
||||||
|
|
||||||
@@ -28,7 +28,11 @@ public class FeedEntryDAO extends GenericDAO<FeedEntry> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public FeedEntry findExisting(String guidHash, Feed feed) {
|
public FeedEntry findExisting(String guidHash, Feed feed) {
|
||||||
return query().select(ENTRY).from(ENTRY).where(ENTRY.guidHash.eq(guidHash), ENTRY.feed.eq(feed)).limit(1).fetchOne();
|
return query().select(ENTRY)
|
||||||
|
.from(ENTRY)
|
||||||
|
.where(ENTRY.guidHash.eq(guidHash), ENTRY.feed.eq(feed))
|
||||||
|
.limit(1)
|
||||||
|
.fetchOne();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> findExistingGuidHashes(Set<String> guidHashes, Feed feed) {
|
public Set<String> findExistingGuidHashes(Set<String> guidHashes, Feed feed) {
|
||||||
@@ -37,13 +41,19 @@ public class FeedEntryDAO extends GenericDAO<FeedEntry> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Set<String> result = new HashSet<>();
|
Set<String> result = new HashSet<>();
|
||||||
for (List<String> batch : Lists.partition(new ArrayList<>(guidHashes), IN_CLAUSE_BATCH_SIZE)) {
|
for (List<String> batch :
|
||||||
result.addAll(query().select(ENTRY.guidHash).from(ENTRY).where(ENTRY.feed.eq(feed), ENTRY.guidHash.in(batch)).fetch());
|
Lists.partition(new ArrayList<>(guidHashes), IN_CLAUSE_BATCH_SIZE)) {
|
||||||
|
result.addAll(
|
||||||
|
query().select(ENTRY.guidHash)
|
||||||
|
.from(ENTRY)
|
||||||
|
.where(ENTRY.feed.eq(feed), ENTRY.guidHash.in(batch))
|
||||||
|
.fetch());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<FeedCapacity> findFeedsExceedingCapacity(long maxCapacity, long max, boolean keepStarredEntries) {
|
public List<FeedCapacity> findFeedsExceedingCapacity(
|
||||||
|
long maxCapacity, long max, boolean keepStarredEntries) {
|
||||||
NumberExpression<Long> count = ENTRY.id.count();
|
NumberExpression<Long> count = ENTRY.id.count();
|
||||||
JPAQuery<Tuple> query = query().select(ENTRY.feed.id, count).from(ENTRY);
|
JPAQuery<Tuple> query = query().select(ENTRY.feed.id, count).from(ENTRY);
|
||||||
|
|
||||||
@@ -51,25 +61,21 @@ public class FeedEntryDAO extends GenericDAO<FeedEntry> {
|
|||||||
query.where(Predicates.isNotStarred(ENTRY));
|
query.where(Predicates.isNotStarred(ENTRY));
|
||||||
}
|
}
|
||||||
|
|
||||||
return query.groupBy(ENTRY.feed)
|
return query.groupBy(ENTRY.feed).having(count.gt(maxCapacity)).limit(max).fetch().stream()
|
||||||
.having(count.gt(maxCapacity))
|
|
||||||
.limit(max)
|
|
||||||
.fetch()
|
|
||||||
.stream()
|
|
||||||
.map(t -> new FeedCapacity(t.get(ENTRY.feed.id), t.get(count)))
|
.map(t -> new FeedCapacity(t.get(ENTRY.feed.id), t.get(count)))
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int delete(Long feedId, long max) {
|
public int delete(Long feedId, long max) {
|
||||||
List<FeedEntry> list = query().selectFrom(ENTRY).where(ENTRY.feed.id.eq(feedId)).limit(max).fetch();
|
List<FeedEntry> list =
|
||||||
|
query().selectFrom(ENTRY).where(ENTRY.feed.id.eq(feedId)).limit(max).fetch();
|
||||||
return delete(list);
|
return delete(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Delete entries older than a certain date */
|
||||||
* Delete entries older than a certain date
|
|
||||||
*/
|
|
||||||
public int deleteEntriesOlderThan(Instant olderThan, long max, boolean keepStarredEntries) {
|
public int deleteEntriesOlderThan(Instant olderThan, long max, boolean keepStarredEntries) {
|
||||||
JPAQuery<FeedEntry> query = query().selectFrom(ENTRY)
|
JPAQuery<FeedEntry> query =
|
||||||
|
query().selectFrom(ENTRY)
|
||||||
.where(ENTRY.published.lt(olderThan))
|
.where(ENTRY.published.lt(olderThan))
|
||||||
.orderBy(ENTRY.published.asc())
|
.orderBy(ENTRY.published.asc())
|
||||||
.limit(max);
|
.limit(max);
|
||||||
@@ -81,11 +87,13 @@ public class FeedEntryDAO extends GenericDAO<FeedEntry> {
|
|||||||
return delete(query.fetch());
|
return delete(query.fetch());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Delete the oldest entries of a feed */
|
||||||
* Delete the oldest entries of a feed
|
|
||||||
*/
|
|
||||||
public int deleteOldEntries(Long feedId, long max, boolean keepStarredEntries) {
|
public int deleteOldEntries(Long feedId, long max, boolean keepStarredEntries) {
|
||||||
JPAQuery<FeedEntry> query = query().selectFrom(ENTRY).where(ENTRY.feed.id.eq(feedId)).orderBy(ENTRY.published.asc()).limit(max);
|
JPAQuery<FeedEntry> query =
|
||||||
|
query().selectFrom(ENTRY)
|
||||||
|
.where(ENTRY.feed.id.eq(feedId))
|
||||||
|
.orderBy(ENTRY.published.asc())
|
||||||
|
.limit(max);
|
||||||
|
|
||||||
if (keepStarredEntries) {
|
if (keepStarredEntries) {
|
||||||
query.where(Predicates.isNotStarred(ENTRY));
|
query.where(Predicates.isNotStarred(ENTRY));
|
||||||
@@ -94,6 +102,5 @@ public class FeedEntryDAO extends GenericDAO<FeedEntry> {
|
|||||||
return delete(query.fetch());
|
return delete(query.fetch());
|
||||||
}
|
}
|
||||||
|
|
||||||
public record FeedCapacity(Long id, Long capacity) {
|
public record FeedCapacity(Long id, Long capacity) {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,5 @@
|
|||||||
package com.commafeed.backend.dao;
|
package com.commafeed.backend.dao;
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import jakarta.inject.Singleton;
|
|
||||||
import jakarta.persistence.EntityManager;
|
|
||||||
|
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
|
||||||
|
|
||||||
import com.commafeed.CommaFeedConfiguration;
|
import com.commafeed.CommaFeedConfiguration;
|
||||||
import com.commafeed.backend.feed.FeedEntryKeyword;
|
import com.commafeed.backend.feed.FeedEntryKeyword;
|
||||||
import com.commafeed.backend.feed.FeedEntryKeyword.Mode;
|
import com.commafeed.backend.feed.FeedEntryKeyword.Mode;
|
||||||
@@ -33,6 +22,17 @@ import com.querydsl.core.types.dsl.Expressions;
|
|||||||
import com.querydsl.core.types.dsl.NumberExpression;
|
import com.querydsl.core.types.dsl.NumberExpression;
|
||||||
import com.querydsl.jpa.impl.JPAQuery;
|
import com.querydsl.jpa.impl.JPAQuery;
|
||||||
|
|
||||||
|
import jakarta.inject.Singleton;
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
|
|
||||||
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
||||||
|
|
||||||
@@ -46,25 +46,33 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
|||||||
private final FeedEntryTagDAO feedEntryTagDAO;
|
private final FeedEntryTagDAO feedEntryTagDAO;
|
||||||
private final CommaFeedConfiguration config;
|
private final CommaFeedConfiguration config;
|
||||||
|
|
||||||
public FeedEntryStatusDAO(EntityManager entityManager, FeedEntryTagDAO feedEntryTagDAO, CommaFeedConfiguration config) {
|
public FeedEntryStatusDAO(
|
||||||
|
EntityManager entityManager,
|
||||||
|
FeedEntryTagDAO feedEntryTagDAO,
|
||||||
|
CommaFeedConfiguration config) {
|
||||||
super(entityManager, FeedEntryStatus.class);
|
super(entityManager, FeedEntryStatus.class);
|
||||||
this.feedEntryTagDAO = feedEntryTagDAO;
|
this.feedEntryTagDAO = feedEntryTagDAO;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FeedEntryStatus getStatus(User user, FeedSubscription sub, FeedEntry entry) {
|
public FeedEntryStatus getStatus(User user, FeedSubscription sub, FeedEntry entry) {
|
||||||
List<FeedEntryStatus> statuses = query().selectFrom(STATUS).where(STATUS.entry.eq(entry), STATUS.subscription.eq(sub)).fetch();
|
List<FeedEntryStatus> statuses =
|
||||||
|
query().selectFrom(STATUS)
|
||||||
|
.where(STATUS.entry.eq(entry), STATUS.subscription.eq(sub))
|
||||||
|
.fetch();
|
||||||
FeedEntryStatus status = statuses.stream().findFirst().orElse(null);
|
FeedEntryStatus status = statuses.stream().findFirst().orElse(null);
|
||||||
return handleStatus(user, status, sub, entry);
|
return handleStatus(user, status, sub, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** creates an artificial "unread" status if status is null */
|
||||||
* creates an artificial "unread" status if status is null
|
private FeedEntryStatus handleStatus(
|
||||||
*/
|
User user, FeedEntryStatus status, FeedSubscription sub, FeedEntry entry) {
|
||||||
private FeedEntryStatus handleStatus(User user, FeedEntryStatus status, FeedSubscription sub, FeedEntry entry) {
|
|
||||||
if (status == null) {
|
if (status == null) {
|
||||||
Instant statusesInstantThreshold = config.database().cleanup().statusesInstantThreshold();
|
Instant statusesInstantThreshold =
|
||||||
boolean read = statusesInstantThreshold != null && entry.getPublished().isBefore(statusesInstantThreshold);
|
config.database().cleanup().statusesInstantThreshold();
|
||||||
|
boolean read =
|
||||||
|
statusesInstantThreshold != null
|
||||||
|
&& entry.getPublished().isBefore(statusesInstantThreshold);
|
||||||
status = new FeedEntryStatus(user, sub, entry);
|
status = new FeedEntryStatus(user, sub, entry);
|
||||||
status.setRead(read);
|
status.setRead(read);
|
||||||
status.setMarkable(!read);
|
status.setMarkable(!read);
|
||||||
@@ -75,20 +83,32 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void fetchTags(User user, List<FeedEntryStatus> statuses) {
|
private void fetchTags(User user, List<FeedEntryStatus> statuses) {
|
||||||
Map<Long, List<FeedEntryTag>> tagsByEntryIds = feedEntryTagDAO.findByEntries(user,
|
Map<Long, List<FeedEntryTag>> tagsByEntryIds =
|
||||||
statuses.stream().map(FeedEntryStatus::getEntry).toList());
|
feedEntryTagDAO.findByEntries(
|
||||||
|
user, statuses.stream().map(FeedEntryStatus::getEntry).toList());
|
||||||
for (FeedEntryStatus status : statuses) {
|
for (FeedEntryStatus status : statuses) {
|
||||||
List<FeedEntryTag> tags = tagsByEntryIds.get(status.getEntry().getId());
|
List<FeedEntryTag> tags = tagsByEntryIds.get(status.getEntry().getId());
|
||||||
status.setTags(tags == null ? List.of() : tags);
|
status.setTags(tags == null ? List.of() : tags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<FeedEntryStatus> findStarred(User user, Instant newerThan, int offset, int limit, ReadingOrder order,
|
public List<FeedEntryStatus> findStarred(
|
||||||
|
User user,
|
||||||
|
List<FeedEntryKeyword> keywords,
|
||||||
|
Instant newerThan,
|
||||||
|
int offset,
|
||||||
|
int limit,
|
||||||
|
ReadingOrder order,
|
||||||
boolean includeContent) {
|
boolean includeContent) {
|
||||||
JPAQuery<FeedEntryStatus> query = query().selectFrom(STATUS).where(STATUS.user.eq(user), STATUS.starred.isTrue());
|
JPAQuery<FeedEntryStatus> query =
|
||||||
if (includeContent) {
|
query().selectFrom(STATUS).where(STATUS.user.eq(user), STATUS.starred.isTrue());
|
||||||
|
if (includeContent || CollectionUtils.isNotEmpty(keywords)) {
|
||||||
query.join(STATUS.entry).fetchJoin();
|
query.join(STATUS.entry).fetchJoin();
|
||||||
query.join(STATUS.entry.content).fetchJoin();
|
query.join(STATUS.entry.content, CONTENT).fetchJoin();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CollectionUtils.isNotEmpty(keywords)) {
|
||||||
|
applyKeywordsFilter(query, keywords);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newerThan != null) {
|
if (newerThan != null) {
|
||||||
@@ -120,10 +140,21 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
|||||||
return statuses;
|
return statuses;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<FeedEntryStatus> findBySubscriptions(User user, List<FeedSubscription> subs, boolean unreadOnly,
|
public List<FeedEntryStatus> findBySubscriptions(
|
||||||
List<FeedEntryKeyword> keywords, Instant newerThan, int offset, int limit, ReadingOrder order, boolean includeContent,
|
User user,
|
||||||
String tag, Long minEntryId, Long maxEntryId) {
|
List<FeedSubscription> subs,
|
||||||
Map<Long, List<FeedSubscription>> subsByFeedId = subs.stream().collect(Collectors.groupingBy(s -> s.getFeed().getId()));
|
boolean unreadOnly,
|
||||||
|
List<FeedEntryKeyword> keywords,
|
||||||
|
Instant newerThan,
|
||||||
|
int offset,
|
||||||
|
int limit,
|
||||||
|
ReadingOrder order,
|
||||||
|
boolean includeContent,
|
||||||
|
String tag,
|
||||||
|
Long minEntryId,
|
||||||
|
Long maxEntryId) {
|
||||||
|
Map<Long, List<FeedSubscription>> subsByFeedId =
|
||||||
|
subs.stream().collect(Collectors.groupingBy(s -> s.getFeed().getId()));
|
||||||
|
|
||||||
JPAQuery<Tuple> query = query().select(ENTRY, STATUS).from(ENTRY);
|
JPAQuery<Tuple> query = query().select(ENTRY, STATUS).from(ENTRY);
|
||||||
query.leftJoin(ENTRY.statuses, STATUS).on(STATUS.subscription.in(subs));
|
query.leftJoin(ENTRY.statuses, STATUS).on(STATUS.subscription.in(subs));
|
||||||
@@ -132,16 +163,9 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
|||||||
if (includeContent || CollectionUtils.isNotEmpty(keywords)) {
|
if (includeContent || CollectionUtils.isNotEmpty(keywords)) {
|
||||||
query.join(ENTRY.content, CONTENT).fetchJoin();
|
query.join(ENTRY.content, CONTENT).fetchJoin();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CollectionUtils.isNotEmpty(keywords)) {
|
if (CollectionUtils.isNotEmpty(keywords)) {
|
||||||
for (FeedEntryKeyword keyword : keywords) {
|
applyKeywordsFilter(query, keywords);
|
||||||
BooleanBuilder or = new BooleanBuilder();
|
|
||||||
or.or(CONTENT.content.containsIgnoreCase(keyword.keyword()));
|
|
||||||
or.or(CONTENT.title.containsIgnoreCase(keyword.keyword()));
|
|
||||||
if (keyword.mode() == Mode.EXCLUDE) {
|
|
||||||
or.not();
|
|
||||||
}
|
|
||||||
query.where(or);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unreadOnly && tag == null) {
|
if (unreadOnly && tag == null) {
|
||||||
@@ -202,8 +226,21 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
|||||||
return statuses;
|
return statuses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void applyKeywordsFilter(JPAQuery<?> query, List<FeedEntryKeyword> keywords) {
|
||||||
|
for (FeedEntryKeyword keyword : keywords) {
|
||||||
|
BooleanBuilder or = new BooleanBuilder();
|
||||||
|
or.or(CONTENT.content.containsIgnoreCase(keyword.keyword()));
|
||||||
|
or.or(CONTENT.title.containsIgnoreCase(keyword.keyword()));
|
||||||
|
if (keyword.mode() == Mode.EXCLUDE) {
|
||||||
|
or.not();
|
||||||
|
}
|
||||||
|
query.where(or);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public UnreadCount getUnreadCount(FeedSubscription sub) {
|
public UnreadCount getUnreadCount(FeedSubscription sub) {
|
||||||
JPAQuery<Tuple> query = query().select(ENTRY.count(), ENTRY.published.max())
|
JPAQuery<Tuple> query =
|
||||||
|
query().select(ENTRY.count(), ENTRY.published.max())
|
||||||
.from(ENTRY)
|
.from(ENTRY)
|
||||||
.leftJoin(ENTRY.statuses, STATUS)
|
.leftJoin(ENTRY.statuses, STATUS)
|
||||||
.on(STATUS.subscription.eq(sub))
|
.on(STATUS.subscription.eq(sub))
|
||||||
@@ -230,7 +267,8 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public long deleteOldStatuses(Instant olderThan, int limit) {
|
public long deleteOldStatuses(Instant olderThan, int limit) {
|
||||||
List<Long> ids = query().select(STATUS.id)
|
List<Long> ids =
|
||||||
|
query().select(STATUS.id)
|
||||||
.from(STATUS)
|
.from(STATUS)
|
||||||
.where(STATUS.entryInserted.lt(olderThan), STATUS.starred.isFalse())
|
.where(STATUS.entryInserted.lt(olderThan), STATUS.starred.isFalse())
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
@@ -245,13 +283,15 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
|||||||
where.and(SUBSCRIPTION.autoMarkAsReadAfterDays.isNotNull());
|
where.and(SUBSCRIPTION.autoMarkAsReadAfterDays.isNotNull());
|
||||||
where.and(SUBSCRIPTION.autoMarkAsReadAfterDays.gt(0));
|
where.and(SUBSCRIPTION.autoMarkAsReadAfterDays.gt(0));
|
||||||
|
|
||||||
NumberExpression<Integer> daysDiff = Expressions.numberTemplate(Integer.class, "TIMESTAMPDIFF(DAY, {0}, {1})", ENTRY.published,
|
NumberExpression<Integer> daysDiff =
|
||||||
now);
|
Expressions.numberTemplate(
|
||||||
|
Integer.class, "TIMESTAMPDIFF(DAY, {0}, {1})", ENTRY.published, now);
|
||||||
where.and(daysDiff.goe(SUBSCRIPTION.autoMarkAsReadAfterDays));
|
where.and(daysDiff.goe(SUBSCRIPTION.autoMarkAsReadAfterDays));
|
||||||
|
|
||||||
where.and(buildUnreadPredicate());
|
where.and(buildUnreadPredicate());
|
||||||
|
|
||||||
List<Tuple> tuples = query().select(ENTRY, STATUS, SUBSCRIPTION)
|
List<Tuple> tuples =
|
||||||
|
query().select(ENTRY, STATUS, SUBSCRIPTION)
|
||||||
.from(ENTRY)
|
.from(ENTRY)
|
||||||
.join(ENTRY.feed, FEED)
|
.join(ENTRY.feed, FEED)
|
||||||
.join(SUBSCRIPTION)
|
.join(SUBSCRIPTION)
|
||||||
@@ -265,7 +305,8 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
|||||||
long updated = 0;
|
long updated = 0;
|
||||||
|
|
||||||
// Update existing statuses
|
// Update existing statuses
|
||||||
List<Long> statusIdsToUpdate = tuples.stream()
|
List<Long> statusIdsToUpdate =
|
||||||
|
tuples.stream()
|
||||||
.map(t -> t.get(STATUS))
|
.map(t -> t.get(STATUS))
|
||||||
.filter(s -> s != null && s.getId() != null)
|
.filter(s -> s != null && s.getId() != null)
|
||||||
.map(FeedEntryStatus::getId)
|
.map(FeedEntryStatus::getId)
|
||||||
@@ -273,7 +314,11 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
|||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
if (!statusIdsToUpdate.isEmpty()) {
|
if (!statusIdsToUpdate.isEmpty()) {
|
||||||
updated += updateQuery(STATUS).where(STATUS.id.in(statusIdsToUpdate)).set(STATUS.read, true).execute();
|
updated +=
|
||||||
|
updateQuery(STATUS)
|
||||||
|
.where(STATUS.id.in(statusIdsToUpdate))
|
||||||
|
.set(STATUS.read, true)
|
||||||
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert new statuses for entries without existing status
|
// Insert new statuses for entries without existing status
|
||||||
@@ -291,5 +336,4 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
|||||||
|
|
||||||
return updated;
|
return updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
package com.commafeed.backend.dao;
|
package com.commafeed.backend.dao;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import jakarta.inject.Singleton;
|
|
||||||
import jakarta.persistence.EntityManager;
|
|
||||||
|
|
||||||
import com.commafeed.backend.model.FeedEntry;
|
import com.commafeed.backend.model.FeedEntry;
|
||||||
import com.commafeed.backend.model.FeedEntryTag;
|
import com.commafeed.backend.model.FeedEntryTag;
|
||||||
import com.commafeed.backend.model.QFeedEntryTag;
|
import com.commafeed.backend.model.QFeedEntryTag;
|
||||||
import com.commafeed.backend.model.User;
|
import com.commafeed.backend.model.User;
|
||||||
|
|
||||||
|
import jakarta.inject.Singleton;
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class FeedEntryTagDAO extends GenericDAO<FeedEntryTag> {
|
public class FeedEntryTagDAO extends GenericDAO<FeedEntryTag> {
|
||||||
|
|
||||||
@@ -30,7 +30,8 @@ public class FeedEntryTagDAO extends GenericDAO<FeedEntryTag> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Map<Long, List<FeedEntryTag>> findByEntries(User user, List<FeedEntry> entries) {
|
public Map<Long, List<FeedEntryTag>> findByEntries(User user, List<FeedEntry> entries) {
|
||||||
return query().selectFrom(TAG)
|
return query()
|
||||||
|
.selectFrom(TAG)
|
||||||
.where(TAG.user.eq(user), TAG.entry.in(entries))
|
.where(TAG.user.eq(user), TAG.entry.in(entries))
|
||||||
.fetch()
|
.fetch()
|
||||||
.stream()
|
.stream()
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
package com.commafeed.backend.dao;
|
package com.commafeed.backend.dao;
|
||||||
|
|
||||||
import java.util.List;
|
import com.commafeed.backend.model.AbstractModel;
|
||||||
import java.util.Set;
|
import com.commafeed.backend.model.Feed;
|
||||||
import java.util.function.Consumer;
|
import com.commafeed.backend.model.FeedCategory;
|
||||||
import java.util.stream.Collectors;
|
import com.commafeed.backend.model.FeedSubscription;
|
||||||
|
import com.commafeed.backend.model.Models;
|
||||||
|
import com.commafeed.backend.model.QFeedSubscription;
|
||||||
|
import com.commafeed.backend.model.User;
|
||||||
|
import com.querydsl.jpa.JPQLQuery;
|
||||||
|
|
||||||
import jakarta.inject.Singleton;
|
import jakarta.inject.Singleton;
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
@@ -15,14 +19,10 @@ import org.hibernate.event.spi.PostCommitInsertEventListener;
|
|||||||
import org.hibernate.event.spi.PostInsertEvent;
|
import org.hibernate.event.spi.PostInsertEvent;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
import com.commafeed.backend.model.AbstractModel;
|
import java.util.List;
|
||||||
import com.commafeed.backend.model.Feed;
|
import java.util.Set;
|
||||||
import com.commafeed.backend.model.FeedCategory;
|
import java.util.function.Consumer;
|
||||||
import com.commafeed.backend.model.FeedSubscription;
|
import java.util.stream.Collectors;
|
||||||
import com.commafeed.backend.model.Models;
|
|
||||||
import com.commafeed.backend.model.QFeedSubscription;
|
|
||||||
import com.commafeed.backend.model.User;
|
|
||||||
import com.querydsl.jpa.JPQLQuery;
|
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class FeedSubscriptionDAO extends GenericDAO<FeedSubscription> {
|
public class FeedSubscriptionDAO extends GenericDAO<FeedSubscription> {
|
||||||
@@ -37,12 +37,14 @@ public class FeedSubscriptionDAO extends GenericDAO<FeedSubscription> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onPostCommitInsert(Consumer<FeedSubscription> consumer) {
|
public void onPostCommitInsert(Consumer<FeedSubscription> consumer) {
|
||||||
entityManager.unwrap(SharedSessionContractImplementor.class)
|
entityManager
|
||||||
|
.unwrap(SharedSessionContractImplementor.class)
|
||||||
.getFactory()
|
.getFactory()
|
||||||
.getServiceRegistry()
|
.getServiceRegistry()
|
||||||
.getService(EventListenerRegistry.class)
|
.getService(EventListenerRegistry.class)
|
||||||
.getEventListenerGroup(EventType.POST_COMMIT_INSERT)
|
.getEventListenerGroup(EventType.POST_COMMIT_INSERT)
|
||||||
.appendListener(new PostCommitInsertEventListener() {
|
.appendListener(
|
||||||
|
new PostCommitInsertEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onPostInsert(PostInsertEvent event) {
|
public void onPostInsert(PostInsertEvent event) {
|
||||||
if (event.getEntity() instanceof FeedSubscription s) {
|
if (event.getEntity() instanceof FeedSubscription s) {
|
||||||
@@ -63,7 +65,8 @@ public class FeedSubscriptionDAO extends GenericDAO<FeedSubscription> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public FeedSubscription findById(User user, Long id) {
|
public FeedSubscription findById(User user, Long id) {
|
||||||
List<FeedSubscription> subs = query().selectFrom(SUBSCRIPTION)
|
List<FeedSubscription> subs =
|
||||||
|
query().selectFrom(SUBSCRIPTION)
|
||||||
.where(SUBSCRIPTION.user.eq(user), SUBSCRIPTION.id.eq(id))
|
.where(SUBSCRIPTION.user.eq(user), SUBSCRIPTION.id.eq(id))
|
||||||
.leftJoin(SUBSCRIPTION.feed)
|
.leftJoin(SUBSCRIPTION.feed)
|
||||||
.fetchJoin()
|
.fetchJoin()
|
||||||
@@ -79,7 +82,8 @@ public class FeedSubscriptionDAO extends GenericDAO<FeedSubscription> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public FeedSubscription findByFeed(User user, Feed feed) {
|
public FeedSubscription findByFeed(User user, Feed feed) {
|
||||||
List<FeedSubscription> subs = query().selectFrom(SUBSCRIPTION)
|
List<FeedSubscription> subs =
|
||||||
|
query().selectFrom(SUBSCRIPTION)
|
||||||
.where(SUBSCRIPTION.user.eq(user), SUBSCRIPTION.feed.eq(feed))
|
.where(SUBSCRIPTION.user.eq(user), SUBSCRIPTION.feed.eq(feed))
|
||||||
.fetch();
|
.fetch();
|
||||||
FeedSubscription sub = subs.stream().findFirst().orElse(null);
|
FeedSubscription sub = subs.stream().findFirst().orElse(null);
|
||||||
@@ -87,7 +91,8 @@ public class FeedSubscriptionDAO extends GenericDAO<FeedSubscription> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<FeedSubscription> findAll(User user) {
|
public List<FeedSubscription> findAll(User user) {
|
||||||
List<FeedSubscription> subs = query().selectFrom(SUBSCRIPTION)
|
List<FeedSubscription> subs =
|
||||||
|
query().selectFrom(SUBSCRIPTION)
|
||||||
.where(SUBSCRIPTION.user.eq(user))
|
.where(SUBSCRIPTION.user.eq(user))
|
||||||
.leftJoin(SUBSCRIPTION.feed)
|
.leftJoin(SUBSCRIPTION.feed)
|
||||||
.fetchJoin()
|
.fetchJoin()
|
||||||
@@ -98,11 +103,15 @@ public class FeedSubscriptionDAO extends GenericDAO<FeedSubscription> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Long count(User user) {
|
public Long count(User user) {
|
||||||
return query().select(SUBSCRIPTION.count()).from(SUBSCRIPTION).where(SUBSCRIPTION.user.eq(user)).fetchOne();
|
return query().select(SUBSCRIPTION.count())
|
||||||
|
.from(SUBSCRIPTION)
|
||||||
|
.where(SUBSCRIPTION.user.eq(user))
|
||||||
|
.fetchOne();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<FeedSubscription> findByCategory(User user, FeedCategory category) {
|
public List<FeedSubscription> findByCategory(User user, FeedCategory category) {
|
||||||
JPQLQuery<FeedSubscription> query = query().selectFrom(SUBSCRIPTION).where(SUBSCRIPTION.user.eq(user));
|
JPQLQuery<FeedSubscription> query =
|
||||||
|
query().selectFrom(SUBSCRIPTION).where(SUBSCRIPTION.user.eq(user));
|
||||||
if (category == null) {
|
if (category == null) {
|
||||||
query.where(SUBSCRIPTION.category.isNull());
|
query.where(SUBSCRIPTION.category.isNull());
|
||||||
} else {
|
} else {
|
||||||
@@ -112,8 +121,14 @@ public class FeedSubscriptionDAO extends GenericDAO<FeedSubscription> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<FeedSubscription> findByCategories(User user, List<FeedCategory> categories) {
|
public List<FeedSubscription> findByCategories(User user, List<FeedCategory> categories) {
|
||||||
Set<Long> categoryIds = categories.stream().map(AbstractModel::getId).collect(Collectors.toSet());
|
Set<Long> categoryIds =
|
||||||
return findAll(user).stream().filter(s -> s.getCategory() != null && categoryIds.contains(s.getCategory().getId())).toList();
|
categories.stream().map(AbstractModel::getId).collect(Collectors.toSet());
|
||||||
|
return findAll(user).stream()
|
||||||
|
.filter(
|
||||||
|
s ->
|
||||||
|
s.getCategory() != null
|
||||||
|
&& categoryIds.contains(s.getCategory().getId()))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<FeedSubscription> initRelations(List<FeedSubscription> list) {
|
private List<FeedSubscription> initRelations(List<FeedSubscription> list) {
|
||||||
|
|||||||
@@ -1,12 +1,5 @@
|
|||||||
package com.commafeed.backend.dao;
|
package com.commafeed.backend.dao;
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
|
||||||
|
|
||||||
import org.hibernate.jpa.SpecHints;
|
|
||||||
|
|
||||||
import com.commafeed.backend.model.AbstractModel;
|
import com.commafeed.backend.model.AbstractModel;
|
||||||
import com.querydsl.core.types.EntityPath;
|
import com.querydsl.core.types.EntityPath;
|
||||||
import com.querydsl.jpa.impl.JPADeleteClause;
|
import com.querydsl.jpa.impl.JPADeleteClause;
|
||||||
@@ -14,8 +7,15 @@ import com.querydsl.jpa.impl.JPAQuery;
|
|||||||
import com.querydsl.jpa.impl.JPAQueryFactory;
|
import com.querydsl.jpa.impl.JPAQueryFactory;
|
||||||
import com.querydsl.jpa.impl.JPAUpdateClause;
|
import com.querydsl.jpa.impl.JPAUpdateClause;
|
||||||
|
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
import org.hibernate.jpa.SpecHints;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public abstract class GenericDAO<T extends AbstractModel> {
|
public abstract class GenericDAO<T extends AbstractModel> {
|
||||||
|
|
||||||
@@ -62,5 +62,4 @@ public abstract class GenericDAO<T extends AbstractModel> {
|
|||||||
query.setHint(SpecHints.HINT_SPEC_QUERY_TIMEOUT, Math.toIntExact(timeout.toMillis()));
|
query.setHint(SpecHints.HINT_SPEC_QUERY_TIMEOUT, Math.toIntExact(timeout.toMillis()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ public class Predicates {
|
|||||||
private static final QFeedEntryStatus STATUS = QFeedEntryStatus.feedEntryStatus;
|
private static final QFeedEntryStatus STATUS = QFeedEntryStatus.feedEntryStatus;
|
||||||
|
|
||||||
public static BooleanExpression isNotStarred(QFeedEntry entry) {
|
public static BooleanExpression isNotStarred(QFeedEntry entry) {
|
||||||
return JPAExpressions.selectOne().from(STATUS).where(STATUS.entry.eq(entry).and(STATUS.starred.isTrue())).notExists();
|
return JPAExpressions.selectOne()
|
||||||
|
.from(STATUS)
|
||||||
|
.where(STATUS.entry.eq(entry).and(STATUS.starred.isTrue()))
|
||||||
|
.notExists();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package com.commafeed.backend.dao;
|
package com.commafeed.backend.dao;
|
||||||
|
|
||||||
import java.util.concurrent.Callable;
|
import io.quarkus.narayana.jta.QuarkusTransaction;
|
||||||
|
|
||||||
import jakarta.inject.Singleton;
|
import jakarta.inject.Singleton;
|
||||||
|
|
||||||
import io.quarkus.narayana.jta.QuarkusTransaction;
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class UnitOfWork {
|
public class UnitOfWork {
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.commafeed.backend.dao;
|
package com.commafeed.backend.dao;
|
||||||
|
|
||||||
import jakarta.inject.Singleton;
|
|
||||||
import jakarta.persistence.EntityManager;
|
|
||||||
|
|
||||||
import com.commafeed.backend.model.QUser;
|
import com.commafeed.backend.model.QUser;
|
||||||
import com.commafeed.backend.model.User;
|
import com.commafeed.backend.model.User;
|
||||||
|
|
||||||
|
import jakarta.inject.Singleton;
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class UserDAO extends GenericDAO<User> {
|
public class UserDAO extends GenericDAO<User> {
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
package com.commafeed.backend.dao;
|
package com.commafeed.backend.dao;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import jakarta.inject.Singleton;
|
|
||||||
import jakarta.persistence.EntityManager;
|
|
||||||
|
|
||||||
import com.commafeed.backend.model.QUserRole;
|
import com.commafeed.backend.model.QUserRole;
|
||||||
import com.commafeed.backend.model.User;
|
import com.commafeed.backend.model.User;
|
||||||
import com.commafeed.backend.model.UserRole;
|
import com.commafeed.backend.model.UserRole;
|
||||||
import com.commafeed.backend.model.UserRole.Role;
|
import com.commafeed.backend.model.UserRole.Role;
|
||||||
|
|
||||||
|
import jakarta.inject.Singleton;
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class UserRoleDAO extends GenericDAO<UserRole> {
|
public class UserRoleDAO extends GenericDAO<UserRole> {
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package com.commafeed.backend.dao;
|
package com.commafeed.backend.dao;
|
||||||
|
|
||||||
import jakarta.inject.Singleton;
|
|
||||||
import jakarta.persistence.EntityManager;
|
|
||||||
|
|
||||||
import com.commafeed.backend.model.QUserSettings;
|
import com.commafeed.backend.model.QUserSettings;
|
||||||
import com.commafeed.backend.model.User;
|
import com.commafeed.backend.model.User;
|
||||||
import com.commafeed.backend.model.UserSettings;
|
import com.commafeed.backend.model.UserSettings;
|
||||||
|
|
||||||
|
import jakarta.inject.Singleton;
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class UserSettingsDAO extends GenericDAO<UserSettings> {
|
public class UserSettingsDAO extends GenericDAO<UserSettings> {
|
||||||
|
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
package com.commafeed.backend.favicon;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import com.commafeed.backend.model.Feed;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public abstract class AbstractFaviconFetcher {
|
|
||||||
|
|
||||||
private static final List<String> ICON_MIMETYPE_BLACKLIST = Arrays.asList("application/xml", "text/html");
|
|
||||||
private static final long MIN_ICON_LENGTH = 100;
|
|
||||||
private static final long MAX_ICON_LENGTH = 100000;
|
|
||||||
|
|
||||||
public abstract Favicon fetch(Feed feed);
|
|
||||||
|
|
||||||
protected boolean isValidIconResponse(byte[] content, String contentType) {
|
|
||||||
if (content == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
long length = content.length;
|
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(contentType)) {
|
|
||||||
contentType = contentType.split(";")[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ICON_MIMETYPE_BLACKLIST.contains(contentType)) {
|
|
||||||
log.debug("Content-Type {} is blacklisted", contentType);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length < MIN_ICON_LENGTH) {
|
|
||||||
log.debug("Length {} below MIN_ICON_LENGTH {}", length, MIN_ICON_LENGTH);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length > MAX_ICON_LENGTH) {
|
|
||||||
log.debug("Length {} greater than MAX_ICON_LENGTH {}", length, MAX_ICON_LENGTH);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,130 +0,0 @@
|
|||||||
package com.commafeed.backend.favicon;
|
|
||||||
|
|
||||||
import jakarta.annotation.Priority;
|
|
||||||
import jakarta.inject.Singleton;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.jsoup.Jsoup;
|
|
||||||
import org.jsoup.nodes.Document;
|
|
||||||
import org.jsoup.select.Elements;
|
|
||||||
|
|
||||||
import com.commafeed.backend.HttpGetter;
|
|
||||||
import com.commafeed.backend.HttpGetter.HttpResult;
|
|
||||||
import com.commafeed.backend.Urls;
|
|
||||||
import com.commafeed.backend.model.Feed;
|
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inspired/Ported from https://github.com/potatolondon/getfavicon
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
@Singleton
|
|
||||||
@Priority(Integer.MIN_VALUE)
|
|
||||||
public class DefaultFaviconFetcher extends AbstractFaviconFetcher {
|
|
||||||
|
|
||||||
private final HttpGetter getter;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Favicon fetch(Feed feed) {
|
|
||||||
Favicon icon = fetch(feed.getLink());
|
|
||||||
if (icon == null) {
|
|
||||||
icon = fetch(feed.getUrl());
|
|
||||||
}
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Favicon fetch(String url) {
|
|
||||||
if (url == null) {
|
|
||||||
log.debug("url is null");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
int doubleSlash = url.indexOf("//");
|
|
||||||
if (doubleSlash == -1) {
|
|
||||||
doubleSlash = 0;
|
|
||||||
} else {
|
|
||||||
doubleSlash += 2;
|
|
||||||
}
|
|
||||||
int firstSlash = url.indexOf('/', doubleSlash);
|
|
||||||
if (firstSlash != -1) {
|
|
||||||
url = url.substring(0, firstSlash);
|
|
||||||
}
|
|
||||||
|
|
||||||
Favicon icon = getIconAtRoot(url);
|
|
||||||
|
|
||||||
if (icon == null) {
|
|
||||||
icon = getIconInPage(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Favicon getIconAtRoot(String url) {
|
|
||||||
byte[] bytes = null;
|
|
||||||
String contentType = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
url = Urls.removeTrailingSlash(url) + "/favicon.ico";
|
|
||||||
log.debug("getting root icon at {}", url);
|
|
||||||
HttpResult result = getter.get(url);
|
|
||||||
bytes = result.content();
|
|
||||||
contentType = result.contentType();
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.debug("Failed to retrieve iconAtRoot for url {}: ", url, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isValidIconResponse(bytes, contentType)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return new Favicon(bytes, contentType);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Favicon getIconInPage(String url) {
|
|
||||||
|
|
||||||
Document doc;
|
|
||||||
try {
|
|
||||||
HttpResult result = getter.get(url);
|
|
||||||
doc = Jsoup.parse(new String(result.content()), url);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.debug("Failed to retrieve page to find icon", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Elements icons = doc.select("link[rel~=(?i)^(shortcut|icon|shortcut icon)$]");
|
|
||||||
|
|
||||||
if (icons.isEmpty()) {
|
|
||||||
log.debug("No icon found in page {}", url);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
String href = icons.getFirst().attr("abs:href");
|
|
||||||
if (StringUtils.isBlank(href)) {
|
|
||||||
log.debug("No icon found in page");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
log.debug("Found unconfirmed iconInPage at {}", href);
|
|
||||||
|
|
||||||
byte[] bytes;
|
|
||||||
String contentType;
|
|
||||||
try {
|
|
||||||
HttpResult result = getter.get(href);
|
|
||||||
bytes = result.content();
|
|
||||||
contentType = result.contentType();
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.debug("Failed to retrieve icon found in page {}", href, e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isValidIconResponse(bytes, contentType)) {
|
|
||||||
log.debug("Invalid icon found for {}", href);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Favicon(bytes, contentType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,32 +1,33 @@
|
|||||||
package com.commafeed.backend.favicon;
|
package com.commafeed.backend.favicon;
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import jakarta.inject.Singleton;
|
|
||||||
|
|
||||||
import org.apache.hc.core5.http.NameValuePair;
|
|
||||||
import org.apache.hc.core5.net.URIBuilder;
|
|
||||||
|
|
||||||
import com.commafeed.backend.HttpGetter;
|
import com.commafeed.backend.HttpGetter;
|
||||||
import com.commafeed.backend.HttpGetter.HttpResult;
|
import com.commafeed.backend.HttpGetter.HttpResult;
|
||||||
import com.commafeed.backend.model.Feed;
|
import com.commafeed.backend.model.Feed;
|
||||||
|
|
||||||
|
import jakarta.annotation.Priority;
|
||||||
|
import jakarta.inject.Singleton;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.apache.hc.core5.http.NameValuePair;
|
||||||
|
import org.apache.hc.core5.net.URIBuilder;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Singleton
|
@Singleton
|
||||||
public class FacebookFaviconFetcher extends AbstractFaviconFetcher {
|
@Priority(3)
|
||||||
|
public class FacebookFaviconFetcher implements FaviconFetcher {
|
||||||
|
|
||||||
private final HttpGetter getter;
|
private final HttpGetter getter;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Favicon fetch(Feed feed) {
|
public Favicon fetch(Feed feed) {
|
||||||
String url = feed.getUrl();
|
String url = feed.getUrl();
|
||||||
|
|
||||||
if (!url.toLowerCase().contains("www.facebook.com")) {
|
if (!url.toLowerCase().contains("www.facebook.com")) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -36,25 +37,19 @@ public class FacebookFaviconFetcher extends AbstractFaviconFetcher {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String iconUrl = String.format("https://graph.facebook.com/%s/picture?type=square&height=16", userName);
|
String iconUrl =
|
||||||
|
String.format(
|
||||||
byte[] bytes = null;
|
"https://graph.facebook.com/%s/picture?type=square&height=16", userName);
|
||||||
String contentType = null;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
log.debug("Getting Facebook user's icon, {}", url);
|
log.debug("Getting Facebook user's icon, {}", url);
|
||||||
|
|
||||||
HttpResult iconResult = getter.get(iconUrl);
|
HttpResult iconResult = getter.get(iconUrl);
|
||||||
bytes = iconResult.content();
|
return new Favicon(iconResult.content(), iconResult.contentType());
|
||||||
contentType = iconResult.contentType();
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.debug("Failed to retrieve Facebook icon", e);
|
log.debug("Failed to retrieve Facebook icon", e);
|
||||||
}
|
|
||||||
|
|
||||||
if (!isValidIconResponse(bytes, contentType)) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new Favicon(bytes, contentType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String extractUserName(String url) {
|
private String extractUserName(String url) {
|
||||||
@@ -67,7 +62,10 @@ public class FacebookFaviconFetcher extends AbstractFaviconFetcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<NameValuePair> params = new URIBuilder(uri).getQueryParams();
|
List<NameValuePair> params = new URIBuilder(uri).getQueryParams();
|
||||||
return params.stream().filter(p -> "id".equals(p.getName())).map(NameValuePair::getValue).findFirst().orElse(null);
|
return params.stream()
|
||||||
|
.filter(p -> "id".equals(p.getName()))
|
||||||
|
.map(NameValuePair::getValue)
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ public record Favicon(byte[] icon, MediaType mediaType) {
|
|||||||
try {
|
try {
|
||||||
return MediaType.valueOf(contentType);
|
return MediaType.valueOf(contentType);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.debug("invalid content type '{}' received, returning default value", contentType, e);
|
log.debug(
|
||||||
|
"invalid content type '{}' received, returning default value", contentType, e);
|
||||||
return DEFAULT_MEDIA_TYPE;
|
return DEFAULT_MEDIA_TYPE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package com.commafeed.backend.favicon;
|
||||||
|
|
||||||
|
import com.commafeed.backend.model.Feed;
|
||||||
|
|
||||||
|
public interface FaviconFetcher {
|
||||||
|
|
||||||
|
Favicon fetch(Feed feed);
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package com.commafeed.backend.favicon;
|
||||||
|
|
||||||
|
import com.commafeed.backend.HttpGetter;
|
||||||
|
import com.commafeed.backend.HttpGetter.HttpResult;
|
||||||
|
import com.commafeed.backend.model.Feed;
|
||||||
|
|
||||||
|
import jakarta.annotation.Priority;
|
||||||
|
import jakarta.inject.Singleton;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
/** Fetch favicon from the url declared in the feed. */
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Singleton
|
||||||
|
@Priority(2)
|
||||||
|
public class FeedFaviconFetcher implements FaviconFetcher {
|
||||||
|
|
||||||
|
private final HttpGetter getter;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Favicon fetch(Feed feed) {
|
||||||
|
String url = feed.getIconUrl();
|
||||||
|
if (url == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
HttpResult result = getter.get(url);
|
||||||
|
return new Favicon(result.content(), result.contentType());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.debug("Failed to retrieve icon declared in the feed {}", url, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package com.commafeed.backend.favicon;
|
||||||
|
|
||||||
|
import com.commafeed.backend.HttpGetter;
|
||||||
|
import com.commafeed.backend.HttpGetter.HttpResult;
|
||||||
|
import com.commafeed.backend.model.Feed;
|
||||||
|
|
||||||
|
import jakarta.annotation.Priority;
|
||||||
|
import jakarta.inject.Singleton;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.jsoup.Jsoup;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.jsoup.select.Elements;
|
||||||
|
|
||||||
|
/** Extracts favicon url from html page. */
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Singleton
|
||||||
|
@Priority(1)
|
||||||
|
public class HtmlFaviconFetcher implements FaviconFetcher {
|
||||||
|
|
||||||
|
private final HttpGetter getter;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Favicon fetch(Feed feed) {
|
||||||
|
String url = feed.getLink();
|
||||||
|
if (url == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Document doc;
|
||||||
|
try {
|
||||||
|
HttpResult result = getter.get(url);
|
||||||
|
doc = Jsoup.parse(new String(result.content()), url);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.debug("Failed to retrieve page to find icon", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Elements icons = doc.select("link[rel~=(?i)^(shortcut|icon|shortcut icon)$]");
|
||||||
|
if (icons.isEmpty()) {
|
||||||
|
log.debug("No icon found in page {}", url);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String href = icons.getFirst().attr("abs:href");
|
||||||
|
if (StringUtils.isBlank(href)) {
|
||||||
|
log.debug("No icon found in page");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
HttpResult result = getter.get(href);
|
||||||
|
return new Favicon(result.content(), result.contentType());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.debug("Failed to retrieve icon found in page {}", href, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package com.commafeed.backend.favicon;
|
||||||
|
|
||||||
|
import com.commafeed.backend.HttpGetter;
|
||||||
|
import com.commafeed.backend.HttpGetter.HttpResult;
|
||||||
|
import com.commafeed.backend.model.Feed;
|
||||||
|
|
||||||
|
import jakarta.annotation.Priority;
|
||||||
|
import jakarta.inject.Singleton;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
/** Fetches favicon from root of the domain (e.g. https://example.com/favicon.ico) */
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Singleton
|
||||||
|
@Priority(0)
|
||||||
|
public class RootFaviconFetcher implements FaviconFetcher {
|
||||||
|
|
||||||
|
private final HttpGetter getter;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Favicon fetch(Feed feed) {
|
||||||
|
String url = feed.getLink();
|
||||||
|
if (url == null) {
|
||||||
|
url = feed.getUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
URI uri = URI.create(url.trim());
|
||||||
|
String faviconUrl =
|
||||||
|
"%s://%s%s/favicon.ico"
|
||||||
|
.formatted(
|
||||||
|
uri.getScheme(),
|
||||||
|
uri.getHost(),
|
||||||
|
uri.getPort() > 0 ? ":" + uri.getPort() : "");
|
||||||
|
|
||||||
|
log.debug("getting root icon at {}", faviconUrl);
|
||||||
|
HttpResult result = getter.get(faviconUrl);
|
||||||
|
return new Favicon(result.content(), result.contentType());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.debug("Failed to retrieve iconAtRoot for url {}: ", url, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,17 +1,5 @@
|
|||||||
package com.commafeed.backend.favicon;
|
package com.commafeed.backend.favicon;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import jakarta.inject.Singleton;
|
|
||||||
import jakarta.ws.rs.core.UriBuilder;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
|
||||||
import org.apache.hc.core5.http.NameValuePair;
|
|
||||||
import org.apache.hc.core5.net.URIBuilder;
|
|
||||||
|
|
||||||
import com.commafeed.CommaFeedConfiguration;
|
import com.commafeed.CommaFeedConfiguration;
|
||||||
import com.commafeed.backend.HttpGetter;
|
import com.commafeed.backend.HttpGetter;
|
||||||
import com.commafeed.backend.HttpGetter.HttpResult;
|
import com.commafeed.backend.HttpGetter.HttpResult;
|
||||||
@@ -23,18 +11,34 @@ import com.fasterxml.jackson.core.JsonPointer;
|
|||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
import jakarta.annotation.Priority;
|
||||||
|
import jakarta.inject.Singleton;
|
||||||
|
import jakarta.ws.rs.core.UriBuilder;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
import org.apache.hc.core5.http.NameValuePair;
|
||||||
|
import org.apache.hc.core5.net.URIBuilder;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Singleton
|
@Singleton
|
||||||
public class YoutubeFaviconFetcher extends AbstractFaviconFetcher {
|
@Priority(3)
|
||||||
|
public class YoutubeFaviconFetcher implements FaviconFetcher {
|
||||||
|
|
||||||
private static final String PART_SNIPPET = "snippet";
|
private static final String PART_SNIPPET = "snippet";
|
||||||
|
|
||||||
private static final JsonPointer CHANNEL_THUMBNAIL_URL = JsonPointer.compile("/items/0/snippet/thumbnails/default/url");
|
private static final JsonPointer CHANNEL_THUMBNAIL_URL =
|
||||||
private static final JsonPointer PLAYLIST_CHANNEL_ID = JsonPointer.compile("/items/0/snippet/channelId");
|
JsonPointer.compile("/items/0/snippet/thumbnails/default/url");
|
||||||
|
private static final JsonPointer PLAYLIST_CHANNEL_ID =
|
||||||
|
JsonPointer.compile("/items/0/snippet/channelId");
|
||||||
|
|
||||||
private final HttpGetter getter;
|
private final HttpGetter getter;
|
||||||
private final CommaFeedConfiguration config;
|
private final CommaFeedConfiguration config;
|
||||||
@@ -53,13 +57,20 @@ public class YoutubeFaviconFetcher extends AbstractFaviconFetcher {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] bytes = null;
|
|
||||||
String contentType = null;
|
|
||||||
try {
|
try {
|
||||||
List<NameValuePair> params = new URIBuilder(url).getQueryParams();
|
List<NameValuePair> params = new URIBuilder(url).getQueryParams();
|
||||||
Optional<NameValuePair> userId = params.stream().filter(nvp -> nvp.getName().equalsIgnoreCase("user")).findFirst();
|
Optional<NameValuePair> userId =
|
||||||
Optional<NameValuePair> channelId = params.stream().filter(nvp -> nvp.getName().equalsIgnoreCase("channel_id")).findFirst();
|
params.stream()
|
||||||
Optional<NameValuePair> playlistId = params.stream().filter(nvp -> nvp.getName().equalsIgnoreCase("playlist_id")).findFirst();
|
.filter(nvp -> nvp.getName().equalsIgnoreCase("user"))
|
||||||
|
.findFirst();
|
||||||
|
Optional<NameValuePair> channelId =
|
||||||
|
params.stream()
|
||||||
|
.filter(nvp -> nvp.getName().equalsIgnoreCase("channel_id"))
|
||||||
|
.findFirst();
|
||||||
|
Optional<NameValuePair> playlistId =
|
||||||
|
params.stream()
|
||||||
|
.filter(nvp -> nvp.getName().equalsIgnoreCase("playlist_id"))
|
||||||
|
.findFirst();
|
||||||
|
|
||||||
byte[] response = null;
|
byte[] response = null;
|
||||||
if (userId.isPresent()) {
|
if (userId.isPresent()) {
|
||||||
@@ -84,21 +95,20 @@ public class YoutubeFaviconFetcher extends AbstractFaviconFetcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
HttpResult iconResult = getter.get(thumbnailUrl.asText());
|
HttpResult iconResult = getter.get(thumbnailUrl.asText());
|
||||||
bytes = iconResult.content();
|
return new Favicon(iconResult.content(), iconResult.contentType());
|
||||||
contentType = iconResult.contentType();
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.debug("Failed to retrieve YouTube icon", e);
|
log.debug("Failed to retrieve YouTube icon", e);
|
||||||
}
|
|
||||||
|
|
||||||
if (!isValidIconResponse(bytes, contentType)) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new Favicon(bytes, contentType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] fetchForUser(String googleAuthKey, String userId)
|
private byte[] fetchForUser(String googleAuthKey, String userId)
|
||||||
throws IOException, NotModifiedException, TooManyRequestsException, SchemeNotAllowedException {
|
throws IOException,
|
||||||
URI uri = UriBuilder.fromUri("https://www.googleapis.com/youtube/v3/channels")
|
NotModifiedException,
|
||||||
|
TooManyRequestsException,
|
||||||
|
SchemeNotAllowedException {
|
||||||
|
URI uri =
|
||||||
|
UriBuilder.fromUri("https://www.googleapis.com/youtube/v3/channels")
|
||||||
.queryParam("part", PART_SNIPPET)
|
.queryParam("part", PART_SNIPPET)
|
||||||
.queryParam("key", googleAuthKey)
|
.queryParam("key", googleAuthKey)
|
||||||
.queryParam("forUsername", userId)
|
.queryParam("forUsername", userId)
|
||||||
@@ -107,8 +117,12 @@ public class YoutubeFaviconFetcher extends AbstractFaviconFetcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private byte[] fetchForChannel(String googleAuthKey, String channelId)
|
private byte[] fetchForChannel(String googleAuthKey, String channelId)
|
||||||
throws IOException, NotModifiedException, TooManyRequestsException, SchemeNotAllowedException {
|
throws IOException,
|
||||||
URI uri = UriBuilder.fromUri("https://www.googleapis.com/youtube/v3/channels")
|
NotModifiedException,
|
||||||
|
TooManyRequestsException,
|
||||||
|
SchemeNotAllowedException {
|
||||||
|
URI uri =
|
||||||
|
UriBuilder.fromUri("https://www.googleapis.com/youtube/v3/channels")
|
||||||
.queryParam("part", PART_SNIPPET)
|
.queryParam("part", PART_SNIPPET)
|
||||||
.queryParam("key", googleAuthKey)
|
.queryParam("key", googleAuthKey)
|
||||||
.queryParam("id", channelId)
|
.queryParam("id", channelId)
|
||||||
@@ -117,8 +131,12 @@ public class YoutubeFaviconFetcher extends AbstractFaviconFetcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private byte[] fetchForPlaylist(String googleAuthKey, String playlistId)
|
private byte[] fetchForPlaylist(String googleAuthKey, String playlistId)
|
||||||
throws IOException, NotModifiedException, TooManyRequestsException, SchemeNotAllowedException {
|
throws IOException,
|
||||||
URI uri = UriBuilder.fromUri("https://www.googleapis.com/youtube/v3/playlists")
|
NotModifiedException,
|
||||||
|
TooManyRequestsException,
|
||||||
|
SchemeNotAllowedException {
|
||||||
|
URI uri =
|
||||||
|
UriBuilder.fromUri("https://www.googleapis.com/youtube/v3/playlists")
|
||||||
.queryParam("part", PART_SNIPPET)
|
.queryParam("part", PART_SNIPPET)
|
||||||
.queryParam("key", googleAuthKey)
|
.queryParam("key", googleAuthKey)
|
||||||
.queryParam("id", playlistId)
|
.queryParam("id", playlistId)
|
||||||
@@ -132,5 +150,4 @@ public class YoutubeFaviconFetcher extends AbstractFaviconFetcher {
|
|||||||
|
|
||||||
return fetchForChannel(googleAuthKey, channelId.asText());
|
return fetchForChannel(googleAuthKey, channelId.asText());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
package com.commafeed.backend.feed;
|
package com.commafeed.backend.feed;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
/** A keyword used in a search query */
|
||||||
|
|
||||||
/**
|
|
||||||
* A keyword used in a search query
|
|
||||||
*/
|
|
||||||
public record FeedEntryKeyword(String keyword, Mode mode) {
|
public record FeedEntryKeyword(String keyword, Mode mode) {
|
||||||
|
|
||||||
public enum Mode {
|
public enum Mode {
|
||||||
INCLUDE, EXCLUDE
|
INCLUDE,
|
||||||
|
EXCLUDE
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<FeedEntryKeyword> fromQueryString(String keywords) {
|
public static List<FeedEntryKeyword> fromQueryString(String keywords) {
|
||||||
|
|||||||
@@ -1,16 +1,5 @@
|
|||||||
package com.commafeed.backend.feed;
|
package com.commafeed.backend.feed;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import jakarta.inject.Singleton;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.apache.commons.lang3.Strings;
|
|
||||||
|
|
||||||
import com.commafeed.backend.Digests;
|
import com.commafeed.backend.Digests;
|
||||||
import com.commafeed.backend.HttpGetter;
|
import com.commafeed.backend.HttpGetter;
|
||||||
import com.commafeed.backend.HttpGetter.HttpRequest;
|
import com.commafeed.backend.HttpGetter.HttpRequest;
|
||||||
@@ -24,11 +13,21 @@ import com.commafeed.backend.feed.parser.FeedParserResult;
|
|||||||
import com.commafeed.backend.urlprovider.FeedURLProvider;
|
import com.commafeed.backend.urlprovider.FeedURLProvider;
|
||||||
|
|
||||||
import io.quarkus.arc.All;
|
import io.quarkus.arc.All;
|
||||||
|
|
||||||
|
import jakarta.inject.Singleton;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
/**
|
import org.apache.commons.lang3.StringUtils;
|
||||||
* Fetches a feed then parses it
|
import org.apache.commons.lang3.Strings;
|
||||||
*/
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/** Fetches a feed then parses it */
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Singleton
|
@Singleton
|
||||||
public class FeedFetcher {
|
public class FeedFetcher {
|
||||||
@@ -37,18 +36,31 @@ public class FeedFetcher {
|
|||||||
private final HttpGetter getter;
|
private final HttpGetter getter;
|
||||||
private final List<FeedURLProvider> urlProviders;
|
private final List<FeedURLProvider> urlProviders;
|
||||||
|
|
||||||
public FeedFetcher(FeedParser parser, HttpGetter getter, @All List<FeedURLProvider> urlProviders) {
|
public FeedFetcher(
|
||||||
|
FeedParser parser, HttpGetter getter, @All List<FeedURLProvider> urlProviders) {
|
||||||
this.parser = parser;
|
this.parser = parser;
|
||||||
this.getter = getter;
|
this.getter = getter;
|
||||||
this.urlProviders = urlProviders;
|
this.urlProviders = urlProviders;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FeedFetcherResult fetch(String feedUrl, boolean extractFeedUrlFromHtml, String lastModified, String eTag,
|
public FeedFetcherResult fetch(
|
||||||
Instant lastPublishedDate, String lastContentHash) throws FeedParsingException, IOException, NotModifiedException,
|
String feedUrl,
|
||||||
TooManyRequestsException, SchemeNotAllowedException, NoFeedFoundException {
|
boolean extractFeedUrlFromHtml,
|
||||||
|
String lastModified,
|
||||||
|
String eTag,
|
||||||
|
Instant lastPublishedDate,
|
||||||
|
String lastContentHash)
|
||||||
|
throws FeedParsingException,
|
||||||
|
IOException,
|
||||||
|
NotModifiedException,
|
||||||
|
TooManyRequestsException,
|
||||||
|
SchemeNotAllowedException,
|
||||||
|
NoFeedFoundException {
|
||||||
log.debug("Fetching feed {}", feedUrl);
|
log.debug("Fetching feed {}", feedUrl);
|
||||||
|
|
||||||
HttpResult result = getter.get(HttpRequest.builder(feedUrl).lastModified(lastModified).eTag(eTag).build());
|
HttpResult result =
|
||||||
|
getter.get(
|
||||||
|
HttpRequest.builder(feedUrl).lastModified(lastModified).eTag(eTag).build());
|
||||||
byte[] content = result.content();
|
byte[] content = result.content();
|
||||||
|
|
||||||
FeedParserResult parserResult;
|
FeedParserResult parserResult;
|
||||||
@@ -56,11 +68,20 @@ public class FeedFetcher {
|
|||||||
parserResult = parser.parse(result.urlAfterRedirect(), content);
|
parserResult = parser.parse(result.urlAfterRedirect(), content);
|
||||||
} catch (FeedParsingException e) {
|
} catch (FeedParsingException e) {
|
||||||
if (extractFeedUrlFromHtml) {
|
if (extractFeedUrlFromHtml) {
|
||||||
String extractedUrl = extractFeedUrl(urlProviders, feedUrl, new String(result.content(), StandardCharsets.UTF_8));
|
String extractedUrl =
|
||||||
|
extractFeedUrl(
|
||||||
|
urlProviders,
|
||||||
|
feedUrl,
|
||||||
|
new String(result.content(), StandardCharsets.UTF_8));
|
||||||
if (StringUtils.isNotBlank(extractedUrl)) {
|
if (StringUtils.isNotBlank(extractedUrl)) {
|
||||||
feedUrl = extractedUrl;
|
feedUrl = extractedUrl;
|
||||||
|
|
||||||
result = getter.get(HttpRequest.builder(extractedUrl).lastModified(lastModified).eTag(eTag).build());
|
result =
|
||||||
|
getter.get(
|
||||||
|
HttpRequest.builder(extractedUrl)
|
||||||
|
.lastModified(lastModified)
|
||||||
|
.eTag(eTag)
|
||||||
|
.build());
|
||||||
content = result.content();
|
content = result.content();
|
||||||
parserResult = parser.parse(result.urlAfterRedirect(), content);
|
parserResult = parser.parse(result.urlAfterRedirect(), content);
|
||||||
} else {
|
} else {
|
||||||
@@ -75,27 +96,39 @@ public class FeedFetcher {
|
|||||||
throw new IOException("Feed content is empty.");
|
throw new IOException("Feed content is empty.");
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean lastModifiedHeaderValueChanged = !Strings.CS.equals(lastModified, result.lastModifiedSince());
|
boolean lastModifiedHeaderValueChanged =
|
||||||
|
!Strings.CS.equals(lastModified, result.lastModifiedSince());
|
||||||
boolean etagHeaderValueChanged = !Strings.CS.equals(eTag, result.eTag());
|
boolean etagHeaderValueChanged = !Strings.CS.equals(eTag, result.eTag());
|
||||||
|
|
||||||
String hash = Digests.sha1Hex(content);
|
String hash = Digests.sha1Hex(content);
|
||||||
if (lastContentHash != null && lastContentHash.equals(hash)) {
|
if (lastContentHash != null && lastContentHash.equals(hash)) {
|
||||||
log.debug("content hash not modified: {}", feedUrl);
|
log.debug("content hash not modified: {}", feedUrl);
|
||||||
throw new NotModifiedException("content hash not modified", lastModifiedHeaderValueChanged ? result.lastModifiedSince() : null,
|
throw new NotModifiedException(
|
||||||
|
"content hash not modified",
|
||||||
|
lastModifiedHeaderValueChanged ? result.lastModifiedSince() : null,
|
||||||
etagHeaderValueChanged ? result.eTag() : null);
|
etagHeaderValueChanged ? result.eTag() : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastPublishedDate != null && lastPublishedDate.equals(parserResult.lastPublishedDate())) {
|
if (lastPublishedDate != null
|
||||||
|
&& lastPublishedDate.equals(parserResult.lastPublishedDate())) {
|
||||||
log.debug("publishedDate not modified: {}", feedUrl);
|
log.debug("publishedDate not modified: {}", feedUrl);
|
||||||
throw new NotModifiedException("publishedDate not modified", lastModifiedHeaderValueChanged ? result.lastModifiedSince() : null,
|
throw new NotModifiedException(
|
||||||
|
"publishedDate not modified",
|
||||||
|
lastModifiedHeaderValueChanged ? result.lastModifiedSince() : null,
|
||||||
etagHeaderValueChanged ? result.eTag() : null);
|
etagHeaderValueChanged ? result.eTag() : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new FeedFetcherResult(parserResult, result.urlAfterRedirect(), result.lastModifiedSince(), result.eTag(), hash,
|
return new FeedFetcherResult(
|
||||||
|
parserResult,
|
||||||
|
result.urlAfterRedirect(),
|
||||||
|
result.lastModifiedSince(),
|
||||||
|
result.eTag(),
|
||||||
|
hash,
|
||||||
result.validFor());
|
result.validFor());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String extractFeedUrl(List<FeedURLProvider> urlProviders, String url, String urlContent) {
|
private static String extractFeedUrl(
|
||||||
|
List<FeedURLProvider> urlProviders, String url, String urlContent) {
|
||||||
return urlProviders.stream()
|
return urlProviders.stream()
|
||||||
.flatMap(provider -> provider.get(url, urlContent).stream())
|
.flatMap(provider -> provider.get(url, urlContent).stream())
|
||||||
.filter(StringUtils::isNotBlank)
|
.filter(StringUtils::isNotBlank)
|
||||||
@@ -103,9 +136,13 @@ public class FeedFetcher {
|
|||||||
.orElse(null);
|
.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public record FeedFetcherResult(FeedParserResult feed, String urlAfterRedirect, String lastModifiedHeader, String lastETagHeader,
|
public record FeedFetcherResult(
|
||||||
String contentHash, Duration validFor) {
|
FeedParserResult feed,
|
||||||
}
|
String urlAfterRedirect,
|
||||||
|
String lastModifiedHeader,
|
||||||
|
String lastETagHeader,
|
||||||
|
String contentHash,
|
||||||
|
Duration validFor) {}
|
||||||
|
|
||||||
public static class NoFeedFoundException extends Exception {
|
public static class NoFeedFoundException extends Exception {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
@@ -114,5 +151,4 @@ public class FeedFetcher {
|
|||||||
super("This URL does not point to an RSS feed or a website with an RSS feed.", cause);
|
super("This URL does not point to an RSS feed or a website with an RSS feed.", cause);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,5 @@
|
|||||||
package com.commafeed.backend.feed;
|
package com.commafeed.backend.feed;
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.BlockingDeque;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.LinkedBlockingDeque;
|
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
|
||||||
import java.util.concurrent.SynchronousQueue;
|
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import jakarta.inject.Singleton;
|
|
||||||
|
|
||||||
import com.codahale.metrics.Gauge;
|
import com.codahale.metrics.Gauge;
|
||||||
import com.codahale.metrics.Meter;
|
import com.codahale.metrics.Meter;
|
||||||
import com.codahale.metrics.MetricRegistry;
|
import com.codahale.metrics.MetricRegistry;
|
||||||
@@ -26,8 +12,22 @@ import com.commafeed.backend.model.FeedEntry;
|
|||||||
import com.commafeed.backend.model.FeedSubscription;
|
import com.commafeed.backend.model.FeedSubscription;
|
||||||
import com.google.common.util.concurrent.MoreExecutors;
|
import com.google.common.util.concurrent.MoreExecutors;
|
||||||
|
|
||||||
|
import jakarta.inject.Singleton;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.BlockingDeque;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.LinkedBlockingDeque;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
import java.util.concurrent.SynchronousQueue;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Singleton
|
@Singleton
|
||||||
public class FeedRefreshEngine {
|
public class FeedRefreshEngine {
|
||||||
@@ -49,8 +49,14 @@ public class FeedRefreshEngine {
|
|||||||
private ThreadPoolExecutor databaseUpdaterExecutor;
|
private ThreadPoolExecutor databaseUpdaterExecutor;
|
||||||
private ThreadPoolExecutor notifierExecutor;
|
private ThreadPoolExecutor notifierExecutor;
|
||||||
|
|
||||||
public FeedRefreshEngine(UnitOfWork unitOfWork, FeedDAO feedDAO, FeedRefreshWorker worker, FeedRefreshUpdater updater,
|
public FeedRefreshEngine(
|
||||||
FeedUpdateNotifier notifier, CommaFeedConfiguration config, MetricRegistry metrics) {
|
UnitOfWork unitOfWork,
|
||||||
|
FeedDAO feedDAO,
|
||||||
|
FeedRefreshWorker worker,
|
||||||
|
FeedRefreshUpdater updater,
|
||||||
|
FeedUpdateNotifier notifier,
|
||||||
|
CommaFeedConfiguration config,
|
||||||
|
MetricRegistry metrics) {
|
||||||
this.unitOfWork = unitOfWork;
|
this.unitOfWork = unitOfWork;
|
||||||
this.feedDAO = feedDAO;
|
this.feedDAO = feedDAO;
|
||||||
this.worker = worker;
|
this.worker = worker;
|
||||||
@@ -61,12 +67,20 @@ public class FeedRefreshEngine {
|
|||||||
|
|
||||||
this.queue = new LinkedBlockingDeque<>();
|
this.queue = new LinkedBlockingDeque<>();
|
||||||
|
|
||||||
metrics.register(MetricRegistry.name(getClass(), "queue", "size"), (Gauge<Integer>) queue::size);
|
metrics.register(
|
||||||
metrics.register(MetricRegistry.name(getClass(), "worker", "active"), (Gauge<Integer>) () -> workerExecutor.getActiveCount());
|
MetricRegistry.name(getClass(), "queue", "size"), (Gauge<Integer>) queue::size);
|
||||||
metrics.register(MetricRegistry.name(getClass(), "updater", "active"),
|
metrics.register(
|
||||||
|
MetricRegistry.name(getClass(), "worker", "active"),
|
||||||
|
(Gauge<Integer>) () -> workerExecutor.getActiveCount());
|
||||||
|
metrics.register(
|
||||||
|
MetricRegistry.name(getClass(), "updater", "active"),
|
||||||
(Gauge<Integer>) () -> databaseUpdaterExecutor.getActiveCount());
|
(Gauge<Integer>) () -> databaseUpdaterExecutor.getActiveCount());
|
||||||
metrics.register(MetricRegistry.name(getClass(), "notifier", "active"), (Gauge<Integer>) () -> notifierExecutor.getActiveCount());
|
metrics.register(
|
||||||
metrics.register(MetricRegistry.name(getClass(), "notifier", "queue"), (Gauge<Integer>) () -> notifierExecutor.getQueue().size());
|
MetricRegistry.name(getClass(), "notifier", "active"),
|
||||||
|
(Gauge<Integer>) () -> notifierExecutor.getActiveCount());
|
||||||
|
metrics.register(
|
||||||
|
MetricRegistry.name(getClass(), "notifier", "queue"),
|
||||||
|
(Gauge<Integer>) () -> notifierExecutor.getQueue().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createExecutors() {
|
private void createExecutors() {
|
||||||
@@ -74,8 +88,11 @@ public class FeedRefreshEngine {
|
|||||||
this.refillLoopExecutor = Executors.newSingleThreadExecutor();
|
this.refillLoopExecutor = Executors.newSingleThreadExecutor();
|
||||||
this.refillExecutor = newDiscardingSingleThreadExecutorService();
|
this.refillExecutor = newDiscardingSingleThreadExecutorService();
|
||||||
this.workerExecutor = newBlockingExecutorService(config.feedRefresh().httpThreads());
|
this.workerExecutor = newBlockingExecutorService(config.feedRefresh().httpThreads());
|
||||||
this.databaseUpdaterExecutor = newBlockingExecutorService(config.feedRefresh().databaseThreads());
|
this.databaseUpdaterExecutor =
|
||||||
this.notifierExecutor = newDiscardingExecutorService(config.pushNotifications().threads(),
|
newBlockingExecutorService(config.feedRefresh().databaseThreads());
|
||||||
|
this.notifierExecutor =
|
||||||
|
newDiscardingExecutorService(
|
||||||
|
config.pushNotifications().threads(),
|
||||||
config.pushNotifications().queueCapacity());
|
config.pushNotifications().queueCapacity());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,17 +104,21 @@ public class FeedRefreshEngine {
|
|||||||
|
|
||||||
private void startFeedProcessingLoop() {
|
private void startFeedProcessingLoop() {
|
||||||
// take a feed from the queue, process it, rince, repeat
|
// take a feed from the queue, process it, rince, repeat
|
||||||
feedProcessingLoopExecutor.submit(() -> {
|
feedProcessingLoopExecutor.submit(
|
||||||
|
() -> {
|
||||||
while (!feedProcessingLoopExecutor.isShutdown()) {
|
while (!feedProcessingLoopExecutor.isShutdown()) {
|
||||||
try {
|
try {
|
||||||
// take() is blocking until a feed is available from the queue
|
// take() is blocking until a feed is available from the queue
|
||||||
Feed feed = queue.take();
|
Feed feed = queue.take();
|
||||||
|
|
||||||
// send the feed to be processed
|
// send the feed to be processed
|
||||||
log.debug("got feed {} from the queue, send it for processing", feed.getId());
|
log.debug(
|
||||||
|
"got feed {} from the queue, send it for processing",
|
||||||
|
feed.getId());
|
||||||
processFeedAsync(feed);
|
processFeedAsync(feed);
|
||||||
|
|
||||||
// we removed a feed from the queue, try to refill it as it may now be empty
|
// we removed a feed from the queue, try to refill it as it may now be
|
||||||
|
// empty
|
||||||
if (queue.isEmpty()) {
|
if (queue.isEmpty()) {
|
||||||
log.debug("took the last feed from the queue, try to refill");
|
log.debug("took the last feed from the queue, try to refill");
|
||||||
refillQueueAsync();
|
refillQueueAsync();
|
||||||
@@ -114,7 +135,8 @@ public class FeedRefreshEngine {
|
|||||||
|
|
||||||
private void startRefillLoop() {
|
private void startRefillLoop() {
|
||||||
// refill the queue at regular intervals if it's empty
|
// refill the queue at regular intervals if it's empty
|
||||||
refillLoopExecutor.submit(() -> {
|
refillLoopExecutor.submit(
|
||||||
|
() -> {
|
||||||
while (!refillLoopExecutor.isShutdown()) {
|
while (!refillLoopExecutor.isShutdown()) {
|
||||||
try {
|
try {
|
||||||
if (queue.isEmpty()) {
|
if (queue.isEmpty()) {
|
||||||
@@ -142,7 +164,8 @@ public class FeedRefreshEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void refillQueueAsync() {
|
private void refillQueueAsync() {
|
||||||
CompletableFuture.runAsync(() -> {
|
CompletableFuture.runAsync(
|
||||||
|
() -> {
|
||||||
if (!queue.isEmpty()) {
|
if (!queue.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -150,14 +173,19 @@ public class FeedRefreshEngine {
|
|||||||
refill.mark();
|
refill.mark();
|
||||||
|
|
||||||
List<Feed> nextUpdatableFeeds = getNextUpdatableFeeds(getBatchSize());
|
List<Feed> nextUpdatableFeeds = getNextUpdatableFeeds(getBatchSize());
|
||||||
log.debug("found {} feeds that are up for refresh", nextUpdatableFeeds.size());
|
log.debug(
|
||||||
|
"found {} feeds that are up for refresh",
|
||||||
|
nextUpdatableFeeds.size());
|
||||||
for (Feed feed : nextUpdatableFeeds) {
|
for (Feed feed : nextUpdatableFeeds) {
|
||||||
// add the feed only if it was not already queued
|
// add the feed only if it was not already queued
|
||||||
if (queue.stream().noneMatch(f -> f.getId().equals(feed.getId()))) {
|
if (queue.stream().noneMatch(f -> f.getId().equals(feed.getId()))) {
|
||||||
queue.addLast(feed);
|
queue.addLast(feed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, refillExecutor).whenComplete((data, ex) -> {
|
},
|
||||||
|
refillExecutor)
|
||||||
|
.whenComplete(
|
||||||
|
(data, ex) -> {
|
||||||
if (ex != null) {
|
if (ex != null) {
|
||||||
log.error("error while refilling the queue", ex);
|
log.error("error while refilling the queue", ex);
|
||||||
}
|
}
|
||||||
@@ -167,31 +195,51 @@ public class FeedRefreshEngine {
|
|||||||
private void processFeedAsync(Feed feed) {
|
private void processFeedAsync(Feed feed) {
|
||||||
CompletableFuture.supplyAsync(() -> worker.update(feed), workerExecutor)
|
CompletableFuture.supplyAsync(() -> worker.update(feed), workerExecutor)
|
||||||
.thenApplyAsync(r -> updater.update(r.feed(), r.entries()), databaseUpdaterExecutor)
|
.thenApplyAsync(r -> updater.update(r.feed(), r.entries()), databaseUpdaterExecutor)
|
||||||
.thenCompose(r -> {
|
.thenCompose(
|
||||||
List<CompletableFuture<Void>> futures = r.insertedUnreadEntriesBySubscription().entrySet().stream().map(e -> {
|
r -> {
|
||||||
|
List<CompletableFuture<Void>> futures =
|
||||||
|
r.insertedUnreadEntriesBySubscription().entrySet().stream()
|
||||||
|
.map(
|
||||||
|
e -> {
|
||||||
FeedSubscription sub = e.getKey();
|
FeedSubscription sub = e.getKey();
|
||||||
List<FeedEntry> entries = e.getValue();
|
List<FeedEntry> entries = e.getValue();
|
||||||
|
|
||||||
notifier.notifyOverWebsocket(sub, entries);
|
notifier.notifyOverWebsocket(sub, entries);
|
||||||
return CompletableFuture.runAsync(() -> notifier.sendPushNotifications(sub, entries), notifierExecutor);
|
return CompletableFuture.runAsync(
|
||||||
}).toList();
|
() ->
|
||||||
return CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new));
|
notifier
|
||||||
|
.sendPushNotifications(
|
||||||
|
sub,
|
||||||
|
entries),
|
||||||
|
notifierExecutor);
|
||||||
})
|
})
|
||||||
.exceptionally(ex -> {
|
.toList();
|
||||||
|
return CompletableFuture.allOf(
|
||||||
|
futures.toArray(CompletableFuture[]::new));
|
||||||
|
})
|
||||||
|
.exceptionally(
|
||||||
|
ex -> {
|
||||||
log.error("error while processing feed {}", feed.getUrl(), ex);
|
log.error("error while processing feed {}", feed.getUrl(), ex);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Feed> getNextUpdatableFeeds(int max) {
|
private List<Feed> getNextUpdatableFeeds(int max) {
|
||||||
return unitOfWork.call(() -> {
|
return unitOfWork.call(
|
||||||
Instant lastLoginThreshold = config.feedRefresh().userInactivityPeriod().isZero() ? null
|
() -> {
|
||||||
: Instant.now().minus(config.feedRefresh().userInactivityPeriod());
|
Instant lastLoginThreshold =
|
||||||
|
config.feedRefresh().userInactivityPeriod().isZero()
|
||||||
|
? null
|
||||||
|
: Instant.now()
|
||||||
|
.minus(config.feedRefresh().userInactivityPeriod());
|
||||||
List<Feed> feeds = feedDAO.findNextUpdatable(max, lastLoginThreshold);
|
List<Feed> feeds = feedDAO.findNextUpdatable(max, lastLoginThreshold);
|
||||||
if (!feeds.isEmpty()) {
|
if (!feeds.isEmpty()) {
|
||||||
// update disabledUntil to prevent feeds from being returned again by feedDAO.findNextUpdatable()
|
// update disabledUntil to prevent feeds from being returned again by
|
||||||
Instant nextUpdateDate = Instant.now().plus(config.feedRefresh().interval());
|
// feedDAO.findNextUpdatable()
|
||||||
feedDAO.setDisabledUntil(feeds.stream().map(AbstractModel::getId).toList(), nextUpdateDate);
|
Instant nextUpdateDate =
|
||||||
|
Instant.now().plus(config.feedRefresh().interval());
|
||||||
|
feedDAO.setDisabledUntil(
|
||||||
|
feeds.stream().map(AbstractModel::getId).toList(), nextUpdateDate);
|
||||||
}
|
}
|
||||||
return feeds;
|
return feeds;
|
||||||
});
|
});
|
||||||
@@ -202,41 +250,50 @@ public class FeedRefreshEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void stop() {
|
public void stop() {
|
||||||
MoreExecutors.shutdownAndAwaitTermination(this.feedProcessingLoopExecutor, config.shutdownTimeout());
|
MoreExecutors.shutdownAndAwaitTermination(
|
||||||
MoreExecutors.shutdownAndAwaitTermination(this.refillLoopExecutor, config.shutdownTimeout());
|
this.feedProcessingLoopExecutor, config.shutdownTimeout());
|
||||||
|
MoreExecutors.shutdownAndAwaitTermination(
|
||||||
|
this.refillLoopExecutor, config.shutdownTimeout());
|
||||||
MoreExecutors.shutdownAndAwaitTermination(this.refillExecutor, config.shutdownTimeout());
|
MoreExecutors.shutdownAndAwaitTermination(this.refillExecutor, config.shutdownTimeout());
|
||||||
MoreExecutors.shutdownAndAwaitTermination(this.workerExecutor, config.shutdownTimeout());
|
MoreExecutors.shutdownAndAwaitTermination(this.workerExecutor, config.shutdownTimeout());
|
||||||
MoreExecutors.shutdownAndAwaitTermination(this.databaseUpdaterExecutor, config.shutdownTimeout());
|
MoreExecutors.shutdownAndAwaitTermination(
|
||||||
|
this.databaseUpdaterExecutor, config.shutdownTimeout());
|
||||||
MoreExecutors.shutdownAndAwaitTermination(this.notifierExecutor, config.shutdownTimeout());
|
MoreExecutors.shutdownAndAwaitTermination(this.notifierExecutor, config.shutdownTimeout());
|
||||||
|
|
||||||
queue.clear();
|
queue.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns an ExecutorService with a single thread that discards tasks if a task is already running
|
* returns an ExecutorService with a single thread that discards tasks if a task is already
|
||||||
|
* running
|
||||||
*/
|
*/
|
||||||
private ThreadPoolExecutor newDiscardingSingleThreadExecutorService() {
|
private ThreadPoolExecutor newDiscardingSingleThreadExecutorService() {
|
||||||
ThreadPoolExecutor pool = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new SynchronousQueue<>());
|
ThreadPoolExecutor pool =
|
||||||
|
new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new SynchronousQueue<>());
|
||||||
pool.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
|
pool.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
|
||||||
return pool;
|
return pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** returns an ExecutorService that discards tasks if the queue is full */
|
||||||
* returns an ExecutorService that discards tasks if the queue is full
|
|
||||||
*/
|
|
||||||
private ThreadPoolExecutor newDiscardingExecutorService(int threads, int queueCapacity) {
|
private ThreadPoolExecutor newDiscardingExecutorService(int threads, int queueCapacity) {
|
||||||
ThreadPoolExecutor pool = new ThreadPoolExecutor(threads, threads, 0L, TimeUnit.MILLISECONDS,
|
ThreadPoolExecutor pool =
|
||||||
|
new ThreadPoolExecutor(
|
||||||
|
threads,
|
||||||
|
threads,
|
||||||
|
0L,
|
||||||
|
TimeUnit.MILLISECONDS,
|
||||||
new LinkedBlockingQueue<>(queueCapacity));
|
new LinkedBlockingQueue<>(queueCapacity));
|
||||||
pool.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
|
pool.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
|
||||||
return pool;
|
return pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** returns an ExecutorService that blocks submissions until a thread is available */
|
||||||
* returns an ExecutorService that blocks submissions until a thread is available
|
|
||||||
*/
|
|
||||||
private ThreadPoolExecutor newBlockingExecutorService(int threads) {
|
private ThreadPoolExecutor newBlockingExecutorService(int threads) {
|
||||||
ThreadPoolExecutor pool = new ThreadPoolExecutor(threads, threads, 0L, TimeUnit.MILLISECONDS, new SynchronousQueue<>());
|
ThreadPoolExecutor pool =
|
||||||
pool.setRejectedExecutionHandler((r, e) -> {
|
new ThreadPoolExecutor(
|
||||||
|
threads, threads, 0L, TimeUnit.MILLISECONDS, new SynchronousQueue<>());
|
||||||
|
pool.setRejectedExecutionHandler(
|
||||||
|
(r, e) -> {
|
||||||
if (e.isShutdown()) {
|
if (e.isShutdown()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
package com.commafeed.backend.feed;
|
package com.commafeed.backend.feed;
|
||||||
|
|
||||||
import java.time.Duration;
|
import com.commafeed.CommaFeedConfiguration;
|
||||||
import java.time.Instant;
|
import com.commafeed.CommaFeedConfiguration.FeedRefreshErrorHandling;
|
||||||
import java.time.InstantSource;
|
import com.google.common.primitives.Longs;
|
||||||
import java.time.temporal.ChronoUnit;
|
|
||||||
|
|
||||||
import jakarta.inject.Singleton;
|
import jakarta.inject.Singleton;
|
||||||
|
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
|
|
||||||
import com.commafeed.CommaFeedConfiguration;
|
import java.time.Duration;
|
||||||
import com.commafeed.CommaFeedConfiguration.FeedRefreshErrorHandling;
|
import java.time.Instant;
|
||||||
import com.google.common.primitives.Longs;
|
import java.time.InstantSource;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class FeedRefreshIntervalCalculator {
|
public class FeedRefreshIntervalCalculator {
|
||||||
@@ -22,7 +22,8 @@ public class FeedRefreshIntervalCalculator {
|
|||||||
private final FeedRefreshErrorHandling errorHandling;
|
private final FeedRefreshErrorHandling errorHandling;
|
||||||
private final InstantSource instantSource;
|
private final InstantSource instantSource;
|
||||||
|
|
||||||
public FeedRefreshIntervalCalculator(CommaFeedConfiguration config, InstantSource instantSource) {
|
public FeedRefreshIntervalCalculator(
|
||||||
|
CommaFeedConfiguration config, InstantSource instantSource) {
|
||||||
this.interval = config.feedRefresh().interval();
|
this.interval = config.feedRefresh().interval();
|
||||||
this.maxInterval = config.feedRefresh().maxInterval();
|
this.maxInterval = config.feedRefresh().maxInterval();
|
||||||
this.empirical = config.feedRefresh().intervalEmpirical();
|
this.empirical = config.feedRefresh().intervalEmpirical();
|
||||||
@@ -30,8 +31,11 @@ public class FeedRefreshIntervalCalculator {
|
|||||||
this.instantSource = instantSource;
|
this.instantSource = instantSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Instant onFetchSuccess(Instant publishedDate, Long averageEntryInterval, Duration validFor) {
|
public Instant onFetchSuccess(
|
||||||
Instant instant = empirical ? computeEmpiricalRefreshInterval(publishedDate, averageEntryInterval)
|
Instant publishedDate, Long averageEntryInterval, Duration validFor) {
|
||||||
|
Instant instant =
|
||||||
|
empirical
|
||||||
|
? computeEmpiricalRefreshInterval(publishedDate, averageEntryInterval)
|
||||||
: instantSource.instant().plus(interval);
|
: instantSource.instant().plus(interval);
|
||||||
return constrainToBounds(ObjectUtils.max(instant, instantSource.instant().plus(validFor)));
|
return constrainToBounds(ObjectUtils.max(instant, instantSource.instant().plus(validFor)));
|
||||||
}
|
}
|
||||||
@@ -49,11 +53,15 @@ public class FeedRefreshIntervalCalculator {
|
|||||||
return constrainToBounds(instantSource.instant().plus(interval));
|
return constrainToBounds(instantSource.instant().plus(interval));
|
||||||
}
|
}
|
||||||
|
|
||||||
Duration retryInterval = errorHandling.backoffInterval().multipliedBy(errorCount - errorHandling.retriesBeforeBackoff() + 1L);
|
Duration retryInterval =
|
||||||
|
errorHandling
|
||||||
|
.backoffInterval()
|
||||||
|
.multipliedBy(errorCount - errorHandling.retriesBeforeBackoff() + 1L);
|
||||||
return constrainToBounds(instantSource.instant().plus(retryInterval));
|
return constrainToBounds(instantSource.instant().plus(retryInterval));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Instant computeEmpiricalRefreshInterval(Instant publishedDate, Long averageEntryInterval) {
|
private Instant computeEmpiricalRefreshInterval(
|
||||||
|
Instant publishedDate, Long averageEntryInterval) {
|
||||||
Instant now = instantSource.instant();
|
Instant now = instantSource.instant();
|
||||||
|
|
||||||
if (publishedDate == null) {
|
if (publishedDate == null) {
|
||||||
@@ -70,7 +78,11 @@ public class FeedRefreshIntervalCalculator {
|
|||||||
} else if (averageEntryInterval != null) {
|
} else if (averageEntryInterval != null) {
|
||||||
// use average time between entries to decide when to refresh next, divided by factor
|
// use average time between entries to decide when to refresh next, divided by factor
|
||||||
int factor = 2;
|
int factor = 2;
|
||||||
long millis = Longs.constrainToRange(averageEntryInterval / factor, interval.toMillis(), maxInterval.dividedBy(4).toMillis());
|
long millis =
|
||||||
|
Longs.constrainToRange(
|
||||||
|
averageEntryInterval / factor,
|
||||||
|
interval.toMillis(),
|
||||||
|
maxInterval.dividedBy(4).toMillis());
|
||||||
return now.plusMillis(millis);
|
return now.plusMillis(millis);
|
||||||
} else {
|
} else {
|
||||||
// unknown case
|
// unknown case
|
||||||
@@ -79,6 +91,8 @@ public class FeedRefreshIntervalCalculator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Instant constrainToBounds(Instant instant) {
|
private Instant constrainToBounds(Instant instant) {
|
||||||
return ObjectUtils.max(ObjectUtils.min(instant, instantSource.instant().plus(maxInterval)), instantSource.instant().plus(interval));
|
return ObjectUtils.max(
|
||||||
|
ObjectUtils.min(instant, instantSource.instant().plus(maxInterval)),
|
||||||
|
instantSource.instant().plus(interval));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,5 @@
|
|||||||
package com.commafeed.backend.feed;
|
package com.commafeed.backend.feed;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.locks.Lock;
|
|
||||||
|
|
||||||
import jakarta.inject.Singleton;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import com.codahale.metrics.Meter;
|
import com.codahale.metrics.Meter;
|
||||||
import com.codahale.metrics.MetricRegistry;
|
import com.codahale.metrics.MetricRegistry;
|
||||||
import com.commafeed.backend.Digests;
|
import com.commafeed.backend.Digests;
|
||||||
@@ -30,11 +15,24 @@ import com.commafeed.backend.service.FeedEntryService;
|
|||||||
import com.commafeed.backend.service.FeedService;
|
import com.commafeed.backend.service.FeedService;
|
||||||
import com.google.common.util.concurrent.Striped;
|
import com.google.common.util.concurrent.Striped;
|
||||||
|
|
||||||
|
import jakarta.inject.Singleton;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
/**
|
import org.apache.commons.lang3.StringUtils;
|
||||||
* Updates the feed in the database and inserts new entries
|
|
||||||
*/
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.locks.Lock;
|
||||||
|
|
||||||
|
/** Updates the feed in the database and inserts new entries */
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Singleton
|
@Singleton
|
||||||
public class FeedRefreshUpdater {
|
public class FeedRefreshUpdater {
|
||||||
@@ -49,7 +47,11 @@ public class FeedRefreshUpdater {
|
|||||||
private final Meter feedUpdated;
|
private final Meter feedUpdated;
|
||||||
private final Meter entryInserted;
|
private final Meter entryInserted;
|
||||||
|
|
||||||
public FeedRefreshUpdater(UnitOfWork unitOfWork, FeedService feedService, FeedEntryService feedEntryService, MetricRegistry metrics,
|
public FeedRefreshUpdater(
|
||||||
|
UnitOfWork unitOfWork,
|
||||||
|
FeedService feedService,
|
||||||
|
FeedEntryService feedEntryService,
|
||||||
|
MetricRegistry metrics,
|
||||||
FeedSubscriptionDAO feedSubscriptionDAO) {
|
FeedSubscriptionDAO feedSubscriptionDAO) {
|
||||||
this.unitOfWork = unitOfWork;
|
this.unitOfWork = unitOfWork;
|
||||||
this.feedService = feedService;
|
this.feedService = feedService;
|
||||||
@@ -62,7 +64,8 @@ public class FeedRefreshUpdater {
|
|||||||
entryInserted = metrics.meter(MetricRegistry.name(getClass(), "entryInserted"));
|
entryInserted = metrics.meter(MetricRegistry.name(getClass(), "entryInserted"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private AddEntryResult addEntry(final Feed feed, final Entry entry, final List<FeedSubscription> subscriptions) {
|
private AddEntryResult addEntry(
|
||||||
|
final Feed feed, final Entry entry, final List<FeedSubscription> subscriptions) {
|
||||||
boolean processed = false;
|
boolean processed = false;
|
||||||
FeedEntry insertedEntry = null;
|
FeedEntry insertedEntry = null;
|
||||||
Set<FeedSubscription> subscriptionsForWhichEntryIsUnread = new HashSet<>();
|
Set<FeedSubscription> subscriptionsForWhichEntryIsUnread = new HashSet<>();
|
||||||
@@ -87,7 +90,9 @@ public class FeedRefreshUpdater {
|
|||||||
locked2 = lock2.tryLock(1, TimeUnit.MINUTES);
|
locked2 = lock2.tryLock(1, TimeUnit.MINUTES);
|
||||||
if (locked1 && locked2) {
|
if (locked1 && locked2) {
|
||||||
processed = true;
|
processed = true;
|
||||||
insertedEntry = unitOfWork.call(() -> {
|
insertedEntry =
|
||||||
|
unitOfWork.call(
|
||||||
|
() -> {
|
||||||
if (feedEntryService.find(feed, entry) != null) {
|
if (feedEntryService.find(feed, entry) != null) {
|
||||||
// entry already exists, nothing to do
|
// entry already exists, nothing to do
|
||||||
return null;
|
return null;
|
||||||
@@ -96,7 +101,8 @@ public class FeedRefreshUpdater {
|
|||||||
FeedEntry feedEntry = feedEntryService.create(feed, entry);
|
FeedEntry feedEntry = feedEntryService.create(feed, entry);
|
||||||
entryInserted.mark();
|
entryInserted.mark();
|
||||||
for (FeedSubscription sub : subscriptions) {
|
for (FeedSubscription sub : subscriptions) {
|
||||||
boolean unread = feedEntryService.applyFilter(sub, feedEntry);
|
boolean unread =
|
||||||
|
feedEntryService.applyFilter(sub, feedEntry);
|
||||||
if (unread) {
|
if (unread) {
|
||||||
subscriptionsForWhichEntryIsUnread.add(sub);
|
subscriptionsForWhichEntryIsUnread.add(sub);
|
||||||
}
|
}
|
||||||
@@ -107,7 +113,11 @@ public class FeedRefreshUpdater {
|
|||||||
log.error("lock timeout for {} - {}", feed.getUrl(), key1);
|
log.error("lock timeout for {} - {}", feed.getUrl(), key1);
|
||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
log.error("interrupted while waiting for lock for {} : {}", feed.getUrl(), e.getMessage(), e);
|
log.error(
|
||||||
|
"interrupted while waiting for lock for {} : {}",
|
||||||
|
feed.getUrl(),
|
||||||
|
e.getMessage(),
|
||||||
|
e);
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
} finally {
|
} finally {
|
||||||
if (locked1) {
|
if (locked1) {
|
||||||
@@ -123,11 +133,13 @@ public class FeedRefreshUpdater {
|
|||||||
public FeedRefreshUpdaterResult update(Feed feed, List<Entry> entries) {
|
public FeedRefreshUpdaterResult update(Feed feed, List<Entry> entries) {
|
||||||
boolean processed = true;
|
boolean processed = true;
|
||||||
long inserted = 0;
|
long inserted = 0;
|
||||||
Map<FeedSubscription, List<FeedEntry>> insertedUnreadEntriesBySubscription = new HashMap<>();
|
Map<FeedSubscription, List<FeedEntry>> insertedUnreadEntriesBySubscription =
|
||||||
|
new HashMap<>();
|
||||||
|
|
||||||
if (!entries.isEmpty()) {
|
if (!entries.isEmpty()) {
|
||||||
List<FeedSubscription> subscriptions = null;
|
List<FeedSubscription> subscriptions = null;
|
||||||
List<Entry> newEntries = unitOfWork.call(() -> feedEntryService.removeExistingEntries(feed, entries));
|
List<Entry> newEntries =
|
||||||
|
unitOfWork.call(() -> feedEntryService.removeExistingEntries(feed, entries));
|
||||||
for (Entry entry : newEntries) {
|
for (Entry entry : newEntries) {
|
||||||
if (subscriptions == null) {
|
if (subscriptions == null) {
|
||||||
subscriptions = unitOfWork.call(() -> feedSubscriptionDAO.findByFeed(feed));
|
subscriptions = unitOfWork.call(() -> feedSubscriptionDAO.findByFeed(feed));
|
||||||
@@ -135,9 +147,12 @@ public class FeedRefreshUpdater {
|
|||||||
AddEntryResult addEntryResult = addEntry(feed, entry, subscriptions);
|
AddEntryResult addEntryResult = addEntry(feed, entry, subscriptions);
|
||||||
processed &= addEntryResult.processed;
|
processed &= addEntryResult.processed;
|
||||||
inserted += addEntryResult.insertedEntry != null ? 1 : 0;
|
inserted += addEntryResult.insertedEntry != null ? 1 : 0;
|
||||||
addEntryResult.subscriptionsForWhichEntryIsUnread.forEach(sub -> {
|
addEntryResult.subscriptionsForWhichEntryIsUnread.forEach(
|
||||||
|
sub -> {
|
||||||
if (addEntryResult.insertedEntry != null) {
|
if (addEntryResult.insertedEntry != null) {
|
||||||
insertedUnreadEntriesBySubscription.computeIfAbsent(sub, k -> new ArrayList<>()).add(addEntryResult.insertedEntry);
|
insertedUnreadEntriesBySubscription
|
||||||
|
.computeIfAbsent(sub, k -> new ArrayList<>())
|
||||||
|
.add(addEntryResult.insertedEntry);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -163,10 +178,11 @@ public class FeedRefreshUpdater {
|
|||||||
return new FeedRefreshUpdaterResult(insertedUnreadEntriesBySubscription);
|
return new FeedRefreshUpdaterResult(insertedUnreadEntriesBySubscription);
|
||||||
}
|
}
|
||||||
|
|
||||||
private record AddEntryResult(boolean processed, FeedEntry insertedEntry, Set<FeedSubscription> subscriptionsForWhichEntryIsUnread) {
|
private record AddEntryResult(
|
||||||
}
|
boolean processed,
|
||||||
|
FeedEntry insertedEntry,
|
||||||
public record FeedRefreshUpdaterResult(Map<FeedSubscription, List<FeedEntry>> insertedUnreadEntriesBySubscription) {
|
Set<FeedSubscription> subscriptionsForWhichEntryIsUnread) {}
|
||||||
}
|
|
||||||
|
|
||||||
|
public record FeedRefreshUpdaterResult(
|
||||||
|
Map<FeedSubscription, List<FeedEntry>> insertedUnreadEntriesBySubscription) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,5 @@
|
|||||||
package com.commafeed.backend.feed;
|
package com.commafeed.backend.feed;
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import jakarta.inject.Singleton;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.Strings;
|
|
||||||
|
|
||||||
import com.codahale.metrics.Meter;
|
import com.codahale.metrics.Meter;
|
||||||
import com.codahale.metrics.MetricRegistry;
|
import com.codahale.metrics.MetricRegistry;
|
||||||
import com.commafeed.CommaFeedConfiguration;
|
import com.commafeed.CommaFeedConfiguration;
|
||||||
@@ -19,10 +9,21 @@ import com.commafeed.backend.feed.FeedFetcher.FeedFetcherResult;
|
|||||||
import com.commafeed.backend.feed.parser.FeedParserResult.Entry;
|
import com.commafeed.backend.feed.parser.FeedParserResult.Entry;
|
||||||
import com.commafeed.backend.model.Feed;
|
import com.commafeed.backend.model.Feed;
|
||||||
|
|
||||||
|
import jakarta.inject.Singleton;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.Strings;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls {@link FeedFetcher} and updates the Feed object, but does not update the database, ({@link FeedRefreshUpdater} does that)
|
* Calls {@link FeedFetcher} and updates the Feed object, but does not update the database, ({@link
|
||||||
|
* FeedRefreshUpdater} does that)
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Singleton
|
@Singleton
|
||||||
@@ -33,20 +34,28 @@ public class FeedRefreshWorker {
|
|||||||
private final CommaFeedConfiguration config;
|
private final CommaFeedConfiguration config;
|
||||||
private final Meter feedFetched;
|
private final Meter feedFetched;
|
||||||
|
|
||||||
public FeedRefreshWorker(FeedRefreshIntervalCalculator refreshIntervalCalculator, FeedFetcher fetcher, CommaFeedConfiguration config,
|
public FeedRefreshWorker(
|
||||||
|
FeedRefreshIntervalCalculator refreshIntervalCalculator,
|
||||||
|
FeedFetcher fetcher,
|
||||||
|
CommaFeedConfiguration config,
|
||||||
MetricRegistry metrics) {
|
MetricRegistry metrics) {
|
||||||
this.refreshIntervalCalculator = refreshIntervalCalculator;
|
this.refreshIntervalCalculator = refreshIntervalCalculator;
|
||||||
this.fetcher = fetcher;
|
this.fetcher = fetcher;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.feedFetched = metrics.meter(MetricRegistry.name(getClass(), "feedFetched"));
|
this.feedFetched = metrics.meter(MetricRegistry.name(getClass(), "feedFetched"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public FeedRefreshWorkerResult update(Feed feed) {
|
public FeedRefreshWorkerResult update(Feed feed) {
|
||||||
try {
|
try {
|
||||||
String url = Optional.ofNullable(feed.getUrlAfterRedirect()).orElse(feed.getUrl());
|
String url = Optional.ofNullable(feed.getUrlAfterRedirect()).orElse(feed.getUrl());
|
||||||
FeedFetcherResult result = fetcher.fetch(url, false, feed.getLastModifiedHeader(), feed.getEtagHeader(),
|
FeedFetcherResult result =
|
||||||
feed.getLastPublishedDate(), feed.getLastContentHash());
|
fetcher.fetch(
|
||||||
|
url,
|
||||||
|
false,
|
||||||
|
feed.getLastModifiedHeader(),
|
||||||
|
feed.getEtagHeader(),
|
||||||
|
feed.getLastPublishedDate(),
|
||||||
|
feed.getLastContentHash());
|
||||||
// stops here if NotModifiedException or any other exception is thrown
|
// stops here if NotModifiedException or any other exception is thrown
|
||||||
|
|
||||||
List<Entry> entries = result.feed().entries();
|
List<Entry> entries = result.feed().entries();
|
||||||
@@ -59,7 +68,10 @@ public class FeedRefreshWorker {
|
|||||||
Duration entriesMaxAge = config.database().cleanup().entriesMaxAge();
|
Duration entriesMaxAge = config.database().cleanup().entriesMaxAge();
|
||||||
if (!entriesMaxAge.isZero()) {
|
if (!entriesMaxAge.isZero()) {
|
||||||
Instant threshold = Instant.now().minus(entriesMaxAge);
|
Instant threshold = Instant.now().minus(entriesMaxAge);
|
||||||
entries = entries.stream().filter(entry -> entry.published().isAfter(threshold)).toList();
|
entries =
|
||||||
|
entries.stream()
|
||||||
|
.filter(entry -> entry.published().isAfter(threshold))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
String urlAfterRedirect = result.urlAfterRedirect();
|
String urlAfterRedirect = result.urlAfterRedirect();
|
||||||
@@ -69,6 +81,7 @@ public class FeedRefreshWorker {
|
|||||||
|
|
||||||
feed.setUrlAfterRedirect(urlAfterRedirect);
|
feed.setUrlAfterRedirect(urlAfterRedirect);
|
||||||
feed.setLink(result.feed().link());
|
feed.setLink(result.feed().link());
|
||||||
|
feed.setIconUrl(result.feed().iconUrl());
|
||||||
feed.setLastModifiedHeader(result.lastModifiedHeader());
|
feed.setLastModifiedHeader(result.lastModifiedHeader());
|
||||||
feed.setEtagHeader(result.lastETagHeader());
|
feed.setEtagHeader(result.lastETagHeader());
|
||||||
feed.setLastContentHash(result.contentHash());
|
feed.setLastContentHash(result.contentHash());
|
||||||
@@ -78,8 +91,11 @@ public class FeedRefreshWorker {
|
|||||||
|
|
||||||
feed.setErrorCount(0);
|
feed.setErrorCount(0);
|
||||||
feed.setMessage(null);
|
feed.setMessage(null);
|
||||||
feed.setDisabledUntil(refreshIntervalCalculator.onFetchSuccess(result.feed().lastPublishedDate(),
|
feed.setDisabledUntil(
|
||||||
result.feed().averageEntryInterval(), result.validFor()));
|
refreshIntervalCalculator.onFetchSuccess(
|
||||||
|
result.feed().lastPublishedDate(),
|
||||||
|
result.feed().averageEntryInterval(),
|
||||||
|
result.validFor()));
|
||||||
|
|
||||||
return new FeedRefreshWorkerResult(feed, entries);
|
return new FeedRefreshWorkerResult(feed, entries);
|
||||||
} catch (NotModifiedException e) {
|
} catch (NotModifiedException e) {
|
||||||
@@ -87,7 +103,9 @@ public class FeedRefreshWorker {
|
|||||||
|
|
||||||
feed.setErrorCount(0);
|
feed.setErrorCount(0);
|
||||||
feed.setMessage(e.getMessage());
|
feed.setMessage(e.getMessage());
|
||||||
feed.setDisabledUntil(refreshIntervalCalculator.onFeedNotModified(feed.getLastPublishedDate(), feed.getAverageEntryInterval()));
|
feed.setDisabledUntil(
|
||||||
|
refreshIntervalCalculator.onFeedNotModified(
|
||||||
|
feed.getLastPublishedDate(), feed.getAverageEntryInterval()));
|
||||||
|
|
||||||
if (e.getNewLastModifiedHeader() != null) {
|
if (e.getNewLastModifiedHeader() != null) {
|
||||||
feed.setLastModifiedHeader(e.getNewLastModifiedHeader());
|
feed.setLastModifiedHeader(e.getNewLastModifiedHeader());
|
||||||
@@ -103,7 +121,9 @@ public class FeedRefreshWorker {
|
|||||||
|
|
||||||
feed.setErrorCount(feed.getErrorCount() + 1);
|
feed.setErrorCount(feed.getErrorCount() + 1);
|
||||||
feed.setMessage("Server indicated that we are sending too many requests");
|
feed.setMessage("Server indicated that we are sending too many requests");
|
||||||
feed.setDisabledUntil(refreshIntervalCalculator.onTooManyRequests(e.getRetryAfter(), feed.getErrorCount()));
|
feed.setDisabledUntil(
|
||||||
|
refreshIntervalCalculator.onTooManyRequests(
|
||||||
|
e.getRetryAfter(), feed.getErrorCount()));
|
||||||
|
|
||||||
return new FeedRefreshWorkerResult(feed, Collections.emptyList());
|
return new FeedRefreshWorkerResult(feed, Collections.emptyList());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -119,7 +139,5 @@ public class FeedRefreshWorker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public record FeedRefreshWorkerResult(Feed feed, List<Entry> entries) {
|
public record FeedRefreshWorkerResult(Feed feed, List<Entry> entries) {}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user