mirror of
https://github.com/Athou/commafeed.git
synced 2026-10-26 15:08:51 +00:00
Compare commits
504 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
689c20d367 | ||
|
|
43588df2b4 | ||
|
|
d2aaddea33 | ||
|
|
de233f8ae5 | ||
|
|
3179e74dc7 | ||
|
|
6f5e9f5d49 | ||
|
|
8a43fdf200 | ||
|
|
69051e5bbb | ||
|
|
c648e7e0ec | ||
|
|
c91cf376ad | ||
|
|
f4e07597d0 | ||
|
|
64b64d3340 | ||
|
|
57ea87871e | ||
|
|
6154d80bb9 | ||
|
|
ad85745f85 | ||
|
|
41fc77322c | ||
|
|
1b83c26417 | ||
|
|
10ea5f0b93 | ||
|
|
032684de68 | ||
|
|
3efec5ce58 | ||
|
|
4ed32964d9 | ||
|
|
05c1d0cc6e | ||
|
|
3c54924971 | ||
|
|
e57dfc0e3f | ||
|
|
eff8bb16a0 | ||
|
|
87e681b71e | ||
|
|
ac73ef4ea7 | ||
|
|
20945e7443 | ||
|
|
b7b1278111 | ||
|
|
6f9378404f | ||
|
|
79787aca6e | ||
|
|
2d90ccf856 | ||
|
|
7f77cf0268 | ||
|
|
f3c390e0e0 | ||
|
|
1fdc471197 | ||
|
|
ecf5d9e50e | ||
|
|
97a49e8faa | ||
|
|
f5a020cdc2 | ||
|
|
1f0507ee65 | ||
|
|
393c90f334 | ||
|
|
03ecc2f49b | ||
|
|
17743adce6 | ||
|
|
126dde103a | ||
|
|
14a25581b4 | ||
|
|
c7c95efb3a | ||
|
|
4c1293d357 | ||
|
|
76a92ea44c | ||
|
|
ba454322db | ||
|
|
a3b9f471e1 | ||
|
|
d58ddc888e | ||
|
|
fe9837c45c | ||
|
|
332d126bd7 | ||
|
|
0c66bf2695 | ||
|
|
4d6d07c98b | ||
|
|
8f7d4bfa10 | ||
|
|
7b3f39001f | ||
|
|
b9630809a0 | ||
|
|
ce3244da5e | ||
|
|
4067297d2a | ||
|
|
03c11fa181 | ||
|
|
3676e78eb9 | ||
|
|
1e08c4486f | ||
|
|
fd8bb60daa | ||
|
|
557d56ffc5 | ||
|
|
30f76a2349 | ||
|
|
cf0fa5e22e | ||
|
|
f16becbd82 | ||
|
|
4855450ddc | ||
|
|
0733aedce5 | ||
|
|
399ad14d9b | ||
|
|
7881ea3c5c | ||
|
|
7e9de622da | ||
|
|
c6655078f2 | ||
|
|
b86cef9499 | ||
|
|
5375ab6e97 | ||
|
|
75920a6473 | ||
|
|
f474e76866 | ||
|
|
d0ae27c4ce | ||
|
|
ab191dded6 | ||
|
|
950b571a9f | ||
|
|
7a153ca69a | ||
|
|
effd8946de | ||
|
|
ae3ad3745c | ||
|
|
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@5298d94fb55a4f185c602eeac5de1b553882abe2 # v1.6.4
|
||||||
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@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.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
|
||||||
|
|||||||
139
CHANGELOG.md
139
CHANGELOG.md
@@ -1,22 +1,69 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [7.3.2]
|
||||||
|
|
||||||
|
- Prevent users from starring/tagging entries that are not theirs and subsequently reading them (GHSA-prfv-88mm-5gpg)
|
||||||
|
|
||||||
|
## [7.3.1]
|
||||||
|
|
||||||
|
- Prevent Host header injection attacks on the password recovery endpoint. A new setting
|
||||||
|
`commafeed.password-recovery-public-base-url` has been added to specify the base URL to use in password recovery
|
||||||
|
(GHSA-hp8h-jqfm-v7x5)
|
||||||
|
emails. This setting is only required when the password recovery feature is enabled, which is not the default.
|
||||||
|
|
||||||
|
## [7.3.0]
|
||||||
|
|
||||||
|
- Add support for the Google Reader API for native mobile apps that don't support the Fever API
|
||||||
|
- The profile menu now works again on mobile when action buttons are at the bottom of the screen
|
||||||
|
- More SSRF protection regarding IPv6 (GHSA-q5qw-345w-55xg)
|
||||||
|
- Changed the default value of `blockLocalAddresses` to make CommaFeed more secure out-of-the-box. See the "Access to
|
||||||
|
local address blocked" section of the README if you subscribe to feeds that are only available on your local network.
|
||||||
|
|
||||||
|
## [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
|
||||||
|
(GHSA-44pq-9929-f8mq)
|
||||||
|
|
||||||
|
## [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 (GHSA-hgrr-mjfp-gmr6)
|
||||||
|
- Prevent DDOS attacks by filtering OPML files during imports (GHSA-83jp-rww3-57rr)
|
||||||
|
|
||||||
## [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)
|
||||||
- The feed refresh engine is now a little bit more performant (#2089)
|
- The feed refresh engine is now a little bit more performant (#2089)
|
||||||
- On shutdown, give the feed refresh engine some time to finish refreshing feeds before killing it. This is controlled by the new `commafeed.shutdown-timeout` setting, which defaults to 2 seconds
|
- On shutdown, give the feed refresh engine some time to finish refreshing feeds before killing it. This is controlled
|
||||||
|
by the new `commafeed.shutdown-timeout` setting, which defaults to 2 seconds
|
||||||
|
|
||||||
## [7.0.0]
|
## [7.0.0]
|
||||||
|
|
||||||
- Replaced the JEXL filter expression for marking feed entries as read automatically with a user-friendly visual query builder. Expressions are now evaluated with Common Expression Language, which is safer than JEXL and sanboxed by default.
|
- Replaced the JEXL filter expression for marking feed entries as read automatically with a user-friendly visual query
|
||||||
- Added a per-feed setting for sending push notifications to ntfy, Gotify or Pushover when new feed entries are discovered (#1610)
|
builder. Expressions are now evaluated with Common Expression Language, which is safer than JEXL and sanboxed by
|
||||||
|
default.
|
||||||
|
- Added a per-feed setting for sending push notifications to ntfy, Gotify or Pushover when new feed entries are
|
||||||
|
discovered (#1610)
|
||||||
- Added a per-feed setting for marking entries as read after a number of days (#2041)
|
- Added a per-feed setting for marking entries as read after a number of days (#2041)
|
||||||
- The default value of `commafeed.http-client.block-local-addresses` is now false, allowing users to subscribe to feeds only available on their local network. This may be a security risk (SSRF) if your instance is accessible by untrusted users, so you may want to set it to true if you host a public instance of CommaFeed with user registeration enabled.
|
- The default value of `commafeed.http-client.block-local-addresses` is now false, allowing users to subscribe to feeds
|
||||||
- When `commafeed.http-client.block-local-addresses` is enabled, SSRF is now also mitigated by blocking public websites redirecting to local ones.
|
only available on their local network. This may be a security risk (SSRF) if your instance is accessible by untrusted
|
||||||
|
users, so you may want to set it to true if you host a public instance of CommaFeed with user registeration enabled.
|
||||||
|
- When `commafeed.http-client.block-local-addresses` is enabled, SSRF is now also mitigated by blocking public websites
|
||||||
|
redirecting to local ones.
|
||||||
|
|
||||||
## [6.2.0]
|
## [6.2.0]
|
||||||
|
|
||||||
- Starred entries are no longer deleted after a certain amount of time, they are now kept indefinitely. The new `commafeed.database.cleanup.keep-starred-entries` setting can be disabled to restore the previous behavior if you want to keep deleting starred entries during normal entries cleanup (#1581)
|
- Starred entries are no longer deleted after a certain amount of time, they are now kept indefinitely. The new
|
||||||
|
`commafeed.database.cleanup.keep-starred-entries` setting can be disabled to restore the previous behavior if you want
|
||||||
|
to keep deleting starred entries during normal entries cleanup (#1581)
|
||||||
|
|
||||||
## [6.1.1]
|
## [6.1.1]
|
||||||
|
|
||||||
@@ -24,16 +71,21 @@
|
|||||||
|
|
||||||
## [6.1.0]
|
## [6.1.0]
|
||||||
|
|
||||||
- When clicking on the password reset link, a random password is no longer generated automatically. The user is now redirected to a page where they can set their own password (#2023)
|
- When clicking on the password reset link, a random password is no longer generated automatically. The user is now
|
||||||
|
redirected to a page where they can set their own password (#2023)
|
||||||
- Use browser preferred language instead of English when using CommaFeed for the first time (#2018)
|
- Use browser preferred language instead of English when using CommaFeed for the first time (#2018)
|
||||||
- The profile menu is now closed when scrolling the page (#2019)
|
- The profile menu is now closed when scrolling the page (#2019)
|
||||||
- The "disable pull to refresh" feature is now disabled by default (#2030)
|
- The "disable pull to refresh" feature is now disabled by default (#2030)
|
||||||
|
|
||||||
## [6.0.0]
|
## [6.0.0]
|
||||||
|
|
||||||
- When booting CommaFeed for the first time, the default "admin" account is no longer created automatically. A setup wizard will guide you through the creation of an admin account
|
- When booting CommaFeed for the first time, the default "admin" account is no longer created automatically. A setup
|
||||||
- Default password complexity requirements have been lowered for local network deployments, where strict password rules are often unnecessary. The `commafeed.users.strict-password-policy` setting has been replaced by `commafeed.users.minimum-password-length` with a default value of `4` (#1916)
|
wizard will guide you through the creation of an admin account
|
||||||
- Email addresses are no longer required when creating users and when they update their profile. The `commafeed.users.email-address-required` setting has been added to restore the previous behavior (#1914)
|
- Default password complexity requirements have been lowered for local network deployments, where strict password rules
|
||||||
|
are often unnecessary. The `commafeed.users.strict-password-policy` setting has been replaced by
|
||||||
|
`commafeed.users.minimum-password-length` with a default value of `4` (#1916)
|
||||||
|
- Email addresses are no longer required when creating users and when they update their profile. The
|
||||||
|
`commafeed.users.email-address-required` setting has been added to restore the previous behavior (#1914)
|
||||||
- Java 25+ is now required to build and run CommaFeed
|
- Java 25+ is now required to build and run CommaFeed
|
||||||
|
|
||||||
## [5.12.1]
|
## [5.12.1]
|
||||||
@@ -63,15 +115,18 @@
|
|||||||
|
|
||||||
## [5.10.0]
|
## [5.10.0]
|
||||||
|
|
||||||
- Add an indicator next to each feed's unread count in the tree to show when new entries are discovered while the app is open (#1762)
|
- Add an indicator next to each feed's unread count in the tree to show when new entries are discovered while the app is
|
||||||
|
open (#1762)
|
||||||
- Feeds with uppercase HTTP:// or HTTPS:// URLs are now correctly handled again
|
- Feeds with uppercase HTTP:// or HTTPS:// URLs are now correctly handled again
|
||||||
- The aarch64 native executable now also works on the Raspberry Pi 5 (#1795)
|
- The aarch64 native executable now also works on the Raspberry Pi 5 (#1795)
|
||||||
- Improve general performance of the UI by reducing the number of re-renders, especially when a lot of entries are displayed (#1087)
|
- Improve general performance of the UI by reducing the number of re-renders, especially when a lot of entries are
|
||||||
|
displayed (#1087)
|
||||||
|
|
||||||
## [5.9.0]
|
## [5.9.0]
|
||||||
|
|
||||||
- A lot of CSS classes have been added to the elements of the application to ease custom CSS rules (#1757)
|
- A lot of CSS classes have been added to the elements of the application to ease custom CSS rules (#1757)
|
||||||
- Added a link in the README to the [documentation](https://athou.github.io/commafeed/documentation/custom-css/) of the new CSS classes
|
- Added a link in the README to the [documentation](https://athou.github.io/commafeed/documentation/custom-css/) of the
|
||||||
|
new CSS classes
|
||||||
- Static resources are now cached for much longer (#1782)
|
- Static resources are now cached for much longer (#1782)
|
||||||
|
|
||||||
## [5.8.0]
|
## [5.8.0]
|
||||||
@@ -80,7 +135,8 @@
|
|||||||
- A font size slider is now available to change the size of the text of feed entries (#1462)
|
- A font size slider is now available to change the size of the text of feed entries (#1462)
|
||||||
- The "mark all as read" confirmation setting now also applies to the "shift+a" keyboard shortcut (#1744)
|
- The "mark all as read" confirmation setting now also applies to the "shift+a" keyboard shortcut (#1744)
|
||||||
- CommaFeed wil try to match the language of the browser before defaulting to english (#1767)
|
- CommaFeed wil try to match the language of the browser before defaulting to english (#1767)
|
||||||
- The default value for the number of entries to keep above the selected entry when scrolling is now 1 instead of 0 to match what other feed readers do
|
- The default value for the number of entries to keep above the selected entry when scrolling is now 1 instead of 0 to
|
||||||
|
match what other feed readers do
|
||||||
|
|
||||||
## [5.7.0]
|
## [5.7.0]
|
||||||
|
|
||||||
@@ -99,14 +155,22 @@
|
|||||||
|
|
||||||
## [5.6.0]
|
## [5.6.0]
|
||||||
|
|
||||||
- To better respect the bandwidth of feed owners, the default value of `commafeed.feed-refresh.interval-empirical` is now true. This means feeds no longer refresh exactly every 5 minutes (the default value of `commafeed.feed-refresh.interval`) but between 5 minutes and 4 hours (the default value of the new `commafeed.feed-refresh.max-interval` setting). The interval is calculated based on feed activity, so highly active feeds refresh more often (#1677)
|
- To better respect the bandwidth of feed owners, the default value of `commafeed.feed-refresh.interval-empirical` is
|
||||||
|
now true. This means feeds no longer refresh exactly every 5 minutes (the default value of
|
||||||
|
`commafeed.feed-refresh.interval`) but between 5 minutes and 4 hours (the default value of the new
|
||||||
|
`commafeed.feed-refresh.max-interval` setting). The interval is calculated based on feed activity, so highly active
|
||||||
|
feeds refresh more often (#1677)
|
||||||
- Many previously hardcoded values used in feed refresh interval calculation are now exposed as settings (#1677)
|
- Many previously hardcoded values used in feed refresh interval calculation are now exposed as settings (#1677)
|
||||||
- Access to local addresses is now blocked to mitigate server-side request forgery (SSRF) attacks, which could potentially expose internal resources. You might want to disable the new `commafeed.http-client.block-local-addresses` setting if you subscribe to feeds only available on your local network and you trust all your users
|
- Access to local addresses is now blocked to mitigate server-side request forgery (SSRF) attacks, which could
|
||||||
- If a feed responds with a "429 - Too many requests" response, a backoff mechanism is triggered when the response does not contain a "Retry-After" header
|
potentially expose internal resources. You might want to disable the new `commafeed.http-client.block-local-addresses`
|
||||||
|
setting if you subscribe to feeds only available on your local network and you trust all your users
|
||||||
|
- If a feed responds with a "429 - Too many requests" response, a backoff mechanism is triggered when the response does
|
||||||
|
not contain a "Retry-After" header
|
||||||
|
|
||||||
## [5.5.0]
|
## [5.5.0]
|
||||||
|
|
||||||
- CommaFeed now honors the Retry-After response header and will not try to refresh a feed sooner than the value of this header
|
- CommaFeed now honors the Retry-After response header and will not try to refresh a feed sooner than the value of this
|
||||||
|
header
|
||||||
- Audio enclosures (e.g. podcasts) now fill available entry width
|
- Audio enclosures (e.g. podcasts) now fill available entry width
|
||||||
- Fix an issue with some labels not correctly internationalized
|
- Fix an issue with some labels not correctly internationalized
|
||||||
|
|
||||||
@@ -123,8 +187,10 @@
|
|||||||
## [5.3.5]
|
## [5.3.5]
|
||||||
|
|
||||||
- Fixed an issue with the aspect ratio of images of some feeds (#1595)
|
- Fixed an issue with the aspect ratio of images of some feeds (#1595)
|
||||||
- CommaFeed now honors the Cache-Control response header and will not try to refresh a feed sooner than its max-age property (#1615)
|
- CommaFeed now honors the Cache-Control response header and will not try to refresh a feed sooner than its max-age
|
||||||
- Added support for compilation with JDK 23+. If you're building CommaFeed from sources with a JDK 17 or 21, you may need to update it to the most recent patch version to support `-proc:full` (#1618)
|
property (#1615)
|
||||||
|
- Added support for compilation with JDK 23+. If you're building CommaFeed from sources with a JDK 17 or 21, you may
|
||||||
|
need to update it to the most recent patch version to support `-proc:full` (#1618)
|
||||||
|
|
||||||
## [5.3.4]
|
## [5.3.4]
|
||||||
|
|
||||||
@@ -151,19 +217,22 @@
|
|||||||
|
|
||||||
- Added an option to keep a number of entries above the selected entry when scrolling
|
- Added an option to keep a number of entries above the selected entry when scrolling
|
||||||
- Added a cache to the HTTP client to reduce the number of requests made to feeds when subscribing (#1431)
|
- Added a cache to the HTTP client to reduce the number of requests made to feeds when subscribing (#1431)
|
||||||
- Feeds are no longer refreshed between the moment its last user unsubscribes and the moment the feed is cleaned up (every hour)
|
- Feeds are no longer refreshed between the moment its last user unsubscribes and the moment the feed is cleaned up
|
||||||
|
(every hour)
|
||||||
- Fixed an issue that could cause entries to not correctly load when using keyboard navigation (#1557)
|
- Fixed an issue that could cause entries to not correctly load when using keyboard navigation (#1557)
|
||||||
|
|
||||||
## [5.1.1]
|
## [5.1.1]
|
||||||
|
|
||||||
- Fixed database migration issue when upgrading from 5.0.0 to 5.1.0 on MariaDB (#1544)
|
- Fixed database migration issue when upgrading from 5.0.0 to 5.1.0 on MariaDB (#1544)
|
||||||
- When feeds without unread entries are hidden from the tree, the feed is displayed in the tree until another one is selected (#1543)
|
- When feeds without unread entries are hidden from the tree, the feed is displayed in the tree until another one is
|
||||||
|
selected (#1543)
|
||||||
|
|
||||||
## [5.1.0]
|
## [5.1.0]
|
||||||
|
|
||||||
- Added a setting for showing/hiding unread count in the browser's tab title/favicon (#1518)
|
- Added a setting for showing/hiding unread count in the browser's tab title/favicon (#1518)
|
||||||
- Fixed an issue that could prevent the app from starting on some systems (#1532)
|
- Fixed an issue that could prevent the app from starting on some systems (#1532)
|
||||||
- Added a cache busting filter for the webapp index.html and openapi documentation to make sure they are always up to date
|
- Added a cache busting filter for the webapp index.html and openapi documentation to make sure they are always up to
|
||||||
|
date
|
||||||
- Reduced database cleanup log verbosity
|
- Reduced database cleanup log verbosity
|
||||||
|
|
||||||
## [5.0.2]
|
## [5.0.2]
|
||||||
@@ -178,9 +247,9 @@
|
|||||||
## [5.0.0]
|
## [5.0.0]
|
||||||
|
|
||||||
CommaFeed is now powered by Quarkus instead of Dropwizard. Read the rationale behind this change in
|
CommaFeed is now powered by Quarkus instead of Dropwizard. Read the rationale behind this change in
|
||||||
the [announcement](https://github.com/Athou/commafeed/discussions/1517).
|
the [announcement](https://github.com/Athou/commafeed/discussions/1517). The gist of it is that CommaFeed can now be
|
||||||
The gist of it is that CommaFeed can now be compiled to a native binary, resulting in blazing fast startup times (around
|
compiled to a native binary, resulting in blazing fast startup times (around 0.3s) and very low memory footprint (<
|
||||||
0.3s) and very low memory footprint (< 50M).
|
50M).
|
||||||
|
|
||||||
- CommaFeed now has a different package for each supported database.
|
- CommaFeed now has a different package for each supported database.
|
||||||
- If you are deploying CommaFeed with a precompiled package, please
|
- If you are deploying CommaFeed with a precompiled package, please
|
||||||
@@ -236,8 +305,8 @@ The gist of it is that CommaFeed can now be compiled to a native binary, resulti
|
|||||||
- add a button in the entry headers to open links in a new tab (#1333)
|
- add a button in the entry headers to open links in a new tab (#1333)
|
||||||
- add two options in the settings to toggle those buttons
|
- add two options in the settings to toggle those buttons
|
||||||
- accept .opml file extension when importing and export with the .opml extension
|
- accept .opml file extension when importing and export with the .opml extension
|
||||||
- the "mark as read" option is no longer shown in the context menu for entries that are too old to be marked as read (
|
- the "mark as read" option is no longer shown in the context menu for entries that are too old to be marked as read
|
||||||
older than `keepStatusDays`) (#1303)
|
(older than `keepStatusDays`) (#1303)
|
||||||
|
|
||||||
## [4.3.3]
|
## [4.3.3]
|
||||||
|
|
||||||
@@ -281,9 +350,8 @@ The gist of it is that CommaFeed can now be compiled to a native binary, resulti
|
|||||||
- it is now possible to open the sidebar on mobile by swiping to the right (#1098)
|
- it is now possible to open the sidebar on mobile by swiping to the right (#1098)
|
||||||
- swiping to mark entries as read/unread changed from swiping right to left because swiping right now opens the sidebar
|
- swiping to mark entries as read/unread changed from swiping right to left because swiping right now opens the sidebar
|
||||||
- the full hierarchy of categories are now displayed in the category dropdown (#1045)
|
- the full hierarchy of categories are now displayed in the category dropdown (#1045)
|
||||||
- added a setting `maxEntriesAgeDays` to delete old entries based on their age during database cleanup.
|
- added a setting `maxEntriesAgeDays` to delete old entries based on their age during database cleanup. The setting is
|
||||||
The setting is disabled by default for existing installations, except for the docker image where it is enabled and set
|
disabled by default for existing installations, except for the docker image where it is enabled and set to 365 days
|
||||||
to 365 days
|
|
||||||
- if user registrations are disabled on your instance which is the default behavior, users are redirected on the login
|
- if user registrations are disabled on your instance which is the default behavior, users are redirected on the login
|
||||||
page instead of the welcome page when not logged in (#1185)
|
page instead of the welcome page when not logged in (#1185)
|
||||||
- the sidebar resizer is no longer shown in the middle of the screen on mobile
|
- the sidebar resizer is no longer shown in the middle of the screen on mobile
|
||||||
@@ -309,8 +377,8 @@ The gist of it is that CommaFeed can now be compiled to a native binary, resulti
|
|||||||
request, reducing CPU usage
|
request, reducing CPU usage
|
||||||
- updated UI library Mantine to 7.0, improving performance
|
- updated UI library Mantine to 7.0, improving performance
|
||||||
- the h2 embedded database is now compacted on shutdown to reclaim unused space
|
- the h2 embedded database is now compacted on shutdown to reclaim unused space
|
||||||
- the admin connector on port 8084 is now disabled in config.yml.example. Disabling it in your config.yml is
|
- the admin connector on port 8084 is now disabled in config.yml.example. Disabling it in your config.yml is recommended
|
||||||
recommended (see https://github.com/Athou/commafeed/commit/929df60f09cce56020b0962ab111cd8349b271b0)
|
(see https://github.com/Athou/commafeed/commit/929df60f09cce56020b0962ab111cd8349b271b0)
|
||||||
- migrated documentation from swagger 2 to openapi 3
|
- migrated documentation from swagger 2 to openapi 3
|
||||||
- added a GET method to the fever api to indicate that the endpoint is working correctly when accessed from a browser
|
- added a GET method to the fever api to indicate that the endpoint is working correctly when accessed from a browser
|
||||||
- the websocket connection can now be disabled, the websocket ping interval and the tree reload interval can now be
|
- the websocket connection can now be disabled, the websocket ping interval and the tree reload interval can now be
|
||||||
@@ -552,7 +620,6 @@ The gist of it is that CommaFeed can now be compiled to a native binary, resulti
|
|||||||
## [2.0.0]
|
## [2.0.0]
|
||||||
|
|
||||||
- The backend has been completely rewritten using Dropwizard instead of TomEE, resulting in a lot less memory
|
- The backend has been completely rewritten using Dropwizard instead of TomEE, resulting in a lot less memory
|
||||||
consumption and better overall performances.
|
consumption and better overall performances. See the README on how to build CommaFeed from now on.
|
||||||
See the README on how to build CommaFeed from now on.
|
|
||||||
- CommaFeed should no longer fetch the same feed multiple times in a row
|
- CommaFeed should no longer fetch the same feed multiple times in a row
|
||||||
- Users can use their username or email to log in
|
- Users can use their username or email to log in
|
||||||
|
|||||||
14
README.md
14
README.md
@@ -15,7 +15,7 @@ Google Reader inspired self-hosted RSS reader, based on Quarkus and React/TypeSc
|
|||||||
- Supports thousands of users and millions of feeds
|
- Supports thousands of users and millions of feeds
|
||||||
- OPML import/export
|
- OPML import/export
|
||||||
- REST API
|
- REST API
|
||||||
- Fever-compatible API for native mobile apps
|
- Fever and Google Reader API for native mobile apps
|
||||||
- Can automatically mark articles as read based on user-defined rules
|
- Can automatically mark articles as read based on user-defined rules
|
||||||
- Push notifications when new articles are published
|
- Push notifications when new articles are published
|
||||||
- Highly customizable with [custom CSS](https://athou.github.io/commafeed/documentation/custom-css) and JavaScript
|
- Highly customizable with [custom CSS](https://athou.github.io/commafeed/documentation/custom-css) and JavaScript
|
||||||
@@ -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:
|
||||||
@@ -159,6 +159,14 @@ named [Semeru](https://developer.ibm.com/languages/java/semeru-runtimes/download
|
|||||||
This is the JVM used in
|
This is the JVM used in
|
||||||
the [Docker image](https://github.com/Athou/commafeed/blob/master/commafeed-server/src/main/docker/Dockerfile.jvm).
|
the [Docker image](https://github.com/Athou/commafeed/blob/master/commafeed-server/src/main/docker/Dockerfile.jvm).
|
||||||
|
|
||||||
|
## FAQ
|
||||||
|
|
||||||
|
### Getting "Access to local address blocked" when adding a feed
|
||||||
|
|
||||||
|
CommaFeed blocks access to local resources by default to prevent [SSRF](https://en.wikipedia.org/wiki/Server-side_request_forgery) attacks.
|
||||||
|
If you want to subscribe to feeds that are only available on your local network, you can disable this security measure by setting the `commafeed.http-client.block-local-addresses` variable to `false`.
|
||||||
|
Do this only if you trust all users of your CommaFeed instance not to access private resources.
|
||||||
|
|
||||||
## Translation
|
## Translation
|
||||||
|
|
||||||
Files for internationalization are
|
Files for internationalization are
|
||||||
|
|||||||
@@ -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.9/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"],
|
|
||||||
}
|
|
||||||
4274
commafeed-client/package-lock.json
generated
4274
commafeed-client/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -12,75 +12,74 @@
|
|||||||
"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.1",
|
||||||
"@mantine/form": "^9.0.1",
|
"@mantine/dates": "9.5.1",
|
||||||
"@mantine/hooks": "^9.0.1",
|
"@mantine/form": "9.5.1",
|
||||||
"@mantine/modals": "^9.0.1",
|
"@mantine/hooks": "9.5.1",
|
||||||
"@mantine/notifications": "^9.0.1",
|
"@mantine/modals": "9.5.1",
|
||||||
"@mantine/spotlight": "^9.0.1",
|
"@mantine/notifications": "9.5.1",
|
||||||
"@monaco-editor/react": "^4.7.0",
|
"@mantine/spotlight": "9.5.1",
|
||||||
"@react-querybuilder/mantine": "^8.14.4",
|
"@monaco-editor/react": "4.7.0",
|
||||||
"@reduxjs/toolkit": "^2.11.2",
|
"@react-querybuilder/mantine": "8.23.0",
|
||||||
"@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.23",
|
||||||
"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.23.0",
|
||||||
"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",
|
"@babel/types": "^8.0.4",
|
||||||
"@lingui/babel-plugin-lingui-macro": "^5.9.5",
|
"@biomejs/biome": "2.5.9",
|
||||||
"@lingui/cli": "^5.9.5",
|
"@lingui/babel-plugin-lingui-macro": "6.6.0",
|
||||||
"@lingui/vite-plugin": "^5.9.5",
|
"@lingui/cli": "6.6.0",
|
||||||
"@testing-library/jest-dom": "^6.9.1",
|
"@lingui/vite-plugin": "6.6.0",
|
||||||
"@testing-library/react": "^16.3.2",
|
"@testing-library/jest-dom": "7.0.1",
|
||||||
"@testing-library/user-event": "^14.6.1",
|
"@testing-library/react": "16.3.2",
|
||||||
"@types/mousetrap": "^1.6.15",
|
"@testing-library/user-event": "14.6.5",
|
||||||
"@types/react": "^19.2.14",
|
"@types/mousetrap": "1.6.15",
|
||||||
"@types/react-dom": "^19.2.3",
|
"@types/react": "19.2.18",
|
||||||
"@types/react-infinite-scroller": "^1.2.5",
|
"@types/react-dom": "19.2.4",
|
||||||
"@types/throttle-debounce": "^5.0.2",
|
"@types/react-infinite-scroller": "1.2.5",
|
||||||
"@types/tinycon": "^0.6.7",
|
"@types/throttle-debounce": "5.0.2",
|
||||||
"@vitejs/plugin-react": "^6.0.1",
|
"@types/tinycon": "0.6.7",
|
||||||
|
"@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.1",
|
||||||
"typescript": "^6.0.2",
|
"vite-plugin-checker": "0.14.5",
|
||||||
"vite": "^8.0.8",
|
"vitest": "4.1.11",
|
||||||
"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.3.2</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.19.0</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>
|
||||||
|
|||||||
@@ -1,62 +1,40 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<svg
|
<svg
|
||||||
height="393.84613"
|
height="393.84613"
|
||||||
width="393.84613"
|
width="393.84613"
|
||||||
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"
|
<defs
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
id="defs3" />
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
<rect
|
||||||
xmlns:svg="http://www.w3.org/2000/svg">
|
fill="#f88a14"
|
||||||
<defs
|
rx="0.53846151"
|
||||||
id="defs3" />
|
ry="0.53846151"
|
||||||
<sodipodi:namedview
|
height="5.0480766"
|
||||||
id="namedview3"
|
width="5.0480766"
|
||||||
pagecolor="#ffffff"
|
id="rect1"
|
||||||
bordercolor="#000000"
|
x="0"
|
||||||
borderopacity="0.25"
|
y="0"
|
||||||
inkscape:showpageshadow="2"
|
style="stroke-width:0.769231" />
|
||||||
inkscape:pageopacity="0.0"
|
<path
|
||||||
inkscape:pagecheckerboard="0"
|
d="m 1.3450904,0.64548657 c 2.9002,0 2.9002,2.91010003 2.9002,2.91010003"
|
||||||
inkscape:deskcolor="#d1d1d1"
|
fill="none"
|
||||||
inkscape:zoom="1.21875"
|
stroke="#ffffff"
|
||||||
inkscape:cx="207.17949"
|
stroke-linecap="round"
|
||||||
inkscape:cy="187.07692"
|
stroke-width="0.78125"
|
||||||
inkscape:window-width="1440"
|
id="path1" />
|
||||||
inkscape:window-height="855"
|
<path
|
||||||
inkscape:window-x="0"
|
d="m 1.3377904,1.9915866 c 1.5705,-0.00908 1.5705,1.5639 1.5705,1.5639"
|
||||||
inkscape:window-y="0"
|
fill="none"
|
||||||
inkscape:window-maximized="1"
|
stroke="#ffffff"
|
||||||
inkscape:current-layer="svg3" />
|
stroke-linecap="round"
|
||||||
<rect
|
stroke-width="0.78125"
|
||||||
fill="#f88a14"
|
id="path2" />
|
||||||
rx="0.53846151"
|
<path
|
||||||
ry="0.53846151"
|
d="m 2.0192904,3.5227866 c 0,0.23366 -0.10712,0.47418 -0.24663,0.6537 -0.1814,0.2333 -0.5705,0.5618 -0.6913,0.5653 0.0402,-0.0662 0.263,-0.5654 0.2563,-0.5654 -0.36423004,0 -0.65950004,-0.29265 -0.65950004,-0.65365 0,-0.361 0.29527,-0.65365 0.65950004,-0.65365 0.36423,0 0.68159,0.29265 0.68159,0.65365 z"
|
||||||
height="5.0480766"
|
fill="#ffffff"
|
||||||
width="5.0480766"
|
id="path3" />
|
||||||
id="rect1"
|
|
||||||
x="0"
|
|
||||||
y="0"
|
|
||||||
style="stroke-width:0.769231" />
|
|
||||||
<path
|
|
||||||
d="m 1.3450904,0.64548657 c 2.9002,0 2.9002,2.91010003 2.9002,2.91010003"
|
|
||||||
fill="none"
|
|
||||||
stroke="#ffffff"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-width="0.78125"
|
|
||||||
id="path1" />
|
|
||||||
<path
|
|
||||||
d="m 1.3377904,1.9915866 c 1.5705,-0.00908 1.5705,1.5639 1.5705,1.5639"
|
|
||||||
fill="none"
|
|
||||||
stroke="#ffffff"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-width="0.78125"
|
|
||||||
id="path2" />
|
|
||||||
<path
|
|
||||||
d="m 2.0192904,3.5227866 c 0,0.23366 -0.10712,0.47418 -0.24663,0.6537 -0.1814,0.2333 -0.5705,0.5618 -0.6913,0.5653 0.0402,-0.0662 0.263,-0.5654 0.2563,-0.5654 -0.36423004,0 -0.65950004,-0.29265 -0.65950004,-0.65365 0,-0.361 0.29527,-0.65365 0.65950004,-0.65365 0.36423,0 0.68159,0.29265 0.68159,0.65365 z"
|
|
||||||
fill="#ffffff"
|
|
||||||
id="path3" />
|
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
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 />
|
||||||
|
|||||||
36
commafeed-client/src/app/client.test.ts
Normal file
36
commafeed-client/src/app/client.test.ts
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import { i18n } from "@lingui/core"
|
||||||
|
import type { AxiosError } from "axios"
|
||||||
|
import { afterEach, describe, expect, it, vi } from "vitest"
|
||||||
|
import { errorToStrings } from "./client"
|
||||||
|
|
||||||
|
const axiosError = (status: number, data: unknown) =>
|
||||||
|
({
|
||||||
|
isAxiosError: true,
|
||||||
|
response: { status, data },
|
||||||
|
}) as AxiosError
|
||||||
|
|
||||||
|
describe("errorToStrings", () => {
|
||||||
|
afterEach(() => vi.restoreAllMocks())
|
||||||
|
|
||||||
|
it("translates known application error types", () => {
|
||||||
|
vi.spyOn(i18n, "_").mockReturnValue("Translated authentication error")
|
||||||
|
const error = axiosError(401, {
|
||||||
|
type: "WRONG_USERNAME_OR_PASSWORD",
|
||||||
|
message: "wrong username or password",
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(errorToStrings(error)).toEqual(["Translated authentication error"])
|
||||||
|
})
|
||||||
|
|
||||||
|
it("preserves backend messages for unexpected errors", () => {
|
||||||
|
const error = axiosError(500, { message: "unexpected error" })
|
||||||
|
|
||||||
|
expect(errorToStrings(error)).toEqual(["unexpected error"])
|
||||||
|
})
|
||||||
|
|
||||||
|
it("preserves backend messages for unknown application error types", () => {
|
||||||
|
const error = axiosError(400, { type: "UNKNOWN_ERROR", message: "unknown error" })
|
||||||
|
|
||||||
|
expect(errorToStrings(error)).toEqual(["unknown error"])
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { i18n, type MessageDescriptor } from "@lingui/core"
|
||||||
|
import { msg } from "@lingui/core/macro"
|
||||||
import axios, { type AxiosError } from "axios"
|
import axios, { type AxiosError } from "axios"
|
||||||
import type {
|
import type {
|
||||||
AddCategoryRequest,
|
AddCategoryRequest,
|
||||||
@@ -6,6 +8,8 @@ import type {
|
|||||||
Category,
|
Category,
|
||||||
CategoryModificationRequest,
|
CategoryModificationRequest,
|
||||||
CollapseRequest,
|
CollapseRequest,
|
||||||
|
CommaFeedApplicationError,
|
||||||
|
CommaFeedExceptionType,
|
||||||
Entries,
|
Entries,
|
||||||
FeedInfo,
|
FeedInfo,
|
||||||
FeedInfoRequest,
|
FeedInfoRequest,
|
||||||
@@ -31,6 +35,10 @@ import type {
|
|||||||
UserModel,
|
UserModel,
|
||||||
} from "./types"
|
} from "./types"
|
||||||
|
|
||||||
|
const applicationErrorMessages = {
|
||||||
|
WRONG_USERNAME_OR_PASSWORD: msg`Wrong username or password`,
|
||||||
|
} satisfies Record<CommaFeedExceptionType, MessageDescriptor>
|
||||||
|
|
||||||
const axiosInstance = axios.create({ baseURL: "./rest", withCredentials: true })
|
const axiosInstance = axios.create({ baseURL: "./rest", withCredentials: true })
|
||||||
axiosInstance.interceptors.response.use(
|
axiosInstance.interceptors.response.use(
|
||||||
response => response,
|
response => response,
|
||||||
@@ -128,14 +136,25 @@ export const errorToStrings = (err: unknown) => {
|
|||||||
let strings: string[] = []
|
let strings: string[] = []
|
||||||
|
|
||||||
if (axios.isAxiosError(err) && err.response) {
|
if (axios.isAxiosError(err) && err.response) {
|
||||||
if (typeof err.response.data === "string") strings.push(err.response.data)
|
if (isCommaFeedApplicationError(err)) {
|
||||||
if (isMessageError(err)) strings.push(err.response.data.message)
|
strings.push(i18n._(applicationErrorMessages[err.response.data.type]))
|
||||||
if (isMessageArrayError(err)) strings = [...strings, ...err.response.data.errors]
|
} else {
|
||||||
|
if (typeof err.response.data === "string") strings.push(err.response.data)
|
||||||
|
if (isMessageError(err)) strings.push(err.response.data.message)
|
||||||
|
if (isMessageArrayError(err)) strings = [...strings, ...err.response.data.errors]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return strings
|
return strings
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isCommaFeedApplicationError(err: AxiosError): err is AxiosError<CommaFeedApplicationError> {
|
||||||
|
const data = err.response?.data
|
||||||
|
if (!data || typeof data !== "object" || !("type" in data)) return false
|
||||||
|
const type = data.type
|
||||||
|
return typeof type === "string" && Object.hasOwn(applicationErrorMessages, type)
|
||||||
|
}
|
||||||
|
|
||||||
function isMessageError(err: AxiosError): err is AxiosError<{ message: string }> {
|
function isMessageError(err: AxiosError): err is AxiosError<{ message: string }> {
|
||||||
return !!err.response && !!err.response.data && typeof err.response.data === "object" && "message" in err.response.data
|
return !!err.response && !!err.response.data && typeof err.response.data === "object" && "message" in err.response.data
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -166,7 +166,6 @@ export const starEntry = createAppAsyncThunk(
|
|||||||
(arg: { entry: Entry; starred: boolean }) => {
|
(arg: { entry: Entry; starred: boolean }) => {
|
||||||
client.entry.star({
|
client.entry.star({
|
||||||
id: arg.entry.id,
|
id: arg.entry.id,
|
||||||
feedId: +arg.entry.feedId,
|
|
||||||
starred: arg.starred,
|
starred: arg.starred,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
@@ -298,7 +297,6 @@ export interface LocalSettings {
|
|||||||
|
|
||||||
export interface StarRequest {
|
export interface StarRequest {
|
||||||
id: string
|
id: string
|
||||||
feedId: number
|
|
||||||
starred: boolean
|
starred: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -339,3 +337,10 @@ export interface AuthenticationError {
|
|||||||
message: string
|
message: string
|
||||||
allowRegistrations: boolean
|
allowRegistrations: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type CommaFeedExceptionType = "WRONG_USERNAME_OR_PASSWORD"
|
||||||
|
|
||||||
|
export interface CommaFeedApplicationError {
|
||||||
|
type: CommaFeedExceptionType
|
||||||
|
message: string
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
|
showNotification({
|
||||||
state.settings.readingOrder = action.meta.arg
|
message: t`Settings saved.`,
|
||||||
|
color: "green",
|
||||||
|
})
|
||||||
})
|
})
|
||||||
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({
|
|
||||||
message: t`Settings saved.`,
|
|
||||||
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,10 +1,11 @@
|
|||||||
<?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" />
|
||||||
<path d="m1.9688,2.875c1.5705-0.00908,1.5705,1.5639,1.5705,1.5639" fill="none" stroke="#FFF" stroke-linecap="round"
|
<path d="m1.9688,2.875c1.5705-0.00908,1.5705,1.5639,1.5705,1.5639" fill="none" stroke="#FFF" stroke-linecap="round"
|
||||||
stroke-width="0.78125" />
|
stroke-width="0.78125" />
|
||||||
<path d="m2.6503,4.4062c0,0.23366-0.10712,0.47418-0.24663,0.6537-0.1814,0.2333-0.5705,0.5618-0.6913,0.5653,0.0402-0.0662,0.263-0.5654,0.2563-0.5654-0.36423,0-0.6595-0.29265-0.6595-0.65365s0.29527-0.65365,0.6595-0.65365,0.68159,0.29265,0.68159,0.65365z"
|
<path d="m2.6503,4.4062c0,0.23366-0.10712,0.47418-0.24663,0.6537-0.1814,0.2333-0.5705,0.5618-0.6913,0.5653,0.0402-0.0662,0.263-0.5654,0.2563-0.5654-0.36423,0-0.6595-0.29265-0.6595-0.65365s0.29527-0.65365,0.6595-0.65365,0.68159,0.29265,0.68159,0.65365z"
|
||||||
fill="#FFF" />
|
fill="#FFF" />
|
||||||
</svg>
|
</svg>
|
||||||
|
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>
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ export function ProfileMenu(props: Readonly<ProfileMenuProps>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu position="bottom-end" closeOnItemClick={false} opened={opened} onChange={setOpened}>
|
<Menu position="bottom-end" closeOnItemClick={false} opened={opened} onChange={setOpened} preventPositionChangeWhenVisible={false}>
|
||||||
<Menu.Target>{props.control}</Menu.Target>
|
<Menu.Target>{props.control}</Menu.Target>
|
||||||
<Menu.Dropdown>
|
<Menu.Dropdown>
|
||||||
{profile && <Menu.Label>{profile.name}</Menu.Label>}
|
{profile && <Menu.Label>{profile.name}</Menu.Label>}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,8 +91,8 @@ export function ProfileSettings() {
|
|||||||
label={<Trans>API key</Trans>}
|
label={<Trans>API key</Trans>}
|
||||||
description={
|
description={
|
||||||
<Trans>
|
<Trans>
|
||||||
This is your API key. It can be used for some read-only API operations and grants access to the Fever API.
|
This is your API key. It can be used for some read-only API operations and grants access to the Fever API
|
||||||
Use the form at the bottom of the page to generate a new API key
|
and the Google Reader API. Use the form at the bottom of the page to generate a new API key
|
||||||
</Trans>
|
</Trans>
|
||||||
}
|
}
|
||||||
readOnly
|
readOnly
|
||||||
@@ -130,6 +130,22 @@ export function ProfileSettings() {
|
|||||||
</Box>
|
</Box>
|
||||||
</Input.Wrapper>
|
</Input.Wrapper>
|
||||||
|
|
||||||
|
<Input.Wrapper
|
||||||
|
label={<Trans>Google Reader API</Trans>}
|
||||||
|
description={
|
||||||
|
<Trans>
|
||||||
|
CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible
|
||||||
|
mobile client. Login with your username and your <u>API key</u>.
|
||||||
|
</Trans>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Box>
|
||||||
|
<Anchor href="rest/googlereader" target="_blank">
|
||||||
|
<Trans>Google Reader API URL</Trans>
|
||||||
|
</Anchor>
|
||||||
|
</Box>
|
||||||
|
</Input.Wrapper>
|
||||||
|
|
||||||
<Divider />
|
<Divider />
|
||||||
|
|
||||||
<PasswordInput
|
<PasswordInput
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -216,6 +210,10 @@ msgstr "إصدار إضافة متصفح CommaFeed هو {browserExtensionVersion
|
|||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
msgstr "CommaFeed متوافق مع Fever API. استخدم عنوان URL التالي في تطبيق الهاتف المتوافق مع Fever. قم بتسجيل الدخول باستخدام اسم المستخدم و <0>مفتاح API</0> الخاص بك."
|
msgstr "CommaFeed متوافق مع Fever API. استخدم عنوان URL التالي في تطبيق الهاتف المتوافق مع Fever. قم بتسجيل الدخول باستخدام اسم المستخدم و <0>مفتاح API</0> الخاص بك."
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
msgstr "CommaFeed متوافق مع Google Reader API. استخدم عنوان URL التالي في تطبيق الهاتف المتوافق مع Google Reader. قم بتسجيل الدخول باستخدام اسم المستخدم و <0>مفتاح API</0> الخاص بك."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
msgstr "CommaFeed التالي العنصر غير المقروء"
|
msgstr "CommaFeed التالي العنصر غير المقروء"
|
||||||
@@ -240,7 +238,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 +291,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 +338,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 +392,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"
|
||||||
@@ -466,6 +458,14 @@ msgstr "انتقل إلى وثائق API."
|
|||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "الأشياء الجيدة"
|
msgstr "الأشياء الجيدة"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API URL"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Grape"
|
msgid "Grape"
|
||||||
msgstr "عنبي"
|
msgstr "عنبي"
|
||||||
@@ -570,7 +570,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 +647,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 +655,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 +761,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 +787,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 +867,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 +875,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 +901,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 +913,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 +941,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 +989,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 +998,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 +1014,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 +1047,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 "الكلمات"
|
||||||
@@ -1095,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
|
|||||||
msgstr "تحتوي هذه الخلاصة على فلتر قديم لا يمكن تحريره ولا يتم تطبيقه. يرجى إعادة إنشاء الفلتر باستخدام محرر التعبيرات الجديد. كان تعبير الفلتر القديم هو: <0>{0}</0>"
|
msgstr "تحتوي هذه الخلاصة على فلتر قديم لا يمكن تحريره ولا يتم تطبيقه. يرجى إعادة إنشاء الفلتر باستخدام محرر التعبيرات الجديد. كان تعبير الفلتر القديم هو: <0>{0}</0>"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
msgstr "هذا هو مفتاح API الخاص بك. يمكن استخدامه لبعض عمليات API للقراءة فقط ويمنح الوصول إلى Fever API. استخدم النموذج الموجود في أسفل الصفحة لإنشاء مفتاح API جديد"
|
msgstr "هذا هو مفتاح API الخاص بك. يمكن استخدامه لبعض عمليات API للقراءة فقط ويمنح حق الوصول إلى Fever API و Google Reader API. استخدم النموذج الموجود أسفل الصفحة لإنشاء مفتاح API جديد"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
||||||
@@ -1136,7 +1118,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 +1130,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 "اسم المستخدم أو البريد الإلكتروني"
|
||||||
@@ -1170,6 +1150,10 @@ msgstr "موقع الكتروني"
|
|||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr "مرحباً! يبدو أن هذه هي المرة الأولى التي تقوم فيها بتشغيل CommaFeed. يرجى إنشاء حساب مسؤول للبدء."
|
msgstr "مرحباً! يبدو أن هذه هي المرة الأولى التي تقوم فيها بتشغيل CommaFeed. يرجى إنشاء حساب مسؤول للبدء."
|
||||||
|
|
||||||
|
#: src/app/client.ts
|
||||||
|
msgid "Wrong username or password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
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
|
||||||
@@ -216,6 +210,10 @@ msgstr "Versió de l'extensió del navegador CommaFeed {browserExtensionVersion}
|
|||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
msgstr "CommaFeed és compatible amb l'API Fever. Utilitzeu l'URL següent al vostre client mòbil compatible amb Fever. Inicieu sessió amb el vostre nom d'usuari i la vostra <0>clau API</0>."
|
msgstr "CommaFeed és compatible amb l'API Fever. Utilitzeu l'URL següent al vostre client mòbil compatible amb Fever. Inicieu sessió amb el vostre nom d'usuari i la vostra <0>clau API</0>."
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
msgstr "CommaFeed és compatible amb l'API de Google Reader. Utilitzeu l'URL següent al vostre client mòbil compatible amb Google Reader. Inicieu sessió amb el vostre nom d'usuari i la vostra <0>clau API</0>."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
msgstr "CommaFeed següent element no llegit"
|
msgstr "CommaFeed següent element no llegit"
|
||||||
@@ -240,7 +238,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 +291,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 +338,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 +392,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"
|
||||||
@@ -466,6 +458,14 @@ msgstr "Vés a la documentació de l'API."
|
|||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "Extres"
|
msgstr "Extres"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API URL"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Grape"
|
msgid "Grape"
|
||||||
msgstr "Raïm"
|
msgstr "Raïm"
|
||||||
@@ -570,7 +570,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 +647,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 +655,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 +761,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 +787,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 +867,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 +875,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 +901,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 +913,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 +941,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 +989,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 +998,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 +1014,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 +1047,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"
|
||||||
@@ -1095,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
|
|||||||
msgstr "Aquest feed té un filtre heretat que no es pot editar i no s'aplica. Torneu a crear el filtre amb el nou editor d'expressions. L'expressió del filtre heretat era: <0>{0}</0>"
|
msgstr "Aquest feed té un filtre heretat que no es pot editar i no s'aplica. Torneu a crear el filtre amb el nou editor d'expressions. L'expressió del filtre heretat era: <0>{0}</0>"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
msgstr "Aquesta és la vostra clau de l'API. Es pot utilitzar per a algunes operacions de l'API de només lectura i permet accedir a l'API Fever. Utilitzeu el formulari de la part inferior de la pàgina per generar una nova clau d'API."
|
msgstr "Aquesta és la vostra clau API. Es pot utilitzar per a algunes operacions de l'API de només lectura i dona accés a l'API Fever i a l'API de Google Reader. Utilitzeu el formulari a la part inferior de la pàgina per generar una nova clau API"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
||||||
@@ -1136,7 +1118,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 +1130,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"
|
||||||
@@ -1170,6 +1150,10 @@ msgstr "Lloc web"
|
|||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr "Benvingut! Sembla que aquesta és la primera vegada que executeu CommaFeed. Creeu un compte d'administrador per començar."
|
msgstr "Benvingut! Sembla que aquesta és la primera vegada que executeu CommaFeed. Creeu un compte d'administrador per començar."
|
||||||
|
|
||||||
|
#: src/app/client.ts
|
||||||
|
msgid "Wrong username or password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
msgstr "Groc"
|
msgstr "Groc"
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -216,6 +210,10 @@ msgstr "Verze rozšíření prohlížeče CommaFeed {browserExtensionVersion}."
|
|||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
msgstr "CommaFeed je kompatibilní s Fever API. Použijte následující URL ve svém mobilním klientovi kompatibilním s Fever. Přihlaste se pomocí svého uživatelského jména a svého <0>klíče API</0>."
|
msgstr "CommaFeed je kompatibilní s Fever API. Použijte následující URL ve svém mobilním klientovi kompatibilním s Fever. Přihlaste se pomocí svého uživatelského jména a svého <0>klíče API</0>."
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
msgstr "CommaFeed je kompatibilní s Google Reader API. Použijte následující URL ve svém mobilním klientovi kompatibilním s Google Reader. Přihlaste se pomocí svého uživatelského jména a svého <0>klíče API</0>."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
msgstr "CommaFeed další nepřečtená položka"
|
msgstr "CommaFeed další nepřečtená položka"
|
||||||
@@ -240,7 +238,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 +291,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 +338,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 +392,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"
|
||||||
@@ -466,6 +458,14 @@ msgstr "Přejděte na dokumentaci API."
|
|||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "Dobroty"
|
msgstr "Dobroty"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API URL"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Grape"
|
msgid "Grape"
|
||||||
msgstr "Hroznová"
|
msgstr "Hroznová"
|
||||||
@@ -570,7 +570,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 +647,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 +655,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 +761,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 +787,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 +867,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 +875,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 +901,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 +913,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 +941,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 +989,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 +998,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 +1014,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 +1047,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"
|
||||||
@@ -1095,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
|
|||||||
msgstr "Tento zdroj má zastaralý filtr, který nelze upravovat a není aplikován. Znovu vytvořte filtr pomocí nového editoru výrazů. Původní výraz filtru byl: <0>{0}</0>"
|
msgstr "Tento zdroj má zastaralý filtr, který nelze upravovat a není aplikován. Znovu vytvořte filtr pomocí nového editoru výrazů. Původní výraz filtru byl: <0>{0}</0>"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
msgstr "Toto je váš klíč API. Lze jej použít pro některé operace API pouze pro čtení a poskytuje přístup k Fever API. Pro vygenerování nového klíče API použijte formulář v dolní části stránky."
|
msgstr "Toto je váš klíč API. Lze jej použít pro některé operace API pouze pro čtení a uděluje přístup k Fever API a Google Reader API. Použijte formulář v dolní části stránky k vygenerování nového klíče API"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
||||||
@@ -1136,7 +1118,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 +1130,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"
|
||||||
@@ -1170,6 +1150,10 @@ msgstr "Webová stránka"
|
|||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr "Vítejte! Zdá se, že je to poprvé, co spouštíte CommaFeed. Chcete-li začít, vytvořte si účet správce."
|
msgstr "Vítejte! Zdá se, že je to poprvé, co spouštíte CommaFeed. Chcete-li začít, vytvořte si účet správce."
|
||||||
|
|
||||||
|
#: src/app/client.ts
|
||||||
|
msgid "Wrong username or password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
msgstr "Žlutá"
|
msgstr "Žlutá"
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -216,6 +210,10 @@ msgstr "Fersiwn estyniad porwr CommaFeed {browserExtensionVersion}."
|
|||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
msgstr "Mae CommaFeed yn gydnaws â'r Fever API. Defnyddiwch y URL canlynol yn eich cleient symudol sy'n gydnaws â Fever. Mewngofnodwch gyda'ch enw defnyddiwr a'ch <0>allwedd API</0>."
|
msgstr "Mae CommaFeed yn gydnaws â'r Fever API. Defnyddiwch y URL canlynol yn eich cleient symudol sy'n gydnaws â Fever. Mewngofnodwch gyda'ch enw defnyddiwr a'ch <0>allwedd API</0>."
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
msgstr "Mae CommaFeed yn gydnaws â Google Reader API. Defnyddiwch y URL canlynol yn eich cleient symudol sy'n gydnaws â Google Reader. Mewngofnodwch gyda'ch enw defnyddiwr a'ch <0>allwedd API</0>."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
msgstr "CommaFeed eitem nesaf heb ei darllen"
|
msgstr "CommaFeed eitem nesaf heb ei darllen"
|
||||||
@@ -240,7 +238,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 +291,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 +338,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 +392,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"
|
||||||
@@ -466,6 +458,14 @@ msgstr "Ewch i'r ddogfennaeth API."
|
|||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "nwyddau"
|
msgstr "nwyddau"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API URL"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Grape"
|
msgid "Grape"
|
||||||
msgstr "Grawnwin"
|
msgstr "Grawnwin"
|
||||||
@@ -570,7 +570,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 +647,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 +655,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 +761,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 +787,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 +867,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 +875,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 +901,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 +913,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 +941,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 +989,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 +998,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 +1014,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 +1047,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"
|
||||||
@@ -1095,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
|
|||||||
msgstr "Mae gan y porthiant hwn hen hidlydd na ellir ei olygu ac nid yw'n cael ei gymhwyso. Crëwch yr hidlydd eto gan ddefnyddio'r golygydd mynegiant newydd. Yr hen fynegiant hidlo oedd: <0>{0}</0>"
|
msgstr "Mae gan y porthiant hwn hen hidlydd na ellir ei olygu ac nid yw'n cael ei gymhwyso. Crëwch yr hidlydd eto gan ddefnyddio'r golygydd mynegiant newydd. Yr hen fynegiant hidlo oedd: <0>{0}</0>"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
msgstr "Dyma'ch allwedd API. Gellir ei ddefnyddio ar gyfer rhai gweithrediadau API darllen-yn-unig ac mae'n caniatáu mynediad i'r Fever API. Defnyddiwch y ffurflen ar waelod y dudalen i gynhyrchu allwedd API newydd"
|
msgstr "Dyma eich allwedd API. Gellir ei defnyddio ar gyfer rhai gweithrediadau API darllen-yn-unig ac mae'n rhoi mynediad i'r Fever API a'r Google Reader API. Defnyddiwch y ffurflen ar waelod y dudalen i gynhyrchu allwedd API newydd"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
||||||
@@ -1136,7 +1118,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 +1130,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"
|
||||||
@@ -1170,6 +1150,10 @@ msgstr "Gwefan"
|
|||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr "Croeso! Ymddengys mai dyma'r tro cyntaf i chi redeg CommaFeed. Creuwch gyfrif gweinyddwr i ddechrau."
|
msgstr "Croeso! Ymddengys mai dyma'r tro cyntaf i chi redeg CommaFeed. Creuwch gyfrif gweinyddwr i ddechrau."
|
||||||
|
|
||||||
|
#: src/app/client.ts
|
||||||
|
msgid "Wrong username or password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
msgstr "Melyn"
|
msgstr "Melyn"
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -216,6 +210,10 @@ msgstr "CommaFeed browserudvidelse version {browserExtensionVersion}."
|
|||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
msgstr "CommaFeed er kompatibel med Fever API. Brug følgende URL i din Fever-kompatible mobilklient. Log ind med dit brugernavn og din <0>API-nøgle</0>."
|
msgstr "CommaFeed er kompatibel med Fever API. Brug følgende URL i din Fever-kompatible mobilklient. Log ind med dit brugernavn og din <0>API-nøgle</0>."
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
msgstr "CommaFeed er kompatibel med Google Reader API. Brug følgende URL i din Google Reader-kompatible mobilklient. Log ind med dit brugernavn og din <0>API-nøgle</0>."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
msgstr "CommaFeed næste ulæste element"
|
msgstr "CommaFeed næste ulæste element"
|
||||||
@@ -240,7 +238,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 +291,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 +338,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 +392,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"
|
||||||
@@ -466,6 +458,14 @@ msgstr "Gå til API-dokumentationen."
|
|||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "Godbidder"
|
msgstr "Godbidder"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API URL"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Grape"
|
msgid "Grape"
|
||||||
msgstr "Grape"
|
msgstr "Grape"
|
||||||
@@ -570,7 +570,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 +647,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 +655,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 +761,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 +787,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 +867,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 +875,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 +901,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 +913,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 +941,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 +989,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 +998,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 +1014,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 +1047,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"
|
||||||
@@ -1095,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
|
|||||||
msgstr "Dette feed har et ældre filter, der ikke kan redigeres og ikke anvendes. Genopret venligst filteret ved hjælp af den nye udtrykseditor. Det ældre filterudtryk var: <0>{0}</0>"
|
msgstr "Dette feed har et ældre filter, der ikke kan redigeres og ikke anvendes. Genopret venligst filteret ved hjælp af den nye udtrykseditor. Det ældre filterudtryk var: <0>{0}</0>"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
msgstr "Dette er din API-nøgle. Den kan bruges til visse skrivebeskyttede API-operationer og giver adgang til Fever API. Brug formularen nederst på siden til at generere en ny API-nøgle"
|
msgstr "Dette er din API-nøgle. Den kan bruges til nogle skrivebeskyttede API-operationer og giver adgang til Fever API og Google Reader API. Brug formularen nederst på siden for at generere en ny API-nøgle"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
||||||
@@ -1136,7 +1118,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 +1130,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"
|
||||||
@@ -1170,6 +1150,10 @@ msgstr "Hjemmeside"
|
|||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr "Velkommen! Det ser ud til at være første gang, du kører CommaFeed. Opret venligst en administratorkonto for at komme i gang."
|
msgstr "Velkommen! Det ser ud til at være første gang, du kører CommaFeed. Opret venligst en administratorkonto for at komme i gang."
|
||||||
|
|
||||||
|
#: src/app/client.ts
|
||||||
|
msgid "Wrong username or password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
msgstr "Gul"
|
msgstr "Gul"
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -216,6 +210,10 @@ msgstr "CommaFeed Browser Erweiterung Version {browserExtensionVersion}."
|
|||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
msgstr "CommaFeed ist mit der Fever-API kompatibel. Verwenden Sie die folgende URL in Ihrem Fever-kompatiblen mobilen Client. Melden Sie sich mit Ihrem Benutzernamen und Ihrem <0>API-Schlüssel</0> an."
|
msgstr "CommaFeed ist mit der Fever-API kompatibel. Verwenden Sie die folgende URL in Ihrem Fever-kompatiblen mobilen Client. Melden Sie sich mit Ihrem Benutzernamen und Ihrem <0>API-Schlüssel</0> an."
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
msgstr "CommaFeed ist mit der Google-Reader-API kompatibel. Verwenden Sie die folgende URL in Ihrem Google-Reader-kompatiblen mobilen Client. Melden Sie sich mit Ihrem Benutzernamen und Ihrem <0>API-Schlüssel</0> an."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
msgstr "CommaFeed nächstes ungelesenes Element"
|
msgstr "CommaFeed nächstes ungelesenes Element"
|
||||||
@@ -240,7 +238,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 +291,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 +338,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 +392,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"
|
||||||
@@ -466,6 +458,14 @@ msgstr "Gehen Sie zur API-Dokumentation."
|
|||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "Goodies"
|
msgstr "Goodies"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API URL"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Grape"
|
msgid "Grape"
|
||||||
msgstr "Traube"
|
msgstr "Traube"
|
||||||
@@ -570,7 +570,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 +647,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 +655,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 +761,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 +787,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 +867,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 +875,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 +901,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 +913,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 +941,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 +989,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 +998,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 +1014,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 +1047,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"
|
||||||
@@ -1095,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
|
|||||||
msgstr "Dieser Feed verfügt über einen veralteten Filter, der nicht bearbeitet werden kann und nicht angewendet wird. Bitte erstellen Sie den Filter mit dem neuen Ausdruckseditor neu. Der veraltete Filterausdruck war: <0>{0}</0>"
|
msgstr "Dieser Feed verfügt über einen veralteten Filter, der nicht bearbeitet werden kann und nicht angewendet wird. Bitte erstellen Sie den Filter mit dem neuen Ausdruckseditor neu. Der veraltete Filterausdruck war: <0>{0}</0>"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
msgstr "Dies ist Ihr API-Schlüssel. Er kann für einige schreibgeschützte API-Vorgänge verwendet werden und ermöglicht den Zugriff auf die Fever-API. Verwenden Sie das Formular unten auf der Seite, um einen neuen API-Schlüssel zu generieren"
|
msgstr "Dies ist Ihr API-Schlüssel. Er kann für einige schreibgeschützte API-Vorgänge verwendet werden und gewährt Zugriff auf die Fever-API und die Google-Reader-API. Verwenden Sie das Formular am Ende der Seite, um einen neuen API-Schlüssel zu generieren"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
||||||
@@ -1136,7 +1118,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 +1130,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"
|
||||||
@@ -1170,6 +1150,10 @@ msgstr "Webseite"
|
|||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr "Willkommen! Dies scheint das erste Mal zu sein, dass Sie CommaFeed ausführen. Bitte erstellen Sie ein Administrator-Konto, um zu beginnen."
|
msgstr "Willkommen! Dies scheint das erste Mal zu sein, dass Sie CommaFeed ausführen. Bitte erstellen Sie ein Administrator-Konto, um zu beginnen."
|
||||||
|
|
||||||
|
#: src/app/client.ts
|
||||||
|
msgid "Wrong username or password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
msgstr "Gelb"
|
msgstr "Gelb"
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -216,6 +210,10 @@ msgstr "CommaFeed browser extension version {browserExtensionVersion}."
|
|||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
msgstr "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgstr "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
msgstr "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
msgstr "CommaFeed next unread item"
|
msgstr "CommaFeed next unread item"
|
||||||
@@ -240,7 +238,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 +291,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 +338,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 +392,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"
|
||||||
@@ -466,6 +458,14 @@ msgstr "Go to the API documentation."
|
|||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "Goodies"
|
msgstr "Goodies"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API"
|
||||||
|
msgstr "Google Reader API"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API URL"
|
||||||
|
msgstr "Google Reader API URL"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Grape"
|
msgid "Grape"
|
||||||
msgstr "Grape"
|
msgstr "Grape"
|
||||||
@@ -570,7 +570,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 +647,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 +655,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 +761,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 +787,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 +867,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 +875,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 +901,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 +913,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 +941,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 +989,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 +998,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 +1014,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 +1047,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"
|
||||||
@@ -1095,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
|
|||||||
msgstr "This feed has a legacy filter that cannot be edited and is not applied. Please recreate the filter using the new expression editor. The legacy filter expression was: <0>{0}</0>"
|
msgstr "This feed has a legacy filter that cannot be edited and is not applied. Please recreate the filter using the new expression editor. The legacy filter expression was: <0>{0}</0>"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
msgstr "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgstr "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
||||||
@@ -1136,7 +1118,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 +1130,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"
|
||||||
@@ -1170,6 +1150,10 @@ msgstr "Website"
|
|||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgstr "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
|
|
||||||
|
#: src/app/client.ts
|
||||||
|
msgid "Wrong username or password"
|
||||||
|
msgstr "Wrong username or password"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
msgstr "Yellow"
|
msgstr "Yellow"
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -217,6 +211,10 @@ msgstr "Versión de la extensión del navegador CommaFeed {browserExtensionVersi
|
|||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
msgstr "CommaFeed es compatible con Fever API. Utilice la siguiente URL en su cliente móvil compatible con Fever. Inicie sesión con su nombre de usuario y su <0>clave API</0>."
|
msgstr "CommaFeed es compatible con Fever API. Utilice la siguiente URL en su cliente móvil compatible con Fever. Inicie sesión con su nombre de usuario y su <0>clave API</0>."
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
msgstr "CommaFeed es compatible con Google Reader API. Utilice la siguiente URL en su cliente móvil compatible con Google Reader. Inicie sesión con su nombre de usuario y su <0>clave API</0>."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
msgstr "CommaFeed siguiente elemento no leído"
|
msgstr "CommaFeed siguiente elemento no leído"
|
||||||
@@ -241,7 +239,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 +292,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 +339,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 +393,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"
|
||||||
@@ -467,6 +459,14 @@ msgstr "Ir a la documentación de la API."
|
|||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "Golosinas"
|
msgstr "Golosinas"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API URL"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Grape"
|
msgid "Grape"
|
||||||
msgstr "Uva"
|
msgstr "Uva"
|
||||||
@@ -571,7 +571,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 +648,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 +656,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 +762,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 +788,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 +868,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 +876,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 +902,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 +914,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 +942,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 +990,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 +999,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 +1015,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 +1048,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"
|
||||||
@@ -1096,8 +1078,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
|
|||||||
msgstr "Este feed tiene un filtro heredado que no se puede editar y no se aplica. Por favor, vuelve a crear el filtro usando el nuevo editor de expresiones. La expresión del filtro heredado era: <0>{0}</0>"
|
msgstr "Este feed tiene un filtro heredado que no se puede editar y no se aplica. Por favor, vuelve a crear el filtro usando el nuevo editor de expresiones. La expresión del filtro heredado era: <0>{0}</0>"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
msgstr "Esta es su clave API. Se puede utilizar para algunas operaciones API de solo lectura y otorga acceso a Fever API. Utilice el formulario en la parte inferior de la página para generar una nueva clave API"
|
msgstr "Esta es su clave API. Se puede utilizar para algunas operaciones API de solo lectura y otorga acceso a la API Fever y a la API de Google Reader. Utilice el formulario en la parte inferior de la página para generar una nueva clave API"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
||||||
@@ -1137,7 +1119,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 +1131,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"
|
||||||
@@ -1171,6 +1151,10 @@ msgstr "Sitio web"
|
|||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr "¡Bienvenido! Parece que esta es la primera vez que ejecutas CommaFeed. Por favor, crea una cuenta de administrador para empezar."
|
msgstr "¡Bienvenido! Parece que esta es la primera vez que ejecutas CommaFeed. Por favor, crea una cuenta de administrador para empezar."
|
||||||
|
|
||||||
|
#: src/app/client.ts
|
||||||
|
msgid "Wrong username or password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
msgstr "Amarillo"
|
msgstr "Amarillo"
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -216,6 +210,10 @@ msgstr "نسخه افزونه مرورگر CommaFeed {browserExtensionVersion}."
|
|||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
msgstr "CommaFeed با Fever API سازگار است. از آدرس زیر در کلاینت موبایل سازگار با Fever استفاده کنید. با نام کاربری و <0>کلید API</0> خود وارد شوید."
|
msgstr "CommaFeed با Fever API سازگار است. از آدرس زیر در کلاینت موبایل سازگار با Fever استفاده کنید. با نام کاربری و <0>کلید API</0> خود وارد شوید."
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
msgstr "CommaFeed با Google Reader API سازگار است. از آدرس زیر در کلاینت موبایل سازگار با Google Reader استفاده کنید. با نام کاربری و <0>کلید API</0> خود وارد شوید."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
msgstr "مورد خوانده نشده بعدی CommaFeed"
|
msgstr "مورد خوانده نشده بعدی CommaFeed"
|
||||||
@@ -240,7 +238,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 +291,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 +338,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 +392,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"
|
||||||
@@ -466,6 +458,14 @@ msgstr "به مستندات API بروید."
|
|||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "خوبی ها"
|
msgstr "خوبی ها"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API URL"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Grape"
|
msgid "Grape"
|
||||||
msgstr "عنبی"
|
msgstr "عنبی"
|
||||||
@@ -570,7 +570,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 +647,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 +655,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 +761,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 +787,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 +867,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 +875,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 +901,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 +913,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 +941,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 +989,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 +998,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 +1014,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 +1047,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 "برچسبها"
|
||||||
@@ -1095,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
|
|||||||
msgstr "این فید دارای یک فیلتر قدیمی است که قابل ویرایش نیست و اعمال نمیشود. لطفاً فیلتر را با استفاده از ویرایشگر جدید بازسازی کنید. عبارت فیلتر قدیمی: <0>{0}</0>"
|
msgstr "این فید دارای یک فیلتر قدیمی است که قابل ویرایش نیست و اعمال نمیشود. لطفاً فیلتر را با استفاده از ویرایشگر جدید بازسازی کنید. عبارت فیلتر قدیمی: <0>{0}</0>"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
msgstr "این کلید API شماست. میتوان از آن برای برخی عملیات API فقط خواندنی استفاده کرد و دسترسی به Fever API را فراهم میکند. از فرم پایین صفحه برای تولید کلید جدید استفاده کنید"
|
msgstr "این کلید API شماست. میتوان از آن برای برخی عملیات فقط خواندنی API استفاده کرد و دسترسی به Fever API و Google Reader API را میدهد. از فرم پایین صفحه برای ایجاد کلید API جدید استفاده کنید"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
||||||
@@ -1136,7 +1118,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 +1130,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 "نام کاربری یا ایمیل"
|
||||||
@@ -1170,6 +1150,10 @@ msgstr "وب سایت"
|
|||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr "خوش آمدید! به نظر میرسد این اولین بار است که CommaFeed را اجرا میکنید. لطفاً برای شروع یک حساب مدیر ایجاد کنید."
|
msgstr "خوش آمدید! به نظر میرسد این اولین بار است که CommaFeed را اجرا میکنید. لطفاً برای شروع یک حساب مدیر ایجاد کنید."
|
||||||
|
|
||||||
|
#: src/app/client.ts
|
||||||
|
msgid "Wrong username or password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
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
|
||||||
@@ -216,6 +210,10 @@ msgstr "CommaFeed-selainlaajennuksen versio {browserExtensionVersion}."
|
|||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
msgstr "CommaFeed on yhteensopiva Fever-API:n kanssa. Käytä seuraavaa URL-osoitetta Fever-yhteensopivassa mobiiliohjelmassasi. Kirjaudu sisään käyttäjätunnuksellasi ja <0>API-avaimellasi</0>."
|
msgstr "CommaFeed on yhteensopiva Fever-API:n kanssa. Käytä seuraavaa URL-osoitetta Fever-yhteensopivassa mobiiliohjelmassasi. Kirjaudu sisään käyttäjätunnuksellasi ja <0>API-avaimellasi</0>."
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
msgstr "CommaFeed on yhteensopiva Google Reader -API:n kanssa. Käytä seuraavaa URL-osoitetta Google Reader -yhteensopivassa mobiiliohjelmassasi. Kirjaudu sisään käyttäjätunnuksellasi ja <0>API-avaimellasi</0>."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
msgstr "CommaFeed seuraava lukematon kohde"
|
msgstr "CommaFeed seuraava lukematon kohde"
|
||||||
@@ -240,7 +238,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 +291,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 +338,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 +392,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"
|
||||||
@@ -466,6 +458,14 @@ msgstr "Siirry API-dokumentaatioon."
|
|||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "Hyvää"
|
msgstr "Hyvää"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API URL"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Grape"
|
msgid "Grape"
|
||||||
msgstr "Viinirypäle"
|
msgstr "Viinirypäle"
|
||||||
@@ -570,7 +570,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 +647,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 +655,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 +761,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 +787,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 +867,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 +875,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 +901,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 +913,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 +941,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 +989,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 +998,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 +1014,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 +1047,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"
|
||||||
@@ -1095,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
|
|||||||
msgstr "Tässä syötteessä on vanha suodatin, jota ei voi muokata ja jota ei sovelleta. Luo suodatin uudelleen käyttämällä uutta lauseke-editoria. Vanha suodatinlauseke oli: <0>{0}</0>"
|
msgstr "Tässä syötteessä on vanha suodatin, jota ei voi muokata ja jota ei sovelleta. Luo suodatin uudelleen käyttämällä uutta lauseke-editoria. Vanha suodatinlauseke oli: <0>{0}</0>"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
msgstr "Tämä on API-avaimesi. Sitä voidaan käyttää joihinkin vain luku -API-toimintoihin ja se antaa pääsyn Fever-API:iin. Käytä sivun alareunassa olevaa lomaketta uuden API-avaimen luomiseen"
|
msgstr "Tämä on API-avaimesi. Sitä voidaan käyttää joihinkin vain luku -API-toimintoihin, ja se myöntää pääsyn Fever-API:hin ja Google Reader -API:hin. Käytä sivun alareunassa olevaa lomaketta luodaksesi uuden API-avaimen"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
||||||
@@ -1136,7 +1118,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 +1130,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"
|
||||||
@@ -1170,6 +1150,10 @@ msgstr "Verkkosivusto"
|
|||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr "Tervetuloa! Näyttää siltä, että suoritat CommaFeediä ensimmäistä kertaa. Luo ylläpitäjän tili aloittaaksesi."
|
msgstr "Tervetuloa! Näyttää siltä, että suoritat CommaFeediä ensimmäistä kertaa. Luo ylläpitäjän tili aloittaaksesi."
|
||||||
|
|
||||||
|
#: src/app/client.ts
|
||||||
|
msgid "Wrong username or password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
msgstr "Keltainen"
|
msgstr "Keltainen"
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -216,6 +210,10 @@ msgstr "Extension CommaFeed pour navigateur version {browserExtensionVersion}."
|
|||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
msgstr "Commafeed est compatible avec l'API Fever, en inscrivant l'URL suivante dans votre client mobile compatible. Entrez votre nom d'utilisateur habituel, et votre <0>clef API</0> comme mot de passe."
|
msgstr "Commafeed est compatible avec l'API Fever, en inscrivant l'URL suivante dans votre client mobile compatible. Entrez votre nom d'utilisateur habituel, et votre <0>clef API</0> comme mot de passe."
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
msgstr "Commafeed est compatible avec l'API Google Reader, en inscrivant l'URL suivante dans votre client mobile compatible. Entrez votre nom d'utilisateur habituel, et votre <0>clef API</0> comme mot de passe."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
msgstr "CommaFeed prochain article non lu"
|
msgstr "CommaFeed prochain article non lu"
|
||||||
@@ -240,7 +238,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 +291,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 +338,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 +392,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"
|
||||||
@@ -466,6 +458,14 @@ msgstr "Aller à la documentation de l'API."
|
|||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "Extensions"
|
msgstr "Extensions"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API"
|
||||||
|
msgstr "API Google Reader"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API URL"
|
||||||
|
msgstr "URL de l'API Google Reader"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Grape"
|
msgid "Grape"
|
||||||
msgstr "Bordeaux"
|
msgstr "Bordeaux"
|
||||||
@@ -570,7 +570,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 +647,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 +655,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 +761,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 +787,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 +867,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 +875,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 +901,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 +913,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 +941,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 +989,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 +998,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 +1014,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 +1047,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"
|
||||||
@@ -1095,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
|
|||||||
msgstr "Ce flux est configuré avec un filtre obsolète, qui ne peut être ni modifié ni appliqué. Vous devez recréer ce filtre à l'aide du nouvel éditeur d'expressions régulières. Le filtre configuré était : <0>{0}</0>"
|
msgstr "Ce flux est configuré avec un filtre obsolète, qui ne peut être ni modifié ni appliqué. Vous devez recréer ce filtre à l'aide du nouvel éditeur d'expressions régulières. Le filtre configuré était : <0>{0}</0>"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
msgstr "Ceci est votre clef API. Elle peut être utilisée pour certaines opérations en lecture seule et donne accès à l'API Fever. Utilisez le formulaire en bas de la page pour générer une nouvelle clef API"
|
msgstr "Ceci est votre clef API. Elle peut être utilisée pour certaines opérations en lecture seule et donne accès à l'API Fever et à l'API Google Reader. Utilisez le formulaire en bas de la page pour générer une nouvelle clef API"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
||||||
@@ -1136,7 +1118,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 +1130,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"
|
||||||
@@ -1170,6 +1150,10 @@ msgstr "Site web"
|
|||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr "Bienvenue ! Il semble que ce soit le premier démarrage de Commafeed. Avant tout, vous devez créer un compte administrateur."
|
msgstr "Bienvenue ! Il semble que ce soit le premier démarrage de Commafeed. Avant tout, vous devez créer un compte administrateur."
|
||||||
|
|
||||||
|
#: src/app/client.ts
|
||||||
|
msgid "Wrong username or password"
|
||||||
|
msgstr "Utilisateur ou mot de passe incorrect"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
msgstr "Jaune"
|
msgstr "Jaune"
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -217,6 +211,10 @@ msgstr "Versión do complemento do navegador para CommaFeed {browserExtensionVer
|
|||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
msgstr "CommaFeed é compatible coa API de Fever. Usa o seguinte URL no teu cliente móbil compatible con Fever. Accede co identificador e a túa <0>clave API</0>."
|
msgstr "CommaFeed é compatible coa API de Fever. Usa o seguinte URL no teu cliente móbil compatible con Fever. Accede co identificador e a túa <0>clave API</0>."
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
msgstr "CommaFeed é compatible coa API de Google Reader. Usa o seguinte URL no teu cliente móbil compatible con Google Reader. Accede co identificador e a túa <0>clave API</0>."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
msgstr "Seguinte elemento non lido en CommaFeed"
|
msgstr "Seguinte elemento non lido en CommaFeed"
|
||||||
@@ -241,7 +239,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 +292,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 +339,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 +393,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"
|
||||||
@@ -467,6 +459,14 @@ msgstr "Ir á documentación da API."
|
|||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "Agasallos"
|
msgstr "Agasallos"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API URL"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Grape"
|
msgid "Grape"
|
||||||
msgstr "Bago"
|
msgstr "Bago"
|
||||||
@@ -571,7 +571,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 +648,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 +656,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 +762,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 +788,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 +868,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 +876,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 +902,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 +914,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 +942,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 +990,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 +999,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 +1015,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 +1048,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"
|
||||||
@@ -1096,8 +1078,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
|
|||||||
msgstr "Esta canle ten un filtro antigo que non se pode editar e que non se aplica. Volve crear o filtro usando o novo editor de expresións. A expresión do filtro antigo era: <0>{0}</0>"
|
msgstr "Esta canle ten un filtro antigo que non se pode editar e que non se aplica. Volve crear o filtro usando o novo editor de expresións. A expresión do filtro antigo era: <0>{0}</0>"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
msgstr "Esta é a túa clave da API. Pode usarse para algunhas operacións da API de só-lectura e concede acceso á API Fever. Usa o formulario da parte inferior da páxina para crear unha nova clave da API"
|
msgstr "Esta é a túa clave da API. Pode usarse para algunhas operacións da API de só-lectura e concede acceso á API Fever e á API de Google Reader. Usa o formulario da parte inferior da páxina para crear unha nova clave da API"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
||||||
@@ -1137,7 +1119,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 +1131,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"
|
||||||
@@ -1171,6 +1151,10 @@ msgstr "Páxina web"
|
|||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr "Benvida! Semella que é a primeira vez que executas CommaFeed. Para comezar, crea unha conta de administración."
|
msgstr "Benvida! Semella que é a primeira vez que executas CommaFeed. Para comezar, crea unha conta de administración."
|
||||||
|
|
||||||
|
#: src/app/client.ts
|
||||||
|
msgid "Wrong username or password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
msgstr "Amarelo"
|
msgstr "Amarelo"
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -216,6 +210,10 @@ msgstr "CommaFeed böngészőbővítmény {browserExtensionVersion} verzió."
|
|||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
msgstr "A CommaFeed kompatibilis a Fever API-val. Használja a következő URL-t Fever-kompatibilis mobilkliensében. Jelentkezzen be felhasználónevével és <0>API-kulcsával</0>."
|
msgstr "A CommaFeed kompatibilis a Fever API-val. Használja a következő URL-t Fever-kompatibilis mobilkliensében. Jelentkezzen be felhasználónevével és <0>API-kulcsával</0>."
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
msgstr "A CommaFeed kompatibilis a Google Reader API-val. Használja a következő URL-t Google Reader-kompatibilis mobilkliensében. Jelentkezzen be felhasználónevével és <0>API-kulcsával</0>."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
msgstr "CommaFeed következő olvasatlan elem"
|
msgstr "CommaFeed következő olvasatlan elem"
|
||||||
@@ -240,7 +238,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 +291,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 +338,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 +392,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"
|
||||||
@@ -466,6 +458,14 @@ msgstr "Nyissa meg az API dokumentációját."
|
|||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "Jók"
|
msgstr "Jók"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API URL"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Grape"
|
msgid "Grape"
|
||||||
msgstr "Szőlő"
|
msgstr "Szőlő"
|
||||||
@@ -570,7 +570,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 +647,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 +655,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 +761,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 +787,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 +867,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 +875,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 +901,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 +913,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 +941,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 +989,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 +998,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 +1014,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 +1047,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"
|
||||||
@@ -1095,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
|
|||||||
msgstr "Ez a feed egy régi szűrővel rendelkezik, amely nem szerkeszthető és nem kerül alkalmazásra. Kérjük, hozza létre újra a szűrőt az új kifejezésszerkesztővel. A régi szűrőkifejezés a következő volt: <0>{0}</0>"
|
msgstr "Ez a feed egy régi szűrővel rendelkezik, amely nem szerkeszthető és nem kerül alkalmazásra. Kérjük, hozza létre újra a szűrőt az új kifejezésszerkesztővel. A régi szűrőkifejezés a következő volt: <0>{0}</0>"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
msgstr "Ez az Ön API-kulcsa. Felhasználható néhány írásvédett API-művelethez, és hozzáférést biztosít a Fever API-hoz. Használja az oldal alján található űrlapot egy új API-kulcs létrehozásához"
|
msgstr "Ez az Ön API-kulcsa. Néhány csak olvasható API-művelethez használható, és hozzáférést biztosít a Fever API-hoz és a Google Reader API-hoz. Használja az oldal alján található űrlapot új API-kulcs létrehozásához"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
||||||
@@ -1136,7 +1118,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 +1130,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"
|
||||||
@@ -1170,6 +1150,10 @@ msgstr "Webhely"
|
|||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr "Üdvözöljük! Úgy tűnik, ez az első alkalom, hogy a CommaFeedet futtatja. Kérjük, hozzon létre egy rendszergazdai fiókot a kezdéshez."
|
msgstr "Üdvözöljük! Úgy tűnik, ez az első alkalom, hogy a CommaFeedet futtatja. Kérjük, hozzon létre egy rendszergazdai fiókot a kezdéshez."
|
||||||
|
|
||||||
|
#: src/app/client.ts
|
||||||
|
msgid "Wrong username or password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
msgstr "Sárga"
|
msgstr "Sárga"
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -216,6 +210,10 @@ msgstr "Ekstensi browser CommaFeed versi {browserExtensionVersion}."
|
|||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
msgstr "CommaFeed kompatibel dengan Fever API. Gunakan URL berikut di klien seluler Anda yang kompatibel dengan Fever. Login dengan nama pengguna dan <0>kunci API</0> Anda."
|
msgstr "CommaFeed kompatibel dengan Fever API. Gunakan URL berikut di klien seluler Anda yang kompatibel dengan Fever. Login dengan nama pengguna dan <0>kunci API</0> Anda."
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
msgstr "CommaFeed kompatibel dengan Google Reader API. Gunakan URL berikut di klien seluler Anda yang kompatibel dengan Google Reader. Login dengan nama pengguna dan <0>kunci API</0> Anda."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
msgstr "CommaFeed item yang belum dibaca berikutnya"
|
msgstr "CommaFeed item yang belum dibaca berikutnya"
|
||||||
@@ -240,7 +238,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 +291,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 +338,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 +392,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"
|
||||||
@@ -466,6 +458,14 @@ msgstr "Buka dokumentasi API."
|
|||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "Pernak-pernik"
|
msgstr "Pernak-pernik"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API URL"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Grape"
|
msgid "Grape"
|
||||||
msgstr "Anggur"
|
msgstr "Anggur"
|
||||||
@@ -570,7 +570,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 +647,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 +655,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 +761,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 +787,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 +867,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 +875,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 +901,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 +913,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 +941,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 +989,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 +998,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 +1014,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 +1047,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"
|
||||||
@@ -1095,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
|
|||||||
msgstr "Umpan ini memiliki filter lama yang tidak dapat diedit dan tidak diterapkan. Silakan buat ulang filter menggunakan editor ekspresi baru. Ekspresi filter lama adalah: <0>{0}</0>"
|
msgstr "Umpan ini memiliki filter lama yang tidak dapat diedit dan tidak diterapkan. Silakan buat ulang filter menggunakan editor ekspresi baru. Ekspresi filter lama adalah: <0>{0}</0>"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
msgstr "Ini adalah kunci API Anda. Ini dapat digunakan untuk beberapa operasi API baca-saja dan memberikan akses ke Fever API. Gunakan formulir di bagian bawah halaman untuk membuat kunci API baru"
|
msgstr "Ini adalah kunci API Anda. Ini dapat digunakan untuk beberapa operasi API yang hanya-baca dan memberikan akses ke Fever API dan Google Reader API. Gunakan formulir di bagian bawah halaman untuk membuat kunci API baru"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
||||||
@@ -1136,7 +1118,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 +1130,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"
|
||||||
@@ -1170,6 +1150,10 @@ msgstr "Situs Web"
|
|||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr "Selamat datang! Ini sepertinya pertama kalinya Anda menjalankan CommaFeed. Silakan buat akun administrator untuk memulai."
|
msgstr "Selamat datang! Ini sepertinya pertama kalinya Anda menjalankan CommaFeed. Silakan buat akun administrator untuk memulai."
|
||||||
|
|
||||||
|
#: src/app/client.ts
|
||||||
|
msgid "Wrong username or password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
msgstr "Kuning"
|
msgstr "Kuning"
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -216,6 +210,10 @@ msgstr "Versione dell'estensione del browser CommaFeed {browserExtensionVersion}
|
|||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
msgstr "CommaFeed è compatibile con l'API Fever. Utilizza il seguente URL nel tuo client mobile compatibile con Fever. Accedi con il tuo nome utente e la tua <0>chiave API</0>."
|
msgstr "CommaFeed è compatibile con l'API Fever. Utilizza il seguente URL nel tuo client mobile compatibile con Fever. Accedi con il tuo nome utente e la tua <0>chiave API</0>."
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
msgstr "CommaFeed è compatibile con l'API Google Reader. Utilizza il seguente URL nel tuo client mobile compatibile con Google Reader. Accedi con il tuo nome utente e la tua <0>chiave API</0>."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
msgstr "CommaFeed successivo elemento non letto"
|
msgstr "CommaFeed successivo elemento non letto"
|
||||||
@@ -240,7 +238,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 +291,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 +338,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 +392,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"
|
||||||
@@ -466,6 +458,14 @@ msgstr "Vai alla documentazione dell'API."
|
|||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "Chicche"
|
msgstr "Chicche"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API URL"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Grape"
|
msgid "Grape"
|
||||||
msgstr "Uva"
|
msgstr "Uva"
|
||||||
@@ -570,7 +570,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 +647,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 +655,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 +761,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 +787,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 +867,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 +875,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 +901,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 +913,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 +941,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 +989,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 +998,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 +1014,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 +1047,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"
|
||||||
@@ -1095,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
|
|||||||
msgstr "Questo feed ha un filtro legacy che non può essere modificato e non viene applicato. Ricrea il filtro utilizzando il nuovo editor di espressioni. L'espressione del filtro legacy era: <0>{0}</0>"
|
msgstr "Questo feed ha un filtro legacy che non può essere modificato e non viene applicato. Ricrea il filtro utilizzando il nuovo editor di espressioni. L'espressione del filtro legacy era: <0>{0}</0>"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
msgstr "Questa è la tua chiave API. Può essere utilizzata per alcune operazioni API di sola lettura e garantisce l'accesso all'API Fever. Utilizza il modulo in fondo alla pagina per generare una nuova chiave API"
|
msgstr "Questa è la tua chiave API. Può essere utilizzata per alcune operazioni API di sola lettura e concede l'accesso all'API Fever e all'API Google Reader. Usa il modulo in fondo alla pagina per generare una nuova chiave API"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
||||||
@@ -1136,7 +1118,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 +1130,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"
|
||||||
@@ -1170,6 +1150,10 @@ msgstr "Sito web"
|
|||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr "Benvenuto! Sembra che sia la prima volta che esegui CommaFeed. Crea un account amministratore per iniziare."
|
msgstr "Benvenuto! Sembra che sia la prima volta che esegui CommaFeed. Crea un account amministratore per iniziare."
|
||||||
|
|
||||||
|
#: src/app/client.ts
|
||||||
|
msgid "Wrong username or password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
msgstr "Giallo"
|
msgstr "Giallo"
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -216,6 +210,10 @@ msgstr "CommaFeed ブラウザー拡張機能のバージョンは {browserExten
|
|||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
msgstr "CommaFeedはFever APIと互換性があります。Fever互換のモバイルクライアントで次のURLを使用してください。ユーザー名と <0>API キー</0> でログインしてください。"
|
msgstr "CommaFeedはFever APIと互換性があります。Fever互換のモバイルクライアントで次のURLを使用してください。ユーザー名と <0>API キー</0> でログインしてください。"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
msgstr "CommaFeedはGoogle Reader APIと互換性があります。Google Reader互換のモバイルクライアントで次のURLを使用してください。ユーザー名と <0>API キー</0> でログインしてください。"
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
msgstr "CommaFeed 次の未読アイテム"
|
msgstr "CommaFeed 次の未読アイテム"
|
||||||
@@ -240,7 +238,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 +291,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 +338,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 +392,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"
|
||||||
@@ -466,6 +458,14 @@ msgstr "APIドキュメントに移動します。"
|
|||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "グッズ"
|
msgstr "グッズ"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API URL"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Grape"
|
msgid "Grape"
|
||||||
msgstr "グレープ"
|
msgstr "グレープ"
|
||||||
@@ -570,7 +570,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 +647,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 +655,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 +761,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 +787,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 +867,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 +875,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 +901,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 +913,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 +941,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 +989,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 +998,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 +1014,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 +1047,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 "タグ"
|
||||||
@@ -1095,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
|
|||||||
msgstr "このフィードには、編集できず適用もされない古い形式のフィルタがあります。新しい式エディタを使用してフィルタを再作成してください。古いフィルタ式は次のとおりでした: <0>{0}</0>"
|
msgstr "このフィードには、編集できず適用もされない古い形式のフィルタがあります。新しい式エディタを使用してフィルタを再作成してください。古いフィルタ式は次のとおりでした: <0>{0}</0>"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
msgstr "これはあなたのAPIキーです。いくつかの読み取り専用API操作に使用できます。これにより、Fever APIへのアクセスが可能になります。ページの下部のフォームを使用して新しいAPIキーを生成します。"
|
msgstr "これはあなたのAPIキーです。一部の読み取り専用API操作に使用でき、Fever APIおよびGoogle Reader APIへのアクセスを許可します。新しいAPIキーを生成するには、ページ下部のフォームを使用してください"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
||||||
@@ -1136,7 +1118,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 +1130,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 "ユーザー名またはメールアドレス"
|
||||||
@@ -1170,6 +1150,10 @@ msgstr "ウェブサイト"
|
|||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr "ようこそ!CommaFeedを初めて実行するようです。開始するには管理者アカウントを作成してください。"
|
msgstr "ようこそ!CommaFeedを初めて実行するようです。開始するには管理者アカウントを作成してください。"
|
||||||
|
|
||||||
|
#: src/app/client.ts
|
||||||
|
msgid "Wrong username or password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
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
|
||||||
@@ -216,6 +210,10 @@ msgstr "CommaFeed 브라우저 확장 프로그램 버전 {browserExtensionVersi
|
|||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
msgstr "CommaFeed는 Fever API와 호환됩니다. Fever 호환 모바일 클라이언트에서 다음 URL을 사용하십시오. 사용자 이름과 <0>API 키</0>로 로그인하십시오."
|
msgstr "CommaFeed는 Fever API와 호환됩니다. Fever 호환 모바일 클라이언트에서 다음 URL을 사용하십시오. 사용자 이름과 <0>API 키</0>로 로그인하십시오."
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
msgstr "CommaFeed는 Google Reader API와 호환됩니다. Google Reader 호환 모바일 클라이언트에서 다음 URL을 사용하십시오. 사용자 이름과 <0>API 키</0>로 로그인하십시오."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
msgstr "다음 읽지 않은 항목을 쉼표로 피드"
|
msgstr "다음 읽지 않은 항목을 쉼표로 피드"
|
||||||
@@ -240,7 +238,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 +291,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 +338,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 +392,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"
|
||||||
@@ -466,6 +458,14 @@ msgstr "API 문서로 이동합니다."
|
|||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "굿즈"
|
msgstr "굿즈"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API URL"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Grape"
|
msgid "Grape"
|
||||||
msgstr "그레이프"
|
msgstr "그레이프"
|
||||||
@@ -570,7 +570,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 +647,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 +655,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 +761,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 +787,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 +867,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 +875,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 +901,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 +913,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 +941,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 +989,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 +998,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 +1014,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 +1047,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 "태그"
|
||||||
@@ -1095,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
|
|||||||
msgstr "이 피드에는 편집할 수 없고 적용되지 않는 기존 필터가 있습니다. 새 표현식 편집기를 사용하여 필터를 다시 만드십시오. 기존 필터 표현식은 <0>{0}</0>이었습니다."
|
msgstr "이 피드에는 편집할 수 없고 적용되지 않는 기존 필터가 있습니다. 새 표현식 편집기를 사용하여 필터를 다시 만드십시오. 기존 필터 표현식은 <0>{0}</0>이었습니다."
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
msgstr "이것은 귀하의 API 키입니다. 일부 읽기 전용 API 작업에 사용할 수 있으며 Fever API에 대한 액세스 권한을 부여합니다. 새 API 키를 생성하려면 페이지 하단의 양식을 사용하십시오."
|
msgstr "이것은 회원님의 API 키입니다. 일부 읽기 전용 API 작업에 사용할 수 있으며 Fever API 및 Google Reader API에 대한 액세스 권한을 부여합니다. 새 API 키를 생성하려면 페이지 하단의 양식을 사용하십시오"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
||||||
@@ -1136,7 +1118,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 +1130,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 "사용자 이름 또는 이메일"
|
||||||
@@ -1170,6 +1150,10 @@ msgstr "웹사이트"
|
|||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr "환영합니다! CommaFeed를 처음 실행하는 것 같습니다. 시작하려면 관리자 계정을 만드십시오."
|
msgstr "환영합니다! CommaFeed를 처음 실행하는 것 같습니다. 시작하려면 관리자 계정을 만드십시오."
|
||||||
|
|
||||||
|
#: src/app/client.ts
|
||||||
|
msgid "Wrong username or password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
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
|
||||||
@@ -216,6 +210,10 @@ msgstr "Ekstensi penyemak imbas CommaFeed versi {browserExtensionVersion}."
|
|||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
msgstr "CommaFeed serasi dengan Fever API. Gunakan URL berikut dalam klien mudah alih serasi Fever anda. Log masuk dengan nama pengguna anda dan <0>kunci API</0> anda."
|
msgstr "CommaFeed serasi dengan Fever API. Gunakan URL berikut dalam klien mudah alih serasi Fever anda. Log masuk dengan nama pengguna anda dan <0>kunci API</0> anda."
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
msgstr "CommaFeed serasi dengan Google Reader API. Gunakan URL berikut dalam klien mudah alih serasi Google Reader anda. Log masuk dengan nama pengguna anda dan <0>kunci API</0> anda."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
msgstr "CommaFeed item belum dibaca seterusnya"
|
msgstr "CommaFeed item belum dibaca seterusnya"
|
||||||
@@ -240,7 +238,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 +291,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 +338,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 +392,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"
|
||||||
@@ -466,6 +458,14 @@ msgstr "Pergi ke dokumentasi API."
|
|||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "Barangan"
|
msgstr "Barangan"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API URL"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Grape"
|
msgid "Grape"
|
||||||
msgstr "Anggur"
|
msgstr "Anggur"
|
||||||
@@ -570,7 +570,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 +647,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 +655,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 +761,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 +787,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 +867,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 +875,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 +901,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 +913,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 +941,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 +989,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 +998,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 +1014,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 +1047,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"
|
||||||
@@ -1095,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
|
|||||||
msgstr "Suapan ini mempunyai penapis warisan yang tidak boleh diedit dan tidak digunakan. Sila buat semula penapis menggunakan editor ungkapan baharu. Ungkapan penapis warisan ialah: <0>{0}</0>"
|
msgstr "Suapan ini mempunyai penapis warisan yang tidak boleh diedit dan tidak digunakan. Sila buat semula penapis menggunakan editor ungkapan baharu. Ungkapan penapis warisan ialah: <0>{0}</0>"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
msgstr "Ini ialah kunci API anda. Ia boleh digunakan untuk beberapa operasi API baca sahaja dan memberikan akses kepada Fever API. Gunakan borang di bahagian bawah halaman untuk menjana kunci API baharu"
|
msgstr "Ini ialah kunci API anda. Ia boleh digunakan untuk sesetengah operasi API baca sahaja dan memberikan akses kepada Fever API dan Google Reader API. Gunakan borang di bahagian bawah halaman untuk menjana kunci API baharu"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
||||||
@@ -1136,7 +1118,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 +1130,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"
|
||||||
@@ -1170,6 +1150,10 @@ msgstr "Laman web"
|
|||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr "Selamat datang! Ini nampaknya kali pertama anda menjalankan CommaFeed. Sila cipta akaun pentadbir untuk bermula."
|
msgstr "Selamat datang! Ini nampaknya kali pertama anda menjalankan CommaFeed. Sila cipta akaun pentadbir untuk bermula."
|
||||||
|
|
||||||
|
#: src/app/client.ts
|
||||||
|
msgid "Wrong username or password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
msgstr "Kuning"
|
msgstr "Kuning"
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -216,6 +210,10 @@ msgstr "CommaFeed nettleserutvidelse versjon {browserExtensionVersion}."
|
|||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
msgstr "CommaFeed er kompatibel med Fever API. Bruk følgende URL i din Fever-kompatible mobilklient. Logg inn med brukernavn og din <0>API-nøkkel</0>."
|
msgstr "CommaFeed er kompatibel med Fever API. Bruk følgende URL i din Fever-kompatible mobilklient. Logg inn med brukernavn og din <0>API-nøkkel</0>."
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
msgstr "CommaFeed er kompatibel med Google Reader API. Bruk følgende URL i din Google Reader-kompatible mobilklient. Logg inn med brukernavn og din <0>API-nøkkel</0>."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
msgstr "CommaFeed neste uleste element"
|
msgstr "CommaFeed neste uleste element"
|
||||||
@@ -240,7 +238,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 +291,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 +338,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 +392,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"
|
||||||
@@ -466,6 +458,14 @@ msgstr "Gå til API-dokumentasjonen."
|
|||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "Godbiter"
|
msgstr "Godbiter"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API URL"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Grape"
|
msgid "Grape"
|
||||||
msgstr "Drue"
|
msgstr "Drue"
|
||||||
@@ -570,7 +570,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 +647,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 +655,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 +761,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 +787,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 +867,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 +875,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 +901,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 +913,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 +941,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 +989,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 +998,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 +1014,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 +1047,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"
|
||||||
@@ -1095,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
|
|||||||
msgstr "Denne feeden har et utdatert filter som ikke kan redigeres og ikke blir brukt. Vennligst opprett filteret på nytt med den nye uttrykkseditoren. Det utdaterte filteruttrykket var: <0>{0}</0>"
|
msgstr "Denne feeden har et utdatert filter som ikke kan redigeres og ikke blir brukt. Vennligst opprett filteret på nytt med den nye uttrykkseditoren. Det utdaterte filteruttrykket var: <0>{0}</0>"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
msgstr "Dette er API-nøkkelen din. Den kan brukes til enkelte skrivebeskyttede API-operasjoner og gir tilgang til Fever API. Bruk skjemaet nederst på siden for å generere en ny API-nøkkel"
|
msgstr "Dette er din API-nøkkel. Den kan brukes til noen skrivebeskyttede API-operasjoner og gir tilgang til Fever API og Google Reader API. Bruk skjemaet nederst på siden for å generere en ny API-nøkkel"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
||||||
@@ -1136,7 +1118,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 +1130,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"
|
||||||
@@ -1170,6 +1150,10 @@ msgstr "Nettsted"
|
|||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr "Velkommen! Det ser ut til å være første gang du kjører CommaFeed. Vennligst opprett en administratorkonto for å komme i gang."
|
msgstr "Velkommen! Det ser ut til å være første gang du kjører CommaFeed. Vennligst opprett en administratorkonto for å komme i gang."
|
||||||
|
|
||||||
|
#: src/app/client.ts
|
||||||
|
msgid "Wrong username or password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
msgstr "Gul"
|
msgstr "Gul"
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -216,6 +210,10 @@ msgstr "CommaFeed browser extensie versie {browserExtensionVersion}."
|
|||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
msgstr "CommaFeed is compatibel met de Fever API. Gebruik de volgende URL in uw Fever-compatibele mobiele client. Log in met uw gebruikersnaam en uw <0>API-sleutel</0>."
|
msgstr "CommaFeed is compatibel met de Fever API. Gebruik de volgende URL in uw Fever-compatibele mobiele client. Log in met uw gebruikersnaam en uw <0>API-sleutel</0>."
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
msgstr "CommaFeed is compatibel met de Google Reader API. Gebruik de volgende URL in uw Google Reader-compatibele mobiele client. Log in met uw gebruikersnaam en uw <0>API-sleutel</0>."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
msgstr "CommaFeed volgende ongelezen item"
|
msgstr "CommaFeed volgende ongelezen item"
|
||||||
@@ -240,7 +238,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 +291,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 +338,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 +392,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"
|
||||||
@@ -466,6 +458,14 @@ msgstr "Ga naar de API-documentatie."
|
|||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "Goederen"
|
msgstr "Goederen"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API URL"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Grape"
|
msgid "Grape"
|
||||||
msgstr "Druif"
|
msgstr "Druif"
|
||||||
@@ -570,7 +570,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 +647,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 +655,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 +761,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 +787,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 +867,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 +875,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 +901,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 +913,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 +941,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 +989,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 +998,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 +1014,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 +1047,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"
|
||||||
@@ -1095,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
|
|||||||
msgstr "Deze feed heeft een legacy-filter dat niet kan worden bewerkt en niet wordt toegepast. Maak het filter opnieuw met de nieuwe expressie-editor. De legacy-filterexpressie was: <0>{0}</0>"
|
msgstr "Deze feed heeft een legacy-filter dat niet kan worden bewerkt en niet wordt toegepast. Maak het filter opnieuw met de nieuwe expressie-editor. De legacy-filterexpressie was: <0>{0}</0>"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
msgstr "Dit is je API-sleutel. Het kan worden gebruikt voor sommige alleen-lezen API-bewerkingen en geeft toegang tot de Fever API. Gebruik het formulier onderaan de pagina om een nieuwe API-sleutel te genereren"
|
msgstr "Dit is uw API-sleutel. Deze kan worden gebruikt voor sommige alleen-lezen API-bewerkingen en geeft toegang tot de Fever API en de Google Reader API. Gebruik het formulier onderaan de pagina om een nieuwe API-sleutel te genereren"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
||||||
@@ -1136,7 +1118,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 +1130,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"
|
||||||
@@ -1170,6 +1150,10 @@ msgstr "Website"
|
|||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr "Welkom! Dit lijkt de eerste keer te zijn dat je CommaFeed draait. Maak een beheerdersaccount aan om aan de slag te gaan."
|
msgstr "Welkom! Dit lijkt de eerste keer te zijn dat je CommaFeed draait. Maak een beheerdersaccount aan om aan de slag te gaan."
|
||||||
|
|
||||||
|
#: src/app/client.ts
|
||||||
|
msgid "Wrong username or password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
msgstr "Geel"
|
msgstr "Geel"
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -216,6 +210,10 @@ msgstr "CommaFeed nettlesarutviding versjon {browserExtensionVersion}."
|
|||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
msgstr "CommaFeed er kompatibel med Fever API. Bruk følgjande URL i din Fever-kompatible mobilklient. Logg inn med brukarnamn og din <0>API-nøkkel</0>."
|
msgstr "CommaFeed er kompatibel med Fever API. Bruk følgjande URL i din Fever-kompatible mobilklient. Logg inn med brukarnamn og din <0>API-nøkkel</0>."
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
msgstr "CommaFeed er kompatibel med Google Reader API. Bruk følgjande URL i din Google Reader-kompatible mobilklient. Logg inn med brukarnamn og din <0>API-nøkkel</0>."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
msgstr "CommaFeed neste ulesne element"
|
msgstr "CommaFeed neste ulesne element"
|
||||||
@@ -240,7 +238,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 +291,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 +338,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 +392,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"
|
||||||
@@ -466,6 +458,14 @@ msgstr "Gå til API-dokumentasjonen."
|
|||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "Godbitar"
|
msgstr "Godbitar"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API URL"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Grape"
|
msgid "Grape"
|
||||||
msgstr "Drue"
|
msgstr "Drue"
|
||||||
@@ -570,7 +570,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 +647,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 +655,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 +761,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 +787,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 +867,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 +875,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 +901,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 +913,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 +941,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 +989,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 +998,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 +1014,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 +1047,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"
|
||||||
@@ -1095,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
|
|||||||
msgstr "Denne suapen har eit gamalt filter som ikkje kan redigerast og som ikkje vert brukt. Ver venleg og lag filteret på nytt med den nye uttrykkseditoren. Det gamle filteruttrykket var: <0>{0}</0>"
|
msgstr "Denne suapen har eit gamalt filter som ikkje kan redigerast og som ikkje vert brukt. Ver venleg og lag filteret på nytt med den nye uttrykkseditoren. Det gamle filteruttrykket var: <0>{0}</0>"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
msgstr "Dette er API-nøkkelen din. Han kan brukast til enkelte skrivebeskytta API-handlingar og gjev tilgang til Fever API. Bruk skjemaet nedst på sida for å laga ein ny API-nøkkel"
|
msgstr "Dette er din API-nøkkel. Ho kan brukast til nokre skrivebeskytta API-operasjonar og gir tilgang til Fever API og Google Reader API. Bruk skjemaet nedst på sida for å generere ein ny API-nøkkel"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
||||||
@@ -1136,7 +1118,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 +1130,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"
|
||||||
@@ -1170,6 +1150,10 @@ msgstr "Nettstad"
|
|||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr "Velkomen! Det ser ut til å vera fyrste gongen du køyrer CommaFeed. Ver venleg og opprett ein administratorkonto for å koma i gang."
|
msgstr "Velkomen! Det ser ut til å vera fyrste gongen du køyrer CommaFeed. Ver venleg og opprett ein administratorkonto for å koma i gang."
|
||||||
|
|
||||||
|
#: src/app/client.ts
|
||||||
|
msgid "Wrong username or password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
msgstr "Gul"
|
msgstr "Gul"
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -216,6 +210,10 @@ msgstr "Wersja rozszerzenia przeglądarki CommaFeed {browserExtensionVersion}."
|
|||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
msgstr "CommaFeed jest kompatybilny z API Fever. Użyj następującego adresu URL w swoim kliencie mobilnym zgodnym z Fever. Zaloguj się przy użyciu swojej nazwy użytkownika i <0>klucza API</0>."
|
msgstr "CommaFeed jest kompatybilny z API Fever. Użyj następującego adresu URL w swoim kliencie mobilnym zgodnym z Fever. Zaloguj się przy użyciu swojej nazwy użytkownika i <0>klucza API</0>."
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
msgstr "CommaFeed jest kompatybilny z API Google Reader. Użyj następującego adresu URL w swoim kliencie mobilnym zgodnym z Google Reader. Zaloguj się przy użyciu swojej nazwy użytkownika i <0>klucza API</0>."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
msgstr "Przecinek następny nieprzeczytany element"
|
msgstr "Przecinek następny nieprzeczytany element"
|
||||||
@@ -240,7 +238,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 +291,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 +338,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 +392,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"
|
||||||
@@ -466,6 +458,14 @@ msgstr "Przejdź do dokumentacji API."
|
|||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "Gadżety"
|
msgstr "Gadżety"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API URL"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Grape"
|
msgid "Grape"
|
||||||
msgstr "Winogronowy"
|
msgstr "Winogronowy"
|
||||||
@@ -570,7 +570,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 +647,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 +655,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 +761,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 +787,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 +867,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 +875,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 +901,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 +913,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 +941,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 +989,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 +998,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 +1014,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 +1047,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"
|
||||||
@@ -1095,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
|
|||||||
msgstr "Ten kanał ma stary filtr, którego nie można edytować i który nie jest stosowany. Proszę utworzyć filtr ponownie, korzystając z nowego edytora wyrażeń. Stare wyrażenie filtra to: <0>{0}</0>"
|
msgstr "Ten kanał ma stary filtr, którego nie można edytować i który nie jest stosowany. Proszę utworzyć filtr ponownie, korzystając z nowego edytora wyrażeń. Stare wyrażenie filtra to: <0>{0}</0>"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
msgstr "To jest Twój klucz API. Może być używany do niektórych operacji API tylko do odczytu i zapewnia dostęp do API Fever. Użyj formularza na dole strony, aby wygenerować nowy klucz API"
|
msgstr "To jest Twój klucz API. Może być używany do niektórych operacji API tylko do odczytu i zapewnia dostęp do API Fever i API Google Reader. Użyj formularza na dole strony, aby wygenerować nowy klucz API"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
||||||
@@ -1136,7 +1118,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 +1130,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"
|
||||||
@@ -1170,6 +1150,10 @@ msgstr "Strona internetowa"
|
|||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr "Witaj! Wygląda na to, że uruchamiasz CommaFeed po raz pierwszy. Aby rozpocząć, utwórz konto administratora."
|
msgstr "Witaj! Wygląda na to, że uruchamiasz CommaFeed po raz pierwszy. Aby rozpocząć, utwórz konto administratora."
|
||||||
|
|
||||||
|
#: src/app/client.ts
|
||||||
|
msgid "Wrong username or password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
msgstr "Żółty"
|
msgstr "Żółty"
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -216,6 +210,10 @@ msgstr "Extensão de navegador CommaFeed versão {browserExtensionVersion}."
|
|||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
msgstr "CommaFeed é compatível com a API Fever. Use a URL a seguir no seu aplicativo móvel compatível com Fever. Entre com seu nome de usuário e sua <0>chave de API</0>."
|
msgstr "CommaFeed é compatível com a API Fever. Use a URL a seguir no seu aplicativo móvel compatível com Fever. Entre com seu nome de usuário e sua <0>chave de API</0>."
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
msgstr "CommaFeed é compatível com a API Google Reader. Use a URL a seguir no seu aplicativo móvel compatível com Google Reader. Entre com seu nome de usuário e sua <0>chave de API</0>."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
msgstr "CommaFeed próximo item não lido"
|
msgstr "CommaFeed próximo item não lido"
|
||||||
@@ -240,7 +238,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 +291,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 +338,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 +392,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"
|
||||||
@@ -466,6 +458,14 @@ msgstr "Vá para a documentação da API."
|
|||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "Brindes"
|
msgstr "Brindes"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API URL"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Grape"
|
msgid "Grape"
|
||||||
msgstr "Uva"
|
msgstr "Uva"
|
||||||
@@ -570,7 +570,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 +647,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 +655,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 +761,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 +787,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 +867,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 +875,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 +901,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 +913,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 +941,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 +989,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 +998,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 +1014,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 +1047,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"
|
||||||
@@ -1095,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
|
|||||||
msgstr "Este feed tem um filtro legado que não pode ser editado e não é aplicado. Recrie o filtro usando o novo editor de expressões. A expressão do filtro legado era: <0>{0}</0>"
|
msgstr "Este feed tem um filtro legado que não pode ser editado e não é aplicado. Recrie o filtro usando o novo editor de expressões. A expressão do filtro legado era: <0>{0}</0>"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
msgstr "Esta é sua chave de API. Ela pode ser usada para algumas operações somente leitura da API e concede acesso à API do Fever. Use o formulário abaixo para gerar uma nova chave de API"
|
msgstr "Esta é sua chave de API. Ela pode ser usada para algumas operações de API somente leitura e concede acesso à API Fever e à API Google Reader. Use o formulário na parte inferior da página para gerar uma nova chave de API"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
||||||
@@ -1136,7 +1118,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 +1130,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"
|
||||||
@@ -1170,6 +1150,10 @@ msgstr "Site"
|
|||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr "Bem-vindo! Esta parece ser a primeira vez que você está executando o CommaFeed. Crie uma conta de administrador para começar."
|
msgstr "Bem-vindo! Esta parece ser a primeira vez que você está executando o CommaFeed. Crie uma conta de administrador para começar."
|
||||||
|
|
||||||
|
#: src/app/client.ts
|
||||||
|
msgid "Wrong username or password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
msgstr "Amarelo"
|
msgstr "Amarelo"
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -216,6 +210,10 @@ msgstr "Версия расширения браузера CommaFeed {browserExt
|
|||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
msgstr "CommaFeed совместим с API Fever. Используйте следующий URL-адрес в мобильном клиенте, совместимом с Fever. Войдите в систему, указав свое имя пользователя и <0>API-ключ</0>."
|
msgstr "CommaFeed совместим с API Fever. Используйте следующий URL-адрес в мобильном клиенте, совместимом с Fever. Войдите в систему, указав свое имя пользователя и <0>API-ключ</0>."
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
msgstr "CommaFeed совместим с API Google Reader. Используйте следующий URL-адрес в мобильном клиенте, совместимом с Google Reader. Войдите в систему, указав свое имя пользователя и <0>API-ключ</0>."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
msgstr "CommaFeed следующий непрочитанный элемент"
|
msgstr "CommaFeed следующий непрочитанный элемент"
|
||||||
@@ -240,7 +238,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 +291,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 +338,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 +392,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"
|
||||||
@@ -466,6 +458,14 @@ msgstr "Перейдите к документации по API."
|
|||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "Сладости"
|
msgstr "Сладости"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API URL"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Grape"
|
msgid "Grape"
|
||||||
msgstr "Виноградный"
|
msgstr "Виноградный"
|
||||||
@@ -570,7 +570,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 +647,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 +655,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 +761,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 +787,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 +867,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 +875,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 +901,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 +913,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 +941,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 +989,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 +998,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 +1014,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 +1047,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 "Теги"
|
||||||
@@ -1095,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
|
|||||||
msgstr "Этот фид имеет устаревший фильтр, который нельзя редактировать и который не применяется. Пожалуйста, создайте фильтр заново, используя новый редактор выражений. Устаревшее выражение фильтра было: <0>{0}</0>"
|
msgstr "Этот фид имеет устаревший фильтр, который нельзя редактировать и который не применяется. Пожалуйста, создайте фильтр заново, используя новый редактор выражений. Устаревшее выражение фильтра было: <0>{0}</0>"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
msgstr "Это ваш ключ API. Он может использоваться для некоторых операций API только для чтения и предоставляет доступ к API Fever. Чтобы сгенерировать новый ключ API, воспользуйтесь формой в нижней части страницы"
|
msgstr "Это ваш ключ API. Он может использоваться для некоторых операций API только для чтения и предоставляет доступ к API Fever и API Google Reader. Используйте форму внизу страницы, чтобы сгенерировать новый ключ API"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
||||||
@@ -1136,7 +1118,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 +1130,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 "Имя пользователя или адрес электронной почты"
|
||||||
@@ -1170,6 +1150,10 @@ msgstr "Веб-сайт"
|
|||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr "Добро пожаловать! Похоже, вы запускаете CommaFeed в первый раз. Пожалуйста, создайте учетную запись администратора, чтобы начать работу."
|
msgstr "Добро пожаловать! Похоже, вы запускаете CommaFeed в первый раз. Пожалуйста, создайте учетную запись администратора, чтобы начать работу."
|
||||||
|
|
||||||
|
#: src/app/client.ts
|
||||||
|
msgid "Wrong username or password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
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
|
||||||
@@ -216,6 +210,10 @@ msgstr "Rozšírenie prehliadača CommaFeed verzie {browserExtensionVersion}."
|
|||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
msgstr "CommaFeed je kompatibilný s Fever API. Vo svojom mobilnom klientovi kompatibilnom s Fever použite nasledujúcu adresu URL. Prihláste sa pomocou svojho používateľského mena a <0>kľúča API</0>."
|
msgstr "CommaFeed je kompatibilný s Fever API. Vo svojom mobilnom klientovi kompatibilnom s Fever použite nasledujúcu adresu URL. Prihláste sa pomocou svojho používateľského mena a <0>kľúča API</0>."
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
msgstr "CommaFeed je kompatibilný s Google Reader API. Vo svojom mobilnom klientovi kompatibilnom s Google Reader použite nasledujúcu adresu URL. Prihláste sa pomocou svojho používateľského mena a <0>kľúča API</0>."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
msgstr "CommaFeed ďalšia neprečítaná položka"
|
msgstr "CommaFeed ďalšia neprečítaná položka"
|
||||||
@@ -240,7 +238,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 +291,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 +338,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 +392,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"
|
||||||
@@ -466,6 +458,14 @@ msgstr "Prejdite na dokumentáciu API."
|
|||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "Dobrôtky"
|
msgstr "Dobrôtky"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API URL"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Grape"
|
msgid "Grape"
|
||||||
msgstr "Hroznová"
|
msgstr "Hroznová"
|
||||||
@@ -570,7 +570,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 +647,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 +655,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 +761,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 +787,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 +867,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 +875,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 +901,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 +913,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 +941,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 +989,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 +998,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 +1014,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 +1047,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"
|
||||||
@@ -1095,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
|
|||||||
msgstr "Tento kanál má starší filter, ktorý sa nedá upravovať a nepoužíva sa. Znova vytvorte filter pomocou nového editora výrazov. Pôvodný výraz filtra bol: <0>{0}</0>"
|
msgstr "Tento kanál má starší filter, ktorý sa nedá upravovať a nepoužíva sa. Znova vytvorte filter pomocou nového editora výrazov. Pôvodný výraz filtra bol: <0>{0}</0>"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
msgstr "Toto je váš kľúč API. Môže sa použiť na niektoré operácie rozhrania API len na čítanie a poskytuje prístup k rozhraniu Fever API. Na vygenerovanie nového kľúča API použite formulár v dolnej časti stránky."
|
msgstr "Toto je váš kľúč API. Môže sa použiť pre niektoré operácie API iba na čítanie a udeľuje prístup k Fever API a Google Reader API. Na vygenerovanie nového kľúča API použite formulár v spodnej časti stránky"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
||||||
@@ -1136,7 +1118,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 +1130,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"
|
||||||
@@ -1170,6 +1150,10 @@ msgstr "Webová stránka"
|
|||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr "Vitajte! Zdá sa, že CommaFeed spúšťate prvýkrát. Ak chcete začať, vytvorte si účet správcu."
|
msgstr "Vitajte! Zdá sa, že CommaFeed spúšťate prvýkrát. Ak chcete začať, vytvorte si účet správcu."
|
||||||
|
|
||||||
|
#: src/app/client.ts
|
||||||
|
msgid "Wrong username or password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
msgstr "Žltá"
|
msgstr "Žltá"
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -216,6 +210,10 @@ msgstr "Webbläsartillägget CommaFeed version {browserExtensionVersion}."
|
|||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
msgstr "CommaFeed är kompatibelt med Fever API. Använd följande URL i din Fever-kompatibla mobilklient. Logga in med ditt användarnamn och din <0>API-nyckel</0>."
|
msgstr "CommaFeed är kompatibelt med Fever API. Använd följande URL i din Fever-kompatibla mobilklient. Logga in med ditt användarnamn och din <0>API-nyckel</0>."
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
msgstr "CommaFeed är kompatibelt med Google Reader API. Använd följande URL i din Google Reader-kompatibla mobilklient. Logga in med ditt användarnamn och din <0>API-nyckel</0>."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
msgstr "CommaFeed nästa olästa objekt"
|
msgstr "CommaFeed nästa olästa objekt"
|
||||||
@@ -240,7 +238,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 +291,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 +338,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 +392,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"
|
||||||
@@ -466,6 +458,14 @@ msgstr "Gå till API-dokumentationen."
|
|||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "Godsaker"
|
msgstr "Godsaker"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API URL"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Grape"
|
msgid "Grape"
|
||||||
msgstr "Lila"
|
msgstr "Lila"
|
||||||
@@ -570,7 +570,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 +647,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 +655,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 +761,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 +787,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 +867,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 +875,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 +901,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 +913,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 +941,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 +989,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 +998,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 +1014,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 +1047,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"
|
||||||
@@ -1095,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
|
|||||||
msgstr "Detta flöde har ett gammalt filter som inte kan redigeras och inte tillämpas. Skapa filtret på nytt med den nya uttryckseditorern. Det gamla filteruttrycket var: <0>{0}</0>"
|
msgstr "Detta flöde har ett gammalt filter som inte kan redigeras och inte tillämpas. Skapa filtret på nytt med den nya uttryckseditorern. Det gamla filteruttrycket var: <0>{0}</0>"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
msgstr "Detta är din API-nyckel. Den kan användas för vissa skrivskyddade API-operationer och ger åtkomst till Fever API. Använd formuläret längst ner på sidan för att generera en ny API-nyckel"
|
msgstr "Det här är din API-nyckel. Den kan användas för vissa skrivskyddade API-åtgärder och ger åtkomst till Fever API och Google Reader API. Använd formuläret längst ner på sidan för att generera en ny API-nyckel"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
||||||
@@ -1136,7 +1118,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 +1130,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"
|
||||||
@@ -1170,6 +1150,10 @@ msgstr "Webbplats"
|
|||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr "Välkommen! Det verkar vara första gången du kör CommaFeed. Skapa ett administratörskonto för att komma igång."
|
msgstr "Välkommen! Det verkar vara första gången du kör CommaFeed. Skapa ett administratörskonto för att komma igång."
|
||||||
|
|
||||||
|
#: src/app/client.ts
|
||||||
|
msgid "Wrong username or password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
msgstr "Gul"
|
msgstr "Gul"
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -216,6 +210,10 @@ msgstr "CommaFeed tarayıcı eklentisi sürüm {browserExtensionVersion}."
|
|||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
msgstr "CommaFeed, Fever API ile uyumludur. Fever uyumlu mobil istemcinizde aşağıdaki URL'yi kullanın. Kullanıcı adınız ve <0>API anahtarınız</0> ile giriş yapın."
|
msgstr "CommaFeed, Fever API ile uyumludur. Fever uyumlu mobil istemcinizde aşağıdaki URL'yi kullanın. Kullanıcı adınız ve <0>API anahtarınız</0> ile giriş yapın."
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
msgstr "CommaFeed, Google Reader API ile uyumludur. Google Reader uyumlu mobil istemcinizde aşağıdaki URL'yi kullanın. Kullanıcı adınız ve <0>API anahtarınız</0> ile giriş yapın."
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
msgstr "CommaFeed sonraki okunmamış öğe"
|
msgstr "CommaFeed sonraki okunmamış öğe"
|
||||||
@@ -240,7 +238,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 +291,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 +338,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 +392,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"
|
||||||
@@ -466,6 +458,14 @@ msgstr "API belgelerine gidin."
|
|||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "İyilikler"
|
msgstr "İyilikler"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API URL"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Grape"
|
msgid "Grape"
|
||||||
msgstr "Üzüm"
|
msgstr "Üzüm"
|
||||||
@@ -570,7 +570,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 +647,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 +655,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 +761,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 +787,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 +867,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 +875,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 +901,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 +913,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 +941,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 +989,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 +998,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 +1014,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 +1047,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"
|
||||||
@@ -1095,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
|
|||||||
msgstr "Bu beslemenin düzenlenemeyen ve uygulanmayan eski bir filtresi var. Lütfen yeni ifade düzenleyiciyi kullanarak filtreyi yeniden oluşturun. Eski filtre ifadesi şuydu: <0>{0}</0>"
|
msgstr "Bu beslemenin düzenlenemeyen ve uygulanmayan eski bir filtresi var. Lütfen yeni ifade düzenleyiciyi kullanarak filtreyi yeniden oluşturun. Eski filtre ifadesi şuydu: <0>{0}</0>"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
msgstr "Bu sizin API anahtarınızdır. Bazı salt okunur API işlemleri için kullanılabilir ve Fever API'sine erişim sağlar. Yeni bir API anahtarı oluşturmak için sayfanın altındaki formu kullanın"
|
msgstr "Bu, API anahtarınızdır. Bazı salt okunur API işlemleri için kullanılabilir ve Fever API ile Google Reader API'ye erişim sağlar. Yeni bir API anahtarı oluşturmak için sayfanın altındaki formu kullanın"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
||||||
@@ -1136,7 +1118,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 +1130,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"
|
||||||
@@ -1170,6 +1150,10 @@ msgstr "Web sitesi"
|
|||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr "Hoş geldiniz! Görünüşe göre CommaFeed'i ilk kez çalıştırıyorsunuz. Başlamak için lütfen bir yönetici hesabı oluşturun."
|
msgstr "Hoş geldiniz! Görünüşe göre CommaFeed'i ilk kez çalıştırıyorsunuz. Başlamak için lütfen bir yönetici hesabı oluşturun."
|
||||||
|
|
||||||
|
#: src/app/client.ts
|
||||||
|
msgid "Wrong username or password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
msgstr "Sarı"
|
msgstr "Sarı"
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -216,6 +210,10 @@ msgstr "CommaFeed的浏览器扩展版本:{browserExtensionVersion}。"
|
|||||||
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
msgstr "CommaFeed 和 Fever API 兼容,可以在您Fever兼容的移动客户端中使用以下网址,通过用户名和<0>API密钥</0>登录。"
|
msgstr "CommaFeed 和 Fever API 兼容,可以在您Fever兼容的移动客户端中使用以下网址,通过用户名和<0>API密钥</0>登录。"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
|
||||||
|
msgstr "CommaFeed 和 Google Reader API 兼容,可以在您Google Reader兼容的移动客户端中使用以下网址,通过用户名和<0>API密钥</0>登录。"
|
||||||
|
|
||||||
#: src/pages/app/AboutPage.tsx
|
#: src/pages/app/AboutPage.tsx
|
||||||
msgid "CommaFeed next unread item"
|
msgid "CommaFeed next unread item"
|
||||||
msgstr "CommaFeed 下一个未读项目"
|
msgstr "CommaFeed 下一个未读项目"
|
||||||
@@ -240,7 +238,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 +291,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 +338,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 +392,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"
|
||||||
@@ -466,6 +458,14 @@ msgstr "API 文档"
|
|||||||
msgid "Goodies"
|
msgid "Goodies"
|
||||||
msgstr "好东西"
|
msgstr "好东西"
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
|
msgid "Google Reader API URL"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Grape"
|
msgid "Grape"
|
||||||
msgstr "深紫"
|
msgstr "深紫"
|
||||||
@@ -570,7 +570,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 +647,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 +655,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 +761,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 +787,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 +867,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 +875,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 +901,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 +913,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 +941,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 +989,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 +998,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 +1014,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 +1047,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 "标签"
|
||||||
@@ -1095,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
|
|||||||
msgstr "此信息流具有无法编辑且未应用的旧版过滤器。请使用新的表达式编辑器重新创建过滤器。旧版过滤器表达式为:<0>{0}</0>"
|
msgstr "此信息流具有无法编辑且未应用的旧版过滤器。请使用新的表达式编辑器重新创建过滤器。旧版过滤器表达式为:<0>{0}</0>"
|
||||||
|
|
||||||
#: src/components/settings/ProfileSettings.tsx
|
#: src/components/settings/ProfileSettings.tsx
|
||||||
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
|
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
|
||||||
msgstr "这是您的API 密钥,它可以被用于Fever API的只读操作及访问授权。使用页面底部的表单生成一个新的API密钥。"
|
msgstr "这是您的 API 密钥。它可用于某些只读 API 操作,并授予对 Fever API 和 Google Reader API 的访问权限。使用页面底部的表单生成新的 API 密钥"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
|
||||||
@@ -1136,7 +1118,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 +1130,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 "用户名或电子邮件"
|
||||||
@@ -1170,6 +1150,10 @@ msgstr "网站"
|
|||||||
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
|
||||||
msgstr "欢迎!当前页仅当您第一次使用CommaFeed时出现,请创建一个管理员帐号以开始使用。"
|
msgstr "欢迎!当前页仅当您第一次使用CommaFeed时出现,请创建一个管理员帐号以开始使用。"
|
||||||
|
|
||||||
|
#: src/app/client.ts
|
||||||
|
msgid "Wrong username or password"
|
||||||
|
msgstr "用户名或密码错误"
|
||||||
|
|
||||||
#: src/components/settings/DisplaySettings.tsx
|
#: src/components/settings/DisplaySettings.tsx
|
||||||
msgid "Yellow"
|
msgid "Yellow"
|
||||||
msgstr "黄"
|
msgstr "黄"
|
||||||
|
|||||||
@@ -15,9 +15,10 @@ dayjs.extend(relativeTime)
|
|||||||
dayjs.extend(duration)
|
dayjs.extend(duration)
|
||||||
|
|
||||||
const root = document.getElementById("root")
|
const root = document.getElementById("root")
|
||||||
root &&
|
if (!root) throw new Error("root element not found")
|
||||||
ReactDOM.createRoot(root).render(
|
|
||||||
<Provider store={store}>
|
ReactDOM.createRoot(root).render(
|
||||||
<App />
|
<Provider store={store}>
|
||||||
</Provider>
|
<App />
|
||||||
)
|
</Provider>
|
||||||
|
)
|
||||||
|
|||||||
@@ -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,61 +251,69 @@ export default function Layout(props: Readonly<LayoutProps>) {
|
|||||||
|
|
||||||
if (loading) return <LoadingPage />
|
if (loading) return <LoadingPage />
|
||||||
return (
|
return (
|
||||||
<Box {...swipeHandlers}>
|
<>
|
||||||
<AppShell
|
<UnreadCountTitleHandler enabled={unreadCountTitle} />
|
||||||
header={{ height: Constants.layout.headerHeight, collapsed: headerInFooter }}
|
<UnreadCountFaviconHandler enabled={unreadCountFavicon} />
|
||||||
footer={{ height: Constants.layout.headerHeight, collapsed: !headerInFooter }}
|
<BrowserExtensionBadgeUnreadCountHandler />
|
||||||
navbar={{
|
<CustomJsHandler />
|
||||||
width: sidebarWidth,
|
<CustomCssHandler />
|
||||||
breakpoint: Constants.layout.mobileBreakpoint,
|
<DisablePullToRefresh enabled={disablePullToRefresh} />
|
||||||
collapsed: { mobile: !mobileMenuOpen, desktop: !props.sidebarVisible },
|
<Box {...swipeHandlers}>
|
||||||
}}
|
<AppShell
|
||||||
padding={{ base: 6, [Constants.layout.mobileBreakpointName]: "md" }}
|
header={{ height: Constants.layout.headerHeight, collapsed: headerInFooter }}
|
||||||
>
|
footer={{ height: Constants.layout.headerHeight, collapsed: !headerInFooter }}
|
||||||
<AppShell.Header>{!headerInFooter && header}</AppShell.Header>
|
navbar={{
|
||||||
<AppShell.Footer>{headerInFooter && header}</AppShell.Footer>
|
width: sidebarWidth,
|
||||||
<AppShell.Navbar p={sidebarPadding}>
|
breakpoint: Constants.layout.mobileBreakpoint,
|
||||||
<AppShell.Section grow component={ScrollArea} mx="-sm" px="sm">
|
collapsed: { mobile: !mobileMenuOpen, desktop: !props.sidebarVisible },
|
||||||
<Box className={classes.sidebarContent}>{props.sidebar}</Box>
|
}}
|
||||||
</AppShell.Section>
|
padding={{ base: 6, [Constants.layout.mobileBreakpointName]: "md" }}
|
||||||
</AppShell.Navbar>
|
>
|
||||||
<OnDesktop>
|
<AppShell.Header>{!headerInFooter && header}</AppShell.Header>
|
||||||
<Draggable
|
<AppShell.Footer>{headerInFooter && header}</AppShell.Footer>
|
||||||
nodeRef={draggableSeparator as RefObject<HTMLElement>}
|
<AppShell.Navbar p={sidebarPadding}>
|
||||||
axis="x"
|
<AppShell.Section grow component={ScrollArea} mx="-sm" px="sm">
|
||||||
defaultPosition={{
|
<Box className={classes.sidebarContent}>{props.sidebar}</Box>
|
||||||
x: sidebarWidth,
|
</AppShell.Section>
|
||||||
y: 0,
|
</AppShell.Navbar>
|
||||||
}}
|
<OnDesktop>
|
||||||
bounds={{
|
<Draggable
|
||||||
left: 120,
|
nodeRef={draggableSeparator as RefObject<HTMLElement>}
|
||||||
right: 1000,
|
axis="x"
|
||||||
}}
|
defaultPosition={{
|
||||||
grid={[30, 30]}
|
x: sidebarWidth,
|
||||||
onDrag={(_e, data) => {
|
y: 0,
|
||||||
dispatch(setSidebarWidth(data.x))
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Box
|
|
||||||
ref={draggableSeparator}
|
|
||||||
style={{
|
|
||||||
position: "fixed",
|
|
||||||
height: "100%",
|
|
||||||
width: "10px",
|
|
||||||
cursor: "ew-resize",
|
|
||||||
}}
|
}}
|
||||||
/>
|
bounds={{
|
||||||
</Draggable>
|
left: 120,
|
||||||
</OnDesktop>
|
right: 1000,
|
||||||
|
}}
|
||||||
|
grid={[30, 30]}
|
||||||
|
onDrag={(_e, data) => {
|
||||||
|
dispatch(setSidebarWidth(data.x))
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
ref={draggableSeparator}
|
||||||
|
style={{
|
||||||
|
position: "fixed",
|
||||||
|
height: "100%",
|
||||||
|
width: "10px",
|
||||||
|
cursor: "ew-resize",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Draggable>
|
||||||
|
</OnDesktop>
|
||||||
|
|
||||||
<AppShell.Main>
|
<AppShell.Main>
|
||||||
<Suspense fallback={<Loader />}>
|
<Suspense fallback={<Loader />}>
|
||||||
<AnnouncementDialog />
|
<AnnouncementDialog />
|
||||||
<MarkAllAsReadConfirmationDialog />
|
<MarkAllAsReadConfirmationDialog />
|
||||||
<Outlet />
|
<Outlet />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</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>
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<!DOCTYPE module PUBLIC
|
<!DOCTYPE module PUBLIC
|
||||||
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
|
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
|
||||||
"https://checkstyle.org/dtds/configuration_1_3.dtd">
|
"https://checkstyle.org/dtds/configuration_1_3.dtd">
|
||||||
|
|
||||||
<module name="Checker">
|
<module name="Checker">
|
||||||
<property name="charset" value="UTF-8" />
|
<property name="charset" value="UTF-8" />
|
||||||
<property name="fileExtensions" value="java" />
|
<property name="fileExtensions" value="java" />
|
||||||
@@ -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" />
|
||||||
|
|
||||||
@@ -60,7 +55,7 @@
|
|||||||
<module name="EmptyCatchBlock">
|
<module name="EmptyCatchBlock">
|
||||||
<property name="exceptionVariableName" value="ignore|ignored" />
|
<property name="exceptionVariableName" value="ignore|ignored" />
|
||||||
<message key="catch.block.empty"
|
<message key="catch.block.empty"
|
||||||
value="Empty catch block. You can use the name 'ignore' or 'ignored' for the exception variable if you really want an empty catch block, but you should strongly consider at the very least logging something." />
|
value="Empty catch block. You can use the name 'ignore' or 'ignored' for the exception variable if you really want an empty catch block, but you should strongly consider at the very least logging something." />
|
||||||
</module>
|
</module>
|
||||||
<module name="LeftCurly" />
|
<module name="LeftCurly" />
|
||||||
<module name="NeedBraces" />
|
<module name="NeedBraces" />
|
||||||
@@ -76,7 +71,7 @@
|
|||||||
<module name="FallThrough" />
|
<module name="FallThrough" />
|
||||||
<module name="IllegalInstantiation">
|
<module name="IllegalInstantiation">
|
||||||
<property name="classes"
|
<property name="classes"
|
||||||
value="java.lang.Boolean, java.lang.Byte, java.lang.Character, java.lang.Double, java.lang.Float, java.lang.Integer, java.lang.Long, java.lang.Short" />
|
value="java.lang.Boolean, java.lang.Byte, java.lang.Character, java.lang.Double, java.lang.Float, java.lang.Integer, java.lang.Long, java.lang.Short" />
|
||||||
</module>
|
</module>
|
||||||
<module name="IllegalType" />
|
<module name="IllegalType" />
|
||||||
<module name="ModifiedControlVariable">
|
<module name="ModifiedControlVariable">
|
||||||
@@ -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
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -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.4.0-jre@sha256:524f0d04723aff42ed4142ab2621fa55f22cb691763cd75b59eee86749e2e872
|
||||||
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:34cd9e9fd437c0a095ec39cb2e73422c9f30821b0d0848ed74fd0d43bae4d958
|
||||||
ARG TARGETARCH
|
ARG TARGETARCH
|
||||||
|
|
||||||
EXPOSE 8082
|
EXPOSE 8082
|
||||||
|
|||||||
@@ -93,3 +93,12 @@ Tags are of the form `<version>-<database>[-jvm]` where:
|
|||||||
- `master` (always points to the latest git commit)
|
- `master` (always points to the latest git commit)
|
||||||
- `<database>` is the database to use (`h2`, `postgresql`, `mysql` or `mariadb`)
|
- `<database>` is the database to use (`h2`, `postgresql`, `mysql` or `mariadb`)
|
||||||
- `-jvm` is optional and indicates that CommaFeed is running on a JVM, and not compiled natively.
|
- `-jvm` is optional and indicates that CommaFeed is running on a JVM, and not compiled natively.
|
||||||
|
|
||||||
|
## FAQ
|
||||||
|
|
||||||
|
### Getting "Access to local address blocked" when adding a feed
|
||||||
|
|
||||||
|
CommaFeed blocks access to local resources by default to prevent [SSRF](https://en.wikipedia.org/wiki/Server-side_request_forgery) attacks.
|
||||||
|
If you want to subscribe to feeds that are only available on your local network, you can disable this security measure by setting the `COMMAFEED_HTTP_CLIENT_BLOCK_LOCAL_ADDRESSES` variable to `false`.
|
||||||
|
Do this only if you trust all users of your CommaFeed instance not to access private resources.
|
||||||
|
|
||||||
|
|||||||
@@ -1,40 +1,59 @@
|
|||||||
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;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.SystemProperties;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Singleton
|
@Singleton
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class CommaFeedApplication {
|
public class CommaFeedApplication {
|
||||||
|
|
||||||
private final FeedRefreshEngine feedRefreshEngine;
|
private final FeedRefreshEngine feedRefreshEngine;
|
||||||
private final TaskScheduler taskScheduler;
|
private final TaskScheduler taskScheduler;
|
||||||
private final CommaFeedConfiguration config;
|
private final CommaFeedConfiguration config;
|
||||||
|
|
||||||
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());
|
// disable entity expansion limits added in JDK24+ (#1961)
|
||||||
|
// we already strip doctype declarations in XMLCleaner to prevent xxe attacks
|
||||||
|
// we also already limit the size of feeds we download in HttpGetter
|
||||||
|
System.setProperty(SystemProperties.JDK_XML_MAX_GENERAL_ENTITY_SIZE_LIMIT, "0");
|
||||||
|
System.setProperty(SystemProperties.JDK_XML_TOTAL_ENTITY_SIZE_LIMIT, "0");
|
||||||
|
|
||||||
feedRefreshEngine.start();
|
PasswordConstraintValidator.setMinimumPasswordLength(
|
||||||
taskScheduler.start();
|
config.users().minimumPasswordLength());
|
||||||
}
|
|
||||||
|
|
||||||
public void stop(@Observes ShutdownEvent ev) {
|
if (config.imageProxyEnabled()) {
|
||||||
log.info("shutting down...");
|
ImageProxyUrl.generateKey();
|
||||||
|
}
|
||||||
|
|
||||||
feedRefreshEngine.stop();
|
if (config.passwordRecoveryEnabled() && config.passwordRecoveryPublicBaseUrl().isEmpty()) {
|
||||||
taskScheduler.stop();
|
throw new IllegalStateException(
|
||||||
}
|
"password recovery is enabled but no public base url is set");
|
||||||
|
}
|
||||||
|
|
||||||
|
feedRefreshEngine.start();
|
||||||
|
taskScheduler.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop(@Observes ShutdownEvent ev) {
|
||||||
|
log.info("shutting down...");
|
||||||
|
|
||||||
|
feedRefreshEngine.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,391 +9,362 @@ 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)
|
||||||
public interface CommaFeedConfiguration {
|
public interface CommaFeedConfiguration {
|
||||||
/**
|
/**
|
||||||
* Whether to expose a robots.txt file that disallows web crawlers and search engine indexers.
|
* Whether to expose a robots.txt file that disallows web crawlers and search engine indexers.
|
||||||
*/
|
*/
|
||||||
@WithDefault("true")
|
@WithDefault("true")
|
||||||
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
|
||||||
@WithDefault("false")
|
* that are followed.
|
||||||
boolean imageProxyEnabled();
|
*/
|
||||||
|
@WithDefault("false")
|
||||||
|
boolean imageProxyEnabled();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
* The base URL of the application to use in the password recovery link in the email. We can't
|
||||||
*/
|
* use the URL sent by the browser of the user because of malicious Host header injection
|
||||||
Optional<String> announcement();
|
* attacks.
|
||||||
|
*/
|
||||||
|
Optional<String> passwordRecoveryPublicBaseUrl();
|
||||||
|
|
||||||
/**
|
/** Message displayed in a notification at the bottom of the page. */
|
||||||
* Google Auth key for fetching Youtube channel favicons.
|
Optional<String> announcement();
|
||||||
*/
|
|
||||||
Optional<String> googleAuthKey();
|
|
||||||
|
|
||||||
/**
|
/** Google Auth key for fetching Youtube channel favicons. */
|
||||||
* HTTP client configuration
|
Optional<String> googleAuthKey();
|
||||||
*/
|
|
||||||
@ConfigDocSection
|
|
||||||
HttpClient httpClient();
|
|
||||||
|
|
||||||
/**
|
/** HTTP client configuration */
|
||||||
* Feed refresh engine settings.
|
@ConfigDocSection
|
||||||
*/
|
HttpClient httpClient();
|
||||||
@ConfigDocSection
|
|
||||||
FeedRefresh feedRefresh();
|
|
||||||
|
|
||||||
/**
|
/** Feed refresh engine settings. */
|
||||||
* Push notification settings.
|
@ConfigDocSection
|
||||||
*/
|
FeedRefresh feedRefresh();
|
||||||
@ConfigDocSection
|
|
||||||
PushNotifications pushNotifications();
|
|
||||||
|
|
||||||
/**
|
/** Push notification settings. */
|
||||||
* Database settings.
|
@ConfigDocSection
|
||||||
*/
|
PushNotifications pushNotifications();
|
||||||
@ConfigDocSection
|
|
||||||
Database database();
|
|
||||||
|
|
||||||
/**
|
/** Database settings. */
|
||||||
* Users settings.
|
@ConfigDocSection
|
||||||
*/
|
Database database();
|
||||||
@ConfigDocSection
|
|
||||||
Users users();
|
|
||||||
|
|
||||||
/**
|
/** Users settings. */
|
||||||
* Websocket settings.
|
@ConfigDocSection
|
||||||
*/
|
Users users();
|
||||||
@ConfigDocSection
|
|
||||||
Websocket websocket();
|
|
||||||
|
|
||||||
/**
|
/** Websocket settings. */
|
||||||
* Duration to wait for the feed refresh engine and the task scheduler to stop when the application is shutting down.
|
@ConfigDocSection
|
||||||
*/
|
Websocket websocket();
|
||||||
@WithDefault("2s")
|
|
||||||
Duration shutdownTimeout();
|
|
||||||
|
|
||||||
interface HttpClient {
|
/**
|
||||||
/**
|
* Duration to wait for the feed refresh engine and the task scheduler to stop when the
|
||||||
* User-Agent string that will be used by the http client, leave empty for the default one.
|
* application is shutting down.
|
||||||
*/
|
*/
|
||||||
Optional<String> userAgent();
|
@WithDefault("2s")
|
||||||
|
Duration shutdownTimeout();
|
||||||
|
|
||||||
/**
|
interface HttpClient {
|
||||||
* Time to wait for a connection to be established.
|
/**
|
||||||
*/
|
* User-Agent string that will be used by the http client, leave empty for the default one.
|
||||||
@WithDefault("5s")
|
*/
|
||||||
Duration connectTimeout();
|
Optional<String> userAgent();
|
||||||
|
|
||||||
/**
|
/** Time to wait for a connection to be established. */
|
||||||
* Time to wait for SSL handshake to complete.
|
@WithDefault("5s")
|
||||||
*/
|
Duration connectTimeout();
|
||||||
@WithDefault("5s")
|
|
||||||
Duration sslHandshakeTimeout();
|
|
||||||
|
|
||||||
/**
|
/** Time to wait for SSL handshake to complete. */
|
||||||
* Time to wait between two packets before timeout.
|
@WithDefault("5s")
|
||||||
*/
|
Duration sslHandshakeTimeout();
|
||||||
@WithDefault("10s")
|
|
||||||
Duration socketTimeout();
|
|
||||||
|
|
||||||
/**
|
/** Time to wait between two packets before timeout. */
|
||||||
* Time to wait for the full response to be received.
|
@WithDefault("10s")
|
||||||
*/
|
Duration socketTimeout();
|
||||||
@WithDefault("10s")
|
|
||||||
Duration responseTimeout();
|
|
||||||
|
|
||||||
/**
|
/** Time to wait for the full response to be received. */
|
||||||
* Time to live for a connection in the pool.
|
@WithDefault("10s")
|
||||||
*/
|
Duration responseTimeout();
|
||||||
@WithDefault("30s")
|
|
||||||
Duration connectionTimeToLive();
|
|
||||||
|
|
||||||
/**
|
/** Time to live for a connection in the pool. */
|
||||||
* Time between eviction runs for idle connections.
|
@WithDefault("30s")
|
||||||
*/
|
Duration connectionTimeToLive();
|
||||||
@WithDefault("1m")
|
|
||||||
Duration idleConnectionsEvictionInterval();
|
|
||||||
|
|
||||||
/**
|
/** Time between eviction runs for idle connections. */
|
||||||
* If a feed is larger than this, it will be discarded to prevent memory issues while parsing the feed.
|
@WithDefault("1m")
|
||||||
*/
|
Duration idleConnectionsEvictionInterval();
|
||||||
@WithDefault("5M")
|
|
||||||
MemorySize maxResponseSize();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prevent access to local addresses to mitigate server-side request forgery (SSRF) attacks, which could potentially expose internal
|
* If a feed is larger than this, it will be discarded to prevent memory issues while
|
||||||
* resources.
|
* parsing the feed.
|
||||||
*
|
*/
|
||||||
* You may want to enable this if you host a public instance of CommaFeed with registrations open.
|
@WithDefault("5M")
|
||||||
*/
|
MemorySize maxResponseSize();
|
||||||
@WithDefault("false")
|
|
||||||
boolean blockLocalAddresses();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HTTP client cache configuration
|
* Prevent access to local addresses to mitigate server-side request forgery (SSRF) attacks,
|
||||||
*/
|
* which could potentially expose internal resources.
|
||||||
@ConfigDocSection
|
*
|
||||||
HttpClientCache cache();
|
* <p>You may want to enable this if you host a public instance of CommaFeed with
|
||||||
}
|
* registrations open.
|
||||||
|
*/
|
||||||
|
@WithDefault("true")
|
||||||
|
boolean blockLocalAddresses();
|
||||||
|
|
||||||
interface HttpClientCache {
|
/** HTTP client cache configuration */
|
||||||
/**
|
@ConfigDocSection
|
||||||
* 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
|
HttpClientCache cache();
|
||||||
* first time or when clicking "fetch all my feeds now").
|
}
|
||||||
*/
|
|
||||||
@WithDefault("true")
|
|
||||||
boolean enabled();
|
|
||||||
|
|
||||||
/**
|
interface HttpClientCache {
|
||||||
* Maximum amount of memory the cache can use.
|
/**
|
||||||
*/
|
* Whether to enable the cache. This cache is used to avoid spamming feeds in short bursts
|
||||||
@WithDefault("10M")
|
* (e.g. when subscribing to a feed for the first time or when clicking "fetch all my feeds
|
||||||
MemorySize maximumMemorySize();
|
* now").
|
||||||
|
*/
|
||||||
|
@WithDefault("true")
|
||||||
|
boolean enabled();
|
||||||
|
|
||||||
/**
|
/** Maximum amount of memory the cache can use. */
|
||||||
* Duration after which an entry is removed from the cache.
|
@WithDefault("10M")
|
||||||
*/
|
MemorySize maximumMemorySize();
|
||||||
@WithDefault("1m")
|
|
||||||
Duration expiration();
|
|
||||||
}
|
|
||||||
|
|
||||||
interface FeedRefresh {
|
/** Duration after which an entry is removed from the cache. */
|
||||||
/**
|
@WithDefault("1m")
|
||||||
* Default amount of time CommaFeed will wait before refreshing a feed.
|
Duration expiration();
|
||||||
*/
|
}
|
||||||
@WithDefault("5m")
|
|
||||||
Duration interval();
|
|
||||||
|
|
||||||
/**
|
interface FeedRefresh {
|
||||||
* Maximum amount of time CommaFeed will wait before refreshing a feed. This is used as an upper bound when:
|
/** Default amount of time CommaFeed will wait before refreshing a feed. */
|
||||||
*
|
@WithDefault("5m")
|
||||||
* <ul>
|
Duration interval();
|
||||||
* <li>an error occurs while refreshing a feed and we're backing off exponentially</li>
|
|
||||||
* <li>we receive a Cache-Control header from the feed</li>
|
|
||||||
* <li>we receive a Retry-After header from the feed</li>
|
|
||||||
* </ul>
|
|
||||||
*/
|
|
||||||
@WithDefault("4h")
|
|
||||||
Duration maxInterval();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If enabled, CommaFeed will calculate the next refresh time based on the feed's average time between entries and the time since
|
* Maximum amount of time CommaFeed will wait before refreshing a feed. This is used as an
|
||||||
* the last entry was published. The interval will be sometimes between the default refresh interval
|
* upper bound when:
|
||||||
* (`commafeed.feed-refresh.interval`) and the maximum refresh interval (`commafeed.feed-refresh.max-interval`).
|
*
|
||||||
*
|
* <ul>
|
||||||
* See {@link FeedRefreshIntervalCalculator} for details.
|
* <li>an error occurs while refreshing a feed and we're backing off exponentially
|
||||||
*/
|
* <li>we receive a Cache-Control header from the feed
|
||||||
@WithDefault("true")
|
* <li>we receive a Retry-After header from the feed
|
||||||
boolean intervalEmpirical();
|
* </ul>
|
||||||
|
*/
|
||||||
|
@WithDefault("4h")
|
||||||
|
Duration maxInterval();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Feed refresh engine error handling settings.
|
* If enabled, CommaFeed will calculate the next refresh time based on the feed's average
|
||||||
*/
|
* time between entries and the time since the last entry was published. The interval will
|
||||||
@ConfigDocSection
|
* be sometimes between the default refresh interval (`commafeed.feed-refresh.interval`) and
|
||||||
FeedRefreshErrorHandling errors();
|
* the maximum refresh interval (`commafeed.feed-refresh.max-interval`).
|
||||||
|
*
|
||||||
|
* <p>See {@link FeedRefreshIntervalCalculator} for details.
|
||||||
|
*/
|
||||||
|
@WithDefault("true")
|
||||||
|
boolean intervalEmpirical();
|
||||||
|
|
||||||
/**
|
/** Feed refresh engine error handling settings. */
|
||||||
* Amount of http threads used to fetch feeds.
|
@ConfigDocSection
|
||||||
*/
|
FeedRefreshErrorHandling errors();
|
||||||
@Min(1)
|
|
||||||
@WithDefault("3")
|
|
||||||
int httpThreads();
|
|
||||||
|
|
||||||
/**
|
/** Amount of http threads used to fetch feeds. */
|
||||||
* Amount of threads used to insert new entries in the database.
|
@Min(1)
|
||||||
*/
|
@WithDefault("3")
|
||||||
@Min(1)
|
int httpThreads();
|
||||||
@WithDefault("1")
|
|
||||||
int databaseThreads();
|
|
||||||
|
|
||||||
/**
|
/** Amount of threads used to insert new entries in the database. */
|
||||||
* Duration after which a user is considered inactive. Feeds for inactive users are not refreshed until they log in again.
|
@Min(1)
|
||||||
*
|
@WithDefault("1")
|
||||||
* 0 to disable.
|
int databaseThreads();
|
||||||
*/
|
|
||||||
@WithDefault("0")
|
|
||||||
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 a user is considered inactive. Feeds for inactive users are not
|
||||||
*/
|
* refreshed until they log in again.
|
||||||
@WithDefault("500ms")
|
*
|
||||||
Duration filteringExpressionEvaluationTimeout();
|
* <p>0 to disable.
|
||||||
|
*/
|
||||||
|
@WithDefault("0")
|
||||||
|
Duration userInactivityPeriod();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Duration after which the "Fetch all my feeds now" action is available again after use to avoid spamming feeds.
|
* Duration after which the evaluation of a filtering expresion to mark an entry as read is
|
||||||
*/
|
* considered to have timed out.
|
||||||
@WithDefault("0")
|
*/
|
||||||
Duration forceRefreshCooldownDuration();
|
@WithDefault("500ms")
|
||||||
}
|
Duration filteringExpressionEvaluationTimeout();
|
||||||
|
|
||||||
interface PushNotifications {
|
/**
|
||||||
/**
|
* Duration after which the "Fetch all my feeds now" action is available again after use to
|
||||||
* Whether to enable push notifications to notify users of new entries in their feeds.
|
* avoid spamming feeds.
|
||||||
*/
|
*/
|
||||||
@WithDefault("true")
|
@WithDefault("0")
|
||||||
boolean enabled();
|
Duration forceRefreshCooldownDuration();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
interface PushNotifications {
|
||||||
* Amount of threads used to send external notifications about new entries.
|
/** Whether to enable push notifications to notify users of new entries in their feeds. */
|
||||||
*/
|
@WithDefault("true")
|
||||||
@Min(1)
|
boolean enabled();
|
||||||
@WithDefault("5")
|
|
||||||
int threads();
|
|
||||||
|
|
||||||
/**
|
/** Amount of threads used to send external notifications about new entries. */
|
||||||
* Maximum amount of notifications that can be queued before new notifications are discarded.
|
@Min(1)
|
||||||
*/
|
@WithDefault("5")
|
||||||
@Min(1)
|
int threads();
|
||||||
@WithDefault("100")
|
|
||||||
int queueCapacity();
|
|
||||||
}
|
|
||||||
|
|
||||||
interface FeedRefreshErrorHandling {
|
/**
|
||||||
/**
|
* Maximum amount of notifications that can be queued before new notifications are
|
||||||
* Number of retries before backoff is applied.
|
* discarded.
|
||||||
*/
|
*/
|
||||||
@Min(0)
|
@Min(1)
|
||||||
@WithDefault("3")
|
@WithDefault("100")
|
||||||
int retriesBeforeBackoff();
|
int queueCapacity();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
interface FeedRefreshErrorHandling {
|
||||||
* Duration to wait before retrying after an error. Will be multiplied by the number of errors since the last successful fetch.
|
/** Number of retries before backoff is applied. */
|
||||||
*/
|
@Min(0)
|
||||||
@WithDefault("1h")
|
@WithDefault("3")
|
||||||
Duration backoffInterval();
|
int retriesBeforeBackoff();
|
||||||
}
|
|
||||||
|
|
||||||
interface Database {
|
/**
|
||||||
/**
|
* Duration to wait before retrying after an error. Will be multiplied by the number of
|
||||||
* Timeout applied to all database queries.
|
* errors since the last successful fetch.
|
||||||
*
|
*/
|
||||||
* 0 to disable.
|
@WithDefault("1h")
|
||||||
*/
|
Duration backoffInterval();
|
||||||
@WithDefault("0")
|
}
|
||||||
Duration queryTimeout();
|
|
||||||
|
|
||||||
/**
|
interface Database {
|
||||||
* Database cleanup settings.
|
/**
|
||||||
*/
|
* Timeout applied to all database queries.
|
||||||
@ConfigDocSection
|
*
|
||||||
Cleanup cleanup();
|
* <p>0 to disable.
|
||||||
|
*/
|
||||||
|
@WithDefault("0")
|
||||||
|
Duration queryTimeout();
|
||||||
|
|
||||||
interface Cleanup {
|
/** Database cleanup settings. */
|
||||||
/**
|
@ConfigDocSection
|
||||||
* Maximum age of feed entries in the database. Older entries will be deleted.
|
Cleanup cleanup();
|
||||||
*
|
|
||||||
* 0 to disable.
|
|
||||||
*/
|
|
||||||
@WithDefault("365d")
|
|
||||||
Duration entriesMaxAge();
|
|
||||||
|
|
||||||
/**
|
interface Cleanup {
|
||||||
* Maximum age of feed entry statuses (read/unread) in the database. Older statuses will be deleted.
|
/**
|
||||||
*
|
* Maximum age of feed entries in the database. Older entries will be deleted.
|
||||||
* 0 to disable.
|
*
|
||||||
*/
|
* <p>0 to disable.
|
||||||
@WithDefault("0")
|
*/
|
||||||
Duration statusesMaxAge();
|
@WithDefault("365d")
|
||||||
|
Duration entriesMaxAge();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum number of entries per feed to keep in the database.
|
* Maximum age of feed entry statuses (read/unread) in the database. Older statuses will
|
||||||
*
|
* be deleted.
|
||||||
* 0 to disable.
|
*
|
||||||
*/
|
* <p>0 to disable.
|
||||||
@WithDefault("500")
|
*/
|
||||||
int maxFeedCapacity();
|
@WithDefault("0")
|
||||||
|
Duration statusesMaxAge();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Limit the number of feeds a user can subscribe to.
|
* Maximum number of entries per feed to keep in the database.
|
||||||
*
|
*
|
||||||
* 0 to disable.
|
* <p>0 to disable.
|
||||||
*/
|
*/
|
||||||
@WithDefault("0")
|
@WithDefault("500")
|
||||||
int maxFeedsPerUser();
|
int maxFeedCapacity();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rows to delete per query while cleaning up old entries.
|
* Limit the number of feeds a user can subscribe to.
|
||||||
*/
|
*
|
||||||
@Positive
|
* <p>0 to disable.
|
||||||
@WithDefault("100")
|
*/
|
||||||
int batchSize();
|
@WithDefault("0")
|
||||||
|
int maxFeedsPerUser();
|
||||||
|
|
||||||
/**
|
/** Rows to delete per query while cleaning up old entries. */
|
||||||
* Whether to keep starred entries when cleaning up old entries.
|
@Positive
|
||||||
*/
|
@WithDefault("100")
|
||||||
@WithDefault("true")
|
int batchSize();
|
||||||
boolean keepStarredEntries();
|
|
||||||
|
|
||||||
default Instant statusesInstantThreshold() {
|
/** Whether to keep starred entries when cleaning up old entries. */
|
||||||
return statusesMaxAge().toMillis() > 0 ? Instant.now().minus(statusesMaxAge()) : null;
|
@WithDefault("true")
|
||||||
}
|
boolean keepStarredEntries();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Users {
|
default Instant statusesInstantThreshold() {
|
||||||
/**
|
return statusesMaxAge().toMillis() > 0
|
||||||
* Whether to let users create accounts for themselves.
|
? Instant.now().minus(statusesMaxAge())
|
||||||
*/
|
: null;
|
||||||
@WithDefault("false")
|
}
|
||||||
boolean allowRegistrations();
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
interface Users {
|
||||||
* Minimum password length for user accounts.
|
/** Whether to let users create accounts for themselves. */
|
||||||
*/
|
@WithDefault("false")
|
||||||
@WithDefault("4")
|
boolean allowRegistrations();
|
||||||
int minimumPasswordLength();
|
|
||||||
|
|
||||||
/**
|
/** Minimum password length for user accounts. */
|
||||||
* Whether an email address is required when creating a user account.
|
@WithDefault("4")
|
||||||
*/
|
int minimumPasswordLength();
|
||||||
@WithDefault("false")
|
|
||||||
boolean emailAddressRequired();
|
|
||||||
|
|
||||||
/**
|
/** Whether an email address is required when creating a user account. */
|
||||||
* Whether to create a demo account the first time the app starts.
|
@WithDefault("false")
|
||||||
*/
|
boolean emailAddressRequired();
|
||||||
@WithDefault("false")
|
|
||||||
boolean createDemoAccount();
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Websocket {
|
/** Whether to create a demo account the first time the app starts. */
|
||||||
/**
|
@WithDefault("false")
|
||||||
* Enable websocket connection so the server can notify web clients that there are new entries for feeds.
|
boolean createDemoAccount();
|
||||||
*/
|
}
|
||||||
@WithDefault("true")
|
|
||||||
boolean enabled();
|
|
||||||
|
|
||||||
/**
|
interface Websocket {
|
||||||
* Interval at which the client will send a ping message on the websocket to keep the connection alive.
|
/**
|
||||||
*/
|
* Enable websocket connection so the server can notify web clients that there are new
|
||||||
@WithDefault("15m")
|
* entries for feeds.
|
||||||
Duration pingInterval();
|
*/
|
||||||
|
@WithDefault("true")
|
||||||
|
boolean enabled();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the websocket connection is disabled or the connection is lost, the client will reload the feed tree at this interval.
|
* Interval at which the client will send a ping message on the websocket to keep the
|
||||||
*/
|
* connection alive.
|
||||||
@WithDefault("30s")
|
*/
|
||||||
Duration treeReloadInterval();
|
@WithDefault("15m")
|
||||||
}
|
Duration pingInterval();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the websocket connection is disabled or the connection is lost, the client will reload
|
||||||
|
* the feed tree at this interval.
|
||||||
|
*/
|
||||||
|
@WithDefault("30s")
|
||||||
|
Duration treeReloadInterval();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,5 +4,5 @@ import lombok.experimental.UtilityClass;
|
|||||||
|
|
||||||
@UtilityClass
|
@UtilityClass
|
||||||
public class CommaFeedConstants {
|
public class CommaFeedConstants {
|
||||||
public static final String USERNAME_DEMO = "demo";
|
public static final String USERNAME_DEMO = "demo";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,24 @@
|
|||||||
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 {
|
||||||
|
|
||||||
@Produces
|
@Produces
|
||||||
@Singleton
|
@Singleton
|
||||||
public InstantSource instantSource() {
|
public InstantSource instantSource() {
|
||||||
return InstantSource.system();
|
return InstantSource.system();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Produces
|
|
||||||
@Singleton
|
|
||||||
public MetricRegistry metricRegistry() {
|
|
||||||
return new MetricRegistry();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@Produces
|
||||||
|
@Singleton
|
||||||
|
public MetricRegistry metricRegistry() {
|
||||||
|
return new MetricRegistry();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +1,29 @@
|
|||||||
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 {
|
||||||
|
|
||||||
private final String version;
|
private final String version;
|
||||||
private final String gitCommit;
|
private final String gitCommit;
|
||||||
|
|
||||||
public CommaFeedVersion() throws IOException {
|
public CommaFeedVersion() throws IOException {
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
try (InputStream stream = getClass().getResourceAsStream("/git.properties")) {
|
try (InputStream stream = getClass().getResourceAsStream("/git.properties")) {
|
||||||
if (stream != null) {
|
if (stream != null) {
|
||||||
properties.load(stream);
|
properties.load(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.version = properties.getProperty("git.build.version", "unknown");
|
|
||||||
this.gitCommit = properties.getProperty("git.commit.id.abbrev", "unknown");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
this.version = properties.getProperty("git.build.version", "unknown");
|
||||||
|
this.gitCommit = properties.getProperty("git.commit.id.abbrev", "unknown");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,55 +1,75 @@
|
|||||||
package com.commafeed;
|
package com.commafeed;
|
||||||
|
|
||||||
|
import com.commafeed.frontend.exception.CommaFeedApplicationException;
|
||||||
|
import com.commafeed.frontend.exception.CommaFeedExceptionType;
|
||||||
|
import com.commafeed.security.CookieService;
|
||||||
|
|
||||||
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
import io.quarkus.security.AuthenticationFailedException;
|
||||||
|
import io.quarkus.security.UnauthorizedException;
|
||||||
|
|
||||||
import jakarta.annotation.Priority;
|
import jakarta.annotation.Priority;
|
||||||
import jakarta.validation.ValidationException;
|
import jakarta.validation.ValidationException;
|
||||||
import jakarta.ws.rs.core.NewCookie;
|
import jakarta.ws.rs.core.NewCookie;
|
||||||
import jakarta.ws.rs.ext.Provider;
|
import jakarta.ws.rs.ext.Provider;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import org.jboss.resteasy.reactive.RestResponse;
|
import org.jboss.resteasy.reactive.RestResponse;
|
||||||
import org.jboss.resteasy.reactive.RestResponse.ResponseBuilder;
|
import org.jboss.resteasy.reactive.RestResponse.ResponseBuilder;
|
||||||
import org.jboss.resteasy.reactive.RestResponse.Status;
|
import org.jboss.resteasy.reactive.RestResponse.Status;
|
||||||
import org.jboss.resteasy.reactive.server.ServerExceptionMapper;
|
import org.jboss.resteasy.reactive.server.ServerExceptionMapper;
|
||||||
|
|
||||||
import com.commafeed.security.CookieService;
|
|
||||||
|
|
||||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
|
||||||
import io.quarkus.security.AuthenticationFailedException;
|
|
||||||
import io.quarkus.security.UnauthorizedException;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Provider
|
@Provider
|
||||||
@Priority(1)
|
@Priority(1)
|
||||||
public class ExceptionMappers {
|
public class ExceptionMappers {
|
||||||
|
|
||||||
private final CookieService cookieService;
|
private final CookieService cookieService;
|
||||||
private final CommaFeedConfiguration config;
|
private final CommaFeedConfiguration config;
|
||||||
|
|
||||||
@ServerExceptionMapper(UnauthorizedException.class)
|
@ServerExceptionMapper(CommaFeedApplicationException.class)
|
||||||
public RestResponse<UnauthorizedResponse> unauthorized(UnauthorizedException e) {
|
public RestResponse<CommaFeedApplicationError> applicationError(
|
||||||
return RestResponse.status(Status.UNAUTHORIZED, new UnauthorizedResponse(e.getMessage(), config.users().allowRegistrations()));
|
CommaFeedApplicationException e) {
|
||||||
}
|
ResponseBuilder<CommaFeedApplicationError> response =
|
||||||
|
ResponseBuilder.create(
|
||||||
|
e.type().status(), new CommaFeedApplicationError(e.type(), e.getMessage()));
|
||||||
|
if (e.type().status() == Status.UNAUTHORIZED) {
|
||||||
|
response.cookie(cookieService.buildLogoutCookie());
|
||||||
|
}
|
||||||
|
return response.build();
|
||||||
|
}
|
||||||
|
|
||||||
@ServerExceptionMapper(AuthenticationFailedException.class)
|
@ServerExceptionMapper(UnauthorizedException.class)
|
||||||
public RestResponse<AuthenticationFailed> authenticationFailed(AuthenticationFailedException e) {
|
public RestResponse<UnauthorizedResponse> unauthorized(UnauthorizedException e) {
|
||||||
NewCookie logoutCookie = cookieService.buildLogoutCookie();
|
return RestResponse.status(
|
||||||
return ResponseBuilder.create(Status.UNAUTHORIZED, new AuthenticationFailed(e.getMessage())).cookie(logoutCookie).build();
|
Status.UNAUTHORIZED,
|
||||||
}
|
new UnauthorizedResponse(e.getMessage(), config.users().allowRegistrations()));
|
||||||
|
}
|
||||||
|
|
||||||
@ServerExceptionMapper(ValidationException.class)
|
@ServerExceptionMapper(AuthenticationFailedException.class)
|
||||||
public RestResponse<ValidationFailed> validationFailed(ValidationException e) {
|
public RestResponse<AuthenticationFailed> authenticationFailed(
|
||||||
return RestResponse.status(Status.BAD_REQUEST, new ValidationFailed(e.getMessage()));
|
AuthenticationFailedException e) {
|
||||||
}
|
NewCookie logoutCookie = cookieService.buildLogoutCookie();
|
||||||
|
return ResponseBuilder.create(Status.UNAUTHORIZED, new AuthenticationFailed(e.getMessage()))
|
||||||
|
.cookie(logoutCookie)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
@RegisterForReflection
|
@ServerExceptionMapper(ValidationException.class)
|
||||||
public record UnauthorizedResponse(String message, boolean allowRegistrations) {
|
public RestResponse<ValidationFailed> validationFailed(ValidationException e) {
|
||||||
}
|
return RestResponse.status(Status.BAD_REQUEST, new ValidationFailed(e.getMessage()));
|
||||||
|
}
|
||||||
|
|
||||||
@RegisterForReflection
|
@RegisterForReflection
|
||||||
public record AuthenticationFailed(String message) {
|
public record UnauthorizedResponse(String message, boolean allowRegistrations) {}
|
||||||
}
|
|
||||||
|
|
||||||
@RegisterForReflection
|
@RegisterForReflection
|
||||||
public record ValidationFailed(String message) {
|
public record AuthenticationFailed(String message) {}
|
||||||
}
|
|
||||||
|
@RegisterForReflection
|
||||||
|
public record ValidationFailed(String message) {}
|
||||||
|
|
||||||
|
@RegisterForReflection
|
||||||
|
public record CommaFeedApplicationError(CommaFeedExceptionType type, 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,18 +8,23 @@ 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
|
||||||
public void customize(ObjectMapper objectMapper) {
|
public void customize(ObjectMapper objectMapper) {
|
||||||
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_DATE_TIMESTAMPS_AS_NANOSECONDS, false)
|
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true)
|
||||||
.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS, false);
|
.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false)
|
||||||
|
.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS, false);
|
||||||
|
|
||||||
// add support for serializing metrics
|
// add support for serializing metrics
|
||||||
objectMapper.registerModule(new MetricsModule(TimeUnit.SECONDS, TimeUnit.SECONDS, false));
|
objectMapper.registerModule(new MetricsModule(TimeUnit.SECONDS, TimeUnit.SECONDS, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,217 +10,340 @@ import com.codahale.metrics.Timer;
|
|||||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
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,
|
||||||
java.util.ArrayList.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,
|
||||||
|
|
||||||
// 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.Atom03Parser.class,
|
com.rometools.rome.io.impl.RSS094Parser.class,
|
||||||
|
com.rometools.rome.io.impl.RSS10Parser.class,
|
||||||
com.rometools.rome.io.impl.SyModuleParser.class, com.rometools.rome.io.impl.DCModuleParser.class,
|
com.rometools.rome.io.impl.RSS20wNSParser.class,
|
||||||
|
com.rometools.rome.io.impl.RSS20Parser.class,
|
||||||
com.rometools.rome.io.impl.RSS090Generator.class, com.rometools.rome.io.impl.RSS091NetscapeGenerator.class,
|
com.rometools.rome.io.impl.Atom10Parser.class,
|
||||||
com.rometools.rome.io.impl.RSS091UserlandGenerator.class, com.rometools.rome.io.impl.RSS092Generator.class,
|
com.rometools.rome.io.impl.Atom03Parser.class,
|
||||||
com.rometools.rome.io.impl.RSS093Generator.class, com.rometools.rome.io.impl.RSS094Generator.class,
|
com.rometools.rome.io.impl.SyModuleParser.class,
|
||||||
com.rometools.rome.io.impl.RSS10Generator.class, com.rometools.rome.io.impl.RSS20Generator.class,
|
com.rometools.rome.io.impl.DCModuleParser.class,
|
||||||
com.rometools.rome.io.impl.Atom10Generator.class, com.rometools.rome.io.impl.Atom03Generator.class,
|
com.rometools.rome.io.impl.RSS090Generator.class,
|
||||||
|
com.rometools.rome.io.impl.RSS091NetscapeGenerator.class,
|
||||||
com.rometools.rome.feed.synd.impl.ConverterForAtom10.class, com.rometools.rome.feed.synd.impl.ConverterForAtom03.class,
|
com.rometools.rome.io.impl.RSS091UserlandGenerator.class,
|
||||||
com.rometools.rome.feed.synd.impl.ConverterForRSS090.class,
|
com.rometools.rome.io.impl.RSS092Generator.class,
|
||||||
com.rometools.rome.feed.synd.impl.ConverterForRSS091Netscape.class,
|
com.rometools.rome.io.impl.RSS093Generator.class,
|
||||||
com.rometools.rome.feed.synd.impl.ConverterForRSS091Userland.class,
|
com.rometools.rome.io.impl.RSS094Generator.class,
|
||||||
com.rometools.rome.feed.synd.impl.ConverterForRSS092.class, com.rometools.rome.feed.synd.impl.ConverterForRSS093.class,
|
com.rometools.rome.io.impl.RSS10Generator.class,
|
||||||
com.rometools.rome.feed.synd.impl.ConverterForRSS094.class, com.rometools.rome.feed.synd.impl.ConverterForRSS10.class,
|
com.rometools.rome.io.impl.RSS20Generator.class,
|
||||||
com.rometools.rome.feed.synd.impl.ConverterForRSS20.class,
|
com.rometools.rome.io.impl.Atom10Generator.class,
|
||||||
|
com.rometools.rome.io.impl.Atom03Generator.class,
|
||||||
com.rometools.modules.mediarss.io.RSS20YahooParser.class,
|
com.rometools.rome.feed.synd.impl.ConverterForAtom10.class,
|
||||||
|
com.rometools.rome.feed.synd.impl.ConverterForAtom03.class,
|
||||||
com.rometools.modules.cc.io.ModuleParserRSS2.class, com.rometools.modules.content.io.ContentModuleParser.class,
|
com.rometools.rome.feed.synd.impl.ConverterForRSS090.class,
|
||||||
com.rometools.modules.itunes.io.ITunesParser.class, com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
com.rometools.rome.feed.synd.impl.ConverterForRSS091Netscape.class,
|
||||||
com.rometools.modules.opensearch.impl.OpenSearchModuleParser.class, com.rometools.modules.georss.SimpleParser.class,
|
com.rometools.rome.feed.synd.impl.ConverterForRSS091Userland.class,
|
||||||
com.rometools.modules.georss.W3CGeoParser.class, com.rometools.modules.photocast.io.Parser.class,
|
com.rometools.rome.feed.synd.impl.ConverterForRSS092.class,
|
||||||
com.rometools.modules.mediarss.io.MediaModuleParser.class, com.rometools.modules.atom.io.AtomModuleParser.class,
|
com.rometools.rome.feed.synd.impl.ConverterForRSS093.class,
|
||||||
com.rometools.modules.itunes.io.ITunesParserOldNamespace.class,
|
com.rometools.rome.feed.synd.impl.ConverterForRSS094.class,
|
||||||
com.rometools.modules.mediarss.io.AlternateMediaModuleParser.class, com.rometools.modules.sle.io.ModuleParser.class,
|
com.rometools.rome.feed.synd.impl.ConverterForRSS10.class,
|
||||||
com.rometools.modules.yahooweather.io.WeatherModuleParser.class, com.rometools.modules.feedpress.io.FeedpressParser.class,
|
com.rometools.rome.feed.synd.impl.ConverterForRSS20.class,
|
||||||
com.rometools.modules.fyyd.io.FyydParser.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.itunes.io.ITunesParserOldNamespace.class,
|
com.rometools.modules.georss.W3CGeoParser.class,
|
||||||
com.rometools.modules.mediarss.io.AlternateMediaModuleParser.class, com.rometools.modules.sle.io.ModuleParser.class,
|
com.rometools.modules.photocast.io.Parser.class,
|
||||||
com.rometools.modules.yahooweather.io.WeatherModuleParser.class, com.rometools.modules.feedpress.io.FeedpressParser.class,
|
com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
||||||
com.rometools.modules.fyyd.io.FyydParser.class,
|
com.rometools.modules.atom.io.AtomModuleParser.class,
|
||||||
|
com.rometools.modules.itunes.io.ITunesParserOldNamespace.class,
|
||||||
com.rometools.modules.cc.io.ModuleParserRSS1.class, com.rometools.modules.content.io.ContentModuleParser.class,
|
com.rometools.modules.mediarss.io.AlternateMediaModuleParser.class,
|
||||||
|
com.rometools.modules.sle.io.ModuleParser.class,
|
||||||
com.rometools.modules.cc.io.ModuleParserRSS2.class, com.rometools.modules.opensearch.impl.OpenSearchModuleParser.class,
|
com.rometools.modules.yahooweather.io.WeatherModuleParser.class,
|
||||||
com.rometools.modules.georss.SimpleParser.class, com.rometools.modules.georss.W3CGeoParser.class,
|
com.rometools.modules.feedpress.io.FeedpressParser.class,
|
||||||
com.rometools.modules.photocast.io.Parser.class, com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
com.rometools.modules.fyyd.io.FyydParser.class,
|
||||||
com.rometools.modules.mediarss.io.AlternateMediaModuleParser.class,
|
com.rometools.modules.cc.io.ModuleParserRSS2.class,
|
||||||
|
com.rometools.modules.content.io.ContentModuleParser.class,
|
||||||
com.rometools.modules.cc.io.ModuleParserRSS2.class, com.rometools.modules.opensearch.impl.OpenSearchModuleParser.class,
|
com.rometools.modules.itunes.io.ITunesParser.class,
|
||||||
com.rometools.modules.georss.SimpleParser.class, com.rometools.modules.georss.W3CGeoParser.class,
|
com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
||||||
com.rometools.modules.photocast.io.Parser.class, com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
com.rometools.modules.opensearch.impl.OpenSearchModuleParser.class,
|
||||||
com.rometools.modules.mediarss.io.AlternateMediaModuleParser.class,
|
com.rometools.modules.georss.SimpleParser.class,
|
||||||
com.rometools.modules.feedpress.io.FeedpressParser.class, com.rometools.modules.fyyd.io.FyydParser.class,
|
com.rometools.modules.georss.W3CGeoParser.class,
|
||||||
|
com.rometools.modules.photocast.io.Parser.class,
|
||||||
com.rometools.modules.cc.io.ModuleParserRSS2.class, com.rometools.modules.base.io.GoogleBaseParser.class,
|
com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
||||||
com.rometools.modules.content.io.ContentModuleParser.class, com.rometools.modules.slash.io.SlashModuleParser.class,
|
com.rometools.modules.atom.io.AtomModuleParser.class,
|
||||||
com.rometools.modules.itunes.io.ITunesParser.class, com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
com.rometools.modules.itunes.io.ITunesParserOldNamespace.class,
|
||||||
com.rometools.modules.atom.io.AtomModuleParser.class, com.rometools.modules.opensearch.impl.OpenSearchModuleParser.class,
|
com.rometools.modules.mediarss.io.AlternateMediaModuleParser.class,
|
||||||
com.rometools.modules.georss.SimpleParser.class, com.rometools.modules.georss.W3CGeoParser.class,
|
com.rometools.modules.sle.io.ModuleParser.class,
|
||||||
com.rometools.modules.photocast.io.Parser.class, com.rometools.modules.itunes.io.ITunesParserOldNamespace.class,
|
com.rometools.modules.yahooweather.io.WeatherModuleParser.class,
|
||||||
com.rometools.modules.mediarss.io.AlternateMediaModuleParser.class, com.rometools.modules.sle.io.ItemParser.class,
|
com.rometools.modules.feedpress.io.FeedpressParser.class,
|
||||||
com.rometools.modules.yahooweather.io.WeatherModuleParser.class,
|
com.rometools.modules.fyyd.io.FyydParser.class,
|
||||||
com.rometools.modules.psc.io.PodloveSimpleChapterParser.class,
|
com.rometools.modules.cc.io.ModuleParserRSS1.class,
|
||||||
|
com.rometools.modules.content.io.ContentModuleParser.class,
|
||||||
com.rometools.modules.cc.io.ModuleParserRSS1.class, com.rometools.modules.base.io.GoogleBaseParser.class,
|
com.rometools.modules.cc.io.ModuleParserRSS2.class,
|
||||||
com.rometools.modules.base.io.CustomTagParser.class, com.rometools.modules.content.io.ContentModuleParser.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.cc.io.ModuleParserRSS2.class, com.rometools.modules.base.io.GoogleBaseParser.class,
|
com.rometools.modules.photocast.io.Parser.class,
|
||||||
com.rometools.modules.base.io.CustomTagParser.class, com.rometools.modules.slash.io.SlashModuleParser.class,
|
com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
||||||
com.rometools.modules.opensearch.impl.OpenSearchModuleParser.class, com.rometools.modules.georss.SimpleParser.class,
|
com.rometools.modules.mediarss.io.AlternateMediaModuleParser.class,
|
||||||
com.rometools.modules.georss.W3CGeoParser.class, com.rometools.modules.photocast.io.Parser.class,
|
com.rometools.modules.cc.io.ModuleParserRSS2.class,
|
||||||
com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
com.rometools.modules.opensearch.impl.OpenSearchModuleParser.class,
|
||||||
com.rometools.modules.mediarss.io.AlternateMediaModuleParser.class,
|
com.rometools.modules.georss.SimpleParser.class,
|
||||||
|
com.rometools.modules.georss.W3CGeoParser.class,
|
||||||
com.rometools.modules.cc.io.ModuleParserRSS2.class, com.rometools.modules.base.io.GoogleBaseParser.class,
|
com.rometools.modules.photocast.io.Parser.class,
|
||||||
com.rometools.modules.base.io.CustomTagParser.class, com.rometools.modules.slash.io.SlashModuleParser.class,
|
com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
||||||
com.rometools.modules.opensearch.impl.OpenSearchModuleParser.class, com.rometools.modules.georss.SimpleParser.class,
|
com.rometools.modules.mediarss.io.AlternateMediaModuleParser.class,
|
||||||
com.rometools.modules.georss.W3CGeoParser.class, com.rometools.modules.photocast.io.Parser.class,
|
com.rometools.modules.feedpress.io.FeedpressParser.class,
|
||||||
com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
com.rometools.modules.fyyd.io.FyydParser.class,
|
||||||
com.rometools.modules.mediarss.io.AlternateMediaModuleParser.class,
|
com.rometools.modules.cc.io.ModuleParserRSS2.class,
|
||||||
com.rometools.modules.thr.io.ThreadingModuleParser.class, com.rometools.modules.psc.io.PodloveSimpleChapterParser.class,
|
com.rometools.modules.base.io.GoogleBaseParser.class,
|
||||||
|
com.rometools.modules.content.io.ContentModuleParser.class,
|
||||||
com.rometools.modules.cc.io.CCModuleGenerator.class, com.rometools.modules.content.io.ContentModuleGenerator.class,
|
com.rometools.modules.slash.io.SlashModuleParser.class,
|
||||||
com.rometools.modules.itunes.io.ITunesGenerator.class,
|
com.rometools.modules.itunes.io.ITunesParser.class,
|
||||||
com.rometools.modules.opensearch.impl.OpenSearchModuleGenerator.class, com.rometools.modules.georss.SimpleGenerator.class,
|
com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
||||||
com.rometools.modules.georss.W3CGeoGenerator.class, com.rometools.modules.photocast.io.Generator.class,
|
com.rometools.modules.atom.io.AtomModuleParser.class,
|
||||||
com.rometools.modules.mediarss.io.MediaModuleGenerator.class, com.rometools.modules.atom.io.AtomModuleGenerator.class,
|
com.rometools.modules.opensearch.impl.OpenSearchModuleParser.class,
|
||||||
com.rometools.modules.sle.io.ModuleGenerator.class, com.rometools.modules.yahooweather.io.WeatherModuleGenerator.class,
|
com.rometools.modules.georss.SimpleParser.class,
|
||||||
com.rometools.modules.feedpress.io.FeedpressGenerator.class, com.rometools.modules.fyyd.io.FyydGenerator.class,
|
com.rometools.modules.georss.W3CGeoParser.class,
|
||||||
|
com.rometools.modules.photocast.io.Parser.class,
|
||||||
com.rometools.modules.content.io.ContentModuleGenerator.class,
|
com.rometools.modules.itunes.io.ITunesParserOldNamespace.class,
|
||||||
|
com.rometools.modules.mediarss.io.AlternateMediaModuleParser.class,
|
||||||
com.rometools.modules.cc.io.CCModuleGenerator.class, com.rometools.modules.opensearch.impl.OpenSearchModuleGenerator.class,
|
com.rometools.modules.sle.io.ItemParser.class,
|
||||||
com.rometools.modules.georss.SimpleGenerator.class, com.rometools.modules.georss.W3CGeoGenerator.class,
|
com.rometools.modules.yahooweather.io.WeatherModuleParser.class,
|
||||||
com.rometools.modules.photocast.io.Generator.class, com.rometools.modules.mediarss.io.MediaModuleGenerator.class,
|
com.rometools.modules.psc.io.PodloveSimpleChapterParser.class,
|
||||||
|
com.rometools.modules.cc.io.ModuleParserRSS1.class,
|
||||||
com.rometools.modules.cc.io.CCModuleGenerator.class, com.rometools.modules.opensearch.impl.OpenSearchModuleGenerator.class,
|
com.rometools.modules.base.io.GoogleBaseParser.class,
|
||||||
com.rometools.modules.georss.SimpleGenerator.class, com.rometools.modules.georss.W3CGeoGenerator.class,
|
com.rometools.modules.base.io.CustomTagParser.class,
|
||||||
com.rometools.modules.photocast.io.Generator.class, com.rometools.modules.mediarss.io.MediaModuleGenerator.class,
|
com.rometools.modules.content.io.ContentModuleParser.class,
|
||||||
com.rometools.modules.feedpress.io.FeedpressGenerator.class, com.rometools.modules.fyyd.io.FyydGenerator.class,
|
com.rometools.modules.slash.io.SlashModuleParser.class,
|
||||||
|
com.rometools.modules.cc.io.ModuleParserRSS2.class,
|
||||||
com.rometools.modules.cc.io.CCModuleGenerator.class, com.rometools.modules.base.io.GoogleBaseGenerator.class,
|
com.rometools.modules.base.io.GoogleBaseParser.class,
|
||||||
com.rometools.modules.base.io.CustomTagGenerator.class, com.rometools.modules.content.io.ContentModuleGenerator.class,
|
com.rometools.modules.base.io.CustomTagParser.class,
|
||||||
com.rometools.modules.slash.io.SlashModuleGenerator.class, com.rometools.modules.itunes.io.ITunesGenerator.class,
|
com.rometools.modules.slash.io.SlashModuleParser.class,
|
||||||
com.rometools.modules.opensearch.impl.OpenSearchModuleGenerator.class, com.rometools.modules.georss.SimpleGenerator.class,
|
com.rometools.modules.opensearch.impl.OpenSearchModuleParser.class,
|
||||||
com.rometools.modules.georss.W3CGeoGenerator.class, com.rometools.modules.photocast.io.Generator.class,
|
com.rometools.modules.georss.SimpleParser.class,
|
||||||
com.rometools.modules.mediarss.io.MediaModuleGenerator.class, com.rometools.modules.atom.io.AtomModuleGenerator.class,
|
com.rometools.modules.georss.W3CGeoParser.class,
|
||||||
com.rometools.modules.yahooweather.io.WeatherModuleGenerator.class,
|
com.rometools.modules.photocast.io.Parser.class,
|
||||||
com.rometools.modules.psc.io.PodloveSimpleChapterGenerator.class,
|
com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
||||||
|
com.rometools.modules.mediarss.io.AlternateMediaModuleParser.class,
|
||||||
com.rometools.modules.base.io.GoogleBaseGenerator.class, com.rometools.modules.content.io.ContentModuleGenerator.class,
|
com.rometools.modules.cc.io.ModuleParserRSS2.class,
|
||||||
com.rometools.modules.slash.io.SlashModuleGenerator.class,
|
com.rometools.modules.base.io.GoogleBaseParser.class,
|
||||||
|
com.rometools.modules.base.io.CustomTagParser.class,
|
||||||
com.rometools.modules.cc.io.CCModuleGenerator.class, com.rometools.modules.base.io.GoogleBaseGenerator.class,
|
com.rometools.modules.slash.io.SlashModuleParser.class,
|
||||||
com.rometools.modules.base.io.CustomTagGenerator.class, com.rometools.modules.slash.io.SlashModuleGenerator.class,
|
com.rometools.modules.opensearch.impl.OpenSearchModuleParser.class,
|
||||||
com.rometools.modules.opensearch.impl.OpenSearchModuleGenerator.class, com.rometools.modules.georss.SimpleGenerator.class,
|
com.rometools.modules.georss.SimpleParser.class,
|
||||||
com.rometools.modules.georss.W3CGeoGenerator.class, com.rometools.modules.photocast.io.Generator.class,
|
com.rometools.modules.georss.W3CGeoParser.class,
|
||||||
com.rometools.modules.mediarss.io.MediaModuleGenerator.class,
|
com.rometools.modules.photocast.io.Parser.class,
|
||||||
|
com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
||||||
com.rometools.modules.cc.io.CCModuleGenerator.class, com.rometools.modules.base.io.CustomTagGenerator.class,
|
com.rometools.modules.mediarss.io.AlternateMediaModuleParser.class,
|
||||||
com.rometools.modules.slash.io.SlashModuleGenerator.class,
|
com.rometools.modules.thr.io.ThreadingModuleParser.class,
|
||||||
com.rometools.modules.opensearch.impl.OpenSearchModuleGenerator.class, com.rometools.modules.georss.SimpleGenerator.class,
|
com.rometools.modules.psc.io.PodloveSimpleChapterParser.class,
|
||||||
com.rometools.modules.georss.W3CGeoGenerator.class, com.rometools.modules.photocast.io.Generator.class,
|
com.rometools.modules.cc.io.CCModuleGenerator.class,
|
||||||
com.rometools.modules.mediarss.io.MediaModuleGenerator.class, com.rometools.modules.thr.io.ThreadingModuleGenerator.class,
|
com.rometools.modules.content.io.ContentModuleGenerator.class,
|
||||||
com.rometools.modules.psc.io.PodloveSimpleChapterGenerator.class,
|
com.rometools.modules.itunes.io.ITunesGenerator.class,
|
||||||
|
com.rometools.modules.opensearch.impl.OpenSearchModuleGenerator.class,
|
||||||
com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
com.rometools.modules.georss.SimpleGenerator.class,
|
||||||
|
com.rometools.modules.georss.W3CGeoGenerator.class,
|
||||||
com.rometools.modules.mediarss.io.MediaModuleGenerator.class,
|
com.rometools.modules.photocast.io.Generator.class,
|
||||||
|
com.rometools.modules.mediarss.io.MediaModuleGenerator.class,
|
||||||
com.rometools.opml.io.impl.OPML10Generator.class, com.rometools.opml.io.impl.OPML20Generator.class,
|
com.rometools.modules.atom.io.AtomModuleGenerator.class,
|
||||||
|
com.rometools.modules.sle.io.ModuleGenerator.class,
|
||||||
com.rometools.opml.io.impl.OPML10Parser.class, com.rometools.opml.io.impl.OPML20Parser.class,
|
com.rometools.modules.yahooweather.io.WeatherModuleGenerator.class,
|
||||||
|
com.rometools.modules.feedpress.io.FeedpressGenerator.class,
|
||||||
com.rometools.opml.feed.synd.impl.ConverterForOPML10.class, com.rometools.opml.feed.synd.impl.ConverterForOPML20.class, })
|
com.rometools.modules.fyyd.io.FyydGenerator.class,
|
||||||
|
com.rometools.modules.content.io.ContentModuleGenerator.class,
|
||||||
public class NativeImageClasses {
|
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.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.psc.io.PodloveSimpleChapterGenerator.class,
|
||||||
|
com.rometools.modules.base.io.GoogleBaseGenerator.class,
|
||||||
|
com.rometools.modules.content.io.ContentModuleGenerator.class,
|
||||||
|
com.rometools.modules.slash.io.SlashModuleGenerator.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.slash.io.SlashModuleGenerator.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.cc.io.CCModuleGenerator.class,
|
||||||
|
com.rometools.modules.base.io.CustomTagGenerator.class,
|
||||||
|
com.rometools.modules.slash.io.SlashModuleGenerator.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.thr.io.ThreadingModuleGenerator.class,
|
||||||
|
com.rometools.modules.psc.io.PodloveSimpleChapterGenerator.class,
|
||||||
|
com.rometools.modules.mediarss.io.MediaModuleParser.class,
|
||||||
|
com.rometools.modules.mediarss.io.MediaModuleGenerator.class,
|
||||||
|
com.rometools.opml.io.impl.OPML10Generator.class,
|
||||||
|
com.rometools.opml.io.impl.OPML20Generator.class,
|
||||||
|
com.rometools.opml.io.impl.OPML10Parser.class,
|
||||||
|
com.rometools.opml.io.impl.OPML20Parser.class,
|
||||||
|
com.rometools.opml.feed.synd.impl.ConverterForOPML10.class,
|
||||||
|
com.rometools.opml.feed.synd.impl.ConverterForOPML20.class,
|
||||||
|
})
|
||||||
|
public class NativeImageClasses {}
|
||||||
|
|||||||
@@ -1,29 +1,29 @@
|
|||||||
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 {
|
||||||
|
|
||||||
public static String sha1Hex(byte[] input) {
|
public static String sha1Hex(byte[] input) {
|
||||||
return hashBytesToHex(Hashing.sha1(), input);
|
return hashBytesToHex(Hashing.sha1(), input);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String sha1Hex(String input) {
|
public static String sha1Hex(String input) {
|
||||||
return hashBytesToHex(Hashing.sha1(), input.getBytes(StandardCharsets.UTF_8));
|
return hashBytesToHex(Hashing.sha1(), input.getBytes(StandardCharsets.UTF_8));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String md5Hex(String input) {
|
public static String md5Hex(String input) {
|
||||||
return hashBytesToHex(Hashing.md5(), input.getBytes(StandardCharsets.UTF_8));
|
return hashBytesToHex(Hashing.md5(), input.getBytes(StandardCharsets.UTF_8));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String hashBytesToHex(HashFunction function, byte[] input) {
|
private static String hashBytesToHex(HashFunction function, byte[] input) {
|
||||||
return function.hashBytes(input).toString();
|
return function.hashBytes(input).toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,22 @@
|
|||||||
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 inet.ipaddr.ipv4.IPv4Address;
|
||||||
|
import inet.ipaddr.ipv6.IPv6Address;
|
||||||
|
|
||||||
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,132 +41,187 @@ 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);
|
||||||
.userAgent()
|
String userAgent =
|
||||||
.orElseGet(() -> String.format("CommaFeed/%s (https://github.com/Athou/commafeed)", version.getVersion()));
|
config.httpClient()
|
||||||
return newClient(config, connectionManager, userAgent);
|
.userAgent()
|
||||||
}
|
.orElseGet(
|
||||||
|
() ->
|
||||||
|
String.format(
|
||||||
|
"CommaFeed/%s (https://github.com/Athou/commafeed)",
|
||||||
|
version.getVersion()));
|
||||||
|
return newClient(config, connectionManager, userAgent);
|
||||||
|
}
|
||||||
|
|
||||||
private CloseableHttpClient newClient(CommaFeedConfiguration config, HttpClientConnectionManager connectionManager, String userAgent) {
|
private CloseableHttpClient newClient(
|
||||||
List<Header> headers = new ArrayList<>();
|
CommaFeedConfiguration config,
|
||||||
headers.add(new BasicHeader(HttpHeaders.ACCEPT_LANGUAGE, "en"));
|
HttpClientConnectionManager connectionManager,
|
||||||
headers.add(new BasicHeader(HttpHeaders.PRAGMA, "No-cache"));
|
String userAgent) {
|
||||||
headers.add(new BasicHeader(HttpHeaders.CACHE_CONTROL, "no-cache"));
|
List<Header> headers = new ArrayList<>();
|
||||||
|
headers.add(new BasicHeader(HttpHeaders.ACCEPT_LANGUAGE, "en"));
|
||||||
|
headers.add(new BasicHeader(HttpHeaders.PRAGMA, "No-cache"));
|
||||||
|
headers.add(new BasicHeader(HttpHeaders.CACHE_CONTROL, "no-cache"));
|
||||||
|
|
||||||
SequencedMap<String, InputStreamFactory> contentDecoderMap = new LinkedHashMap<>();
|
SequencedMap<String, InputStreamFactory> contentDecoderMap = new LinkedHashMap<>();
|
||||||
contentDecoderMap.put(ContentCoding.GZIP.token(), GZIPInputStream::new);
|
contentDecoderMap.put(ContentCoding.GZIP.token(), GZIPInputStream::new);
|
||||||
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 =
|
||||||
? new BlockLocalAddressesRedirectStrategy(DNS_RESOLVER)
|
config.httpClient().blockLocalAddresses()
|
||||||
: new DefaultRedirectStrategy();
|
? new BlockLocalAddressesRedirectStrategy(DNS_RESOLVER)
|
||||||
|
: new DefaultRedirectStrategy();
|
||||||
|
|
||||||
return HttpClientBuilder.create()
|
return HttpClientBuilder.create()
|
||||||
.useSystemProperties()
|
.disableConnectionState()
|
||||||
.disableAutomaticRetries()
|
.useSystemProperties()
|
||||||
.disableCookieManagement()
|
.disableAutomaticRetries()
|
||||||
.setUserAgent(userAgent)
|
.disableCookieManagement()
|
||||||
.setDefaultHeaders(headers)
|
.setUserAgent(userAgent)
|
||||||
.setConnectionManager(connectionManager)
|
.setDefaultHeaders(headers)
|
||||||
.evictExpiredConnections()
|
.setConnectionManager(connectionManager)
|
||||||
.evictIdleConnections(TimeValue.of(config.httpClient().idleConnectionsEvictionInterval()))
|
.evictExpiredConnections()
|
||||||
.setContentDecoderRegistry(new LinkedHashMap<>(contentDecoderMap))
|
.evictIdleConnections(
|
||||||
.setRedirectStrategy(redirectStrategy)
|
TimeValue.of(config.httpClient().idleConnectionsEvictionInterval()))
|
||||||
.build();
|
.setContentDecoderRegistry(new LinkedHashMap<>(contentDecoderMap))
|
||||||
}
|
.setRedirectStrategy(redirectStrategy)
|
||||||
|
.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 =
|
||||||
: DNS_RESOLVER;
|
SSLFactory.builder().withUnsafeTrustMaterial().withUnsafeHostnameVerifier().build();
|
||||||
|
DnsResolver dnsResolver =
|
||||||
|
config.httpClient().blockLocalAddresses()
|
||||||
|
? new BlockLocalAddressesDnsResolver(DNS_RESOLVER)
|
||||||
|
: DNS_RESOLVER;
|
||||||
|
|
||||||
return PoolingHttpClientConnectionManagerBuilder.create()
|
return PoolingHttpClientConnectionManagerBuilder.create()
|
||||||
.setTlsSocketStrategy(Apache5SslUtils.toTlsSocketStrategy(sslFactory))
|
.setTlsSocketStrategy(Apache5SslUtils.toTlsSocketStrategy(sslFactory))
|
||||||
.setDefaultConnectionConfig(ConnectionConfig.custom()
|
.setDefaultConnectionConfig(
|
||||||
.setConnectTimeout(Timeout.of(config.httpClient().connectTimeout()))
|
ConnectionConfig.custom()
|
||||||
.setSocketTimeout(Timeout.of(config.httpClient().socketTimeout()))
|
.setConnectTimeout(Timeout.of(config.httpClient().connectTimeout()))
|
||||||
.setTimeToLive(Timeout.of(config.httpClient().connectionTimeToLive()))
|
.setSocketTimeout(Timeout.of(config.httpClient().socketTimeout()))
|
||||||
.build())
|
.setTimeToLive(
|
||||||
.setDefaultTlsConfig(TlsConfig.custom().setHandshakeTimeout(Timeout.of(config.httpClient().sslHandshakeTimeout())).build())
|
Timeout.of(config.httpClient().connectionTimeToLive()))
|
||||||
.setMaxConnPerRoute(poolSize)
|
.build())
|
||||||
.setMaxConnTotal(poolSize)
|
.setDefaultTlsConfig(
|
||||||
.setDnsResolver(dnsResolver)
|
TlsConfig.custom()
|
||||||
.build();
|
.setHandshakeTimeout(
|
||||||
|
Timeout.of(config.httpClient().sslHandshakeTimeout()))
|
||||||
|
.build())
|
||||||
|
.setMaxConnPerRoute(poolSize)
|
||||||
|
.setMaxConnTotal(poolSize)
|
||||||
|
.setDnsResolver(dnsResolver)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
private static boolean isLocalAddress(InetAddress address) {
|
||||||
|
return isLocalAddress(new IPAddressNetwork.IPAddressGenerator().from(address));
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean isLocalAddress(InetAddress address) {
|
private static boolean isLocalAddress(IPAddress ip) {
|
||||||
return address.isSiteLocalAddress() || address.isAnyLocalAddress() || address.isLinkLocalAddress() || address.isLoopbackAddress()
|
if (ip.isLocal() || ip.isLoopback() || ip.isMulticast() || CGNAT_RANGE.contains(ip)) {
|
||||||
|| address.isMulticastAddress();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private record BlockLocalAddressesDnsResolver(DnsResolver delegate) implements DnsResolver {
|
if (!ip.isIPv6()) {
|
||||||
@Override
|
return false;
|
||||||
public InetAddress[] resolve(String host) throws UnknownHostException {
|
}
|
||||||
InetAddress[] addresses = delegate.resolve(host);
|
|
||||||
for (InetAddress addr : addresses) {
|
|
||||||
if (isLocalAddress(addr)) {
|
|
||||||
throw new UnknownHostException("Access to local address blocked: " + addr.getHostAddress());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return addresses;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
// IPv6 transition mechanisms embed an IPv4 address that must be validated too, otherwise
|
||||||
public String resolveCanonicalHostname(String host) throws UnknownHostException {
|
// they could be used to smuggle a blocked IPv4 target past the IPv6-only checks above
|
||||||
return delegate.resolveCanonicalHostname(host);
|
IPv6Address ipv6 = ip.toIPv6();
|
||||||
}
|
if (ipv6.isIPv4Mapped() || ipv6.isIPv4Compatible() || ipv6.isWellKnownIPv4Translatable()) {
|
||||||
}
|
// IPv4-mapped (::ffff:x.x.x.x), IPv4-compatible (::x.x.x.x) and NAT64
|
||||||
|
// (64:ff9b::/96, RFC 6052) addresses all embed the IPv4 address in the lowest 32 bits
|
||||||
|
return isLocalAddress(ipv6.getEmbeddedIPv4Address());
|
||||||
|
}
|
||||||
|
if (ipv6.is6To4()) {
|
||||||
|
// 6to4 (2002::/16, RFC 3056) embeds the IPv4 address in bits 16-47
|
||||||
|
return isLocalAddress(ipv6.get6To4IPv4Address());
|
||||||
|
}
|
||||||
|
if (ipv6.isTeredo()) {
|
||||||
|
// Teredo (2001::/32, RFC 4380) embeds the IPv4 address in the lowest 32 bits,
|
||||||
|
// obfuscated with a bitwise complement
|
||||||
|
IPv4Address obfuscated = ipv6.getEmbeddedIPv4Address();
|
||||||
|
return isLocalAddress(new IPv4Address(~obfuscated.intValue()));
|
||||||
|
}
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
return false;
|
||||||
private static class BlockLocalAddressesRedirectStrategy extends DefaultRedirectStrategy {
|
}
|
||||||
|
|
||||||
private final DnsResolver delegate;
|
private record BlockLocalAddressesDnsResolver(DnsResolver delegate) implements DnsResolver {
|
||||||
|
@Override
|
||||||
|
public InetAddress[] resolve(String host) throws UnknownHostException {
|
||||||
|
InetAddress[] addresses = delegate.resolve(host);
|
||||||
|
for (InetAddress addr : addresses) {
|
||||||
|
if (isLocalAddress(addr)) {
|
||||||
|
throw new UnknownHostException(
|
||||||
|
"Access to local address blocked: " + addr.getHostAddress());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return addresses;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public URI getLocationURI(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException {
|
public String resolveCanonicalHostname(String host) throws UnknownHostException {
|
||||||
URI redirectUri = super.getLocationURI(request, response, context);
|
return delegate.resolveCanonicalHostname(host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String host = redirectUri.getHost();
|
@RequiredArgsConstructor
|
||||||
if (host == null) {
|
private static class BlockLocalAddressesRedirectStrategy extends DefaultRedirectStrategy {
|
||||||
throw new HttpException("Redirect URI does not have a host: " + redirectUri);
|
|
||||||
}
|
|
||||||
|
|
||||||
InetAddress[] addresses;
|
private final DnsResolver delegate;
|
||||||
try {
|
|
||||||
addresses = delegate.resolve(host);
|
|
||||||
} catch (UnknownHostException e) {
|
|
||||||
throw new HttpException("Unknown host: " + host);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (InetAddress addr : addresses) {
|
@Override
|
||||||
if (isLocalAddress(addr)) {
|
public URI getLocationURI(HttpRequest request, HttpResponse response, HttpContext context)
|
||||||
throw new HttpException("Access to local address blocked: " + addr.getHostAddress());
|
throws HttpException {
|
||||||
}
|
URI redirectUri = super.getLocationURI(request, response, context);
|
||||||
}
|
|
||||||
|
|
||||||
return redirectUri;
|
String host = redirectUri.getHost();
|
||||||
}
|
if (host == null) {
|
||||||
}
|
throw new HttpException("Redirect URI does not have a host: " + redirectUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
InetAddress[] addresses;
|
||||||
|
try {
|
||||||
|
addresses = delegate.resolve(host);
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
throw new HttpException("Unknown host: " + host);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (InetAddress addr : addresses) {
|
||||||
|
if (isLocalAddress(addr)) {
|
||||||
|
throw new HttpException(
|
||||||
|
"Access to local address blocked: " + addr.getHostAddress());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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,284 +34,335 @@ 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 {
|
||||||
private final CommaFeedConfiguration config;
|
private final CommaFeedConfiguration config;
|
||||||
private final InstantSource instantSource;
|
private final InstantSource instantSource;
|
||||||
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(
|
||||||
MetricRegistry metrics) {
|
CommaFeedConfiguration config,
|
||||||
this.config = config;
|
InstantSource instantSource,
|
||||||
this.instantSource = instantSource;
|
HttpClientFactory httpClientFactory,
|
||||||
this.client = httpClientFactory.newClient(config.feedRefresh().httpThreads());
|
MetricRegistry metrics) {
|
||||||
this.cache = newCache(config);
|
this.config = config;
|
||||||
|
this.instantSource = instantSource;
|
||||||
|
this.client = httpClientFactory.newClient(config.feedRefresh().httpThreads());
|
||||||
|
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)
|
||||||
return get(HttpRequest.builder(url).build());
|
throws IOException,
|
||||||
}
|
NotModifiedException,
|
||||||
|
TooManyRequestsException,
|
||||||
|
SchemeNotAllowedException {
|
||||||
|
return get(HttpRequest.builder(url).build());
|
||||||
|
}
|
||||||
|
|
||||||
public HttpResult get(HttpRequest request)
|
public HttpResult get(HttpRequest request)
|
||||||
throws IOException, NotModifiedException, TooManyRequestsException, SchemeNotAllowedException {
|
throws IOException,
|
||||||
URI uri = URI.create(request.getUrl());
|
NotModifiedException,
|
||||||
ensureHttpScheme(uri.getScheme());
|
TooManyRequestsException,
|
||||||
|
SchemeNotAllowedException {
|
||||||
|
URI uri = URI.create(request.getUrl());
|
||||||
|
ensureHttpScheme(uri.getScheme());
|
||||||
|
|
||||||
final HttpResponse response;
|
final HttpResponse response;
|
||||||
if (cache == null) {
|
if (cache == null) {
|
||||||
response = invoke(request);
|
response = invoke(request);
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
response = cache.get(request, () -> invoke(request));
|
response = cache.get(request, () -> invoke(request));
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
if (e.getCause() instanceof IOException ioe) {
|
if (e.getCause() instanceof IOException ioe) {
|
||||||
throw ioe;
|
throw ioe;
|
||||||
} else {
|
} else {
|
||||||
throw Lombok.sneakyThrow(e);
|
throw Lombok.sneakyThrow(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
throw new TooManyRequestsException(response.retryAfter());
|
|| code == HttpStatus.SC_SERVICE_UNAVAILABLE && response.retryAfter() != null) {
|
||||||
}
|
throw new TooManyRequestsException(response.retryAfter());
|
||||||
|
}
|
||||||
|
|
||||||
if (code == HttpStatus.SC_NOT_MODIFIED) {
|
if (code == HttpStatus.SC_NOT_MODIFIED) {
|
||||||
throw new NotModifiedException("'304 - not modified' http code received");
|
throw new NotModifiedException("'304 - not modified' http code received");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code >= 300) {
|
if (code >= 300) {
|
||||||
throw new HttpResponseException(code, "Server returned HTTP error code " + code);
|
throw new HttpResponseException(code, "Server returned HTTP error code " + code);
|
||||||
}
|
}
|
||||||
|
|
||||||
String lastModifiedHeader = response.lastModifiedHeader();
|
String lastModifiedHeader = response.lastModifiedHeader();
|
||||||
String eTagHeader = response.eTagHeader();
|
String eTagHeader = response.eTagHeader();
|
||||||
|
|
||||||
Duration validFor = Optional.ofNullable(response.cacheControl())
|
Duration validFor =
|
||||||
.filter(cc -> cc.getMaxAge() >= 0)
|
Optional.ofNullable(response.cacheControl())
|
||||||
.map(cc -> Duration.ofSeconds(cc.getMaxAge()))
|
.filter(cc -> cc.getMaxAge() >= 0)
|
||||||
.orElse(Duration.ZERO);
|
.map(cc -> Duration.ofSeconds(cc.getMaxAge()))
|
||||||
|
.orElse(Duration.ZERO);
|
||||||
|
|
||||||
return new HttpResult(response.content(), response.contentType(), lastModifiedHeader, eTagHeader, response.urlAfterRedirect(),
|
return new HttpResult(
|
||||||
validFor);
|
response.content(),
|
||||||
}
|
response.contentType(),
|
||||||
|
lastModifiedHeader,
|
||||||
|
eTagHeader,
|
||||||
|
response.urlAfterRedirect(),
|
||||||
|
validFor);
|
||||||
|
}
|
||||||
|
|
||||||
private void ensureHttpScheme(String scheme) throws SchemeNotAllowedException {
|
private void ensureHttpScheme(String scheme) throws SchemeNotAllowedException {
|
||||||
if (!"http".equalsIgnoreCase(scheme) && !"https".equalsIgnoreCase(scheme)) {
|
if (!"http".equalsIgnoreCase(scheme) && !"https".equalsIgnoreCase(scheme)) {
|
||||||
throw new SchemeNotAllowedException(scheme);
|
throw new SchemeNotAllowedException(scheme);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private HttpResponse invoke(HttpRequest request) throws IOException {
|
private HttpResponse invoke(HttpRequest request) throws IOException {
|
||||||
log.debug("fetching {}", request.getUrl());
|
log.debug("fetching {}", request.getUrl());
|
||||||
|
|
||||||
HttpClientContext context = HttpClientContext.create();
|
HttpClientContext context = HttpClientContext.create();
|
||||||
context.setRequestConfig(RequestConfig.custom()
|
context.setRequestConfig(
|
||||||
.setResponseTimeout(Timeout.of(config.httpClient().responseTimeout()))
|
RequestConfig.custom()
|
||||||
// causes issues with some feeds
|
.setResponseTimeout(Timeout.of(config.httpClient().responseTimeout()))
|
||||||
// see https://github.com/Athou/commafeed/issues/1572
|
// causes issues with some feeds
|
||||||
// and https://issues.apache.org/jira/browse/HTTPCLIENT-2344
|
// see https://github.com/Athou/commafeed/issues/1572
|
||||||
.setProtocolUpgradeEnabled(false)
|
// and https://issues.apache.org/jira/browse/HTTPCLIENT-2344
|
||||||
.build());
|
.setProtocolUpgradeEnabled(false)
|
||||||
|
.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,
|
||||||
int code = resp.getCode();
|
resp -> {
|
||||||
String lastModifiedHeader = Optional.ofNullable(resp.getFirstHeader(HttpHeaders.LAST_MODIFIED))
|
byte[] content =
|
||||||
.map(NameValuePair::getValue)
|
resp.getEntity() == null
|
||||||
.map(StringUtils::trimToNull)
|
? null
|
||||||
.orElse(null);
|
: toByteArray(
|
||||||
String eTagHeader = Optional.ofNullable(resp.getFirstHeader(HttpHeaders.ETAG))
|
resp.getEntity(),
|
||||||
.map(NameValuePair::getValue)
|
config.httpClient().maxResponseSize().asLongValue());
|
||||||
.map(StringUtils::trimToNull)
|
int code = resp.getCode();
|
||||||
.orElse(null);
|
String lastModifiedHeader =
|
||||||
|
Optional.ofNullable(resp.getFirstHeader(HttpHeaders.LAST_MODIFIED))
|
||||||
|
.map(NameValuePair::getValue)
|
||||||
|
.map(StringUtils::trimToNull)
|
||||||
|
.orElse(null);
|
||||||
|
String eTagHeader =
|
||||||
|
Optional.ofNullable(resp.getFirstHeader(HttpHeaders.ETAG))
|
||||||
|
.map(NameValuePair::getValue)
|
||||||
|
.map(StringUtils::trimToNull)
|
||||||
|
.orElse(null);
|
||||||
|
|
||||||
CacheControl cacheControl = Optional.ofNullable(resp.getFirstHeader(HttpHeaders.CACHE_CONTROL))
|
CacheControl cacheControl =
|
||||||
.map(NameValuePair::getValue)
|
Optional.ofNullable(resp.getFirstHeader(HttpHeaders.CACHE_CONTROL))
|
||||||
.map(StringUtils::trimToNull)
|
.map(NameValuePair::getValue)
|
||||||
.map(HttpGetter::toCacheControl)
|
.map(StringUtils::trimToNull)
|
||||||
.orElse(null);
|
.map(HttpGetter::toCacheControl)
|
||||||
|
.orElse(null);
|
||||||
|
|
||||||
Instant retryAfter = Optional.ofNullable(resp.getFirstHeader(HttpHeaders.RETRY_AFTER))
|
Instant retryAfter =
|
||||||
.map(NameValuePair::getValue)
|
Optional.ofNullable(resp.getFirstHeader(HttpHeaders.RETRY_AFTER))
|
||||||
.map(StringUtils::trimToNull)
|
.map(NameValuePair::getValue)
|
||||||
.map(this::toInstant)
|
.map(StringUtils::trimToNull)
|
||||||
.orElse(null);
|
.map(this::toInstant)
|
||||||
|
.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(RedirectLocations::getAll)
|
.map(HttpEntity::getContentType)
|
||||||
.map(l -> Iterables.getLast(l, null))
|
.orElse(null);
|
||||||
.map(URI::toString)
|
String urlAfterRedirect =
|
||||||
.orElse(request.getUrl());
|
Optional.ofNullable(context.getRedirectLocations())
|
||||||
|
.map(RedirectLocations::getAll)
|
||||||
|
.map(l -> Iterables.getLast(l, null))
|
||||||
|
.map(URI::toString)
|
||||||
|
.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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private static CacheControl toCacheControl(String headerValue) {
|
private static CacheControl toCacheControl(String headerValue) {
|
||||||
try {
|
try {
|
||||||
return CacheControlDelegate.INSTANCE.fromString(headerValue);
|
return CacheControlDelegate.INSTANCE.fromString(headerValue);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.debug("Invalid Cache-Control header: {}", headerValue);
|
log.debug("Invalid Cache-Control header: {}", headerValue);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Instant toInstant(String headerValue) {
|
private Instant toInstant(String headerValue) {
|
||||||
if (headerValue == null) {
|
if (headerValue == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StringUtils.isNumeric(headerValue)) {
|
if (StringUtils.isNumeric(headerValue)) {
|
||||||
return instantSource.instant().plusSeconds(Long.parseLong(headerValue));
|
return instantSource.instant().plusSeconds(Long.parseLong(headerValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
return DateUtils.parseStandardDate(headerValue);
|
return DateUtils.parseStandardDate(headerValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
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()) {
|
||||||
if (input == null) {
|
if (input == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
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)"
|
||||||
return bytes;
|
.formatted(maxBytes));
|
||||||
}
|
}
|
||||||
}
|
return bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Cache<HttpRequest, HttpResponse> newCache(CommaFeedConfiguration config) {
|
private static Cache<HttpRequest, HttpResponse> newCache(CommaFeedConfiguration config) {
|
||||||
HttpClientCache cacheConfig = config.httpClient().cache();
|
HttpClientCache cacheConfig = config.httpClient().cache();
|
||||||
if (!cacheConfig.enabled()) {
|
if (!cacheConfig.enabled()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CacheBuilder.newBuilder()
|
return CacheBuilder.newBuilder()
|
||||||
.weigher((HttpRequest key, HttpResponse value) -> value.content() != null ? value.content().length : 0)
|
.weigher(
|
||||||
.maximumWeight(cacheConfig.maximumMemorySize().asLongValue())
|
(HttpRequest key, HttpResponse value) ->
|
||||||
.expireAfterWrite(cacheConfig.expiration())
|
value.content() != null ? value.content().length : 0)
|
||||||
.build();
|
.maximumWeight(cacheConfig.maximumMemorySize().asLongValue())
|
||||||
}
|
.expireAfterWrite(cacheConfig.expiration())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
public static class SchemeNotAllowedException extends Exception {
|
public static class SchemeNotAllowedException extends Exception {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
public SchemeNotAllowedException(String scheme) {
|
public SchemeNotAllowedException(String scheme) {
|
||||||
super("Scheme not allowed: " + scheme);
|
super("Scheme not allowed: " + scheme);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
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(
|
||||||
super(message);
|
String message, String newLastModifiedHeader, String newEtagHeader) {
|
||||||
this.newLastModifiedHeader = newLastModifiedHeader;
|
super(message);
|
||||||
this.newEtagHeader = newEtagHeader;
|
this.newLastModifiedHeader = newLastModifiedHeader;
|
||||||
}
|
this.newEtagHeader = newEtagHeader;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Getter
|
@Getter
|
||||||
public static class TooManyRequestsException extends Exception {
|
public static class TooManyRequestsException extends Exception {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private final Instant retryAfter;
|
private final Instant retryAfter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public static class HttpResponseException extends IOException {
|
public static class HttpResponseException extends IOException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private final int code;
|
private final int code;
|
||||||
|
|
||||||
public HttpResponseException(int code, String message) {
|
public HttpResponseException(int code, String message) {
|
||||||
super(message);
|
super(message);
|
||||||
this.code = code;
|
this.code = code;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Builder(builderMethodName = "")
|
@Builder(builderMethodName = "")
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode
|
||||||
@Getter
|
@Getter
|
||||||
public static class HttpRequest {
|
public static class HttpRequest {
|
||||||
private String url;
|
private String url;
|
||||||
private String lastModified;
|
private String lastModified;
|
||||||
private String eTag;
|
private String eTag;
|
||||||
|
|
||||||
public static HttpRequestBuilder builder(String url) {
|
public static HttpRequestBuilder builder(String url) {
|
||||||
return new HttpRequestBuilder().url(url);
|
return new HttpRequestBuilder().url(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassicHttpRequest toClassicHttpRequest() {
|
public ClassicHttpRequest toClassicHttpRequest() {
|
||||||
ClassicHttpRequest req = ClassicRequestBuilder.get(url).build();
|
ClassicHttpRequest req = ClassicRequestBuilder.get(url).build();
|
||||||
if (lastModified != null) {
|
if (lastModified != null) {
|
||||||
req.addHeader(HttpHeaders.IF_MODIFIED_SINCE, lastModified);
|
req.addHeader(HttpHeaders.IF_MODIFIED_SINCE, lastModified);
|
||||||
}
|
}
|
||||||
if (eTag != null) {
|
if (eTag != null) {
|
||||||
req.addHeader(HttpHeaders.IF_NONE_MATCH, eTag);
|
req.addHeader(HttpHeaders.IF_NONE_MATCH, eTag);
|
||||||
}
|
}
|
||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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,106 +1,129 @@
|
|||||||
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;
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isHttps(String url) {
|
return url.toLowerCase(Locale.ROOT).startsWith("http://");
|
||||||
return url.startsWith("https://");
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isAbsolute(String url) {
|
public static boolean isHttps(String url) {
|
||||||
return isHttp(url) || isHttps(url);
|
if (url == null) {
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
return url.toLowerCase(Locale.ROOT).startsWith("https://");
|
||||||
*
|
}
|
||||||
* @param relativeUrl
|
|
||||||
* the url of the entry
|
|
||||||
* @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
|
|
||||||
*/
|
|
||||||
public static String toAbsolute(String relativeUrl, String feedLink, String feedUrl) {
|
|
||||||
String baseUrl = (feedLink != null && isAbsolute(feedLink)) ? feedLink : feedUrl;
|
|
||||||
if (baseUrl == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
public static boolean isAbsolute(String url) {
|
||||||
return URI.create(baseUrl).resolve(relativeUrl).toString();
|
return isHttp(url) || isHttps(url);
|
||||||
} catch (IllegalArgumentException e) {
|
}
|
||||||
log.debug("Unable to create absolute url from relative url: {} base: {}", relativeUrl, baseUrl, e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String removeTrailingSlash(String url) {
|
/** remove malicious 'javascript: 'URLs * */
|
||||||
if (url == null) {
|
public static String sanitize(String url) {
|
||||||
return null;
|
if (url == null) {
|
||||||
}
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (url.endsWith("/")) {
|
if (!isHttp(url) && !isHttps(url)) {
|
||||||
url = url.substring(0, url.length() - 1);
|
return null;
|
||||||
}
|
}
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
return url;
|
||||||
* 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) {
|
|
||||||
if (url == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
ParsedUrl parsedUrl = ParsedUrl.parseUrl(url);
|
/**
|
||||||
Canonicalizer.AGGRESSIVE.canonicalize(parsedUrl);
|
* @param relativeUrl the url of the entry
|
||||||
String normalized = parsedUrl.toString();
|
* @param feedLink the url of the feed as described in the feed
|
||||||
if (normalized == null) {
|
* @param feedUrl the url of the feed that we used to fetch the feed
|
||||||
normalized = url;
|
* @return an absolute url pointing to the entry
|
||||||
}
|
*/
|
||||||
|
public static String toAbsolute(String relativeUrl, String feedLink, String feedUrl) {
|
||||||
|
String baseUrl = (feedLink != null && isAbsolute(feedLink)) ? feedLink : feedUrl;
|
||||||
|
if (baseUrl == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// convert to lower case, the url probably won't work in some cases
|
try {
|
||||||
// after that but we don't care we just want to compare urls to avoid
|
return URI.create(baseUrl).resolve(relativeUrl).toString();
|
||||||
// duplicates
|
} catch (IllegalArgumentException e) {
|
||||||
normalized = normalized.toLowerCase();
|
log.debug(
|
||||||
|
"Unable to create absolute url from relative url: {} base: {}",
|
||||||
|
relativeUrl,
|
||||||
|
baseUrl,
|
||||||
|
e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// store all urls as http
|
public static String removeTrailingSlash(String url) {
|
||||||
if (normalized.startsWith("https")) {
|
if (url == null) {
|
||||||
normalized = "http" + normalized.substring(5);
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove the www. part
|
if (url.endsWith("/")) {
|
||||||
normalized = normalized.replace("//www.", "//");
|
url = url.substring(0, url.length() - 1);
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
// feedproxy redirects to feedburner
|
/**
|
||||||
normalized = normalized.replace("feedproxy.google.com", "feeds.feedburner.com");
|
* 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) {
|
||||||
|
if (url == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// feedburner feeds have a special treatment
|
ParsedUrl parsedUrl = ParsedUrl.parseUrl(url);
|
||||||
if (normalized.split(ESCAPED_QUESTION_MARK)[0].contains("feedburner.com")) {
|
Canonicalizer.AGGRESSIVE.canonicalize(parsedUrl);
|
||||||
normalized = normalized.replace("feeds2.feedburner.com", "feeds.feedburner.com");
|
String normalized = parsedUrl.toString();
|
||||||
normalized = normalized.split(ESCAPED_QUESTION_MARK)[0];
|
if (normalized == null) {
|
||||||
normalized = Strings.CS.removeEnd(normalized, "/");
|
normalized = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
return normalized;
|
// convert to lower case, the url probably won't work in some cases
|
||||||
}
|
// after that but we don't care we just want to compare urls to avoid
|
||||||
|
// duplicates
|
||||||
|
normalized = normalized.toLowerCase();
|
||||||
|
|
||||||
|
// store all urls as http
|
||||||
|
if (normalized.startsWith("https")) {
|
||||||
|
normalized = "http" + normalized.substring(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove the www. part
|
||||||
|
normalized = normalized.replace("//www.", "//");
|
||||||
|
|
||||||
|
// feedproxy redirects to feedburner
|
||||||
|
normalized = normalized.replace("feedproxy.google.com", "feeds.feedburner.com");
|
||||||
|
|
||||||
|
// feedburner feeds have a special treatment
|
||||||
|
if (QUESTION_MARK.split(normalized)[0].contains("feedburner.com")) {
|
||||||
|
normalized = normalized.replace("feeds2.feedburner.com", "feeds.feedburner.com");
|
||||||
|
normalized = QUESTION_MARK.split(normalized)[0];
|
||||||
|
normalized = Strings.CS.removeEnd(normalized, "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
return normalized;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,71 +1,78 @@
|
|||||||
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> {
|
||||||
|
|
||||||
private static final QFeedCategory CATEGORY = QFeedCategory.feedCategory;
|
private static final QFeedCategory CATEGORY = QFeedCategory.feedCategory;
|
||||||
|
|
||||||
public FeedCategoryDAO(EntityManager entityManager) {
|
public FeedCategoryDAO(EntityManager entityManager) {
|
||||||
super(entityManager, FeedCategory.class);
|
super(entityManager, FeedCategory.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
Predicate parentPredicate;
|
Predicate parentPredicate;
|
||||||
if (parent == null) {
|
if (parent == null) {
|
||||||
parentPredicate = CATEGORY.parent.isNull();
|
parentPredicate = CATEGORY.parent.isNull();
|
||||||
} 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) {
|
||||||
Predicate parentPredicate;
|
Predicate parentPredicate;
|
||||||
if (parent == null) {
|
if (parent == null) {
|
||||||
parentPredicate = CATEGORY.parent.isNull();
|
parentPredicate = CATEGORY.parent.isNull();
|
||||||
} else {
|
} else {
|
||||||
parentPredicate = CATEGORY.parent.eq(parent);
|
parentPredicate = CATEGORY.parent.eq(parent);
|
||||||
}
|
}
|
||||||
return query().selectFrom(CATEGORY).where(CATEGORY.user.eq(user), parentPredicate).fetch();
|
return query().selectFrom(CATEGORY).where(CATEGORY.user.eq(user), parentPredicate).fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<FeedCategory> findAllChildrenCategories(User user, FeedCategory parent) {
|
public List<FeedCategory> findAllChildrenCategories(User user, FeedCategory parent) {
|
||||||
return findAll(user).stream().filter(c -> isChild(c, parent)).toList();
|
return findAll(user).stream().filter(c -> isChild(c, parent)).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isChild(FeedCategory child, FeedCategory parent) {
|
|
||||||
if (parent == null) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
boolean isChild = false;
|
|
||||||
while (child != null) {
|
|
||||||
if (Objects.equals(child.getId(), parent.getId())) {
|
|
||||||
isChild = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
child = child.getParent();
|
|
||||||
}
|
|
||||||
return isChild;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
private boolean isChild(FeedCategory child, FeedCategory parent) {
|
||||||
|
if (parent == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
boolean isChild = false;
|
||||||
|
while (child != null) {
|
||||||
|
if (Objects.equals(child.getId(), parent.getId())) {
|
||||||
|
isChild = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
child = child.getParent();
|
||||||
|
}
|
||||||
|
return isChild;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,64 +1,72 @@
|
|||||||
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> {
|
||||||
|
|
||||||
private static final QFeed FEED = QFeed.feed;
|
private static final QFeed FEED = QFeed.feed;
|
||||||
private static final QFeedSubscription SUBSCRIPTION = QFeedSubscription.feedSubscription;
|
private static final QFeedSubscription SUBSCRIPTION = QFeedSubscription.feedSubscription;
|
||||||
|
|
||||||
public FeedDAO(EntityManager entityManager) {
|
public FeedDAO(EntityManager entityManager) {
|
||||||
super(entityManager, Feed.class);
|
super(entityManager, Feed.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Feed> findByIds(List<Long> id) {
|
public List<Feed> findByIds(List<Long> id) {
|
||||||
return query().selectFrom(FEED).where(FEED.id.in(id)).fetch();
|
return query().selectFrom(FEED).where(FEED.id.in(id)).fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
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 =
|
||||||
.distinct()
|
query().selectFrom(FEED)
|
||||||
// join on subscriptions to only refresh feeds that have subscribers
|
.distinct()
|
||||||
.join(SUBSCRIPTION)
|
// join on subscriptions to only refresh feeds that have subscribers
|
||||||
.on(SUBSCRIPTION.feed.eq(FEED))
|
.join(SUBSCRIPTION)
|
||||||
.where(FEED.disabledUntil.isNull().or(FEED.disabledUntil.lt(Instant.now())));
|
.on(SUBSCRIPTION.feed.eq(FEED))
|
||||||
|
.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));
|
||||||
}
|
}
|
||||||
|
|
||||||
return query.orderBy(FEED.disabledUntil.asc()).limit(count).fetch();
|
return query.orderBy(FEED.disabledUntil.asc()).limit(count).fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDisabledUntil(List<Long> feedIds, Instant date) {
|
public void setDisabledUntil(List<Long> feedIds, Instant date) {
|
||||||
updateQuery(FEED).set(FEED.disabledUntil, date).where(FEED.id.in(feedIds)).execute();
|
updateQuery(FEED).set(FEED.disabledUntil, date).where(FEED.id.in(feedIds)).execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Feed findByUrl(String normalizedUrl, String normalizedUrlHash) {
|
public Feed findByUrl(String normalizedUrl, String normalizedUrlHash) {
|
||||||
return query().selectFrom(FEED)
|
return query()
|
||||||
.where(FEED.normalizedUrlHash.eq(normalizedUrlHash))
|
.selectFrom(FEED)
|
||||||
.fetch()
|
.where(FEED.normalizedUrlHash.eq(normalizedUrlHash))
|
||||||
.stream()
|
.fetch()
|
||||||
.filter(f -> Strings.CS.equals(normalizedUrl, f.getNormalizedUrl()))
|
.stream()
|
||||||
.findFirst()
|
.filter(f -> Strings.CS.equals(normalizedUrl, f.getNormalizedUrl()))
|
||||||
.orElse(null);
|
.findFirst()
|
||||||
}
|
.orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
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,36 +1,40 @@
|
|||||||
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> {
|
||||||
|
|
||||||
private static final QFeedEntryContent CONTENT = QFeedEntryContent.feedEntryContent;
|
private static final QFeedEntryContent CONTENT = QFeedEntryContent.feedEntryContent;
|
||||||
private static final QFeedEntry ENTRY = QFeedEntry.feedEntry;
|
private static final QFeedEntry ENTRY = QFeedEntry.feedEntry;
|
||||||
|
|
||||||
public FeedEntryContentDAO(EntityManager entityManager) {
|
public FeedEntryContentDAO(EntityManager entityManager) {
|
||||||
super(entityManager, FeedEntryContent.class);
|
super(entityManager, FeedEntryContent.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 =
|
||||||
.from(CONTENT)
|
query().select(CONTENT.id)
|
||||||
.leftJoin(ENTRY)
|
.from(CONTENT)
|
||||||
.on(ENTRY.content.id.eq(CONTENT.id))
|
.leftJoin(ENTRY)
|
||||||
.where(ENTRY.id.isNull())
|
.on(ENTRY.content.id.eq(CONTENT.id))
|
||||||
.limit(max)
|
.where(ENTRY.id.isNull())
|
||||||
.fetch();
|
.limit(max)
|
||||||
return deleteQuery(CONTENT).where(CONTENT.id.in(ids)).execute();
|
.fetch();
|
||||||
}
|
return deleteQuery(CONTENT).where(CONTENT.id.in(ids)).execute();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,83 +8,99 @@ 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> {
|
||||||
|
|
||||||
private static final QFeedEntry ENTRY = QFeedEntry.feedEntry;
|
private static final QFeedEntry ENTRY = QFeedEntry.feedEntry;
|
||||||
private static final int IN_CLAUSE_BATCH_SIZE = 1000;
|
private static final int IN_CLAUSE_BATCH_SIZE = 1000;
|
||||||
|
|
||||||
public FeedEntryDAO(EntityManager entityManager) {
|
public FeedEntryDAO(EntityManager entityManager) {
|
||||||
super(entityManager, FeedEntry.class);
|
super(entityManager, FeedEntry.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
if (guidHashes.isEmpty()) {
|
if (guidHashes.isEmpty()) {
|
||||||
return Set.of();
|
return Set.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
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(
|
||||||
return result;
|
query().select(ENTRY.guidHash)
|
||||||
}
|
.from(ENTRY)
|
||||||
|
.where(ENTRY.feed.eq(feed), ENTRY.guidHash.in(batch))
|
||||||
|
.fetch());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public List<FeedCapacity> findFeedsExceedingCapacity(long maxCapacity, long max, boolean keepStarredEntries) {
|
public List<FeedCapacity> findFeedsExceedingCapacity(
|
||||||
NumberExpression<Long> count = ENTRY.id.count();
|
long maxCapacity, long max, boolean keepStarredEntries) {
|
||||||
JPAQuery<Tuple> query = query().select(ENTRY.feed.id, count).from(ENTRY);
|
NumberExpression<Long> count = ENTRY.id.count();
|
||||||
|
JPAQuery<Tuple> query = query().select(ENTRY.feed.id, count).from(ENTRY);
|
||||||
|
|
||||||
if (keepStarredEntries) {
|
if (keepStarredEntries) {
|
||||||
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))
|
.map(t -> new FeedCapacity(t.get(ENTRY.feed.id), t.get(count)))
|
||||||
.limit(max)
|
.toList();
|
||||||
.fetch()
|
}
|
||||||
.stream()
|
|
||||||
.map(t -> new FeedCapacity(t.get(ENTRY.feed.id), t.get(count)))
|
|
||||||
.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 =
|
||||||
return delete(list);
|
query().selectFrom(ENTRY).where(ENTRY.feed.id.eq(feedId)).limit(max).fetch();
|
||||||
}
|
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) {
|
||||||
*/
|
JPAQuery<FeedEntry> query =
|
||||||
public int deleteEntriesOlderThan(Instant olderThan, long max, boolean keepStarredEntries) {
|
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);
|
|
||||||
|
|
||||||
if (keepStarredEntries) {
|
if (keepStarredEntries) {
|
||||||
query.where(Predicates.isNotStarred(ENTRY));
|
query.where(Predicates.isNotStarred(ENTRY));
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
*/
|
JPAQuery<FeedEntry> query =
|
||||||
public int deleteOldEntries(Long feedId, long max, boolean keepStarredEntries) {
|
query().selectFrom(ENTRY)
|
||||||
JPAQuery<FeedEntry> query = query().selectFrom(ENTRY).where(ENTRY.feed.id.eq(feedId)).orderBy(ENTRY.published.asc()).limit(max);
|
.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));
|
||||||
}
|
}
|
||||||
|
|
||||||
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,263 +22,318 @@ 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> {
|
||||||
|
|
||||||
private static final QFeedEntryStatus STATUS = QFeedEntryStatus.feedEntryStatus;
|
private static final QFeedEntryStatus STATUS = QFeedEntryStatus.feedEntryStatus;
|
||||||
private static final QFeedEntry ENTRY = QFeedEntry.feedEntry;
|
private static final QFeedEntry ENTRY = QFeedEntry.feedEntry;
|
||||||
private static final QFeed FEED = QFeed.feed;
|
private static final QFeed FEED = QFeed.feed;
|
||||||
private static final QFeedEntryContent CONTENT = QFeedEntryContent.feedEntryContent;
|
private static final QFeedEntryContent CONTENT = QFeedEntryContent.feedEntryContent;
|
||||||
private static final QFeedEntryTag TAG = QFeedEntryTag.feedEntryTag;
|
private static final QFeedEntryTag TAG = QFeedEntryTag.feedEntryTag;
|
||||||
private static final QFeedSubscription SUBSCRIPTION = QFeedSubscription.feedSubscription;
|
private static final QFeedSubscription SUBSCRIPTION = QFeedSubscription.feedSubscription;
|
||||||
|
|
||||||
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(
|
||||||
super(entityManager, FeedEntryStatus.class);
|
EntityManager entityManager,
|
||||||
this.feedEntryTagDAO = feedEntryTagDAO;
|
FeedEntryTagDAO feedEntryTagDAO,
|
||||||
this.config = config;
|
CommaFeedConfiguration config) {
|
||||||
}
|
super(entityManager, FeedEntryStatus.class);
|
||||||
|
this.feedEntryTagDAO = feedEntryTagDAO;
|
||||||
|
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 =
|
||||||
FeedEntryStatus status = statuses.stream().findFirst().orElse(null);
|
query().selectFrom(STATUS)
|
||||||
return handleStatus(user, status, sub, entry);
|
.where(STATUS.entry.eq(entry), STATUS.subscription.eq(sub))
|
||||||
}
|
.fetch();
|
||||||
|
FeedEntryStatus status = statuses.stream().findFirst().orElse(null);
|
||||||
|
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 =
|
||||||
Instant statusesInstantThreshold = config.database().cleanup().statusesInstantThreshold();
|
config.database().cleanup().statusesInstantThreshold();
|
||||||
boolean read = statusesInstantThreshold != null && entry.getPublished().isBefore(statusesInstantThreshold);
|
boolean read =
|
||||||
status = new FeedEntryStatus(user, sub, entry);
|
statusesInstantThreshold != null
|
||||||
status.setRead(read);
|
&& entry.getPublished().isBefore(statusesInstantThreshold);
|
||||||
status.setMarkable(!read);
|
status = new FeedEntryStatus(user, sub, entry);
|
||||||
} else {
|
status.setRead(read);
|
||||||
status.setMarkable(true);
|
status.setMarkable(!read);
|
||||||
}
|
} else {
|
||||||
return status;
|
status.setMarkable(true);
|
||||||
}
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
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(
|
||||||
for (FeedEntryStatus status : statuses) {
|
user, statuses.stream().map(FeedEntryStatus::getEntry).toList());
|
||||||
List<FeedEntryTag> tags = tagsByEntryIds.get(status.getEntry().getId());
|
for (FeedEntryStatus status : statuses) {
|
||||||
status.setTags(tags == null ? List.of() : tags);
|
List<FeedEntryTag> tags = tagsByEntryIds.get(status.getEntry().getId());
|
||||||
}
|
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(
|
||||||
boolean includeContent) {
|
User user,
|
||||||
JPAQuery<FeedEntryStatus> query = query().selectFrom(STATUS).where(STATUS.user.eq(user), STATUS.starred.isTrue());
|
List<FeedEntryKeyword> keywords,
|
||||||
if (includeContent) {
|
Instant newerThan,
|
||||||
query.join(STATUS.entry).fetchJoin();
|
int offset,
|
||||||
query.join(STATUS.entry.content).fetchJoin();
|
int limit,
|
||||||
}
|
ReadingOrder order,
|
||||||
|
boolean includeContent) {
|
||||||
|
JPAQuery<FeedEntryStatus> query =
|
||||||
|
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.content, CONTENT).fetchJoin();
|
||||||
|
}
|
||||||
|
|
||||||
if (newerThan != null) {
|
if (CollectionUtils.isNotEmpty(keywords)) {
|
||||||
query.where(STATUS.entryInserted.gt(newerThan));
|
applyKeywordsFilter(query, keywords);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (order == ReadingOrder.ASC) {
|
if (newerThan != null) {
|
||||||
query.orderBy(STATUS.entryPublished.asc(), STATUS.id.asc());
|
query.where(STATUS.entryInserted.gt(newerThan));
|
||||||
} else {
|
}
|
||||||
query.orderBy(STATUS.entryPublished.desc(), STATUS.id.desc());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset > -1) {
|
if (order == ReadingOrder.ASC) {
|
||||||
query.offset(offset);
|
query.orderBy(STATUS.entryPublished.asc(), STATUS.id.asc());
|
||||||
}
|
} else {
|
||||||
|
query.orderBy(STATUS.entryPublished.desc(), STATUS.id.desc());
|
||||||
|
}
|
||||||
|
|
||||||
if (limit > -1) {
|
if (offset > -1) {
|
||||||
query.limit(limit);
|
query.offset(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(query, config.database().queryTimeout());
|
if (limit > -1) {
|
||||||
|
query.limit(limit);
|
||||||
|
}
|
||||||
|
|
||||||
List<FeedEntryStatus> statuses = query.fetch();
|
setTimeout(query, config.database().queryTimeout());
|
||||||
statuses.forEach(s -> s.setMarkable(true));
|
|
||||||
if (includeContent) {
|
|
||||||
fetchTags(user, statuses);
|
|
||||||
}
|
|
||||||
|
|
||||||
return statuses;
|
List<FeedEntryStatus> statuses = query.fetch();
|
||||||
}
|
statuses.forEach(s -> s.setMarkable(true));
|
||||||
|
if (includeContent) {
|
||||||
|
fetchTags(user, statuses);
|
||||||
|
}
|
||||||
|
|
||||||
public List<FeedEntryStatus> findBySubscriptions(User user, List<FeedSubscription> subs, boolean unreadOnly,
|
return statuses;
|
||||||
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);
|
public List<FeedEntryStatus> findBySubscriptions(
|
||||||
query.leftJoin(ENTRY.statuses, STATUS).on(STATUS.subscription.in(subs));
|
User user,
|
||||||
query.where(ENTRY.feed.id.in(subsByFeedId.keySet()));
|
List<FeedSubscription> subs,
|
||||||
|
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()));
|
||||||
|
|
||||||
if (includeContent || CollectionUtils.isNotEmpty(keywords)) {
|
JPAQuery<Tuple> query = query().select(ENTRY, STATUS).from(ENTRY);
|
||||||
query.join(ENTRY.content, CONTENT).fetchJoin();
|
query.leftJoin(ENTRY.statuses, STATUS).on(STATUS.subscription.in(subs));
|
||||||
}
|
query.where(ENTRY.feed.id.in(subsByFeedId.keySet()));
|
||||||
if (CollectionUtils.isNotEmpty(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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unreadOnly && tag == null) {
|
if (includeContent || CollectionUtils.isNotEmpty(keywords)) {
|
||||||
query.where(buildUnreadPredicate());
|
query.join(ENTRY.content, CONTENT).fetchJoin();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tag != null) {
|
if (CollectionUtils.isNotEmpty(keywords)) {
|
||||||
BooleanBuilder and = new BooleanBuilder();
|
applyKeywordsFilter(query, keywords);
|
||||||
and.and(TAG.user.id.eq(user.getId()));
|
}
|
||||||
and.and(TAG.name.eq(tag));
|
|
||||||
query.join(ENTRY.tags, TAG).on(and);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newerThan != null) {
|
if (unreadOnly && tag == null) {
|
||||||
query.where(ENTRY.inserted.goe(newerThan));
|
query.where(buildUnreadPredicate());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (minEntryId != null) {
|
if (tag != null) {
|
||||||
query.where(ENTRY.id.gt(minEntryId));
|
BooleanBuilder and = new BooleanBuilder();
|
||||||
}
|
and.and(TAG.user.id.eq(user.getId()));
|
||||||
|
and.and(TAG.name.eq(tag));
|
||||||
|
query.join(ENTRY.tags, TAG).on(and);
|
||||||
|
}
|
||||||
|
|
||||||
if (maxEntryId != null) {
|
if (newerThan != null) {
|
||||||
query.where(ENTRY.id.lt(maxEntryId));
|
query.where(ENTRY.inserted.goe(newerThan));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (order != null) {
|
if (minEntryId != null) {
|
||||||
if (order == ReadingOrder.ASC) {
|
query.where(ENTRY.id.gt(minEntryId));
|
||||||
query.orderBy(ENTRY.published.asc(), ENTRY.id.asc());
|
}
|
||||||
} else {
|
|
||||||
query.orderBy(ENTRY.published.desc(), ENTRY.id.desc());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset > -1) {
|
if (maxEntryId != null) {
|
||||||
query.offset(offset);
|
query.where(ENTRY.id.lt(maxEntryId));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (limit > -1) {
|
if (order != null) {
|
||||||
query.limit(limit);
|
if (order == ReadingOrder.ASC) {
|
||||||
}
|
query.orderBy(ENTRY.published.asc(), ENTRY.id.asc());
|
||||||
|
} else {
|
||||||
|
query.orderBy(ENTRY.published.desc(), ENTRY.id.desc());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setTimeout(query, config.database().queryTimeout());
|
if (offset > -1) {
|
||||||
|
query.offset(offset);
|
||||||
|
}
|
||||||
|
|
||||||
List<FeedEntryStatus> statuses = new ArrayList<>();
|
if (limit > -1) {
|
||||||
List<Tuple> tuples = query.fetch();
|
query.limit(limit);
|
||||||
for (Tuple tuple : tuples) {
|
}
|
||||||
FeedEntry e = tuple.get(ENTRY);
|
|
||||||
FeedEntryStatus s = tuple.get(STATUS);
|
|
||||||
for (FeedSubscription sub : subsByFeedId.get(e.getFeed().getId())) {
|
|
||||||
statuses.add(handleStatus(user, s, sub, e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (includeContent) {
|
setTimeout(query, config.database().queryTimeout());
|
||||||
fetchTags(user, statuses);
|
|
||||||
}
|
|
||||||
|
|
||||||
return statuses;
|
List<FeedEntryStatus> statuses = new ArrayList<>();
|
||||||
}
|
List<Tuple> tuples = query.fetch();
|
||||||
|
for (Tuple tuple : tuples) {
|
||||||
|
FeedEntry e = tuple.get(ENTRY);
|
||||||
|
FeedEntryStatus s = tuple.get(STATUS);
|
||||||
|
for (FeedSubscription sub : subsByFeedId.get(e.getFeed().getId())) {
|
||||||
|
statuses.add(handleStatus(user, s, sub, e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public UnreadCount getUnreadCount(FeedSubscription sub) {
|
if (includeContent) {
|
||||||
JPAQuery<Tuple> query = query().select(ENTRY.count(), ENTRY.published.max())
|
fetchTags(user, statuses);
|
||||||
.from(ENTRY)
|
}
|
||||||
.leftJoin(ENTRY.statuses, STATUS)
|
|
||||||
.on(STATUS.subscription.eq(sub))
|
|
||||||
.where(ENTRY.feed.eq(sub.getFeed()))
|
|
||||||
.where(buildUnreadPredicate());
|
|
||||||
|
|
||||||
Tuple tuple = query.fetchOne();
|
return statuses;
|
||||||
Long count = tuple.get(ENTRY.count());
|
}
|
||||||
Instant published = tuple.get(ENTRY.published.max());
|
|
||||||
return new UnreadCount(sub.getId(), count == null ? 0 : count, published);
|
|
||||||
}
|
|
||||||
|
|
||||||
private BooleanBuilder buildUnreadPredicate() {
|
private void applyKeywordsFilter(JPAQuery<?> query, List<FeedEntryKeyword> keywords) {
|
||||||
BooleanBuilder or = new BooleanBuilder();
|
for (FeedEntryKeyword keyword : keywords) {
|
||||||
or.or(STATUS.read.isNull());
|
BooleanBuilder or = new BooleanBuilder();
|
||||||
or.or(STATUS.read.isFalse());
|
or.or(CONTENT.content.containsIgnoreCase(keyword.keyword()));
|
||||||
|
or.or(CONTENT.title.containsIgnoreCase(keyword.keyword()));
|
||||||
|
if (keyword.mode() == Mode.EXCLUDE) {
|
||||||
|
or.not();
|
||||||
|
}
|
||||||
|
query.where(or);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Instant statusesInstantThreshold = config.database().cleanup().statusesInstantThreshold();
|
public UnreadCount getUnreadCount(FeedSubscription sub) {
|
||||||
if (statusesInstantThreshold != null) {
|
JPAQuery<Tuple> query =
|
||||||
return or.and(ENTRY.published.goe(statusesInstantThreshold));
|
query().select(ENTRY.count(), ENTRY.published.max())
|
||||||
} else {
|
.from(ENTRY)
|
||||||
return or;
|
.leftJoin(ENTRY.statuses, STATUS)
|
||||||
}
|
.on(STATUS.subscription.eq(sub))
|
||||||
}
|
.where(ENTRY.feed.eq(sub.getFeed()))
|
||||||
|
.where(buildUnreadPredicate());
|
||||||
|
|
||||||
public long deleteOldStatuses(Instant olderThan, int limit) {
|
Tuple tuple = query.fetchOne();
|
||||||
List<Long> ids = query().select(STATUS.id)
|
Long count = tuple.get(ENTRY.count());
|
||||||
.from(STATUS)
|
Instant published = tuple.get(ENTRY.published.max());
|
||||||
.where(STATUS.entryInserted.lt(olderThan), STATUS.starred.isFalse())
|
return new UnreadCount(sub.getId(), count == null ? 0 : count, published);
|
||||||
.limit(limit)
|
}
|
||||||
.fetch();
|
|
||||||
return deleteQuery(STATUS).where(STATUS.id.in(ids)).execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
public long autoMarkAsRead(int limit) {
|
private BooleanBuilder buildUnreadPredicate() {
|
||||||
Instant now = Instant.now();
|
BooleanBuilder or = new BooleanBuilder();
|
||||||
|
or.or(STATUS.read.isNull());
|
||||||
|
or.or(STATUS.read.isFalse());
|
||||||
|
|
||||||
BooleanBuilder where = new BooleanBuilder();
|
Instant statusesInstantThreshold = config.database().cleanup().statusesInstantThreshold();
|
||||||
where.and(SUBSCRIPTION.autoMarkAsReadAfterDays.isNotNull());
|
if (statusesInstantThreshold != null) {
|
||||||
where.and(SUBSCRIPTION.autoMarkAsReadAfterDays.gt(0));
|
return or.and(ENTRY.published.goe(statusesInstantThreshold));
|
||||||
|
} else {
|
||||||
|
return or;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NumberExpression<Integer> daysDiff = Expressions.numberTemplate(Integer.class, "TIMESTAMPDIFF(DAY, {0}, {1})", ENTRY.published,
|
public long deleteOldStatuses(Instant olderThan, int limit) {
|
||||||
now);
|
List<Long> ids =
|
||||||
where.and(daysDiff.goe(SUBSCRIPTION.autoMarkAsReadAfterDays));
|
query().select(STATUS.id)
|
||||||
|
.from(STATUS)
|
||||||
|
.where(STATUS.entryInserted.lt(olderThan), STATUS.starred.isFalse())
|
||||||
|
.limit(limit)
|
||||||
|
.fetch();
|
||||||
|
return deleteQuery(STATUS).where(STATUS.id.in(ids)).execute();
|
||||||
|
}
|
||||||
|
|
||||||
where.and(buildUnreadPredicate());
|
public long autoMarkAsRead(int limit) {
|
||||||
|
Instant now = Instant.now();
|
||||||
|
|
||||||
List<Tuple> tuples = query().select(ENTRY, STATUS, SUBSCRIPTION)
|
BooleanBuilder where = new BooleanBuilder();
|
||||||
.from(ENTRY)
|
where.and(SUBSCRIPTION.autoMarkAsReadAfterDays.isNotNull());
|
||||||
.join(ENTRY.feed, FEED)
|
where.and(SUBSCRIPTION.autoMarkAsReadAfterDays.gt(0));
|
||||||
.join(SUBSCRIPTION)
|
|
||||||
.on(SUBSCRIPTION.feed.eq(FEED))
|
|
||||||
.leftJoin(ENTRY.statuses, STATUS)
|
|
||||||
.on(STATUS.subscription.eq(SUBSCRIPTION))
|
|
||||||
.where(where)
|
|
||||||
.limit(limit)
|
|
||||||
.fetch();
|
|
||||||
|
|
||||||
long updated = 0;
|
NumberExpression<Integer> daysDiff =
|
||||||
|
Expressions.numberTemplate(
|
||||||
|
Integer.class, "TIMESTAMPDIFF(DAY, {0}, {1})", ENTRY.published, now);
|
||||||
|
where.and(daysDiff.goe(SUBSCRIPTION.autoMarkAsReadAfterDays));
|
||||||
|
|
||||||
// Update existing statuses
|
where.and(buildUnreadPredicate());
|
||||||
List<Long> statusIdsToUpdate = tuples.stream()
|
|
||||||
.map(t -> t.get(STATUS))
|
|
||||||
.filter(s -> s != null && s.getId() != null)
|
|
||||||
.map(FeedEntryStatus::getId)
|
|
||||||
.distinct()
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
if (!statusIdsToUpdate.isEmpty()) {
|
List<Tuple> tuples =
|
||||||
updated += updateQuery(STATUS).where(STATUS.id.in(statusIdsToUpdate)).set(STATUS.read, true).execute();
|
query().select(ENTRY, STATUS, SUBSCRIPTION)
|
||||||
}
|
.from(ENTRY)
|
||||||
|
.join(ENTRY.feed, FEED)
|
||||||
|
.join(SUBSCRIPTION)
|
||||||
|
.on(SUBSCRIPTION.feed.eq(FEED))
|
||||||
|
.leftJoin(ENTRY.statuses, STATUS)
|
||||||
|
.on(STATUS.subscription.eq(SUBSCRIPTION))
|
||||||
|
.where(where)
|
||||||
|
.limit(limit)
|
||||||
|
.fetch();
|
||||||
|
|
||||||
// Insert new statuses for entries without existing status
|
long updated = 0;
|
||||||
for (Tuple tuple : tuples) {
|
|
||||||
FeedEntryStatus status = tuple.get(STATUS);
|
|
||||||
if (status == null || status.getId() == null) {
|
|
||||||
FeedEntry entry = tuple.get(ENTRY);
|
|
||||||
FeedSubscription sub = tuple.get(SUBSCRIPTION);
|
|
||||||
FeedEntryStatus newStatus = new FeedEntryStatus(sub.getUser(), sub, entry);
|
|
||||||
newStatus.setRead(true);
|
|
||||||
persist(newStatus);
|
|
||||||
updated++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return updated;
|
// Update existing statuses
|
||||||
}
|
List<Long> statusIdsToUpdate =
|
||||||
|
tuples.stream()
|
||||||
|
.map(t -> t.get(STATUS))
|
||||||
|
.filter(s -> s != null && s.getId() != null)
|
||||||
|
.map(FeedEntryStatus::getId)
|
||||||
|
.distinct()
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
if (!statusIdsToUpdate.isEmpty()) {
|
||||||
|
updated +=
|
||||||
|
updateQuery(STATUS)
|
||||||
|
.where(STATUS.id.in(statusIdsToUpdate))
|
||||||
|
.set(STATUS.read, true)
|
||||||
|
.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert new statuses for entries without existing status
|
||||||
|
for (Tuple tuple : tuples) {
|
||||||
|
FeedEntryStatus status = tuple.get(STATUS);
|
||||||
|
if (status == null || status.getId() == null) {
|
||||||
|
FeedEntry entry = tuple.get(ENTRY);
|
||||||
|
FeedSubscription sub = tuple.get(SUBSCRIPTION);
|
||||||
|
FeedEntryStatus newStatus = new FeedEntryStatus(sub.getUser(), sub, entry);
|
||||||
|
newStatus.setRead(true);
|
||||||
|
persist(newStatus);
|
||||||
|
updated++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,39 +1,40 @@
|
|||||||
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> {
|
||||||
|
|
||||||
private static final QFeedEntryTag TAG = QFeedEntryTag.feedEntryTag;
|
private static final QFeedEntryTag TAG = QFeedEntryTag.feedEntryTag;
|
||||||
|
|
||||||
public FeedEntryTagDAO(EntityManager entityManager) {
|
public FeedEntryTagDAO(EntityManager entityManager) {
|
||||||
super(entityManager, FeedEntryTag.class);
|
super(entityManager, FeedEntryTag.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> findByUser(User user) {
|
public List<String> findByUser(User user) {
|
||||||
return query().selectDistinct(TAG.name).from(TAG).where(TAG.user.eq(user)).fetch();
|
return query().selectDistinct(TAG.name).from(TAG).where(TAG.user.eq(user)).fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<FeedEntryTag> findByEntry(User user, FeedEntry entry) {
|
public List<FeedEntryTag> findByEntry(User user, FeedEntry entry) {
|
||||||
return query().selectFrom(TAG).where(TAG.user.eq(user), TAG.entry.eq(entry)).fetch();
|
return query().selectFrom(TAG).where(TAG.user.eq(user), TAG.entry.eq(entry)).fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
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()
|
||||||
.where(TAG.user.eq(user), TAG.entry.in(entries))
|
.selectFrom(TAG)
|
||||||
.fetch()
|
.where(TAG.user.eq(user), TAG.entry.in(entries))
|
||||||
.stream()
|
.fetch()
|
||||||
.collect(Collectors.groupingBy(t -> t.getEntry().getId()));
|
.stream()
|
||||||
}
|
.collect(Collectors.groupingBy(t -> t.getEntry().getId()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,117 +19,128 @@ 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> {
|
||||||
|
|
||||||
private static final QFeedSubscription SUBSCRIPTION = QFeedSubscription.feedSubscription;
|
private static final QFeedSubscription SUBSCRIPTION = QFeedSubscription.feedSubscription;
|
||||||
|
|
||||||
private final EntityManager entityManager;
|
private final EntityManager entityManager;
|
||||||
|
|
||||||
public FeedSubscriptionDAO(EntityManager entityManager) {
|
public FeedSubscriptionDAO(EntityManager entityManager) {
|
||||||
super(entityManager, FeedSubscription.class);
|
super(entityManager, FeedSubscription.class);
|
||||||
this.entityManager = entityManager;
|
this.entityManager = entityManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onPostCommitInsert(Consumer<FeedSubscription> consumer) {
|
public void onPostCommitInsert(Consumer<FeedSubscription> consumer) {
|
||||||
entityManager.unwrap(SharedSessionContractImplementor.class)
|
entityManager
|
||||||
.getFactory()
|
.unwrap(SharedSessionContractImplementor.class)
|
||||||
.getServiceRegistry()
|
.getFactory()
|
||||||
.getService(EventListenerRegistry.class)
|
.getServiceRegistry()
|
||||||
.getEventListenerGroup(EventType.POST_COMMIT_INSERT)
|
.getService(EventListenerRegistry.class)
|
||||||
.appendListener(new PostCommitInsertEventListener() {
|
.getEventListenerGroup(EventType.POST_COMMIT_INSERT)
|
||||||
@Override
|
.appendListener(
|
||||||
public void onPostInsert(PostInsertEvent event) {
|
new PostCommitInsertEventListener() {
|
||||||
if (event.getEntity() instanceof FeedSubscription s) {
|
@Override
|
||||||
consumer.accept(s);
|
public void onPostInsert(PostInsertEvent event) {
|
||||||
}
|
if (event.getEntity() instanceof FeedSubscription s) {
|
||||||
}
|
consumer.accept(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean requiresPostCommitHandling(EntityPersister persister) {
|
public boolean requiresPostCommitHandling(EntityPersister persister) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPostInsertCommitFailed(PostInsertEvent event) {
|
public void onPostInsertCommitFailed(PostInsertEvent event) {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public FeedSubscription findById(User user, Long id) {
|
public FeedSubscription findById(User user, Long id) {
|
||||||
List<FeedSubscription> subs = query().selectFrom(SUBSCRIPTION)
|
List<FeedSubscription> subs =
|
||||||
.where(SUBSCRIPTION.user.eq(user), SUBSCRIPTION.id.eq(id))
|
query().selectFrom(SUBSCRIPTION)
|
||||||
.leftJoin(SUBSCRIPTION.feed)
|
.where(SUBSCRIPTION.user.eq(user), SUBSCRIPTION.id.eq(id))
|
||||||
.fetchJoin()
|
.leftJoin(SUBSCRIPTION.feed)
|
||||||
.leftJoin(SUBSCRIPTION.category)
|
.fetchJoin()
|
||||||
.fetchJoin()
|
.leftJoin(SUBSCRIPTION.category)
|
||||||
.fetch();
|
.fetchJoin()
|
||||||
FeedSubscription sub = subs.stream().findFirst().orElse(null);
|
.fetch();
|
||||||
return initRelations(sub);
|
FeedSubscription sub = subs.stream().findFirst().orElse(null);
|
||||||
}
|
return initRelations(sub);
|
||||||
|
}
|
||||||
|
|
||||||
public List<FeedSubscription> findByFeed(Feed feed) {
|
public List<FeedSubscription> findByFeed(Feed feed) {
|
||||||
return query().selectFrom(SUBSCRIPTION).where(SUBSCRIPTION.feed.eq(feed)).fetch();
|
return query().selectFrom(SUBSCRIPTION).where(SUBSCRIPTION.feed.eq(feed)).fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
public FeedSubscription findByFeed(User user, Feed feed) {
|
public FeedSubscription findByFeed(User user, Feed feed) {
|
||||||
List<FeedSubscription> subs = query().selectFrom(SUBSCRIPTION)
|
List<FeedSubscription> subs =
|
||||||
.where(SUBSCRIPTION.user.eq(user), SUBSCRIPTION.feed.eq(feed))
|
query().selectFrom(SUBSCRIPTION)
|
||||||
.fetch();
|
.where(SUBSCRIPTION.user.eq(user), SUBSCRIPTION.feed.eq(feed))
|
||||||
FeedSubscription sub = subs.stream().findFirst().orElse(null);
|
.fetch();
|
||||||
return initRelations(sub);
|
FeedSubscription sub = subs.stream().findFirst().orElse(null);
|
||||||
}
|
return initRelations(sub);
|
||||||
|
}
|
||||||
|
|
||||||
public List<FeedSubscription> findAll(User user) {
|
public List<FeedSubscription> findAll(User user) {
|
||||||
List<FeedSubscription> subs = query().selectFrom(SUBSCRIPTION)
|
List<FeedSubscription> subs =
|
||||||
.where(SUBSCRIPTION.user.eq(user))
|
query().selectFrom(SUBSCRIPTION)
|
||||||
.leftJoin(SUBSCRIPTION.feed)
|
.where(SUBSCRIPTION.user.eq(user))
|
||||||
.fetchJoin()
|
.leftJoin(SUBSCRIPTION.feed)
|
||||||
.leftJoin(SUBSCRIPTION.category)
|
.fetchJoin()
|
||||||
.fetchJoin()
|
.leftJoin(SUBSCRIPTION.category)
|
||||||
.fetch();
|
.fetchJoin()
|
||||||
return initRelations(subs);
|
.fetch();
|
||||||
}
|
return initRelations(subs);
|
||||||
|
}
|
||||||
|
|
||||||
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 =
|
||||||
if (category == null) {
|
query().selectFrom(SUBSCRIPTION).where(SUBSCRIPTION.user.eq(user));
|
||||||
query.where(SUBSCRIPTION.category.isNull());
|
if (category == null) {
|
||||||
} else {
|
query.where(SUBSCRIPTION.category.isNull());
|
||||||
query.where(SUBSCRIPTION.category.eq(category));
|
} else {
|
||||||
}
|
query.where(SUBSCRIPTION.category.eq(category));
|
||||||
return initRelations(query.fetch());
|
}
|
||||||
}
|
return initRelations(query.fetch());
|
||||||
|
}
|
||||||
|
|
||||||
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) {
|
||||||
list.forEach(this::initRelations);
|
list.forEach(this::initRelations);
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
private FeedSubscription initRelations(FeedSubscription sub) {
|
private FeedSubscription initRelations(FeedSubscription sub) {
|
||||||
if (sub != null) {
|
if (sub != null) {
|
||||||
Models.initialize(sub.getFeed());
|
Models.initialize(sub.getFeed());
|
||||||
Models.initialize(sub.getCategory());
|
Models.initialize(sub.getCategory());
|
||||||
}
|
}
|
||||||
return sub;
|
return sub;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,53 +7,59 @@ 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> {
|
||||||
|
|
||||||
private final EntityManager entityManager;
|
private final EntityManager entityManager;
|
||||||
private final Class<T> entityClass;
|
private final Class<T> entityClass;
|
||||||
|
|
||||||
protected JPAQueryFactory query() {
|
protected JPAQueryFactory query() {
|
||||||
return new JPAQueryFactory(entityManager);
|
return new JPAQueryFactory(entityManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected JPAUpdateClause updateQuery(EntityPath<T> entityPath) {
|
protected JPAUpdateClause updateQuery(EntityPath<T> entityPath) {
|
||||||
return new JPAUpdateClause(entityManager, entityPath);
|
return new JPAUpdateClause(entityManager, entityPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected JPADeleteClause deleteQuery(EntityPath<T> entityPath) {
|
protected JPADeleteClause deleteQuery(EntityPath<T> entityPath) {
|
||||||
return new JPADeleteClause(entityManager, entityPath);
|
return new JPADeleteClause(entityManager, entityPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void persist(T model) {
|
public void persist(T model) {
|
||||||
entityManager.persist(model);
|
entityManager.persist(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
public T merge(T model) {
|
public T merge(T model) {
|
||||||
return entityManager.merge(model);
|
return entityManager.merge(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
public T findById(Long id) {
|
public T findById(Long id) {
|
||||||
return entityManager.find(entityClass, id);
|
return entityManager.find(entityClass, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete(T object) {
|
public void delete(T object) {
|
||||||
if (object != null) {
|
if (object != null) {
|
||||||
entityManager.remove(object);
|
entityManager.remove(object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int delete(Collection<T> objects) {
|
public int delete(Collection<T> objects) {
|
||||||
objects.forEach(this::delete);
|
objects.forEach(this::delete);
|
||||||
return objects.size();
|
return objects.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setTimeout(JPAQuery<?> query, Duration timeout) {
|
|
||||||
if (!timeout.isZero()) {
|
|
||||||
query.setHint(SpecHints.HINT_SPEC_QUERY_TIMEOUT, Math.toIntExact(timeout.toMillis()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
protected void setTimeout(JPAQuery<?> query, Duration timeout) {
|
||||||
|
if (!timeout.isZero()) {
|
||||||
|
query.setHint(SpecHints.HINT_SPEC_QUERY_TIMEOUT, Math.toIntExact(timeout.toMillis()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,9 +10,12 @@ import lombok.experimental.UtilityClass;
|
|||||||
@UtilityClass
|
@UtilityClass
|
||||||
public class Predicates {
|
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,19 +1,19 @@
|
|||||||
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 {
|
||||||
|
|
||||||
public void run(Runnable runnable) {
|
public void run(Runnable runnable) {
|
||||||
QuarkusTransaction.joiningExisting().run(runnable);
|
QuarkusTransaction.joiningExisting().run(runnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T call(Callable<T> callable) {
|
public <T> T call(Callable<T> callable) {
|
||||||
return QuarkusTransaction.joiningExisting().call(callable);
|
return QuarkusTransaction.joiningExisting().call(callable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +1,33 @@
|
|||||||
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> {
|
||||||
|
|
||||||
private static final QUser USER = QUser.user;
|
private static final QUser USER = QUser.user;
|
||||||
|
|
||||||
public UserDAO(EntityManager entityManager) {
|
public UserDAO(EntityManager entityManager) {
|
||||||
super(entityManager, User.class);
|
super(entityManager, User.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public User findByName(String name) {
|
public User findByName(String name) {
|
||||||
return query().selectFrom(USER).where(USER.name.equalsIgnoreCase(name)).fetchOne();
|
return query().selectFrom(USER).where(USER.name.equalsIgnoreCase(name)).fetchOne();
|
||||||
}
|
}
|
||||||
|
|
||||||
public User findByApiKey(String key) {
|
public User findByApiKey(String key) {
|
||||||
return query().selectFrom(USER).where(USER.apiKey.equalsIgnoreCase(key)).fetchOne();
|
return query().selectFrom(USER).where(USER.apiKey.equalsIgnoreCase(key)).fetchOne();
|
||||||
}
|
}
|
||||||
|
|
||||||
public User findByEmail(String email) {
|
public User findByEmail(String email) {
|
||||||
return query().selectFrom(USER).where(USER.email.equalsIgnoreCase(email)).fetchOne();
|
return query().selectFrom(USER).where(USER.email.equalsIgnoreCase(email)).fetchOne();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long count() {
|
public long count() {
|
||||||
return query().select(USER.count()).from(USER).fetchOne();
|
return query().select(USER.count()).from(USER).fetchOne();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,39 +1,39 @@
|
|||||||
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> {
|
||||||
|
|
||||||
private static final QUserRole ROLE = QUserRole.userRole;
|
private static final QUserRole ROLE = QUserRole.userRole;
|
||||||
|
|
||||||
public UserRoleDAO(EntityManager entityManager) {
|
public UserRoleDAO(EntityManager entityManager) {
|
||||||
super(entityManager, UserRole.class);
|
super(entityManager, UserRole.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<UserRole> findAll() {
|
public List<UserRole> findAll() {
|
||||||
return query().selectFrom(ROLE).leftJoin(ROLE.user).fetchJoin().distinct().fetch();
|
return query().selectFrom(ROLE).leftJoin(ROLE.user).fetchJoin().distinct().fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<UserRole> findAll(User user) {
|
public List<UserRole> findAll(User user) {
|
||||||
return query().selectFrom(ROLE).where(ROLE.user.eq(user)).distinct().fetch();
|
return query().selectFrom(ROLE).where(ROLE.user.eq(user)).distinct().fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Role> findRoles(User user) {
|
public Set<Role> findRoles(User user) {
|
||||||
return findAll(user).stream().map(UserRole::getRole).collect(Collectors.toSet());
|
return findAll(user).stream().map(UserRole::getRole).collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
public long countAdmins() {
|
public long countAdmins() {
|
||||||
return query().select(ROLE.count()).from(ROLE).where(ROLE.role.eq(Role.ADMIN)).fetchOne();
|
return query().select(ROLE.count()).from(ROLE).where(ROLE.role.eq(Role.ADMIN)).fetchOne();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
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> {
|
||||||
|
|
||||||
private static final QUserSettings SETTINGS = QUserSettings.userSettings;
|
private static final QUserSettings SETTINGS = QUserSettings.userSettings;
|
||||||
|
|
||||||
public UserSettingsDAO(EntityManager entityManager) {
|
public UserSettingsDAO(EntityManager entityManager) {
|
||||||
super(entityManager, UserSettings.class);
|
super(entityManager, UserSettings.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserSettings findByUser(User user) {
|
public UserSettings findByUser(User user) {
|
||||||
return query().selectFrom(SETTINGS).where(SETTINGS.user.eq(user)).fetchFirst();
|
return query().selectFrom(SETTINGS).where(SETTINGS.user.eq(user)).fetchFirst();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,73 +1,71 @@
|
|||||||
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")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (!url.toLowerCase().contains("www.facebook.com")) {
|
String userName = extractUserName(url);
|
||||||
return null;
|
if (userName == null) {
|
||||||
}
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
String userName = extractUserName(url);
|
String iconUrl =
|
||||||
if (userName == null) {
|
String.format(
|
||||||
return null;
|
"https://graph.facebook.com/%s/picture?type=square&height=16", userName);
|
||||||
}
|
|
||||||
|
|
||||||
String iconUrl = String.format("https://graph.facebook.com/%s/picture?type=square&height=16", userName);
|
try {
|
||||||
|
log.debug("Getting Facebook user's icon, {}", url);
|
||||||
|
|
||||||
byte[] bytes = null;
|
HttpResult iconResult = getter.get(iconUrl);
|
||||||
String contentType = null;
|
return new Favicon(iconResult.content(), iconResult.contentType());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.debug("Failed to retrieve Facebook icon", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
private String extractUserName(String url) {
|
||||||
log.debug("Getting Facebook user's icon, {}", url);
|
URI uri;
|
||||||
|
try {
|
||||||
HttpResult iconResult = getter.get(iconUrl);
|
uri = new URI(url);
|
||||||
bytes = iconResult.content();
|
} catch (URISyntaxException e) {
|
||||||
contentType = iconResult.contentType();
|
log.debug("could not parse url", e);
|
||||||
} catch (Exception e) {
|
return null;
|
||||||
log.debug("Failed to retrieve Facebook icon", e);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!isValidIconResponse(bytes, contentType)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return new Favicon(bytes, contentType);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String extractUserName(String url) {
|
|
||||||
URI uri;
|
|
||||||
try {
|
|
||||||
uri = new URI(url);
|
|
||||||
} catch (URISyntaxException e) {
|
|
||||||
log.debug("could not parse url", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<NameValuePair> params = new URIBuilder(uri).getQueryParams();
|
|
||||||
return params.stream().filter(p -> "id".equals(p.getName())).map(NameValuePair::getValue).findFirst().orElse(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
List<NameValuePair> params = new URIBuilder(uri).getQueryParams();
|
||||||
|
return params.stream()
|
||||||
|
.filter(p -> "id".equals(p.getName()))
|
||||||
|
.map(NameValuePair::getValue)
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,18 +7,19 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public record Favicon(byte[] icon, MediaType mediaType) {
|
public record Favicon(byte[] icon, MediaType mediaType) {
|
||||||
|
|
||||||
private static final MediaType DEFAULT_MEDIA_TYPE = MediaType.valueOf("image/x-icon");
|
private static final MediaType DEFAULT_MEDIA_TYPE = MediaType.valueOf("image/x-icon");
|
||||||
|
|
||||||
public Favicon(byte[] icon, String contentType) {
|
public Favicon(byte[] icon, String contentType) {
|
||||||
this(icon, parseMediaType(contentType));
|
this(icon, parseMediaType(contentType));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MediaType parseMediaType(String contentType) {
|
private static MediaType parseMediaType(String contentType) {
|
||||||
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(
|
||||||
return DEFAULT_MEDIA_TYPE;
|
"invalid content type '{}' received, returning default value", contentType, e);
|
||||||
}
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user