mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-11-15 05:12:18 +01:00
Compare commits
846
Commits
fix_set_token
...
v3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
94f3035489 | ||
|
|
1eb5b9f1bc | ||
|
|
c6918b6828 | ||
|
|
c5e6e463e4 | ||
|
|
95aa00af90 | ||
|
|
1d89e3a58c | ||
|
|
75d85e971b | ||
|
|
41cbcf551d | ||
|
|
3e0333877b | ||
|
|
2dde0bf1c7 | ||
|
|
1e60d7af64 | ||
|
|
83dce682e8 | ||
|
|
f88fdf1321 | ||
|
|
20fd0cd700 | ||
|
|
9b055f80a6 | ||
|
|
04acd53667 | ||
|
|
92bae242f1 | ||
|
|
49c0ef6c07 | ||
|
|
34b037087b | ||
|
|
f57ca09f6e | ||
|
|
844b04c6ae | ||
|
|
149bae7d73 | ||
|
|
d6d0cf6b8f | ||
|
|
c38fe60360 | ||
|
|
087099faa3 | ||
|
|
8c87ae8bad | ||
|
|
ce41ce489c | ||
|
|
b31af26837 | ||
|
|
4072054e00 | ||
|
|
f1f57d6595 | ||
|
|
7aaa734d3e | ||
|
|
48d9309eb2 | ||
|
|
f85d03ce26 | ||
|
|
616c8ba152 | ||
|
|
edb1f7efc9 | ||
|
|
92517f473b | ||
|
|
9715c7a8f7 | ||
|
|
95cb5bad27 | ||
|
|
5cb461f9b5 | ||
|
|
16aa80ed5c | ||
|
|
743d915220 | ||
|
|
34715558df | ||
|
|
2a0507ffc6 | ||
|
|
cff295fdc9 | ||
|
|
6b60beff6e | ||
|
|
db433ce076 | ||
|
|
5edd20dfa3 | ||
|
|
3563d49424 | ||
|
|
06935b78b5 | ||
|
|
4aee64da07 | ||
|
|
02cf2da4fa | ||
|
|
366320bf94 | ||
|
|
a2cba8dd05 | ||
|
|
86bc18487b | ||
|
|
9e18cb41e9 | ||
|
|
7d10b8fc4a | ||
|
|
14bec248f1 | ||
|
|
ff57368f37 | ||
|
|
f589397008 | ||
|
|
fa4f6b58f3 | ||
|
|
1acfd2ae54 | ||
|
|
91717e3b96 | ||
|
|
282d8b8bf6 | ||
|
|
fb4c3ba984 | ||
|
|
72a1c656f9 | ||
|
|
273693e8ad | ||
|
|
d22c468215 | ||
|
|
c654de4630 | ||
|
|
aef33df8d3 | ||
|
|
63a883e595 | ||
|
|
b8b069eca6 | ||
|
|
0fd0483021 | ||
|
|
8463b8426a | ||
|
|
e874d31e64 | ||
|
|
557f56ff21 | ||
|
|
7f296a5135 | ||
|
|
b5134a3287 | ||
|
|
8fb7a856d5 | ||
|
|
ad8b235058 | ||
|
|
186733f6af | ||
|
|
1e5443f054 | ||
|
|
18e32410ad | ||
|
|
5077f87e0c | ||
|
|
608d3ddde8 | ||
|
|
4c27a7b68e | ||
|
|
a3b150d049 | ||
|
|
088c4f542f | ||
|
|
6acb4b9005 | ||
|
|
8781930ced | ||
|
|
4236eef5c4 | ||
|
|
b14224a6d8 | ||
|
|
a6128a6c98 | ||
|
|
8a2a45751e | ||
|
|
83e9a82f8f | ||
|
|
bf4f74cb93 | ||
|
|
1e88ff01e7 | ||
|
|
5ec4a8a46e | ||
|
|
99e2c45482 | ||
|
|
3c5d191c33 | ||
|
|
b67cbffbf9 | ||
|
|
eeaa408a2d | ||
|
|
4b67c170ce | ||
|
|
d21aec237c | ||
|
|
632ccd5cbf | ||
|
|
62efd5c583 | ||
|
|
9244f9ea5a | ||
|
|
7e76eed8bb | ||
|
|
e4e212cca7 | ||
|
|
fb43db4f75 | ||
|
|
3b4895b1b0 | ||
|
|
a06639886b | ||
|
|
37d7ee20ed | ||
|
|
eb8ed7f5b6 | ||
|
|
3d62a103ae | ||
|
|
42bf9512b0 | ||
|
|
5cb75a85ec | ||
|
|
3c1bbc7f8e | ||
|
|
b204395b8e | ||
|
|
e4c69fe68b | ||
|
|
def8fca33a | ||
|
|
e8ed987034 | ||
|
|
d5be05b11e | ||
|
|
580f9fb649 | ||
|
|
7aecf129ac | ||
|
|
4056f37390 | ||
|
|
6bc2a89827 | ||
|
|
eba1909c9c | ||
|
|
010a73a16a | ||
|
|
ed6663054f | ||
|
|
01263e9379 | ||
|
|
1ab6120596 | ||
|
|
c097655c5c | ||
|
|
9f541063db | ||
|
|
3f2da7febc | ||
|
|
24c68507e7 | ||
|
|
b325d0ee1d | ||
|
|
5f6fa4adbf | ||
|
|
78130a7823 | ||
|
|
e4556b0307 | ||
|
|
6f57182da0 | ||
|
|
1aef21169c | ||
|
|
e02c859437 | ||
|
|
9f475ef3d5 | ||
|
|
5ad5768308 | ||
|
|
d38bf9e868 | ||
|
|
1027b85e68 | ||
|
|
67992540c0 | ||
|
|
733c795989 | ||
|
|
0a797ab8be | ||
|
|
fbfb24c264 | ||
|
|
2440fb37c4 | ||
|
|
65c075283c | ||
|
|
198b2c27b8 | ||
|
|
d6398e54dd | ||
|
|
c0b9110e4e | ||
|
|
13432209ee | ||
|
|
0571747fab | ||
|
|
ec2738cb0f | ||
|
|
a7ebb3e1af | ||
|
|
513a0679f5 | ||
|
|
3f9afe57bc | ||
|
|
ac63b0c7fc | ||
|
|
1b46d68027 | ||
|
|
d511612f21 | ||
|
|
94400acdcd | ||
|
|
6caa1aa2da | ||
|
|
32fae4a7c6 | ||
|
|
96d4021a3c | ||
|
|
49826f5163 | ||
|
|
76e33a2a4e | ||
|
|
1a440811c5 | ||
|
|
529a16b718 | ||
|
|
032f0b6b51 | ||
|
|
f5bfa1edd6 | ||
|
|
4dfad46722 | ||
|
|
c86f336536 | ||
|
|
1876bfbfe7 | ||
|
|
a7b380cd7a | ||
|
|
71c5d27ea5 | ||
|
|
83707e08bf | ||
|
|
e8d1b58bd2 | ||
|
|
aff79b5579 | ||
|
|
321d8bfda1 | ||
|
|
a3ff41f90e | ||
|
|
60f9ac93f7 | ||
|
|
bd61a43458 | ||
|
|
df6ec07f18 | ||
|
|
6d02aa3aa0 | ||
|
|
144fe743c6 | ||
|
|
0851b346d0 | ||
|
|
53e904314e | ||
|
|
84f80f1903 | ||
|
|
98b1f4abad | ||
|
|
ec0d147d6d | ||
|
|
a7825bb461 | ||
|
|
09be7799f6 | ||
|
|
dc6a8a7292 | ||
|
|
0c075674a0 | ||
|
|
5b13820cb4 | ||
|
|
d5b4d57fe3 | ||
|
|
f12b64495a | ||
|
|
43f3150a52 | ||
|
|
65d3a668e3 | ||
|
|
2b5297bee8 | ||
|
|
08caeb5975 | ||
|
|
6c170a5064 | ||
|
|
4b62f90964 | ||
|
|
e9ea511c90 | ||
|
|
c6afeb7dc9 | ||
|
|
35a2c5e87c | ||
|
|
4c71a076e7 | ||
|
|
e56c1099e6 | ||
|
|
dc0b24a03f | ||
|
|
c900676be7 | ||
|
|
a6cde926ee | ||
|
|
e8db14fe33 | ||
|
|
e9b533637f | ||
|
|
8b97da500d | ||
|
|
37b42601ef | ||
|
|
5da4ec51ce | ||
|
|
4c65a87d5c | ||
|
|
0e5618dcd8 | ||
|
|
d063d851e1 | ||
|
|
6458e6d3d2 | ||
|
|
70953d8c82 | ||
|
|
2d9f63963e | ||
|
|
f12abca3fc | ||
|
|
bced308462 | ||
|
|
528d03fef3 | ||
|
|
b93c3133a9 | ||
|
|
8d9db8d103 | ||
|
|
08bbf9cd9d | ||
|
|
95af4812cd | ||
|
|
8ec547e302 | ||
|
|
32e4da8c92 | ||
|
|
0ce37004af | ||
|
|
527745b54e | ||
|
|
3c016314e6 | ||
|
|
59c7d0275c | ||
|
|
4883d0f60c | ||
|
|
9d9ab49664 | ||
|
|
82aec5f60c | ||
|
|
7ee5e1bdf6 | ||
|
|
3bb53d939d | ||
|
|
6f03467f35 | ||
|
|
b2f593f1c4 | ||
|
|
58dcda36a5 | ||
|
|
354e0bf793 | ||
|
|
0784373b61 | ||
|
|
2f219ea3cc | ||
|
|
56e60b8420 | ||
|
|
9b92b5de34 | ||
|
|
3417c0c721 | ||
|
|
cbda0360aa | ||
|
|
036bc081f0 | ||
|
|
42947e2e64 | ||
|
|
c4e7172c2f | ||
|
|
4502d37d4f | ||
|
|
e70e4b9d40 | ||
|
|
aacdcc47ec | ||
|
|
499b52b4dd | ||
|
|
1bad2d9072 | ||
|
|
c009db9f28 | ||
|
|
325469c5a5 | ||
|
|
c97b36e11c | ||
|
|
e944b2a2f5 | ||
|
|
2d0a5462d2 | ||
|
|
72dc75482f | ||
|
|
cac74f3477 | ||
|
|
1ad11b2b9e | ||
|
|
50eeca2e0f | ||
|
|
4f21fc023c | ||
|
|
52a485d135 | ||
|
|
3b025076e8 | ||
|
|
6d5d89429d | ||
|
|
c010f0e1eb | ||
|
|
eee377e081 | ||
|
|
b0aaa24660 | ||
|
|
47ea6b5092 | ||
|
|
4b060febc2 | ||
|
|
40869bcf39 | ||
|
|
3942805129 | ||
|
|
dc446862c1 | ||
|
|
379f6c716a | ||
|
|
47457ee1e7 | ||
|
|
cb6ff9eedf | ||
|
|
5dc01261c1 | ||
|
|
cbc103cf05 | ||
|
|
e79256d0fb | ||
|
|
f8ef56c6bc | ||
|
|
62d7097e23 | ||
|
|
92df92ec99 | ||
|
|
1c229e0627 | ||
|
|
f8a71cc514 | ||
|
|
63de5bb2d5 | ||
|
|
2c3108a1fa | ||
|
|
928051744a | ||
|
|
3ccdcaec1a | ||
|
|
f47bbc7886 | ||
|
|
7c0ca44727 | ||
|
|
d6a2e5596b | ||
|
|
a5362de9cc | ||
|
|
9ab35ef418 | ||
|
|
79cc9765cf | ||
|
|
5b2a788cfc | ||
|
|
80b39abaa2 | ||
|
|
b41db23994 | ||
|
|
125f265f55 | ||
|
|
aa4a191567 | ||
|
|
e431ea0472 | ||
|
|
e3388d4446 | ||
|
|
88879f1409 | ||
|
|
3e0099e8d9 | ||
|
|
f558182d94 | ||
|
|
a30fe15b10 | ||
|
|
0bbf8bde5c | ||
|
|
0e2cdde731 | ||
|
|
bc6bfbe804 | ||
|
|
2755204168 | ||
|
|
2d4df273f0 | ||
|
|
d73b64a19c | ||
|
|
b7e8a0474a | ||
|
|
39adefb632 | ||
|
|
24cab79c66 | ||
|
|
b27f21fd95 | ||
|
|
09fa0b38f5 | ||
|
|
455e605162 | ||
|
|
88667d00a1 | ||
|
|
94c426bd97 | ||
|
|
522b9735e2 | ||
|
|
5a6b3d8e61 | ||
|
|
64cbf59609 | ||
|
|
fda1a6ea9b | ||
|
|
c4c8b8d0f2 | ||
|
|
ab3bd6f4a1 | ||
|
|
093124aac6 | ||
|
|
5de92d08f9 | ||
|
|
8b89b27654 | ||
|
|
3faa6f3e7d | ||
|
|
9821c31f8e | ||
|
|
efe2a22674 | ||
|
|
9634c46bc5 | ||
|
|
5f8db24b96 | ||
|
|
e781ff5eae | ||
|
|
32a17c0044 | ||
|
|
f84831d6f1 | ||
|
|
dc54d42dcf | ||
|
|
15af7407ff | ||
|
|
5d9682410a | ||
|
|
4bdd76d94c | ||
|
|
7c0d9efe91 | ||
|
|
874e9e1856 | ||
|
|
6d3773a0b8 | ||
|
|
a47c869d0b | ||
|
|
eb0383d37a | ||
|
|
e66ffb9c23 | ||
|
|
972193b193 | ||
|
|
690a7e0da9 | ||
|
|
d9355ac3aa | ||
|
|
fbe1d1eed6 | ||
|
|
e83aca572e | ||
|
|
367826ce64 | ||
|
|
6e6c43c53c | ||
|
|
6479cdb66d | ||
|
|
635e132325 | ||
|
|
45dd843ce1 | ||
|
|
7c956b1582 | ||
|
|
9afa39e29e | ||
|
|
5f8450602e | ||
|
|
fa6dae1a53 | ||
|
|
a1d439b8d5 | ||
|
|
2f32673991 | ||
|
|
c1a6b51d78 | ||
|
|
6c2e13fb4e | ||
|
|
210fa55b6a | ||
|
|
fb8ca043ad | ||
|
|
69d7c399b8 | ||
|
|
a35ba05600 | ||
|
|
40f42b2ab6 | ||
|
|
cf4b9e938d | ||
|
|
31120ad111 | ||
|
|
cd8640f00e | ||
|
|
d0ba455ed6 | ||
|
|
e5b7aea46c | ||
|
|
2f2d026b06 | ||
|
|
c156b063f5 | ||
|
|
e6d49a2d53 | ||
|
|
6d3404272c | ||
|
|
a9e12657f5 | ||
|
|
c0319ebbac | ||
|
|
1d0b7e383a | ||
|
|
9f5d8386f3 | ||
|
|
6e0da3bf7a | ||
|
|
ee6016f70e | ||
|
|
f1a2e56054 | ||
|
|
d2915e689f | ||
|
|
05d9ab81f9 | ||
|
|
75eed9d09a | ||
|
|
e5af2f336b | ||
|
|
ade1752e97 | ||
|
|
fa5fa7b788 | ||
|
|
b01facc034 | ||
|
|
dd4fc09909 | ||
|
|
c15cb48def | ||
|
|
fe13456a2b | ||
|
|
2ee893062f | ||
|
|
31630f50a5 | ||
|
|
edfce46058 | ||
|
|
cc5244c596 | ||
|
|
b8942c5931 | ||
|
|
6e5feee78a | ||
|
|
e7cb0466e6 | ||
|
|
6c7221d37d | ||
|
|
1f3fa80ddd | ||
|
|
87f3766299 | ||
|
|
d08cef11ed | ||
|
|
7201cced42 | ||
|
|
4f8fbbc979 | ||
|
|
e55fed4a33 | ||
|
|
dcbeecff7a | ||
|
|
32276aacd9 | ||
|
|
b921a08809 | ||
|
|
c089336e41 | ||
|
|
5107b0307c | ||
|
|
8498378bca | ||
|
|
b61e2c30f2 | ||
|
|
cfeb6bd502 | ||
|
|
077b523bd6 | ||
|
|
b8a2d113f0 | ||
|
|
e1ae4f2d31 | ||
|
|
7aa2f84daa | ||
|
|
da0a64daed | ||
|
|
dfce15a74c | ||
|
|
3e4225bced | ||
|
|
e6d99d07f0 | ||
|
|
122fc34a75 | ||
|
|
e5c0a9d22c | ||
|
|
3bf136a20b | ||
|
|
b387d9484a | ||
|
|
e8668d9f22 | ||
|
|
f3e90bd420 | ||
|
|
4bf15bbffd | ||
|
|
04eb3bc437 | ||
|
|
81e96df9c5 | ||
|
|
44aff23e1b | ||
|
|
cc48d9f26d | ||
|
|
ac08e897ee | ||
|
|
3c2eec8279 | ||
|
|
7b37c98e88 | ||
|
|
088353ae26 | ||
|
|
e003544edd | ||
|
|
076ece6fe7 | ||
|
|
14f72ab7d4 | ||
|
|
ebcb122eb8 | ||
|
|
626596b192 | ||
|
|
10a4777ddf | ||
|
|
0ecbb1c3f4 | ||
|
|
dc2398a072 | ||
|
|
c1e21d31ee | ||
|
|
70e6efc3d0 | ||
|
|
092c504eb1 | ||
|
|
f7d7c9a4f5 | ||
|
|
8bdcabf973 | ||
|
|
646c861bcc | ||
|
|
ee60169995 | ||
|
|
afb4108c30 | ||
|
|
2e2d857ce0 | ||
|
|
ed5766b4ab | ||
|
|
a33e87db99 | ||
|
|
5de942aefb | ||
|
|
bcfe1e9647 | ||
|
|
503f4611b2 | ||
|
|
648983708e | ||
|
|
991d25f628 | ||
|
|
d2a7c3c381 | ||
|
|
219a9fc6d5 | ||
|
|
ba2259d174 | ||
|
|
d7bfccdc4a | ||
|
|
5f1edcb609 | ||
|
|
329e3c7179 | ||
|
|
919ea32416 | ||
|
|
3b6419bc1b | ||
|
|
d4fdb47c7f | ||
|
|
cee9b9d8e3 | ||
|
|
9441346b0a | ||
|
|
6b8464c270 | ||
|
|
d12f727603 | ||
|
|
1552c250df | ||
|
|
623c2fba12 | ||
|
|
be27908d44 | ||
|
|
7a39d581a1 | ||
|
|
53a416fd28 | ||
|
|
7393c03218 | ||
|
|
594589da3d | ||
|
|
44d7deae99 | ||
|
|
ff9e87c4d5 | ||
|
|
c2fd87d55c | ||
|
|
27843c3f9b | ||
|
|
0ec2ced011 | ||
|
|
552ed43243 | ||
|
|
0606738b38 | ||
|
|
a5d2c1bd64 | ||
|
|
d8e272e091 | ||
|
|
3e9ca51088 | ||
|
|
8758c62ae2 | ||
|
|
db9019a94f | ||
|
|
39b8b9df4f | ||
|
|
a36f097095 | ||
|
|
ae0ccb1b47 | ||
|
|
f178841e57 | ||
|
|
568b154e8a | ||
|
|
8c5678b573 | ||
|
|
e51c7b2be1 | ||
|
|
d460757df4 | ||
|
|
cd295c03ca | ||
|
|
38dd1beff7 | ||
|
|
61b72aff9d | ||
|
|
9eda4e36fa | ||
|
|
a05cb170a2 | ||
|
|
c75d976320 | ||
|
|
ab9b798bfa | ||
|
|
40783c8644 | ||
|
|
a0137fcb42 | ||
|
|
9fdda6be62 | ||
|
|
b0c073dd7e | ||
|
|
b83e2836f6 | ||
|
|
f91be18527 | ||
|
|
c1f4e4120e | ||
|
|
b42c7421b0 | ||
|
|
82f512d405 | ||
|
|
01a833ea59 | ||
|
|
f1c39e8587 | ||
|
|
5e68936c20 | ||
|
|
a4c9b062c1 | ||
|
|
763d8810e3 | ||
|
|
3316505d1c | ||
|
|
2cf6e8a5fe | ||
|
|
961d066bdd | ||
|
|
372c9a5322 | ||
|
|
f77de1743e | ||
|
|
a5750deaaf | ||
|
|
0c7b738b7c | ||
|
|
c3c9e7731d | ||
|
|
d3b5612fc0 | ||
|
|
96ef0129ed | ||
|
|
85546b7dd7 | ||
|
|
d59714d804 | ||
|
|
96693659bf | ||
|
|
ee2d8d1f71 | ||
|
|
f03b0915eb | ||
|
|
a92ba564bd | ||
|
|
e684a8dc43 | ||
|
|
6db6b862e6 | ||
|
|
57c7b123f0 | ||
|
|
fd593caafc | ||
|
|
d0a3f74710 | ||
|
|
b1921e7034 | ||
|
|
538a5065a4 | ||
|
|
166e0442a0 | ||
|
|
816a47a4ba | ||
|
|
141211590f | ||
|
|
b01e7570d3 | ||
|
|
0a8662d198 | ||
|
|
0a4de61eff | ||
|
|
0a82d6a41b | ||
|
|
3f6162f53c | ||
|
|
888190a6be | ||
|
|
ce4ff4f894 | ||
|
|
1da3ab7fdc | ||
|
|
4f30cbf2f6 | ||
|
|
a87ea32715 | ||
|
|
feed827223 | ||
|
|
797dba2448 | ||
|
|
f0acbb2e81 | ||
|
|
fc06aa2c78 | ||
|
|
4224f44259 | ||
|
|
2592467d09 | ||
|
|
37beb7b37c | ||
|
|
cafd92e206 | ||
|
|
3e876e3383 | ||
|
|
29752798f3 | ||
|
|
8c86ca4ea5 | ||
|
|
00c62fa494 | ||
|
|
6c7f3c7e77 | ||
|
|
aec8acbdd7 | ||
|
|
6e19ad7777 | ||
|
|
3aa95fec11 | ||
|
|
37dd46d31f | ||
|
|
54a996634e | ||
|
|
54a5e368c2 | ||
|
|
2d313851d2 | ||
|
|
eb00b19457 | ||
|
|
bbae9acc2d | ||
|
|
a4e8f01f0e | ||
|
|
6bdf402da8 | ||
|
|
80b0e3546e | ||
|
|
161f3cb177 | ||
|
|
4a4d4a8f17 | ||
|
|
b21046027c | ||
|
|
3a163e1746 | ||
|
|
3c4e80f1c1 | ||
|
|
2f3036faba | ||
|
|
3934461c46 | ||
|
|
123351e08a | ||
|
|
1280ddfe74 | ||
|
|
7e89b97a6d | ||
|
|
20de2ea388 | ||
|
|
dbb5ee79ac | ||
|
|
c6dabd2620 | ||
|
|
26f949b9ba | ||
|
|
7630dbdcb7 | ||
|
|
a164c17d38 | ||
|
|
03da194953 | ||
|
|
9ce6de3100 | ||
|
|
e040396b20 | ||
|
|
bcbec67fec | ||
|
|
1543021685 | ||
|
|
577e6aaec9 | ||
|
|
77579acfd4 | ||
|
|
9ca98ca750 | ||
|
|
feb225d3a6 | ||
|
|
e501aa4f1e | ||
|
|
104f6e6c58 | ||
|
|
552d8ae3b8 | ||
|
|
a41e9bae5d | ||
|
|
a456865ec0 | ||
|
|
85d5531bc1 | ||
|
|
4b840f9c97 | ||
|
|
b9510a69fe | ||
|
|
d737a66af2 | ||
|
|
576d18d8d6 | ||
|
|
d238b02bd2 | ||
|
|
c6cb13ed39 | ||
|
|
44c5dce8aa | ||
|
|
b726bee4e5 | ||
|
|
b07e449043 | ||
|
|
9273e61f1e | ||
|
|
1b4a7acf13 | ||
|
|
68c1395bdf | ||
|
|
a007a9ec98 | ||
|
|
8b33b5e383 | ||
|
|
c81b762d52 | ||
|
|
c53a5c5a0b | ||
|
|
83af75a582 | ||
|
|
60389a3bf3 | ||
|
|
20cceb3a8f | ||
|
|
7562fb2c21 | ||
|
|
c7647aafd7 | ||
|
|
4a73247e5c | ||
|
|
326086c197 | ||
|
|
5ff5245476 | ||
|
|
856cf180a5 | ||
|
|
fbe9971a8b | ||
|
|
6ea70608a1 | ||
|
|
ba7160c305 | ||
|
|
7d048b7a50 | ||
|
|
afab429c75 | ||
|
|
50e2fe7fd2 | ||
|
|
c7c21cc137 | ||
|
|
7e4c7a7e3b | ||
|
|
40babc9650 | ||
|
|
7a94f014ea | ||
|
|
32adb1bafd | ||
|
|
f9a6239049 | ||
|
|
8dee1ec942 | ||
|
|
58e43cc6a7 | ||
|
|
b8999fbc37 | ||
|
|
0dda4b6b27 | ||
|
|
817f2f6915 | ||
|
|
77fc6bba1a | ||
|
|
c66d652a53 | ||
|
|
86bddba5c3 | ||
|
|
7779fd2972 | ||
|
|
05a4577792 | ||
|
|
56dc042282 | ||
|
|
95973243a6 | ||
|
|
18ad23d016 | ||
|
|
e258f122f1 | ||
|
|
18200a8f01 | ||
|
|
9c47f404c9 | ||
|
|
2f6de71a3a | ||
|
|
deb121c523 | ||
|
|
320e4dfb47 | ||
|
|
6194c48549 | ||
|
|
6aa9ecaaba | ||
|
|
b3d020b89f | ||
|
|
e196a6e5ca | ||
|
|
73cf22b499 | ||
|
|
ac7464ce7e | ||
|
|
84e742f2a5 | ||
|
|
a1e882cbf1 | ||
|
|
09121acbd5 | ||
|
|
5b9df84ba3 | ||
|
|
266db491aa | ||
|
|
c7a317a87b | ||
|
|
b027f3bda1 | ||
|
|
cea991b82f | ||
|
|
7e2b51e6d2 | ||
|
|
8f310b6bf0 | ||
|
|
b2a5fb46f1 | ||
|
|
6d7639853b | ||
|
|
3a16acbba4 | ||
|
|
027e1efaca | ||
|
|
d1fabba86b | ||
|
|
b290a4ada3 | ||
|
|
bb477c617e | ||
|
|
9238c38842 | ||
|
|
d268516fcb | ||
|
|
d353cff1ae | ||
|
|
604f17f60b | ||
|
|
3911a7273b | ||
|
|
138bb563b8 | ||
|
|
3801ef062a | ||
|
|
e4b9ac5446 | ||
|
|
9987d219f8 | ||
|
|
dc7045c562 | ||
|
|
2cc6e56bd1 | ||
|
|
a89a24e48e | ||
|
|
a968aca304 | ||
|
|
8d1f460640 | ||
|
|
553ffd1934 | ||
|
|
fd4932cdbb | ||
|
|
dcaca43817 | ||
|
|
0eed4e82f9 | ||
|
|
2ed2328401 | ||
|
|
8b260c8bc6 | ||
|
|
7dcb9b98a0 | ||
|
|
311ac7104e | ||
|
|
2c45b28d48 | ||
|
|
b53613f82c | ||
|
|
751371abb8 | ||
|
|
6365c02875 | ||
|
|
fb3834156b | ||
|
|
c03f3f722d | ||
|
|
a06f48ca29 | ||
|
|
9d79552dda | ||
|
|
ed98614b6f | ||
|
|
09dd2cc79c | ||
|
|
e87237048a | ||
|
|
d71968fd80 | ||
|
|
f83c605ae1 | ||
|
|
4325f470dd | ||
|
|
800ecf8e82 | ||
|
|
5cb143d50b | ||
|
|
798c73c66c | ||
|
|
0fa7c46274 | ||
|
|
c2d420ec70 | ||
|
|
152daf7bf3 | ||
|
|
8d99249e50 | ||
|
|
c6724ba353 | ||
|
|
a519d44666 | ||
|
|
7e8bf977cc | ||
|
|
4018be6330 | ||
|
|
99a3867ce9 | ||
|
|
2116f60133 | ||
|
|
794f0ef42a | ||
|
|
3e423839a1 | ||
|
|
2773c8c4a9 | ||
|
|
e510174f12 | ||
|
|
08c9e8d47d | ||
|
|
1908ec3df5 | ||
|
|
df3878d4ca | ||
|
|
1097de6f1f | ||
|
|
e408070b19 | ||
|
|
af67c2e86f | ||
|
|
6a52d2a968 | ||
|
|
3337b3af18 | ||
|
|
835d2c7f36 | ||
|
|
03f91099e0 | ||
|
|
c04afd0787 | ||
|
|
b03bd79f5d | ||
|
|
5ef632a7eb | ||
|
|
79b4042e8e | ||
|
|
8f718ef91c | ||
|
|
4053b20623 | ||
|
|
c4d654635f | ||
|
|
ef5d0ffa48 | ||
|
|
6a826cdb36 | ||
|
|
1d837f5f21 | ||
|
|
80873b379c | ||
|
|
82a8f8f126 | ||
|
|
4725a466da | ||
|
|
031edc870c | ||
|
|
625e2445b5 | ||
|
|
1640af2f1c | ||
|
|
c76f76cc27 | ||
|
|
74af212293 | ||
|
|
e04efb9c6a | ||
|
|
ee17e7a555 | ||
|
|
694a852c07 | ||
|
|
18068bb261 | ||
|
|
71257f6c6c | ||
|
|
4d70929d2e | ||
|
|
578e9559e4 | ||
|
|
894ea0b80a | ||
|
|
e54571f011 | ||
|
|
77d7a50b99 | ||
|
|
32da0f1224 | ||
|
|
2054accdc9 | ||
|
|
7d8b857c77 | ||
|
|
0107cb4782 | ||
|
|
f273eee807 | ||
|
|
4af21b079a | ||
|
|
c9eaf2db2d | ||
|
|
cae1560344 | ||
|
|
a5fb0d9cdb | ||
|
|
53c80d9798 | ||
|
|
832165716b | ||
|
|
d9f2d8bf1d | ||
|
|
a7a3a56509 | ||
|
|
4082fadf90 | ||
|
|
93160b83bf | ||
|
|
472240f994 | ||
|
|
c3f0fb8e5e | ||
|
|
b156ebeb9f | ||
|
|
e4c775c847 | ||
|
|
45e8e72759 | ||
|
|
0ae7340889 | ||
|
|
8c38987d92 | ||
|
|
878f0787ba | ||
|
|
880d85eaef | ||
|
|
f7aaebc1de | ||
|
|
d96ebbe82d | ||
|
|
70d67156f0 | ||
|
|
f293b317be | ||
|
|
1f23794f88 | ||
|
|
e6bfd118f6 | ||
|
|
1166400ab1 | ||
|
|
55f0ac871b | ||
|
|
3584f6e24f | ||
|
|
23bf2594c8 | ||
|
|
8fb460ce05 | ||
|
|
8c4bbfd6a2 | ||
|
|
742961e0b8 | ||
|
|
e9a705587a | ||
|
|
bf6d81b333 | ||
|
|
9c44fc0d01 | ||
|
|
5017e7ce9e | ||
|
|
9da0be6d36 | ||
|
|
c41bdb951c | ||
|
|
54815ea9c7 | ||
|
|
679ffed0ea | ||
|
|
09397cf3de | ||
|
|
de25763a74 | ||
|
|
a894ceb9cf | ||
|
|
387e58a714 |
No files matched your search
@@ -1,40 +1,31 @@
|
|||||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
||||||
// README at: https://github.com/devcontainers/templates/tree/main/src/javascript-node
|
// README at: https://github.com/devcontainers/templates/tree/main/src/javascript-node
|
||||||
{
|
{
|
||||||
"name": "Audiobookshelf",
|
"name": "Audiobookshelf",
|
||||||
"build": {
|
"build": {
|
||||||
"dockerfile": "Dockerfile",
|
"dockerfile": "Dockerfile",
|
||||||
// Update 'VARIANT' to pick a Node version: 18, 16, 14.
|
// Update 'VARIANT' to pick a Node version: 18, 16, 14.
|
||||||
// Append -bullseye or -buster to pin to an OS version.
|
// Append -bullseye or -buster to pin to an OS version.
|
||||||
// Use -bullseye variants on local arm64/Apple Silicon.
|
// Use -bullseye variants on local arm64/Apple Silicon.
|
||||||
"args": {
|
"args": {
|
||||||
"VARIANT": "20"
|
"VARIANT": "24"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mounts": [
|
"mounts": ["source=abs-server-node_modules,target=${containerWorkspaceFolder}/node_modules,type=volume", "source=abs-client-node_modules,target=${containerWorkspaceFolder}/client/node_modules,type=volume"],
|
||||||
"source=abs-server-node_modules,target=${containerWorkspaceFolder}/node_modules,type=volume",
|
// Features to add to the dev container. More info: https://containers.dev/features.
|
||||||
"source=abs-client-node_modules,target=${containerWorkspaceFolder}/client/node_modules,type=volume"
|
// "features": {},
|
||||||
],
|
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||||
// Features to add to the dev container. More info: https://containers.dev/features.
|
"forwardPorts": [3000, 3333],
|
||||||
// "features": {},
|
// Use 'postCreateCommand' to run commands after the container is created.
|
||||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
"postCreateCommand": "sh .devcontainer/post-create.sh",
|
||||||
"forwardPorts": [
|
// Configure tool-specific properties.
|
||||||
3000,
|
"customizations": {
|
||||||
3333
|
// Configure properties specific to VS Code.
|
||||||
],
|
"vscode": {
|
||||||
// Use 'postCreateCommand' to run commands after the container is created.
|
// Add the IDs of extensions you want installed when the container is created.
|
||||||
"postCreateCommand": "sh .devcontainer/post-create.sh",
|
"extensions": ["dbaeumer.vscode-eslint", "octref.vetur"]
|
||||||
// Configure tool-specific properties.
|
}
|
||||||
"customizations": {
|
}
|
||||||
// Configure properties specific to VS Code.
|
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
|
||||||
"vscode": {
|
// "remoteUser": "root"
|
||||||
// Add the IDs of extensions you want installed when the container is created.
|
}
|
||||||
"extensions": [
|
|
||||||
"dbaeumer.vscode-eslint",
|
|
||||||
"octref.vetur"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
|
|
||||||
// "remoteUser": "root"
|
|
||||||
}
|
|
||||||
@@ -47,7 +47,7 @@ jobs:
|
|||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v2
|
uses: github/codeql-action/init@v3
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
@@ -60,7 +60,7 @@ jobs:
|
|||||||
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
|
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
|
||||||
# If this step fails, then you should remove it and run the build manually (see below)
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@v2
|
uses: github/codeql-action/autobuild@v3
|
||||||
|
|
||||||
# ℹ️ Command-line programs to run using the OS shell.
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||||
@@ -73,6 +73,6 @@ jobs:
|
|||||||
# ./location_of_script_within_repo/buildscript.sh
|
# ./location_of_script_within_repo/buildscript.sh
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v2
|
uses: github/codeql-action/analyze@v3
|
||||||
with:
|
with:
|
||||||
category: '/language:${{matrix.language}}'
|
category: '/language:${{matrix.language}}'
|
||||||
@@ -34,7 +34,7 @@ jobs:
|
|||||||
- name: Set up Node.js
|
- name: Set up Node.js
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 24
|
||||||
cache: 'npm'
|
cache: 'npm'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
|
|||||||
@@ -0,0 +1,102 @@
|
|||||||
|
# Builds the v3 test image
|
||||||
|
#
|
||||||
|
# Moves the :v3 tag on Docker Hub and GHCR, the same way master
|
||||||
|
# moves :edge. Using the server's v3 branch and react-client master.
|
||||||
|
#
|
||||||
|
# repository_dispatch (build-v3) is for triggering a build on updates to react-client
|
||||||
|
|
||||||
|
name: Build and Push v3 Docker Image
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
branches: [v3]
|
||||||
|
repository_dispatch:
|
||||||
|
types: [build-v3]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
if: ${{ github.repository == 'advplyr/audiobookshelf' && (github.event_name != 'push' || !contains(github.event.head_commit.message, 'skip ci')) }}
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Check out server
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ github.event_name == 'repository_dispatch' && 'v3' || github.sha }}
|
||||||
|
|
||||||
|
- name: Check out React client
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
repository: audiobookshelf/audiobookshelf-client-react
|
||||||
|
ref: master
|
||||||
|
path: client-react
|
||||||
|
|
||||||
|
- name: Server sha
|
||||||
|
id: server-sha
|
||||||
|
run: echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- name: Client sha
|
||||||
|
id: client-sha
|
||||||
|
working-directory: client-react
|
||||||
|
run: echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- name: Docker meta
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: advplyr/audiobookshelf,ghcr.io/${{ github.repository_owner }}/audiobookshelf
|
||||||
|
flavor: |
|
||||||
|
latest=false
|
||||||
|
tags: |
|
||||||
|
type=raw,value=v3
|
||||||
|
labels: |
|
||||||
|
audiobookshelf.server.sha=${{ steps.server-sha.outputs.sha }}
|
||||||
|
audiobookshelf.client.sha=${{ steps.client-sha.outputs.sha }}
|
||||||
|
|
||||||
|
- name: Setup QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Cache Docker layers
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: /tmp/.buildx-cache
|
||||||
|
key: ${{ runner.os }}-buildx-v3-${{ github.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-buildx-v3-
|
||||||
|
|
||||||
|
- name: Login to Dockerhub
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||||
|
|
||||||
|
- name: Login to ghcr
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.repository_owner }}
|
||||||
|
password: ${{ secrets.GHCR_PASSWORD }}
|
||||||
|
|
||||||
|
- name: Build image
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
file: client-react/Dockerfile
|
||||||
|
context: .
|
||||||
|
build-contexts: |
|
||||||
|
abs-client=client-react
|
||||||
|
abs-server=.
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
push: true
|
||||||
|
cache-from: type=local,src=/tmp/.buildx-cache
|
||||||
|
cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
|
||||||
|
|
||||||
|
- name: Move cache
|
||||||
|
run: |
|
||||||
|
rm -rf /tmp/.buildx-cache
|
||||||
|
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
|
||||||
@@ -19,6 +19,8 @@ on:
|
|||||||
- server/**
|
- server/**
|
||||||
- index.js
|
- index.js
|
||||||
- package.json
|
- package.json
|
||||||
|
- tsconfig.server.json
|
||||||
|
- Dockerfile
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ jobs:
|
|||||||
- name: Set up node
|
- name: Set up node
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 24
|
||||||
cache: 'npm'
|
cache: 'npm'
|
||||||
|
|
||||||
# The only argument is the `directory`, which is where the i18n files are
|
# The only argument is the `directory`, which is where the i18n files are
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ on:
|
|||||||
- test/**
|
- test/**
|
||||||
- index.js
|
- index.js
|
||||||
- package.json
|
- package.json
|
||||||
|
- tsconfig.server.json
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
@@ -23,10 +24,10 @@ jobs:
|
|||||||
- name: setup node
|
- name: setup node
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 24
|
||||||
cache: 'npm'
|
cache: 'npm'
|
||||||
|
|
||||||
- name: install pkg (using yao-pkg fork for targeting node20)
|
- name: install pkg (using yao-pkg fork for targeting node24)
|
||||||
run: npm install -g @yao-pkg/pkg
|
run: npm install -g @yao-pkg/pkg
|
||||||
|
|
||||||
- name: get client dependencies
|
- name: get client dependencies
|
||||||
@@ -37,11 +38,11 @@ jobs:
|
|||||||
working-directory: client
|
working-directory: client
|
||||||
run: npm run generate
|
run: npm run generate
|
||||||
|
|
||||||
- name: get server dependencies
|
- name: get server dependencies and compile server
|
||||||
run: npm ci --only=production
|
run: npm ci && npm run build:server && npm prune --omit=dev
|
||||||
|
|
||||||
- name: build binary
|
- name: build binary
|
||||||
run: pkg -t node20-linux-x64 -o audiobookshelf .
|
run: pkg --config package.json -t node24-linux-x64 -o audiobookshelf dist-server/index.js
|
||||||
|
|
||||||
- name: run audiobookshelf
|
- name: run audiobookshelf
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ jobs:
|
|||||||
- name: Set up node
|
- name: Set up node
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 24
|
||||||
cache: 'npm'
|
cache: 'npm'
|
||||||
|
|
||||||
# Install Redocly CLI
|
# Install Redocly CLI
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
name: Prepare translation credits
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release-notes:
|
||||||
|
if: github.event_name == 'workflow_dispatch' || contains(github.event.head_commit.message, 'weblate')
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- id: translator-credits
|
||||||
|
uses: audiobookshelf/get-translator-credits@v1.1.0
|
||||||
|
|
||||||
|
- name: Show translator credits
|
||||||
|
run: |
|
||||||
|
printf '%s\n' "${{ steps.translator-credits.outputs.credits }}"
|
||||||
@@ -28,11 +28,14 @@ jobs:
|
|||||||
- name: Set up Node.js
|
- name: Set up Node.js
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 24
|
||||||
cache: 'npm'
|
cache: 'npm'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm ci
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Run lint
|
||||||
|
run: npm run lint
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: npm test
|
run: npm test
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
/client/.nuxt/
|
/client/.nuxt/
|
||||||
/client/dist/
|
/client/dist/
|
||||||
/dist/
|
/dist/
|
||||||
|
/dist-server/
|
||||||
/deploy/
|
/deploy/
|
||||||
/coverage/
|
/coverage/
|
||||||
/.nyc_output/
|
/.nyc_output/
|
||||||
|
|||||||
+16
-7
@@ -2,15 +2,23 @@ ARG NUSQLITE3_DIR="/usr/local/lib/nusqlite3"
|
|||||||
ARG NUSQLITE3_PATH="${NUSQLITE3_DIR}/libnusqlite3.so"
|
ARG NUSQLITE3_PATH="${NUSQLITE3_DIR}/libnusqlite3.so"
|
||||||
|
|
||||||
### STAGE 0: Build client ###
|
### STAGE 0: Build client ###
|
||||||
FROM node:20-alpine AS build-client
|
FROM node:24-alpine AS build-client
|
||||||
|
|
||||||
WORKDIR /client
|
WORKDIR /client
|
||||||
COPY /client /client
|
COPY /client /client
|
||||||
RUN npm ci && npm cache clean --force
|
RUN npm ci && npm cache clean --force
|
||||||
RUN npm run generate
|
RUN npm run generate
|
||||||
|
|
||||||
### STAGE 1: Build server ###
|
### STAGE 1: Compile server on the builder CPU (avoid QEMU SIGILL from tsc on arm64) ###
|
||||||
FROM node:20-alpine AS build-server
|
FROM --platform=$BUILDPLATFORM node:24-alpine AS compile-server
|
||||||
|
|
||||||
|
WORKDIR /server
|
||||||
|
COPY index.js package* tsconfig.server.json /server
|
||||||
|
COPY /server /server/server
|
||||||
|
RUN npm ci --include=dev --ignore-scripts && npm run build:server
|
||||||
|
|
||||||
|
### STAGE 2: Install native server deps for the target arch ###
|
||||||
|
FROM node:24-alpine AS build-server
|
||||||
|
|
||||||
ARG NUSQLITE3_DIR
|
ARG NUSQLITE3_DIR
|
||||||
ARG TARGETPLATFORM
|
ARG TARGETPLATFORM
|
||||||
@@ -27,6 +35,7 @@ RUN apk add --no-cache --update \
|
|||||||
WORKDIR /server
|
WORKDIR /server
|
||||||
COPY index.js package* /server
|
COPY index.js package* /server
|
||||||
COPY /server /server/server
|
COPY /server /server/server
|
||||||
|
COPY --from=compile-server /server/dist-server /server/dist-server
|
||||||
|
|
||||||
RUN case "$TARGETPLATFORM" in \
|
RUN case "$TARGETPLATFORM" in \
|
||||||
"linux/amd64") \
|
"linux/amd64") \
|
||||||
@@ -38,10 +47,10 @@ RUN case "$TARGETPLATFORM" in \
|
|||||||
unzip /tmp/library.zip -d $NUSQLITE3_DIR && \
|
unzip /tmp/library.zip -d $NUSQLITE3_DIR && \
|
||||||
rm /tmp/library.zip
|
rm /tmp/library.zip
|
||||||
|
|
||||||
RUN npm ci --only=production
|
RUN npm ci --omit=dev
|
||||||
|
|
||||||
### STAGE 2: Create minimal runtime image ###
|
### STAGE 3: Create minimal runtime image ###
|
||||||
FROM node:20-alpine
|
FROM node:24-alpine
|
||||||
|
|
||||||
ARG NUSQLITE3_DIR
|
ARG NUSQLITE3_DIR
|
||||||
ARG NUSQLITE3_PATH
|
ARG NUSQLITE3_PATH
|
||||||
@@ -70,4 +79,4 @@ ENV NUSQLITE3_DIR=${NUSQLITE3_DIR}
|
|||||||
ENV NUSQLITE3_PATH=${NUSQLITE3_PATH}
|
ENV NUSQLITE3_PATH=${NUSQLITE3_PATH}
|
||||||
|
|
||||||
ENTRYPOINT ["tini", "--"]
|
ENTRYPOINT ["tini", "--"]
|
||||||
CMD ["node", "index.js"]
|
CMD ["node", "dist-server/index.js"]
|
||||||
@@ -22,7 +22,7 @@ add_user() {
|
|||||||
declare -r descr="${4:-No description}"
|
declare -r descr="${4:-No description}"
|
||||||
declare -r shell="${5:-/bin/false}"
|
declare -r shell="${5:-/bin/false}"
|
||||||
|
|
||||||
if ! getent passwd | grep -q "^$user:"; then
|
if ! getent passwd "$user" 2>&1 >/dev/null; then
|
||||||
echo "Creating system user: $user in $group with $descr and shell $shell"
|
echo "Creating system user: $user in $group with $descr and shell $shell"
|
||||||
useradd $uid_flags --gid $group --no-create-home --system --shell $shell -c "$descr" $user
|
useradd $uid_flags --gid $group --no-create-home --system --shell $shell -c "$descr" $user
|
||||||
fi
|
fi
|
||||||
@@ -39,7 +39,7 @@ add_group() {
|
|||||||
declare -r gid_flags="--gid $gid"
|
declare -r gid_flags="--gid $gid"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! getent group | grep -q "^$group:" ; then
|
if ! getent group "$group" 2>&1 >/dev/null; then
|
||||||
echo "Creating system group: $group"
|
echo "Creating system group: $group"
|
||||||
groupadd $gid_flags --system $group
|
groupadd $gid_flags --system $group
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ ExecReload=/bin/kill -HUP $MAINPID
|
|||||||
Restart=always
|
Restart=always
|
||||||
User=audiobookshelf
|
User=audiobookshelf
|
||||||
Group=audiobookshelf
|
Group=audiobookshelf
|
||||||
|
Environment=HOME=/var/cache/audiobookshelf
|
||||||
|
CacheDirectory=audiobookshelf
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
+10
-4
@@ -16,7 +16,7 @@ echo "--------------------"
|
|||||||
|
|
||||||
cd client
|
cd client
|
||||||
rm -rf node_modules
|
rm -rf node_modules
|
||||||
npm ci --unsafe-perm=true --allow-root
|
npm ci
|
||||||
npm run generate
|
npm run generate
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
@@ -24,7 +24,8 @@ echo ">>> Building Server"
|
|||||||
echo "--------------------"
|
echo "--------------------"
|
||||||
|
|
||||||
rm -rf node_modules
|
rm -rf node_modules
|
||||||
npm ci --unsafe-perm=true --allow-root
|
npm ci
|
||||||
|
npm run build:server
|
||||||
|
|
||||||
echo ">>> Packaging"
|
echo ">>> Packaging"
|
||||||
echo "--------------------"
|
echo "--------------------"
|
||||||
@@ -34,7 +35,6 @@ echo "--------------------"
|
|||||||
mkdir -p dist
|
mkdir -p dist
|
||||||
rm -rf dist/debian
|
rm -rf dist/debian
|
||||||
cp -R build/debian dist/debian
|
cp -R build/debian dist/debian
|
||||||
chmod -R 775 dist/debian
|
|
||||||
|
|
||||||
controlfile="Package: audiobookshelf
|
controlfile="Package: audiobookshelf
|
||||||
Version: $VERSION
|
Version: $VERSION
|
||||||
@@ -47,8 +47,14 @@ Description: $DESCRIPTION"
|
|||||||
|
|
||||||
echo "$controlfile" > dist/debian/DEBIAN/control;
|
echo "$controlfile" > dist/debian/DEBIAN/control;
|
||||||
|
|
||||||
|
# Package contents: directories 0755, files 0644 (including the systemd unit).
|
||||||
|
# Maintainer scripts must stay executable so dpkg can run them.
|
||||||
|
find dist/debian -type d -exec chmod 755 {} +
|
||||||
|
find dist/debian -type f -exec chmod 644 {} +
|
||||||
|
chmod 755 dist/debian/DEBIAN/preinst dist/debian/DEBIAN/postinst dist/debian/DEBIAN/prerm
|
||||||
|
|
||||||
# Package debian
|
# Package debian
|
||||||
pkg -t node20-linux-x64 -o dist/debian/usr/share/audiobookshelf/audiobookshelf .
|
pkg --config package.json -t node24-linux-x64 -o dist/debian/usr/share/audiobookshelf/audiobookshelf dist-server/index.js
|
||||||
|
|
||||||
fakeroot dpkg-deb -Zxz --build dist/debian
|
fakeroot dpkg-deb -Zxz --build dist/debian
|
||||||
|
|
||||||
|
|||||||
@@ -196,6 +196,7 @@ export default {
|
|||||||
requestBatchQuickEmbed() {
|
requestBatchQuickEmbed() {
|
||||||
const payload = {
|
const payload = {
|
||||||
message: this.$strings.MessageConfirmQuickEmbed,
|
message: this.$strings.MessageConfirmQuickEmbed,
|
||||||
|
allowHtml: true,
|
||||||
callback: (confirmed) => {
|
callback: (confirmed) => {
|
||||||
if (confirmed) {
|
if (confirmed) {
|
||||||
this.$axios
|
this.$axios
|
||||||
|
|||||||
@@ -300,6 +300,8 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
userUpdated(user) {
|
userUpdated(user) {
|
||||||
|
if (user.id !== this.$store.state.user.user.id) return
|
||||||
|
|
||||||
if (user.seriesHideFromContinueListening && user.seriesHideFromContinueListening.length) {
|
if (user.seriesHideFromContinueListening && user.seriesHideFromContinueListening.length) {
|
||||||
this.removeAllSeriesFromContinueSeries(user.seriesHideFromContinueListening)
|
this.removeAllSeriesFromContinueSeries(user.seriesHideFromContinueListening)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,10 +93,10 @@ export default {
|
|||||||
editAuthor(author) {
|
editAuthor(author) {
|
||||||
this.$store.commit('globals/showEditAuthorModal', author)
|
this.$store.commit('globals/showEditAuthorModal', author)
|
||||||
},
|
},
|
||||||
editItem(libraryItem) {
|
editItem(libraryItem, tab = 'details') {
|
||||||
var itemIds = this.shelf.entities.map((e) => e.id)
|
var itemIds = this.shelf.entities.map((e) => e.id)
|
||||||
this.$store.commit('setBookshelfBookIds', itemIds)
|
this.$store.commit('setBookshelfBookIds', itemIds)
|
||||||
this.$store.commit('showEditModal', libraryItem)
|
this.$store.commit('showEditModalOnTab', { libraryItem, tab: tab || 'details' })
|
||||||
},
|
},
|
||||||
editEpisode({ libraryItem, episode }) {
|
editEpisode({ libraryItem, episode }) {
|
||||||
this.$store.commit('setEpisodeTableEpisodeIds', [episode.id])
|
this.$store.commit('setEpisodeTableEpisodeIds', [episode.id])
|
||||||
|
|||||||
@@ -3,24 +3,18 @@
|
|||||||
<div class="flex md:hidden h-10 items-center">
|
<div class="flex md:hidden h-10 items-center">
|
||||||
<nuxt-link :to="`/library/${currentLibraryId}`" class="grow h-full flex justify-center items-center" :class="isHomePage ? 'bg-primary/80' : 'bg-primary/40'">
|
<nuxt-link :to="`/library/${currentLibraryId}`" class="grow h-full flex justify-center items-center" :class="isHomePage ? 'bg-primary/80' : 'bg-primary/40'">
|
||||||
<p v-if="isHomePage || isPodcastLibrary" class="text-sm">{{ $strings.ButtonHome }}</p>
|
<p v-if="isHomePage || isPodcastLibrary" class="text-sm">{{ $strings.ButtonHome }}</p>
|
||||||
<svg v-else xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<span v-else class="material-symbols text-lg">home</span>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
|
|
||||||
</svg>
|
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
<nuxt-link :to="`/library/${currentLibraryId}/bookshelf`" class="grow h-full flex justify-center items-center" :class="isLibraryPage ? 'bg-primary/80' : 'bg-primary/40'">
|
<nuxt-link :to="`/library/${currentLibraryId}/bookshelf`" class="grow h-full flex justify-center items-center" :class="isLibraryPage ? 'bg-primary/80' : 'bg-primary/40'">
|
||||||
<p v-if="isLibraryPage || isPodcastLibrary" class="text-sm">{{ $strings.ButtonLibrary }}</p>
|
<p v-if="isLibraryPage || isPodcastLibrary" class="text-sm">{{ $strings.ButtonLibrary }}</p>
|
||||||
<svg v-else xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<span v-else class="material-symbols text-lg">import_contacts</span>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253" />
|
|
||||||
</svg>
|
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
<nuxt-link v-if="isPodcastLibrary" :to="`/library/${currentLibraryId}/podcast/latest`" class="grow h-full flex justify-center items-center" :class="isPodcastLatestPage ? 'bg-primary/80' : 'bg-primary/40'">
|
<nuxt-link v-if="isPodcastLibrary" :to="`/library/${currentLibraryId}/podcast/latest`" class="grow h-full flex justify-center items-center" :class="isPodcastLatestPage ? 'bg-primary/80' : 'bg-primary/40'">
|
||||||
<p class="text-sm">{{ $strings.ButtonLatest }}</p>
|
<p class="text-sm">{{ $strings.ButtonLatest }}</p>
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
<nuxt-link v-if="isBookLibrary" :to="`/library/${currentLibraryId}/bookshelf/series`" class="grow h-full flex justify-center items-center" :class="isSeriesPage ? 'bg-primary/80' : 'bg-primary/40'">
|
<nuxt-link v-if="isBookLibrary" :to="`/library/${currentLibraryId}/bookshelf/series`" class="grow h-full flex justify-center items-center" :class="isSeriesPage ? 'bg-primary/80' : 'bg-primary/40'">
|
||||||
<p v-if="isSeriesPage" class="text-sm">{{ $strings.ButtonSeries }}</p>
|
<p v-if="isSeriesPage" class="text-sm">{{ $strings.ButtonSeries }}</p>
|
||||||
<svg v-else xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<span v-else class="material-symbols text-lg">view_column</span>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 17V7m0 10a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2h2a2 2 0 012 2m0 10a2 2 0 002 2h2a2 2 0 002-2M9 7a2 2 0 012-2h2a2 2 0 012 2m0 10V7m0 10a2 2 0 002 2h2a2 2 0 002-2V7a2 2 0 00-2-2h-2a2 2 0 00-2 2" />
|
|
||||||
</svg>
|
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
<nuxt-link v-if="showPlaylists" :to="`/library/${currentLibraryId}/bookshelf/playlists`" class="grow h-full flex justify-center items-center" :class="isPlaylistsPage ? 'bg-primary/80' : 'bg-primary/40'">
|
<nuxt-link v-if="showPlaylists" :to="`/library/${currentLibraryId}/bookshelf/playlists`" class="grow h-full flex justify-center items-center" :class="isPlaylistsPage ? 'bg-primary/80' : 'bg-primary/40'">
|
||||||
<p v-if="isPlaylistsPage || isPodcastLibrary" class="text-sm">{{ $strings.ButtonPlaylists }}</p>
|
<p v-if="isPlaylistsPage || isPodcastLibrary" class="text-sm">{{ $strings.ButtonPlaylists }}</p>
|
||||||
@@ -32,12 +26,7 @@
|
|||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
<nuxt-link v-if="isBookLibrary" :to="`/library/${currentLibraryId}/bookshelf/authors`" class="grow h-full flex justify-center items-center" :class="isAuthorsPage ? 'bg-primary/80' : 'bg-primary/40'">
|
<nuxt-link v-if="isBookLibrary" :to="`/library/${currentLibraryId}/bookshelf/authors`" class="grow h-full flex justify-center items-center" :class="isAuthorsPage ? 'bg-primary/80' : 'bg-primary/40'">
|
||||||
<p v-if="isAuthorsPage" class="text-sm">{{ $strings.ButtonAuthors }}</p>
|
<p v-if="isAuthorsPage" class="text-sm">{{ $strings.ButtonAuthors }}</p>
|
||||||
<svg v-else class="w-5 h-5" viewBox="0 0 24 24">
|
<span v-else class="material-symbols text-lg">groups</span>
|
||||||
<path
|
|
||||||
fill="currentColor"
|
|
||||||
d="M12,5.5A3.5,3.5 0 0,1 15.5,9A3.5,3.5 0 0,1 12,12.5A3.5,3.5 0 0,1 8.5,9A3.5,3.5 0 0,1 12,5.5M5,8C5.56,8 6.08,8.15 6.53,8.42C6.38,9.85 6.8,11.27 7.66,12.38C7.16,13.34 6.16,14 5,14A3,3 0 0,1 2,11A3,3 0 0,1 5,8M19,8A3,3 0 0,1 22,11A3,3 0 0,1 19,14C17.84,14 16.84,13.34 16.34,12.38C17.2,11.27 17.62,9.85 17.47,8.42C17.92,8.15 18.44,8 19,8M5.5,18.25C5.5,16.18 8.41,14.5 12,14.5C15.59,14.5 18.5,16.18 18.5,18.25V20H5.5V18.25M0,20V18.5C0,17.11 1.89,15.94 4.45,15.6C3.86,16.28 3.5,17.22 3.5,18.25V20H0M24,20H20.5V18.25C20.5,17.22 20.14,16.28 19.55,15.6C22.11,15.94 24,17.11 24,18.5V20Z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
<nuxt-link v-if="isPodcastLibrary && userIsAdminOrUp" :to="`/library/${currentLibraryId}/podcast/search`" class="grow h-full flex justify-center items-center" :class="isPodcastSearchPage ? 'bg-primary/80' : 'bg-primary/40'">
|
<nuxt-link v-if="isPodcastLibrary && userIsAdminOrUp" :to="`/library/${currentLibraryId}/podcast/search`" class="grow h-full flex justify-center items-center" :class="isPodcastSearchPage ? 'bg-primary/80' : 'bg-primary/40'">
|
||||||
<p class="text-sm">{{ $strings.ButtonAdd }}</p>
|
<p class="text-sm">{{ $strings.ButtonAdd }}</p>
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
<div v-if="entityName === 'collections' || entityName === 'playlists'" class="flex justify-center mt-4">
|
<div v-if="entityName === 'collections' || entityName === 'playlists'" class="flex justify-center mt-4">
|
||||||
{{ emptyMessageHelp }}
|
{{ emptyMessageHelp }}
|
||||||
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex ml-2">
|
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex ml-2">
|
||||||
<a href="https://www.audiobookshelf.org/guides/collections" target="_blank" class="inline-flex">
|
<a href="https://audiobookshelf.org/docs/documentation/libraries/common-content/playlists" target="_blank" class="inline-flex">
|
||||||
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
|
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
|
||||||
</a>
|
</a>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
@@ -232,11 +232,11 @@ export default {
|
|||||||
clearFilter() {
|
clearFilter() {
|
||||||
this.$store.dispatch('user/updateUserSettings', { filterBy: 'all' })
|
this.$store.dispatch('user/updateUserSettings', { filterBy: 'all' })
|
||||||
},
|
},
|
||||||
editEntity(entity) {
|
editEntity(entity, tab = 'details') {
|
||||||
if (this.entityName === 'items' || this.entityName === 'series-books') {
|
if (this.entityName === 'items' || this.entityName === 'series-books') {
|
||||||
const bookIds = this.entities.map((e) => e.id)
|
const bookIds = this.entities.map((e) => e.id)
|
||||||
this.$store.commit('setBookshelfBookIds', bookIds)
|
this.$store.commit('setBookshelfBookIds', bookIds)
|
||||||
this.$store.commit('showEditModal', entity)
|
this.$store.commit('showEditModalOnTab', { libraryItem: entity, tab: tab || 'details' })
|
||||||
} else if (this.entityName === 'collections') {
|
} else if (this.entityName === 'collections') {
|
||||||
this.$store.commit('globals/setEditCollection', entity)
|
this.$store.commit('globals/setEditCollection', entity)
|
||||||
} else if (this.entityName === 'playlists') {
|
} else if (this.entityName === 'playlists') {
|
||||||
|
|||||||
@@ -5,9 +5,7 @@
|
|||||||
|
|
||||||
<div id="siderail-buttons-container" role="navigation" aria-label="Library Navigation" :class="{ 'player-open': streamLibraryItem }" class="w-full overflow-y-auto overflow-x-hidden">
|
<div id="siderail-buttons-container" role="navigation" aria-label="Library Navigation" :class="{ 'player-open': streamLibraryItem }" class="w-full overflow-y-auto overflow-x-hidden">
|
||||||
<nuxt-link :to="`/library/${currentLibraryId}`" class="w-full h-20 flex flex-col items-center justify-center text-white border-b border-primary/70 hover:bg-primary cursor-pointer relative" :class="homePage ? 'bg-primary/80' : 'bg-bg/60'">
|
<nuxt-link :to="`/library/${currentLibraryId}`" class="w-full h-20 flex flex-col items-center justify-center text-white border-b border-primary/70 hover:bg-primary cursor-pointer relative" :class="homePage ? 'bg-primary/80' : 'bg-bg/60'">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<span class="material-symbols text-2xl">home</span>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
|
|
||||||
</svg>
|
|
||||||
|
|
||||||
<p class="pt-1.5 text-center leading-4" style="font-size: 0.9rem">{{ $strings.ButtonHome }}</p>
|
<p class="pt-1.5 text-center leading-4" style="font-size: 0.9rem">{{ $strings.ButtonHome }}</p>
|
||||||
|
|
||||||
@@ -23,9 +21,7 @@
|
|||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
|
|
||||||
<nuxt-link :to="`/library/${currentLibraryId}/bookshelf`" class="w-full h-20 flex flex-col items-center justify-center text-white border-b border-primary/70 hover:bg-primary cursor-pointer relative" :class="showLibrary ? 'bg-primary/80' : 'bg-bg/60'">
|
<nuxt-link :to="`/library/${currentLibraryId}/bookshelf`" class="w-full h-20 flex flex-col items-center justify-center text-white border-b border-primary/70 hover:bg-primary cursor-pointer relative" :class="showLibrary ? 'bg-primary/80' : 'bg-bg/60'">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<span class="material-symbols text-2xl">import_contacts</span>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253" />
|
|
||||||
</svg>
|
|
||||||
|
|
||||||
<p class="pt-1.5 text-center leading-4" style="font-size: 0.9rem">{{ $strings.ButtonLibrary }}</p>
|
<p class="pt-1.5 text-center leading-4" style="font-size: 0.9rem">{{ $strings.ButtonLibrary }}</p>
|
||||||
|
|
||||||
@@ -33,9 +29,7 @@
|
|||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
|
|
||||||
<nuxt-link v-if="isBookLibrary" :to="`/library/${currentLibraryId}/bookshelf/series`" class="w-full h-20 flex flex-col items-center justify-center text-white/80 border-b border-primary/70 hover:bg-primary cursor-pointer relative" :class="isSeriesPage ? 'bg-primary/80' : 'bg-bg/60'">
|
<nuxt-link v-if="isBookLibrary" :to="`/library/${currentLibraryId}/bookshelf/series`" class="w-full h-20 flex flex-col items-center justify-center text-white/80 border-b border-primary/70 hover:bg-primary cursor-pointer relative" :class="isSeriesPage ? 'bg-primary/80' : 'bg-bg/60'">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<span class="material-symbols text-2xl">view_column</span>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 17V7m0 10a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2h2a2 2 0 012 2m0 10a2 2 0 002 2h2a2 2 0 002-2M9 7a2 2 0 012-2h2a2 2 0 012 2m0 10V7m0 10a2 2 0 002 2h2a2 2 0 002-2V7a2 2 0 00-2-2h-2a2 2 0 00-2 2" />
|
|
||||||
</svg>
|
|
||||||
|
|
||||||
<p class="pt-1.5 text-center leading-4" style="font-size: 0.9rem">{{ $strings.ButtonSeries }}</p>
|
<p class="pt-1.5 text-center leading-4" style="font-size: 0.9rem">{{ $strings.ButtonSeries }}</p>
|
||||||
|
|
||||||
@@ -59,12 +53,7 @@
|
|||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
|
|
||||||
<nuxt-link v-if="isBookLibrary" :to="`/library/${currentLibraryId}/bookshelf/authors`" class="w-full h-20 flex flex-col items-center justify-center text-white/80 border-b border-primary/70 hover:bg-primary cursor-pointer relative" :class="isAuthorsPage ? 'bg-primary/80' : 'bg-bg/60'">
|
<nuxt-link v-if="isBookLibrary" :to="`/library/${currentLibraryId}/bookshelf/authors`" class="w-full h-20 flex flex-col items-center justify-center text-white/80 border-b border-primary/70 hover:bg-primary cursor-pointer relative" :class="isAuthorsPage ? 'bg-primary/80' : 'bg-bg/60'">
|
||||||
<svg class="w-6 h-6" viewBox="0 0 24 24">
|
<span class="material-symbols text-2xl">groups</span>
|
||||||
<path
|
|
||||||
fill="currentColor"
|
|
||||||
d="M12,5.5A3.5,3.5 0 0,1 15.5,9A3.5,3.5 0 0,1 12,12.5A3.5,3.5 0 0,1 8.5,9A3.5,3.5 0 0,1 12,5.5M5,8C5.56,8 6.08,8.15 6.53,8.42C6.38,9.85 6.8,11.27 7.66,12.38C7.16,13.34 6.16,14 5,14A3,3 0 0,1 2,11A3,3 0 0,1 5,8M19,8A3,3 0 0,1 22,11A3,3 0 0,1 19,14C17.84,14 16.84,13.34 16.34,12.38C17.2,11.27 17.62,9.85 17.47,8.42C17.92,8.15 18.44,8 19,8M5.5,18.25C5.5,16.18 8.41,14.5 12,14.5C15.59,14.5 18.5,16.18 18.5,18.25V20H5.5V18.25M0,20V18.5C0,17.11 1.89,15.94 4.45,15.6C3.86,16.28 3.5,17.22 3.5,18.25V20H0M24,20H20.5V18.25C20.5,17.22 20.14,16.28 19.55,15.6C22.11,15.94 24,17.11 24,18.5V20Z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
|
|
||||||
<p class="pt-1 text-center leading-4" style="font-size: 0.9rem">{{ $strings.ButtonAuthors }}</p>
|
<p class="pt-1 text-center leading-4" style="font-size: 0.9rem">{{ $strings.ButtonAuthors }}</p>
|
||||||
|
|
||||||
@@ -116,7 +105,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="w-full h-12 px-1 py-2 border-t border-black/20 bg-bg absolute left-0" :style="{ bottom: streamLibraryItem ? '224px' : '65px' }">
|
<div class="w-full h-12 px-1 py-2 border-t border-black/20 bg-bg absolute left-0" :style="{ bottom: streamLibraryItem ? '224px' : '65px' }">
|
||||||
<p class="underline font-mono text-xs text-center text-gray-300 leading-3 mb-1" @click="clickChangelog">v{{ $config.version }}</p>
|
<p class="underline font-mono text-xs text-center text-gray-300 leading-3 mb-1 cursor-pointer" @click="clickChangelog">v{{ $config.version }}</p>
|
||||||
<a v-if="hasUpdate" :href="githubTagUrl" target="_blank" class="text-warning text-xxs text-center block leading-3">Update</a>
|
<a v-if="hasUpdate" :href="githubTagUrl" target="_blank" class="text-warning text-xxs text-center block leading-3">Update</a>
|
||||||
<p v-else class="text-xxs text-gray-400 leading-3 text-center italic">{{ Source }}</p>
|
<p v-else class="text-xxs text-gray-400 leading-3 text-center italic">{{ Source }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -13,9 +13,17 @@
|
|||||||
<div class="grow" />
|
<div class="grow" />
|
||||||
<p class="text-sm md:text-base">{{ book.publishedYear }}</p>
|
<p class="text-sm md:text-base">{{ book.publishedYear }}</p>
|
||||||
</div>
|
</div>
|
||||||
<p v-if="book.author" class="text-gray-300 text-xs md:text-sm">{{ $getString('LabelByAuthor', [book.author]) }}</p>
|
|
||||||
<p v-if="book.narrator" class="text-gray-400 text-xs">{{ $strings.LabelNarrators }}: {{ book.narrator }}</p>
|
<div class="flex items-center">
|
||||||
<p v-if="book.duration" class="text-gray-400 text-xs">{{ $strings.LabelDuration }}: {{ $elapsedPrettyExtended(bookDuration, false) }} {{ bookDurationComparison }}</p>
|
<div>
|
||||||
|
<p v-if="book.author" class="text-gray-300 text-xs md:text-sm">{{ $getString('LabelByAuthor', [book.author]) }}</p>
|
||||||
|
<p v-if="book.narrator" class="text-gray-400 text-xs">{{ $strings.LabelNarrators }}: {{ book.narrator }}</p>
|
||||||
|
<p v-if="book.duration" class="text-gray-400 text-xs">{{ $strings.LabelDuration }}: {{ $elapsedPrettyExtended(bookDuration, false) }} {{ bookDurationComparison }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="grow" />
|
||||||
|
<div v-if="book.matchConfidence" class="rounded-full px-2 py-1 text-xs whitespace-nowrap text-white" :class="book.matchConfidence > 0.95 ? 'bg-success/80' : 'bg-info/80'">{{ $strings.LabelMatchConfidence }}: {{ (book.matchConfidence * 100).toFixed(0) }}%</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div v-if="book.series?.length" class="flex py-1 -mx-1">
|
<div v-if="book.series?.length" class="flex py-1 -mx-1">
|
||||||
<div v-for="(series, index) in book.series" :key="index" class="bg-white/10 rounded-full px-1 py-0.5 mx-1">
|
<div v-for="(series, index) in book.series" :key="index" class="bg-white/10 rounded-full px-1 py-0.5 mx-1">
|
||||||
<p class="leading-3 text-xs text-gray-400">
|
<p class="leading-3 text-xs text-gray-400">
|
||||||
|
|||||||
@@ -62,7 +62,24 @@
|
|||||||
</widgets-alert>
|
</widgets-alert>
|
||||||
|
|
||||||
<div v-if="isNonInteractable" class="absolute top-0 left-0 w-full h-full bg-black/50 flex items-center justify-center z-20">
|
<div v-if="isNonInteractable" class="absolute top-0 left-0 w-full h-full bg-black/50 flex items-center justify-center z-20">
|
||||||
<ui-loading-indicator :text="nonInteractionLabel" />
|
<ui-loading-indicator>
|
||||||
|
<div class="mb-4">
|
||||||
|
<span class="text-lg font-medium text-white">
|
||||||
|
{{ nonInteractionLabel }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="isUploading" class="w-64 mx-auto mb-2">
|
||||||
|
<div class="flex items-center justify-center mb-2">
|
||||||
|
<span class="text-sm font-medium text-white/60 text-center w-full">
|
||||||
|
{{ uploadProgressText }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="w-full bg-primary/20 rounded-full h-2.5">
|
||||||
|
<div class="bg-green-500 h-2.5 rounded-full transition-all duration-300 ease-out" :style="{ width: uploadProgressPercent + '%' }"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ui-loading-indicator>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -91,7 +108,11 @@ export default {
|
|||||||
isUploading: false,
|
isUploading: false,
|
||||||
uploadFailed: false,
|
uploadFailed: false,
|
||||||
uploadSuccess: false,
|
uploadSuccess: false,
|
||||||
isFetchingMetadata: false
|
isFetchingMetadata: false,
|
||||||
|
uploadProgress: {
|
||||||
|
loaded: 0,
|
||||||
|
total: 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -116,6 +137,15 @@ export default {
|
|||||||
} else if (this.isFetchingMetadata) {
|
} else if (this.isFetchingMetadata) {
|
||||||
return this.$strings.LabelFetchingMetadata
|
return this.$strings.LabelFetchingMetadata
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
uploadProgressPercent() {
|
||||||
|
if (this.uploadProgress.total === 0) return 0
|
||||||
|
return Math.min(100, Math.round((this.uploadProgress.loaded / this.uploadProgress.total) * 100))
|
||||||
|
},
|
||||||
|
uploadProgressText() {
|
||||||
|
const loaded = this.$bytesPretty(this.uploadProgress.loaded)
|
||||||
|
const total = this.$bytesPretty(this.uploadProgress.total)
|
||||||
|
return `${this.uploadProgressPercent}% (${loaded} / ${total})`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -123,6 +153,21 @@ export default {
|
|||||||
this.isUploading = status === 'uploading'
|
this.isUploading = status === 'uploading'
|
||||||
this.uploadFailed = status === 'failed'
|
this.uploadFailed = status === 'failed'
|
||||||
this.uploadSuccess = status === 'success'
|
this.uploadSuccess = status === 'success'
|
||||||
|
|
||||||
|
if (status !== 'uploading') {
|
||||||
|
this.uploadProgress = {
|
||||||
|
loaded: 0,
|
||||||
|
total: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setUploadProgress(progress) {
|
||||||
|
if (this.isUploading && progress) {
|
||||||
|
this.uploadProgress = {
|
||||||
|
loaded: progress.loaded || 0,
|
||||||
|
total: progress.total || 0
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
titleUpdated() {
|
titleUpdated() {
|
||||||
this.error = ''
|
this.error = ''
|
||||||
|
|||||||
@@ -78,7 +78,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Error widget -->
|
<!-- Error widget -->
|
||||||
<ui-tooltip cy-id="ErrorTooltip" v-if="showError" :text="errorText" class="absolute bottom-4e left-0 z-10">
|
<ui-tooltip cy-id="ErrorTooltip" v-if="showError" :text="errorText" plaintext class="absolute bottom-4e left-0 z-10">
|
||||||
<div :style="{ height: 1.5 + 'em', width: 2.5 + 'em' }" class="bg-error rounded-r-full shadow-md flex items-center justify-end border-r border-b border-red-300">
|
<div :style="{ height: 1.5 + 'em', width: 2.5 + 'em' }" class="bg-error rounded-r-full shadow-md flex items-center justify-end border-r border-b border-red-300">
|
||||||
<span class="material-symbols text-red-100 pr-1e" :style="{ fontSize: 0.875 + 'em' }">priority_high</span>
|
<span class="material-symbols text-red-100 pr-1e" :style="{ fontSize: 0.875 + 'em' }">priority_high</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -101,7 +101,8 @@
|
|||||||
<!-- Podcast Episode # -->
|
<!-- Podcast Episode # -->
|
||||||
<div cy-id="podcastEpisodeNumber" v-if="recentEpisodeNumber !== null && !isHovering && !isSelectionMode && !processing" class="absolute rounded-lg bg-black/90 box-shadow-md z-10" :style="{ top: 0.375 + 'em', right: 0.375 + 'em', padding: `${0.1}em ${0.25}em` }">
|
<div cy-id="podcastEpisodeNumber" v-if="recentEpisodeNumber !== null && !isHovering && !isSelectionMode && !processing" class="absolute rounded-lg bg-black/90 box-shadow-md z-10" :style="{ top: 0.375 + 'em', right: 0.375 + 'em', padding: `${0.1}em ${0.25}em` }">
|
||||||
<p :style="{ fontSize: 0.8 + 'em' }">
|
<p :style="{ fontSize: 0.8 + 'em' }">
|
||||||
Episode<span v-if="recentEpisodeNumber"> #{{ recentEpisodeNumber }}</span>
|
Episode
|
||||||
|
<span v-if="recentEpisodeNumber">#{{ recentEpisodeNumber }}</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -120,12 +121,12 @@
|
|||||||
<!-- Alternative bookshelf title/author/sort -->
|
<!-- Alternative bookshelf title/author/sort -->
|
||||||
<div cy-id="detailBottom" :id="`description-area-${index}`" v-if="isAlternativeBookshelfView || isAuthorBookshelfView" dir="auto" class="relative mt-2e mb-2e left-0 z-50 w-full">
|
<div cy-id="detailBottom" :id="`description-area-${index}`" v-if="isAlternativeBookshelfView || isAuthorBookshelfView" dir="auto" class="relative mt-2e mb-2e left-0 z-50 w-full">
|
||||||
<div :style="{ fontSize: 0.9 + 'em' }">
|
<div :style="{ fontSize: 0.9 + 'em' }">
|
||||||
<ui-tooltip v-if="displayTitle" :text="displayTitle" :disabled="!displayTitleTruncated" direction="bottom" :delayOnShow="500" class="flex items-center">
|
<ui-tooltip v-if="displayTitle" :text="displayTitle" plaintext :disabled="!displayTitleTruncated" direction="bottom" :delayOnShow="500" class="flex items-center">
|
||||||
<p cy-id="title" ref="displayTitle" class="truncate">{{ displayTitle }}</p>
|
<p cy-id="title" ref="displayTitle" class="truncate">{{ displayTitle }}</p>
|
||||||
<widgets-explicit-indicator cy-id="explicitIndicator" v-if="isExplicit" />
|
<widgets-explicit-indicator cy-id="explicitIndicator" v-if="isExplicit" />
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<ui-tooltip v-if="showSubtitles" :text="displaySubtitle" :disabled="!displaySubtitleTruncated" direction="bottom" :delayOnShow="500" class="flex items-center">
|
<ui-tooltip v-if="showSubtitles" :text="displaySubtitle" plaintext :disabled="!displaySubtitleTruncated" direction="bottom" :delayOnShow="500" class="flex items-center">
|
||||||
<p cy-id="subtitle" class="truncate" ref="displaySubtitle" :style="{ fontSize: 0.6 + 'em' }">{{ displaySubtitle }}</p>
|
<p cy-id="subtitle" class="truncate" ref="displaySubtitle" :style="{ fontSize: 0.6 + 'em' }">{{ displaySubtitle }}</p>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
<p cy-id="line2" class="truncate text-gray-400" :style="{ fontSize: 0.8 + 'em' }">{{ displayLineTwo || ' ' }}</p>
|
<p cy-id="line2" class="truncate text-gray-400" :style="{ fontSize: 0.8 + 'em' }">{{ displayLineTwo || ' ' }}</p>
|
||||||
@@ -200,6 +201,9 @@ export default {
|
|||||||
dateFormat() {
|
dateFormat() {
|
||||||
return this.store.getters['getServerSetting']('dateFormat')
|
return this.store.getters['getServerSetting']('dateFormat')
|
||||||
},
|
},
|
||||||
|
timeFormat() {
|
||||||
|
return this.store.getters['getServerSetting']('timeFormat')
|
||||||
|
},
|
||||||
_libraryItem() {
|
_libraryItem() {
|
||||||
return this.libraryItem || {}
|
return this.libraryItem || {}
|
||||||
},
|
},
|
||||||
@@ -345,6 +349,18 @@ export default {
|
|||||||
if (this.mediaMetadata.publishedYear) return this.$getString('LabelPublishedDate', [this.mediaMetadata.publishedYear])
|
if (this.mediaMetadata.publishedYear) return this.$getString('LabelPublishedDate', [this.mediaMetadata.publishedYear])
|
||||||
return '\u00A0'
|
return '\u00A0'
|
||||||
}
|
}
|
||||||
|
if (this.orderBy === 'progress') {
|
||||||
|
if (!this.userProgressLastUpdated) return '\u00A0'
|
||||||
|
return this.$getString('LabelLastProgressDate', [this.$formatDatetime(this.userProgressLastUpdated, this.dateFormat, this.timeFormat)])
|
||||||
|
}
|
||||||
|
if (this.orderBy === 'progress.createdAt') {
|
||||||
|
if (!this.userProgressStartedDate) return '\u00A0'
|
||||||
|
return this.$getString('LabelStartedDate', [this.$formatDatetime(this.userProgressStartedDate, this.dateFormat, this.timeFormat)])
|
||||||
|
}
|
||||||
|
if (this.orderBy === 'progress.finishedAt') {
|
||||||
|
if (!this.userProgressFinishedDate) return '\u00A0'
|
||||||
|
return this.$getString('LabelFinishedDate', [this.$formatDatetime(this.userProgressFinishedDate, this.dateFormat, this.timeFormat)])
|
||||||
|
}
|
||||||
return null
|
return null
|
||||||
},
|
},
|
||||||
episodeProgress() {
|
episodeProgress() {
|
||||||
@@ -377,6 +393,18 @@ export default {
|
|||||||
let progressPercent = this.itemIsFinished ? 1 : this.booksInSeries ? this.seriesProgressPercent : this.useEBookProgress ? this.userProgress?.ebookProgress || 0 : this.userProgress?.progress || 0
|
let progressPercent = this.itemIsFinished ? 1 : this.booksInSeries ? this.seriesProgressPercent : this.useEBookProgress ? this.userProgress?.ebookProgress || 0 : this.userProgress?.progress || 0
|
||||||
return Math.max(Math.min(1, progressPercent), 0)
|
return Math.max(Math.min(1, progressPercent), 0)
|
||||||
},
|
},
|
||||||
|
userProgressLastUpdated() {
|
||||||
|
if (!this.userProgress) return null
|
||||||
|
return this.userProgress.lastUpdate
|
||||||
|
},
|
||||||
|
userProgressStartedDate() {
|
||||||
|
if (!this.userProgress) return null
|
||||||
|
return this.userProgress.startedAt
|
||||||
|
},
|
||||||
|
userProgressFinishedDate() {
|
||||||
|
if (!this.userProgress) return null
|
||||||
|
return this.userProgress.finishedAt
|
||||||
|
},
|
||||||
itemIsFinished() {
|
itemIsFinished() {
|
||||||
if (this.booksInSeries) return this.seriesIsFinished
|
if (this.booksInSeries) return this.seriesIsFinished
|
||||||
return this.userProgress ? !!this.userProgress.isFinished : false
|
return this.userProgress ? !!this.userProgress.isFinished : false
|
||||||
@@ -760,11 +788,11 @@ export default {
|
|||||||
},
|
},
|
||||||
showEditModalFiles() {
|
showEditModalFiles() {
|
||||||
// More menu func
|
// More menu func
|
||||||
this.store.commit('showEditModalOnTab', { libraryItem: this.libraryItem, tab: 'files' })
|
this.$emit('edit', this.libraryItem, 'files')
|
||||||
},
|
},
|
||||||
showEditModalMatch() {
|
showEditModalMatch() {
|
||||||
// More menu func
|
// More menu func
|
||||||
this.store.commit('showEditModalOnTab', { libraryItem: this.libraryItem, tab: 'match' })
|
this.$emit('edit', this.libraryItem, 'match')
|
||||||
},
|
},
|
||||||
sendToDevice(deviceName) {
|
sendToDevice(deviceName) {
|
||||||
// More menu func
|
// More menu func
|
||||||
|
|||||||
@@ -338,6 +338,18 @@ export default {
|
|||||||
const series = this.series.find((se) => se.id == decoded)
|
const series = this.series.find((se) => se.id == decoded)
|
||||||
if (series) filterValue = series.name
|
if (series) filterValue = series.name
|
||||||
}
|
}
|
||||||
|
} else if (parts[0] === 'progress') {
|
||||||
|
const item = this.progress.find((p) => p.id == decoded)
|
||||||
|
if (item) filterValue = item.name
|
||||||
|
} else if (parts[0] === 'tracks') {
|
||||||
|
const item = this.tracks.find((t) => t.id == decoded)
|
||||||
|
if (item) filterValue = item.name
|
||||||
|
} else if (parts[0] === 'ebooks') {
|
||||||
|
const item = this.ebooks.find((e) => e.id == decoded)
|
||||||
|
if (item) filterValue = item.name
|
||||||
|
} else if (parts[0] === 'missing') {
|
||||||
|
const item = this.missing.find((m) => m.id == decoded)
|
||||||
|
if (item) filterValue = item.name
|
||||||
} else {
|
} else {
|
||||||
filterValue = decoded
|
filterValue = decoded
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<ul v-show="showMenu" class="absolute z-10 mt-1 w-full bg-bg border border-black-200 shadow-lg max-h-96 rounded-md py-1 ring-1 ring-black/5 overflow-auto focus:outline-hidden text-sm" role="menu">
|
<ul v-show="showMenu" class="librarySortMenu absolute z-10 mt-1 w-full bg-bg border border-black-200 shadow-lg max-h-96 rounded-md py-1 ring-1 ring-black/5 overflow-auto focus:outline-hidden text-sm" role="menu">
|
||||||
<template v-for="item in selectItems">
|
<template v-for="item in selectItems">
|
||||||
<li :key="item.value" class="select-none relative py-2 pr-9 cursor-pointer hover:bg-white/5" :class="item.value === selected ? 'bg-white/5 text-yellow-400' : 'text-gray-200 hover:text-white'" role="menuitem" @click="clickedOption(item.value)">
|
<li :key="item.value" class="select-none relative py-2 pr-9 cursor-pointer hover:bg-white/5" :class="item.value === selected ? 'bg-white/5 text-yellow-400' : 'text-gray-200 hover:text-white'" role="menuitem" @click="clickedOption(item.value)">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
@@ -130,6 +130,18 @@ export default {
|
|||||||
text: this.$strings.LabelFileModified,
|
text: this.$strings.LabelFileModified,
|
||||||
value: 'mtimeMs'
|
value: 'mtimeMs'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
text: this.$strings.LabelLibrarySortByProgress,
|
||||||
|
value: 'progress'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: this.$strings.LabelLibrarySortByProgressStarted,
|
||||||
|
value: 'progress.createdAt'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: this.$strings.LabelLibrarySortByProgressFinished,
|
||||||
|
value: 'progress.finishedAt'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
text: this.$strings.LabelRandomly,
|
text: this.$strings.LabelRandomly,
|
||||||
value: 'random'
|
value: 'random'
|
||||||
@@ -191,3 +203,9 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.librarySortMenu {
|
||||||
|
max-height: calc(100vh - 125px);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -88,7 +88,7 @@ export default {
|
|||||||
},
|
},
|
||||||
providers() {
|
providers() {
|
||||||
if (this.isPodcast) return this.$store.state.scanners.podcastProviders
|
if (this.isPodcast) return this.$store.state.scanners.podcastProviders
|
||||||
return this.$store.state.scanners.providers
|
return this.$store.state.scanners.bookProviders
|
||||||
},
|
},
|
||||||
libraryProvider() {
|
libraryProvider() {
|
||||||
return this.$store.getters['libraries/getLibraryProvider'](this.currentLibraryId) || 'google'
|
return this.$store.getters['libraries/getLibraryProvider'](this.currentLibraryId) || 'google'
|
||||||
@@ -96,6 +96,9 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
init() {
|
init() {
|
||||||
|
// Fetch providers when modal is shown
|
||||||
|
this.$store.dispatch('scanners/fetchProviders')
|
||||||
|
|
||||||
// If we don't have a set provider (first open of dialog) or we've switched library, set
|
// If we don't have a set provider (first open of dialog) or we've switched library, set
|
||||||
// the selected provider to the current library default provider
|
// the selected provider to the current library default provider
|
||||||
if (!this.options.provider || this.lastUsedLibrary != this.currentLibraryId) {
|
if (!this.options.provider || this.lastUsedLibrary != this.currentLibraryId) {
|
||||||
@@ -127,8 +130,7 @@ export default {
|
|||||||
this.show = false
|
this.show = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
mounted() {}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
<div class="px-6 py-8 w-full text-sm rounded-lg bg-bg shadow-lg border border-black-300 overflow-y-auto overflow-x-hidden" style="max-height: 80vh">
|
<div class="px-6 py-8 w-full text-sm rounded-lg bg-bg shadow-lg border border-black-300 overflow-y-auto overflow-x-hidden" style="max-height: 80vh">
|
||||||
<div class="absolute top-0 right-0 p-4">
|
<div class="absolute top-0 right-0 p-4">
|
||||||
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex ml-2">
|
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex ml-2">
|
||||||
<a href="https://www.audiobookshelf.org/guides/media-item-shares" target="_blank" class="inline-flex">
|
<a href="https://audiobookshelf.org/docs/documentation/libraries/common-content/public-shares#media-item-shares" target="_blank" class="inline-flex">
|
||||||
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
|
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
|
||||||
</a>
|
</a>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
<div class="text-sm flex items-center justify-center text-gray-200">
|
<div class="text-sm flex items-center justify-center text-gray-200">
|
||||||
<p>{{ $strings.MessageBookshelfNoCollectionsHelp }}</p>
|
<p>{{ $strings.MessageBookshelfNoCollectionsHelp }}</p>
|
||||||
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex ml-2">
|
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex ml-2">
|
||||||
<a href="https://www.audiobookshelf.org/guides/collections" target="_blank" class="inline-flex">
|
<a href="https://audiobookshelf.org/docs/documentation/libraries/common-content/playlists" target="_blank" class="inline-flex">
|
||||||
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
|
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
|
||||||
</a>
|
</a>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
@@ -227,7 +227,7 @@ export default {
|
|||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed to create collection', error)
|
console.error('Failed to create collection', error)
|
||||||
var errMsg = error.response ? error.response.data || '' : ''
|
var errMsg = error.response ? error.response.data || '' : ''
|
||||||
this.$toast.error(this.$strings.ToastCollectionCreateFailed + ': ' + errMsg)
|
this.$toast.error(errMsg)
|
||||||
this.processing = false
|
this.processing = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,19 +51,21 @@
|
|||||||
<form @submit.prevent="submitSearchForm">
|
<form @submit.prevent="submitSearchForm">
|
||||||
<div class="flex flex-wrap sm:flex-nowrap items-center justify-start -mx-1">
|
<div class="flex flex-wrap sm:flex-nowrap items-center justify-start -mx-1">
|
||||||
<div class="w-48 grow p-1">
|
<div class="w-48 grow p-1">
|
||||||
<ui-dropdown v-model="provider" :items="providers" :label="$strings.LabelProvider" small />
|
<ui-dropdown v-model="provider" :items="providers" :disabled="searchInProgress" :label="$strings.LabelProvider" small />
|
||||||
</div>
|
</div>
|
||||||
<div class="w-72 grow p-1">
|
<div class="w-72 grow p-1">
|
||||||
<ui-text-input-with-label v-model="searchTitle" :label="searchTitleLabel" :placeholder="$strings.PlaceholderSearch" />
|
<ui-text-input-with-label v-model="searchTitle" :disabled="searchInProgress" :label="searchTitleLabel" :placeholder="$strings.PlaceholderSearch" />
|
||||||
</div>
|
</div>
|
||||||
<div v-show="provider != 'itunes' && provider != 'audiobookcovers'" class="w-72 grow p-1">
|
<div v-show="provider != 'itunes' && provider != 'audiobookcovers'" class="w-72 grow p-1">
|
||||||
<ui-text-input-with-label v-model="searchAuthor" :label="$strings.LabelAuthor" />
|
<ui-text-input-with-label v-model="searchAuthor" :disabled="searchInProgress" :label="$strings.LabelAuthor" />
|
||||||
</div>
|
</div>
|
||||||
<ui-btn class="mt-5 ml-1 md:min-w-24" :padding-x="4" type="submit">{{ $strings.ButtonSearch }}</ui-btn>
|
<ui-btn v-if="!searchInProgress" class="mt-5 ml-1 md:min-w-24" :padding-x="4" type="submit">{{ $strings.ButtonSearch }}</ui-btn>
|
||||||
|
<ui-btn v-else class="mt-5 ml-1 md:min-w-24" :padding-x="4" type="button" color="bg-error" @click.prevent="cancelCurrentSearch">{{ $strings.ButtonCancel }}</ui-btn>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<div v-if="hasSearched" class="flex items-center flex-wrap justify-center sm:max-h-80 sm:overflow-y-scroll mt-2 max-w-full">
|
<div v-if="hasSearched" class="flex items-center flex-wrap justify-center sm:max-h-80 sm:overflow-y-scroll mt-2 max-w-full">
|
||||||
<p v-if="!coversFound.length">{{ $strings.MessageNoCoversFound }}</p>
|
<p v-if="searchInProgress && !coversFound.length" class="text-gray-300 py-4">{{ $strings.MessageLoading }}</p>
|
||||||
|
<p v-else-if="!searchInProgress && !coversFound.length" class="text-gray-300 py-4">{{ $strings.MessageNoCoversFound }}</p>
|
||||||
<template v-for="cover in coversFound">
|
<template v-for="cover in coversFound">
|
||||||
<div :key="cover" class="m-0.5 mb-5 border-2 border-transparent hover:border-yellow-300 cursor-pointer" :class="cover === coverPath ? 'border-yellow-300' : ''" @click="updateCover(cover)">
|
<div :key="cover" class="m-0.5 mb-5 border-2 border-transparent hover:border-yellow-300 cursor-pointer" :class="cover === coverPath ? 'border-yellow-300' : ''" @click="updateCover(cover)">
|
||||||
<covers-preview-cover :src="cover" :width="80" show-open-new-tab :book-cover-aspect-ratio="bookCoverAspectRatio" />
|
<covers-preview-cover :src="cover" :width="80" show-open-new-tab :book-cover-aspect-ratio="bookCoverAspectRatio" />
|
||||||
@@ -105,7 +107,10 @@ export default {
|
|||||||
showLocalCovers: false,
|
showLocalCovers: false,
|
||||||
previewUpload: null,
|
previewUpload: null,
|
||||||
selectedFile: null,
|
selectedFile: null,
|
||||||
provider: 'google'
|
provider: 'google',
|
||||||
|
currentSearchRequestId: null,
|
||||||
|
searchInProgress: false,
|
||||||
|
socketListenersActive: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@@ -128,8 +133,8 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
providers() {
|
providers() {
|
||||||
if (this.isPodcast) return this.$store.state.scanners.podcastProviders
|
if (this.isPodcast) return this.$store.state.scanners.podcastCoverProviders
|
||||||
return [{ text: 'All', value: 'all' }, ...this.$store.state.scanners.providers, ...this.$store.state.scanners.coverOnlyProviders]
|
return this.$store.state.scanners.bookCoverProviders
|
||||||
},
|
},
|
||||||
searchTitleLabel() {
|
searchTitleLabel() {
|
||||||
if (this.provider.startsWith('audible')) return this.$strings.LabelSearchTitleOrASIN
|
if (this.provider.startsWith('audible')) return this.$strings.LabelSearchTitleOrASIN
|
||||||
@@ -186,6 +191,9 @@ export default {
|
|||||||
_file.localPath = `${process.env.serverUrl}/api/items/${this.libraryItemId}/file/${file.ino}?token=${this.userToken}`
|
_file.localPath = `${process.env.serverUrl}/api/items/${this.libraryItemId}/file/${file.ino}?token=${this.userToken}`
|
||||||
return _file
|
return _file
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
socket() {
|
||||||
|
return this.$root.socket
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -235,7 +243,19 @@ export default {
|
|||||||
this.searchTitle = this.mediaMetadata.title || ''
|
this.searchTitle = this.mediaMetadata.title || ''
|
||||||
this.searchAuthor = this.mediaMetadata.authorName || ''
|
this.searchAuthor = this.mediaMetadata.authorName || ''
|
||||||
if (this.isPodcast) this.provider = 'itunes'
|
if (this.isPodcast) this.provider = 'itunes'
|
||||||
else this.provider = localStorage.getItem('book-cover-provider') || localStorage.getItem('book-provider') || 'google'
|
else {
|
||||||
|
// Migrate from 'all' to 'best' (only once)
|
||||||
|
const migrationKey = 'book-cover-provider-migrated'
|
||||||
|
const currentProvider = localStorage.getItem('book-cover-provider') || localStorage.getItem('book-provider') || 'google'
|
||||||
|
|
||||||
|
if (!localStorage.getItem(migrationKey) && currentProvider === 'all') {
|
||||||
|
localStorage.setItem('book-cover-provider', 'best')
|
||||||
|
localStorage.setItem(migrationKey, 'true')
|
||||||
|
this.provider = 'best'
|
||||||
|
} else {
|
||||||
|
this.provider = currentProvider
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
removeCover() {
|
removeCover() {
|
||||||
if (!this.coverPath) {
|
if (!this.coverPath) {
|
||||||
@@ -291,22 +311,116 @@ export default {
|
|||||||
console.error('PersistProvider', error)
|
console.error('PersistProvider', error)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
generateRequestId() {
|
||||||
|
return `cover-search-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
|
||||||
|
},
|
||||||
|
addSocketListeners() {
|
||||||
|
if (!this.socket || this.socketListenersActive) return
|
||||||
|
|
||||||
|
this.socket.on('cover_search_result', this.handleSearchResult)
|
||||||
|
this.socket.on('cover_search_complete', this.handleSearchComplete)
|
||||||
|
this.socket.on('cover_search_error', this.handleSearchError)
|
||||||
|
this.socket.on('cover_search_provider_error', this.handleProviderError)
|
||||||
|
this.socket.on('cover_search_cancelled', this.handleSearchCancelled)
|
||||||
|
this.socket.on('disconnect', this.handleSocketDisconnect)
|
||||||
|
this.socketListenersActive = true
|
||||||
|
},
|
||||||
|
removeSocketListeners() {
|
||||||
|
if (!this.socket || !this.socketListenersActive) return
|
||||||
|
|
||||||
|
this.socket.off('cover_search_result', this.handleSearchResult)
|
||||||
|
this.socket.off('cover_search_complete', this.handleSearchComplete)
|
||||||
|
this.socket.off('cover_search_error', this.handleSearchError)
|
||||||
|
this.socket.off('cover_search_provider_error', this.handleProviderError)
|
||||||
|
this.socket.off('cover_search_cancelled', this.handleSearchCancelled)
|
||||||
|
this.socket.off('disconnect', this.handleSocketDisconnect)
|
||||||
|
this.socketListenersActive = false
|
||||||
|
},
|
||||||
|
handleSearchResult(data) {
|
||||||
|
if (data.requestId !== this.currentSearchRequestId) return
|
||||||
|
|
||||||
|
// Add new covers to the list (avoiding duplicates)
|
||||||
|
const newCovers = data.covers.filter((cover) => !this.coversFound.includes(cover))
|
||||||
|
this.coversFound.push(...newCovers)
|
||||||
|
},
|
||||||
|
handleSearchComplete(data) {
|
||||||
|
if (data.requestId !== this.currentSearchRequestId) return
|
||||||
|
|
||||||
|
this.searchInProgress = false
|
||||||
|
this.currentSearchRequestId = null
|
||||||
|
},
|
||||||
|
handleSearchError(data) {
|
||||||
|
if (data.requestId !== this.currentSearchRequestId) return
|
||||||
|
|
||||||
|
console.error('[Cover Search] Search error:', data.error)
|
||||||
|
this.$toast.error(this.$strings.ToastCoverSearchFailed)
|
||||||
|
this.searchInProgress = false
|
||||||
|
this.currentSearchRequestId = null
|
||||||
|
},
|
||||||
|
handleProviderError(data) {
|
||||||
|
if (data.requestId !== this.currentSearchRequestId) return
|
||||||
|
|
||||||
|
console.warn(`[Cover Search] Provider ${data.provider} failed:`, data.error)
|
||||||
|
},
|
||||||
|
handleSearchCancelled(data) {
|
||||||
|
if (data.requestId !== this.currentSearchRequestId) return
|
||||||
|
|
||||||
|
this.searchInProgress = false
|
||||||
|
this.currentSearchRequestId = null
|
||||||
|
},
|
||||||
|
handleSocketDisconnect() {
|
||||||
|
// If we were in the middle of a search, cancel it (server can't send results anymore)
|
||||||
|
if (this.searchInProgress && this.currentSearchRequestId) {
|
||||||
|
this.searchInProgress = false
|
||||||
|
this.currentSearchRequestId = null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
cancelCurrentSearch() {
|
||||||
|
if (!this.currentSearchRequestId || !this.socket?.connected) {
|
||||||
|
console.error('[Cover Search] Socket not connected')
|
||||||
|
this.$toast.error(this.$strings.ToastConnectionNotAvailable)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.socket.emit('cancel_cover_search', this.currentSearchRequestId)
|
||||||
|
this.currentSearchRequestId = null
|
||||||
|
this.searchInProgress = false
|
||||||
|
},
|
||||||
async submitSearchForm() {
|
async submitSearchForm() {
|
||||||
|
if (!this.socket?.connected) {
|
||||||
|
console.error('[Cover Search] Socket not connected')
|
||||||
|
this.$toast.error(this.$strings.ToastConnectionNotAvailable)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cancel any existing search
|
||||||
|
if (this.searchInProgress) {
|
||||||
|
this.cancelCurrentSearch()
|
||||||
|
}
|
||||||
|
|
||||||
// Store provider in local storage
|
// Store provider in local storage
|
||||||
this.persistProvider()
|
this.persistProvider()
|
||||||
|
|
||||||
this.isProcessing = true
|
// Setup socket listeners if not already done
|
||||||
const searchQuery = this.getSearchQuery()
|
this.addSocketListeners()
|
||||||
const results = await this.$axios
|
|
||||||
.$get(`/api/search/covers?${searchQuery}`)
|
// Clear previous results
|
||||||
.then((res) => res.results)
|
this.coversFound = []
|
||||||
.catch((error) => {
|
|
||||||
console.error('Failed', error)
|
|
||||||
return []
|
|
||||||
})
|
|
||||||
this.coversFound = results
|
|
||||||
this.isProcessing = false
|
|
||||||
this.hasSearched = true
|
this.hasSearched = true
|
||||||
|
this.searchInProgress = true
|
||||||
|
|
||||||
|
// Generate unique request ID
|
||||||
|
const requestId = this.generateRequestId()
|
||||||
|
this.currentSearchRequestId = requestId
|
||||||
|
|
||||||
|
// Emit search request via WebSocket
|
||||||
|
this.socket.emit('search_covers', {
|
||||||
|
requestId,
|
||||||
|
title: this.searchTitle,
|
||||||
|
author: this.searchAuthor || '',
|
||||||
|
provider: this.provider,
|
||||||
|
podcast: this.isPodcast
|
||||||
|
})
|
||||||
},
|
},
|
||||||
setCover(coverFile) {
|
setCover(coverFile) {
|
||||||
this.isProcessing = true
|
this.isProcessing = true
|
||||||
@@ -320,6 +434,20 @@ export default {
|
|||||||
this.isProcessing = false
|
this.isProcessing = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// Setup socket listeners when component is mounted
|
||||||
|
this.addSocketListeners()
|
||||||
|
// Fetch providers if not already loaded
|
||||||
|
this.$store.dispatch('scanners/fetchProviders')
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
// Cancel any ongoing search when component is destroyed
|
||||||
|
if (this.searchInProgress) {
|
||||||
|
this.cancelCurrentSearch()
|
||||||
|
}
|
||||||
|
// Remove socket listeners
|
||||||
|
this.removeSocketListeners()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
<div id="match-wrapper" class="w-full h-full overflow-hidden px-2 md:px-4 py-4 md:py-6 relative">
|
<div id="match-wrapper" class="w-full h-full overflow-hidden px-2 md:px-4 py-4 md:py-6 relative">
|
||||||
<form @submit.prevent="submitSearch">
|
<form @submit.prevent="submitSearch">
|
||||||
<div class="flex flex-wrap md:flex-nowrap items-center justify-start -mx-1">
|
<div class="flex flex-wrap md:flex-nowrap items-center justify-start -mx-1">
|
||||||
<div class="w-36 px-1">
|
<div v-if="providersLoaded" class="w-36 px-1">
|
||||||
<ui-dropdown v-model="provider" :items="providers" :label="$strings.LabelProvider" small />
|
<ui-dropdown v-model="provider" :items="providers" :label="$strings.LabelProvider" small />
|
||||||
</div>
|
</div>
|
||||||
<div class="grow md:w-72 px-1">
|
<div class="grow md:w-72 px-1">
|
||||||
@@ -77,8 +77,8 @@
|
|||||||
<ui-checkbox v-model="selectedMatchUsage.author" checkbox-bg="bg" @input="checkboxToggled" />
|
<ui-checkbox v-model="selectedMatchUsage.author" checkbox-bg="bg" @input="checkboxToggled" />
|
||||||
<div class="grow ml-4">
|
<div class="grow ml-4">
|
||||||
<ui-text-input-with-label v-model="selectedMatch.author" :disabled="!selectedMatchUsage.author" :label="$strings.LabelAuthor" />
|
<ui-text-input-with-label v-model="selectedMatch.author" :disabled="!selectedMatchUsage.author" :label="$strings.LabelAuthor" />
|
||||||
<p v-if="mediaMetadata.authorName" class="text-xs ml-1 text-white/60">
|
<p v-if="mediaMetadata.authorName || (isPodcast && mediaMetadata.author)" class="text-xs ml-1 text-white/60">
|
||||||
{{ $strings.LabelCurrently }} <a title="$strings.LabelClickToUseCurrentValue" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('author', mediaMetadata.authorName)">{{ mediaMetadata.authorName }}</a>
|
{{ $strings.LabelCurrently }} <a :title="$strings.LabelClickToUseCurrentValue" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('author', isPodcast ? mediaMetadata.author : mediaMetadata.authorName)">{{ isPodcast ? mediaMetadata.author : mediaMetadata.authorName }}</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -87,7 +87,7 @@
|
|||||||
<div class="grow ml-4">
|
<div class="grow ml-4">
|
||||||
<ui-multi-select v-model="selectedMatch.narrator" :items="narrators" :disabled="!selectedMatchUsage.narrator" :label="$strings.LabelNarrators" />
|
<ui-multi-select v-model="selectedMatch.narrator" :items="narrators" :disabled="!selectedMatchUsage.narrator" :label="$strings.LabelNarrators" />
|
||||||
<p v-if="mediaMetadata.narratorName" class="text-xs ml-1 text-white/60">
|
<p v-if="mediaMetadata.narratorName" class="text-xs ml-1 text-white/60">
|
||||||
{{ $strings.LabelCurrently }} <a title="$strings.LabelClickToUseCurrentValue" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('narrator', mediaMetadata.narrators)">{{ mediaMetadata.narratorName }}</a>
|
{{ $strings.LabelCurrently }} <a :title="$strings.LabelClickToUseCurrentValue" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('narrator', mediaMetadata.narrators)">{{ mediaMetadata.narratorName }}</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -96,7 +96,7 @@
|
|||||||
<div class="grow ml-4">
|
<div class="grow ml-4">
|
||||||
<ui-rich-text-editor v-model="selectedMatch.description" :disabled="!selectedMatchUsage.description" :label="$strings.LabelDescription" />
|
<ui-rich-text-editor v-model="selectedMatch.description" :disabled="!selectedMatchUsage.description" :label="$strings.LabelDescription" />
|
||||||
<p v-if="mediaMetadata.description" class="text-xs ml-1 text-white/60">
|
<p v-if="mediaMetadata.description" class="text-xs ml-1 text-white/60">
|
||||||
{{ $strings.LabelCurrently }} <a title="$strings.LabelClickToUseCurrentValue" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('description', mediaMetadata.description)">{{ mediaMetadata.descriptionPlain.substr(0, 100) + (mediaMetadata.descriptionPlain.length > 100 ? '...' : '') }}</a>
|
{{ $strings.LabelCurrently }} <a :title="$strings.LabelClickToUseCurrentValue" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('description', mediaMetadata.description)">{{ mediaMetadata.descriptionPlain.substr(0, 100) + (mediaMetadata.descriptionPlain.length > 100 ? '...' : '') }}</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -105,7 +105,7 @@
|
|||||||
<div class="grow ml-4">
|
<div class="grow ml-4">
|
||||||
<ui-text-input-with-label v-model="selectedMatch.publisher" :disabled="!selectedMatchUsage.publisher" :label="$strings.LabelPublisher" />
|
<ui-text-input-with-label v-model="selectedMatch.publisher" :disabled="!selectedMatchUsage.publisher" :label="$strings.LabelPublisher" />
|
||||||
<p v-if="mediaMetadata.publisher" class="text-xs ml-1 text-white/60">
|
<p v-if="mediaMetadata.publisher" class="text-xs ml-1 text-white/60">
|
||||||
{{ $strings.LabelCurrently }} <a title="$strings.LabelClickToUseCurrentValue" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('publisher', mediaMetadata.publisher)">{{ mediaMetadata.publisher }}</a>
|
{{ $strings.LabelCurrently }} <a :title="$strings.LabelClickToUseCurrentValue" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('publisher', mediaMetadata.publisher)">{{ mediaMetadata.publisher }}</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -114,7 +114,7 @@
|
|||||||
<div class="grow ml-4">
|
<div class="grow ml-4">
|
||||||
<ui-text-input-with-label v-model="selectedMatch.publishedYear" :disabled="!selectedMatchUsage.publishedYear" :label="$strings.LabelPublishYear" />
|
<ui-text-input-with-label v-model="selectedMatch.publishedYear" :disabled="!selectedMatchUsage.publishedYear" :label="$strings.LabelPublishYear" />
|
||||||
<p v-if="mediaMetadata.publishedYear" class="text-xs ml-1 text-white/60">
|
<p v-if="mediaMetadata.publishedYear" class="text-xs ml-1 text-white/60">
|
||||||
{{ $strings.LabelCurrently }} <a title="$strings.LabelClickToUseCurrentValue" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('publishedYear', mediaMetadata.publishedYear)">{{ mediaMetadata.publishedYear }}</a>
|
{{ $strings.LabelCurrently }} <a :title="$strings.LabelClickToUseCurrentValue" class="cursor-pointer hover:underline" @click.stop="setMatchFieldValue('publishedYear', mediaMetadata.publishedYear)">{{ mediaMetadata.publishedYear }}</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -253,6 +253,7 @@ export default {
|
|||||||
hasSearched: false,
|
hasSearched: false,
|
||||||
selectedMatch: null,
|
selectedMatch: null,
|
||||||
selectedMatchOrig: null,
|
selectedMatchOrig: null,
|
||||||
|
waitingForProviders: false,
|
||||||
selectedMatchUsage: {
|
selectedMatchUsage: {
|
||||||
title: true,
|
title: true,
|
||||||
subtitle: true,
|
subtitle: true,
|
||||||
@@ -285,9 +286,19 @@ export default {
|
|||||||
handler(newVal) {
|
handler(newVal) {
|
||||||
if (newVal) this.init()
|
if (newVal) this.init()
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
providersLoaded(isLoaded) {
|
||||||
|
// Complete initialization once providers are loaded
|
||||||
|
if (isLoaded && this.waitingForProviders) {
|
||||||
|
this.waitingForProviders = false
|
||||||
|
this.initProviderAndSearch()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
providersLoaded() {
|
||||||
|
return this.$store.getters['scanners/areProvidersLoaded']
|
||||||
|
},
|
||||||
isProcessing: {
|
isProcessing: {
|
||||||
get() {
|
get() {
|
||||||
return this.processing
|
return this.processing
|
||||||
@@ -319,7 +330,7 @@ export default {
|
|||||||
},
|
},
|
||||||
providers() {
|
providers() {
|
||||||
if (this.isPodcast) return this.$store.state.scanners.podcastProviders
|
if (this.isPodcast) return this.$store.state.scanners.podcastProviders
|
||||||
return this.$store.state.scanners.providers
|
return this.$store.state.scanners.bookProviders
|
||||||
},
|
},
|
||||||
searchTitleLabel() {
|
searchTitleLabel() {
|
||||||
if (this.provider.startsWith('audible')) return this.$strings.LabelSearchTitleOrASIN
|
if (this.provider.startsWith('audible')) return this.$strings.LabelSearchTitleOrASIN
|
||||||
@@ -400,7 +411,9 @@ export default {
|
|||||||
this.$toast.warning(this.$strings.ToastTitleRequired)
|
this.$toast.warning(this.$strings.ToastTitleRequired)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.persistProvider()
|
if (!this.isPodcast) {
|
||||||
|
this.persistProvider()
|
||||||
|
}
|
||||||
this.runSearch()
|
this.runSearch()
|
||||||
},
|
},
|
||||||
async runSearch() {
|
async runSearch() {
|
||||||
@@ -476,6 +489,24 @@ export default {
|
|||||||
|
|
||||||
this.checkboxToggled()
|
this.checkboxToggled()
|
||||||
},
|
},
|
||||||
|
initProviderAndSearch() {
|
||||||
|
// Set provider based on media type
|
||||||
|
if (this.isPodcast) {
|
||||||
|
this.provider = 'itunes'
|
||||||
|
} else {
|
||||||
|
this.provider = this.getDefaultBookProvider()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prefer using ASIN if set and using audible provider
|
||||||
|
if (this.provider.startsWith('audible') && this.libraryItem.media.metadata.asin) {
|
||||||
|
this.searchTitle = this.libraryItem.media.metadata.asin
|
||||||
|
this.searchAuthor = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.searchTitle) {
|
||||||
|
this.submitSearch()
|
||||||
|
}
|
||||||
|
},
|
||||||
init() {
|
init() {
|
||||||
this.clearSelectedMatch()
|
this.clearSelectedMatch()
|
||||||
this.initSelectedMatchUsage()
|
this.initSelectedMatchUsage()
|
||||||
@@ -493,19 +524,13 @@ export default {
|
|||||||
}
|
}
|
||||||
this.searchTitle = this.libraryItem.media.metadata.title
|
this.searchTitle = this.libraryItem.media.metadata.title
|
||||||
this.searchAuthor = this.libraryItem.media.metadata.authorName || ''
|
this.searchAuthor = this.libraryItem.media.metadata.authorName || ''
|
||||||
if (this.isPodcast) this.provider = 'itunes'
|
|
||||||
else {
|
|
||||||
this.provider = this.getDefaultBookProvider()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prefer using ASIN if set and using audible provider
|
// Wait for providers to be loaded before setting provider and searching
|
||||||
if (this.provider.startsWith('audible') && this.libraryItem.media.metadata.asin) {
|
if (this.providersLoaded || this.isPodcast) {
|
||||||
this.searchTitle = this.libraryItem.media.metadata.asin
|
this.waitingForProviders = false
|
||||||
this.searchAuthor = ''
|
this.initProviderAndSearch()
|
||||||
}
|
} else {
|
||||||
|
this.waitingForProviders = true
|
||||||
if (this.searchTitle) {
|
|
||||||
this.submitSearch()
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
selectMatch(match) {
|
selectMatch(match) {
|
||||||
@@ -635,6 +660,10 @@ export default {
|
|||||||
this.selectedMatch = null
|
this.selectedMatch = null
|
||||||
this.selectedMatchOrig = null
|
this.selectedMatchOrig = null
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// Fetch providers if not already loaded
|
||||||
|
this.$store.dispatch('scanners/fetchProviders')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -158,6 +158,8 @@ export default {
|
|||||||
this.isProcessing = true
|
this.isProcessing = true
|
||||||
var updateResult = await this.$axios.$patch(`/api/items/${this.libraryItemId}/media`, updatePayload).catch((error) => {
|
var updateResult = await this.$axios.$patch(`/api/items/${this.libraryItemId}/media`, updatePayload).catch((error) => {
|
||||||
console.error('Failed to update', error)
|
console.error('Failed to update', error)
|
||||||
|
const errorMessage = typeof error?.response?.data === 'string' ? error?.response?.data : null
|
||||||
|
this.$toast.error(errorMessage || this.$strings.ToastFailedToUpdate)
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
this.isProcessing = false
|
this.isProcessing = false
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ export default {
|
|||||||
quickEmbed() {
|
quickEmbed() {
|
||||||
const payload = {
|
const payload = {
|
||||||
message: this.$strings.MessageConfirmQuickEmbed,
|
message: this.$strings.MessageConfirmQuickEmbed,
|
||||||
|
allowHtml: true,
|
||||||
callback: (confirmed) => {
|
callback: (confirmed) => {
|
||||||
if (confirmed) {
|
if (confirmed) {
|
||||||
this.$axios
|
this.$axios
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ export default {
|
|||||||
},
|
},
|
||||||
providers() {
|
providers() {
|
||||||
if (this.mediaType === 'podcast') return this.$store.state.scanners.podcastProviders
|
if (this.mediaType === 'podcast') return this.$store.state.scanners.podcastProviders
|
||||||
return this.$store.state.scanners.providers
|
return this.$store.state.scanners.bookProviders
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -156,6 +156,8 @@ export default {
|
|||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.init()
|
this.init()
|
||||||
|
// Fetch providers if not already loaded
|
||||||
|
this.$store.dispatch('scanners/fetchProviders')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<div class="flex items-center justify-between md:justify-start mb-4">
|
<div class="flex items-center justify-between md:justify-start mb-4">
|
||||||
<p class="text-sm text-gray-300 pr-2">{{ $strings.LabelMetadataOrderOfPrecedenceDescription }}</p>
|
<p class="text-sm text-gray-300 pr-2">{{ $strings.LabelMetadataOrderOfPrecedenceDescription }}</p>
|
||||||
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex">
|
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex">
|
||||||
<a href="https://www.audiobookshelf.org/guides/book-scanner" target="_blank" class="inline-flex">
|
<a href="https://audiobookshelf.org/docs/documentation/libraries/book-library/book-metadata" target="_blank" class="inline-flex">
|
||||||
<span class="material-symbols text-xl w-5">help_outline</span>
|
<span class="material-symbols text-xl w-5">help_outline</span>
|
||||||
</a>
|
</a>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
|
|||||||
@@ -104,7 +104,6 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
provider: null,
|
|
||||||
useSquareBookCovers: false,
|
useSquareBookCovers: false,
|
||||||
enableWatcher: false,
|
enableWatcher: false,
|
||||||
skipMatchingMediaWithAsin: false,
|
skipMatchingMediaWithAsin: false,
|
||||||
@@ -134,10 +133,6 @@ export default {
|
|||||||
isPodcastLibrary() {
|
isPodcastLibrary() {
|
||||||
return this.mediaType === 'podcast'
|
return this.mediaType === 'podcast'
|
||||||
},
|
},
|
||||||
providers() {
|
|
||||||
if (this.mediaType === 'podcast') return this.$store.state.scanners.podcastProviders
|
|
||||||
return this.$store.state.scanners.providers
|
|
||||||
},
|
|
||||||
maskAsFinishedWhenItems() {
|
maskAsFinishedWhenItems() {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
<div class="text-sm flex items-center justify-center text-gray-200">
|
<div class="text-sm flex items-center justify-center text-gray-200">
|
||||||
<p>{{ $strings.MessageNoUserPlaylistsHelp }}</p>
|
<p>{{ $strings.MessageNoUserPlaylistsHelp }}</p>
|
||||||
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex ml-2">
|
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex ml-2">
|
||||||
<a href="https://www.audiobookshelf.org/guides/collections" target="_blank" class="inline-flex">
|
<a href="https://audiobookshelf.org/docs/documentation/libraries/common-content/playlists" target="_blank" class="inline-flex">
|
||||||
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
|
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
|
||||||
</a>
|
</a>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
@@ -97,7 +97,10 @@ export default {
|
|||||||
...playlist
|
...playlist
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.sort((a, b) => (a.isItemIncluded ? -1 : 1))
|
.sort((a, b) => {
|
||||||
|
if (a.isItemIncluded !== b.isItemIncluded) return a.isItemIncluded ? -1 : 1
|
||||||
|
return a.name.localeCompare(b.name)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
isBatch() {
|
isBatch() {
|
||||||
return this.selectedPlaylistItems.length > 1
|
return this.selectedPlaylistItems.length > 1
|
||||||
|
|||||||
@@ -94,7 +94,6 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.processing = false
|
this.processing = false
|
||||||
this.$toast.success(`${this.episodes.length} episode${this.episodes.length > 1 ? 's' : ''} removed`)
|
|
||||||
this.show = false
|
this.show = false
|
||||||
this.$emit('clearSelected')
|
this.$emit('clearSelected')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ export default {
|
|||||||
.$patch(`/api/podcasts/${this.libraryItem.id}/episode/${this.episodeId}`, updatePayload)
|
.$patch(`/api/podcasts/${this.libraryItem.id}/episode/${this.episodeId}`, updatePayload)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.isProcessing = false
|
this.isProcessing = false
|
||||||
this.$toast.success('Podcast episode updated')
|
this.$toast.success(this.$strings.ToastPodcastEpisodeUpdated)
|
||||||
this.$emit('selectTab', 'details')
|
this.$emit('selectTab', 'details')
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
<ui-tooltip direction="top" :text="jumpBackwardText">
|
<ui-tooltip direction="top" :text="jumpBackwardText">
|
||||||
<button :aria-label="jumpForwardText" class="text-gray-300" @mousedown.prevent @mouseup.prevent @click.stop="jumpBackward">
|
<button :aria-label="jumpBackwardText" class="text-gray-300" @mousedown.prevent @mouseup.prevent @click.stop="jumpBackward">
|
||||||
<span class="material-symbols text-2xl sm:text-3xl">replay</span>
|
<span class="material-symbols text-2xl sm:text-3xl">replay</span>
|
||||||
</button>
|
</button>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
<div class="absolute top-0 left-0 right-0 w-full h-36 bg-linear-to-t from-transparent via-black-500 to-black-700 opacity-90 pointer-events-none" />
|
<div class="absolute top-0 left-0 right-0 w-full h-36 bg-linear-to-t from-transparent via-black-500 to-black-700 opacity-90 pointer-events-none" />
|
||||||
<div ref="content" class="relative text-white" :style="{ height: modalHeight, width: modalWidth }" v-click-outside="clickedOutside">
|
<div ref="content" class="relative text-white" :style="{ height: modalHeight, width: modalWidth }" v-click-outside="clickedOutside">
|
||||||
<div class="px-4 w-full text-sm py-6 rounded-lg bg-bg shadow-lg border border-black-300">
|
<div class="px-4 w-full text-sm py-6 rounded-lg bg-bg shadow-lg border border-black-300">
|
||||||
<p id="confirm-prompt-message" class="text-lg mb-6 mt-2 px-1" v-html="message" />
|
<p v-if="allowHtmlMessage" id="confirm-prompt-message" class="text-lg mb-6 mt-2 px-1" v-html="sanitizedMessage" />
|
||||||
|
<p v-else id="confirm-prompt-message" class="text-lg mb-6 mt-2 px-1">{{ message }}</p>
|
||||||
|
|
||||||
<ui-checkbox v-if="checkboxLabel" v-model="checkboxValue" checkbox-bg="bg" :label="checkboxLabel" label-class="pl-2 text-base" class="mb-6 px-1" />
|
<ui-checkbox v-if="checkboxLabel" v-model="checkboxValue" checkbox-bg="bg" :label="checkboxLabel" label-class="pl-2 text-base" class="mb-6 px-1" />
|
||||||
|
|
||||||
@@ -52,6 +53,17 @@ export default {
|
|||||||
message() {
|
message() {
|
||||||
return this.confirmPromptOptions.message || ''
|
return this.confirmPromptOptions.message || ''
|
||||||
},
|
},
|
||||||
|
allowHtmlMessage() {
|
||||||
|
return !!this.confirmPromptOptions.allowHtml
|
||||||
|
},
|
||||||
|
sanitizedMessage() {
|
||||||
|
if (!this.allowHtmlMessage) return this.message
|
||||||
|
|
||||||
|
return this.escapeHtml(this.message)
|
||||||
|
.replace(/<br\s*\/?>/gi, '<br>')
|
||||||
|
.replace(/<code>/gi, '<code>')
|
||||||
|
.replace(/<\/code>/gi, '</code>')
|
||||||
|
},
|
||||||
callback() {
|
callback() {
|
||||||
return this.confirmPromptOptions.callback
|
return this.confirmPromptOptions.callback
|
||||||
},
|
},
|
||||||
@@ -103,6 +115,14 @@ export default {
|
|||||||
if (this.callback) this.callback(true, this.checkboxValue)
|
if (this.callback) this.callback(true, this.checkboxValue)
|
||||||
this.show = false
|
this.show = false
|
||||||
},
|
},
|
||||||
|
escapeHtml(value) {
|
||||||
|
return String(value)
|
||||||
|
.replace(/&/g, '&')
|
||||||
|
.replace(/</g, '<')
|
||||||
|
.replace(/>/g, '>')
|
||||||
|
.replace(/"/g, '"')
|
||||||
|
.replace(/'/g, ''')
|
||||||
|
},
|
||||||
setShow() {
|
setShow() {
|
||||||
this.checkboxValue = this.checkboxDefaultValue
|
this.checkboxValue = this.checkboxDefaultValue
|
||||||
this.$eventBus.$emit('showing-prompt', true)
|
this.$eventBus.$emit('showing-prompt', true)
|
||||||
|
|||||||
@@ -99,22 +99,32 @@ export default {
|
|||||||
return `/api/items/${this.libraryItemId}/ebook`
|
return `/api/items/${this.libraryItemId}/ebook`
|
||||||
},
|
},
|
||||||
themeRules() {
|
themeRules() {
|
||||||
const isDark = this.ereaderSettings.theme === 'dark'
|
const theme = this.ereaderSettings.theme
|
||||||
const fontColor = isDark ? '#fff' : '#000'
|
const isDark = theme === 'dark'
|
||||||
const backgroundColor = isDark ? 'rgb(35 35 35)' : 'rgb(255, 255, 255)'
|
const isSepia = theme === 'sepia'
|
||||||
|
|
||||||
|
const fontColor = isDark
|
||||||
|
? '#fff'
|
||||||
|
: isSepia
|
||||||
|
? '#5b4636'
|
||||||
|
: '#000'
|
||||||
|
|
||||||
|
const backgroundColor = isDark
|
||||||
|
? 'rgb(35 35 35)'
|
||||||
|
: isSepia
|
||||||
|
? 'rgb(244, 236, 216)'
|
||||||
|
: 'rgb(255, 255, 255)'
|
||||||
|
|
||||||
const lineSpacing = this.ereaderSettings.lineSpacing / 100
|
const lineSpacing = this.ereaderSettings.lineSpacing / 100
|
||||||
|
const fontScale = this.ereaderSettings.fontScale / 100
|
||||||
const fontScale = this.ereaderSettings.fontScale / 100
|
const textStroke = this.ereaderSettings.textStroke / 100
|
||||||
|
|
||||||
const textStroke = this.ereaderSettings.textStroke / 100
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'*': {
|
'*': {
|
||||||
color: `${fontColor}!important`,
|
color: `${fontColor}!important`,
|
||||||
'background-color': `${backgroundColor}!important`,
|
'background-color': `${backgroundColor}!important`,
|
||||||
'line-height': lineSpacing * fontScale + 'rem!important',
|
'line-height': `${lineSpacing * fontScale}rem!important`,
|
||||||
'-webkit-text-stroke': textStroke + 'px ' + fontColor + '!important'
|
'-webkit-text-stroke': `${textStroke}px ${fontColor}!important`
|
||||||
},
|
},
|
||||||
a: {
|
a: {
|
||||||
color: `${fontColor}!important`
|
color: `${fontColor}!important`
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="show" id="reader" :data-theme="ereaderTheme" class="group absolute top-0 left-0 w-full z-60 data-[theme=dark]:bg-primary data-[theme=dark]:text-white data-[theme=light]:bg-white data-[theme=light]:text-black" :class="{ 'reader-player-open': !!streamLibraryItem }">
|
<div v-if="show" id="reader" :data-theme="ereaderTheme" class="group absolute top-0 left-0 w-full z-60 data-[theme=dark]:bg-primary data-[theme=dark]:text-white data-[theme=light]:bg-white data-[theme=light]:text-black data-[theme=sepia]:bg-[rgb(244,236,216)] data-[theme=sepia]:text-[#5b4636]" :class="{ 'reader-player-open': !!streamLibraryItem }">
|
||||||
<div class="absolute top-4 left-4 z-20 flex items-center">
|
<div class="absolute top-4 left-4 z-20 flex items-center">
|
||||||
<button v-if="isEpub" @click="toggleToC" type="button" aria-label="Table of contents menu" class="inline-flex opacity-80 hover:opacity-100">
|
<button v-if="isEpub" @click="toggleToC" type="button" aria-label="Table of contents menu" class="inline-flex opacity-80 hover:opacity-100">
|
||||||
<span class="material-symbols text-2xl">menu</span>
|
<span class="material-symbols text-2xl">menu</span>
|
||||||
@@ -27,7 +27,12 @@
|
|||||||
|
|
||||||
<!-- TOC side nav -->
|
<!-- TOC side nav -->
|
||||||
<div v-if="tocOpen" class="w-full h-full overflow-y-scroll absolute inset-0 bg-black/20 z-20" @click.stop.prevent="toggleToC"></div>
|
<div v-if="tocOpen" class="w-full h-full overflow-y-scroll absolute inset-0 bg-black/20 z-20" @click.stop.prevent="toggleToC"></div>
|
||||||
<div v-if="isEpub" class="w-96 h-full max-h-full absolute top-0 left-0 shadow-xl transition-transform z-30 group-data-[theme=dark]:bg-primary group-data-[theme=dark]:text-white group-data-[theme=light]:bg-white group-data-[theme=light]:text-black" :class="tocOpen ? 'translate-x-0' : '-translate-x-96'" @click.stop.prevent>
|
<div
|
||||||
|
v-if="isEpub"
|
||||||
|
class="w-96 h-full max-h-full absolute top-0 left-0 shadow-xl transition-transform z-30 group-data-[theme=dark]:bg-primary group-data-[theme=dark]:text-white group-data-[theme=light]:bg-white group-data-[theme=light]:text-black group-data-[theme=sepia]:bg-[rgb(244,236,216)] group-data-[theme=sepia]:text-[#5b4636]"
|
||||||
|
:class="tocOpen ? 'translate-x-0' : '-translate-x-96'"
|
||||||
|
@click.stop.prevent
|
||||||
|
>
|
||||||
<div class="flex flex-col p-4 h-full">
|
<div class="flex flex-col p-4 h-full">
|
||||||
<div class="flex items-center mb-2">
|
<div class="flex items-center mb-2">
|
||||||
<button @click.stop.prevent="toggleToC" type="button" aria-label="Close table of contents" class="inline-flex opacity-80 hover:opacity-100">
|
<button @click.stop.prevent="toggleToC" type="button" aria-label="Close table of contents" class="inline-flex opacity-80 hover:opacity-100">
|
||||||
@@ -37,7 +42,7 @@
|
|||||||
<p class="text-lg font-semibold ml-2">{{ $strings.HeaderTableOfContents }}</p>
|
<p class="text-lg font-semibold ml-2">{{ $strings.HeaderTableOfContents }}</p>
|
||||||
</div>
|
</div>
|
||||||
<form @submit.prevent="searchBook" @click.stop.prevent>
|
<form @submit.prevent="searchBook" @click.stop.prevent>
|
||||||
<ui-text-input clearable ref="input" @clear="searchBook" v-model="searchQuery" :placeholder="$strings.PlaceholderSearch" class="h-8 w-full text-sm flex mb-2" />
|
<ui-text-input clearable ref="input" @clear="searchBook" v-model="searchQuery" :placeholder="$strings.PlaceholderSearch" custom-input-class="text-inherit !bg-inherit" class="h-8 w-full text-sm flex mb-2" />
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div class="overflow-y-auto">
|
<div class="overflow-y-auto">
|
||||||
@@ -181,6 +186,10 @@ export default {
|
|||||||
text: this.$strings.LabelThemeDark,
|
text: this.$strings.LabelThemeDark,
|
||||||
value: 'dark'
|
value: 'dark'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
text: this.$strings.LabelThemeSepia,
|
||||||
|
value: 'sepia'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
text: this.$strings.LabelThemeLight,
|
text: this.$strings.LabelThemeLight,
|
||||||
value: 'light'
|
value: 'light'
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
<div :key="n" class="absolute pointer-events-none left-0 h-px bg-white/10" :style="{ top: n * lineSpacing - lineSpacing / 2 + 'px', width: '360px', marginLeft: '24px' }" />
|
<div :key="n" class="absolute pointer-events-none left-0 h-px bg-white/10" :style="{ top: n * lineSpacing - lineSpacing / 2 + 'px', width: '360px', marginLeft: '24px' }" />
|
||||||
|
|
||||||
<div :key="`dot-${n}`" class="absolute z-10" :style="{ left: points[n - 1].x + 'px', bottom: points[n - 1].y + 'px' }">
|
<div :key="`dot-${n}`" class="absolute z-10" :style="{ left: points[n - 1].x + 'px', bottom: points[n - 1].y + 'px' }">
|
||||||
<ui-tooltip :text="last7DaysOfListening[n - 1].minutesListening" direction="top">
|
<ui-tooltip :text="last7DaysOfListening[n - 1].minutesListening" plaintext direction="top">
|
||||||
<div class="h-2 w-2 bg-yellow-400 hover:bg-yellow-300 rounded-full transform duration-150 transition-transform hover:scale-125" />
|
<div class="h-2 w-2 bg-yellow-400 hover:bg-yellow-300 rounded-full transform duration-150 transition-transform hover:scale-125" />
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
</div>
|
</div>
|
||||||
@@ -186,10 +186,16 @@ export default {
|
|||||||
daysInARow() {
|
daysInARow() {
|
||||||
var count = 0
|
var count = 0
|
||||||
while (true) {
|
while (true) {
|
||||||
var _date = this.$addDaysToToday(count * -1)
|
const _date = this.$addDaysToToday(count * -1 - 1)
|
||||||
var datestr = this.$formatJsDate(_date, 'yyyy-MM-dd')
|
const datestr = this.$formatJsDate(_date, 'yyyy-MM-dd')
|
||||||
|
|
||||||
if (!this.listeningStatsDays[datestr] || this.listeningStatsDays[datestr] === 0) {
|
if (!this.listeningStatsDays[datestr] || this.listeningStatsDays[datestr] === 0) {
|
||||||
|
// don't require listening today to count towards days in a row, but do count it if already listened today
|
||||||
|
const today = this.$formatJsDate(new Date(), 'yyyy-MM-dd')
|
||||||
|
if (this.listeningStatsDays[today]) {
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
|
||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
count++
|
count++
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ export default {
|
|||||||
|
|
||||||
this.showingTooltipIndex = index
|
this.showingTooltipIndex = index
|
||||||
this.tooltipEl.style.display = 'block'
|
this.tooltipEl.style.display = 'block'
|
||||||
this.tooltipTextEl.innerHTML = block.value ? `<strong>${this.$elapsedPretty(block.value, true)} listening</strong> on ${block.datePretty}` : `No listening sessions on ${block.datePretty}`
|
this.tooltipTextEl.innerHTML = block.value ? this.$getString('MessageHeatmapListeningTimeTooltip', [this.$elapsedPrettyLocalized(block.value, true), block.datePretty]) : this.$getString('MessageHeatmapNoListeningSessions', [block.datePretty])
|
||||||
|
|
||||||
const calculateRect = this.tooltipEl.getBoundingClientRect()
|
const calculateRect = this.tooltipEl.getBoundingClientRect()
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-wrap justify-center mt-6">
|
<div class="flex flex-wrap justify-center mt-6">
|
||||||
<div class="flex p-2">
|
<div class="flex p-2">
|
||||||
<svg class="h-14 w-14" viewBox="0 0 24 24">
|
<span class="material-symbols text-5xl py-1">newsstand</span>
|
||||||
<path fill="currentColor" d="M9 3V18H12V3H9M12 5L16 18L19 17L15 4L12 5M5 5V18H8V5H5M3 19V21H21V19H3Z" />
|
|
||||||
</svg>
|
|
||||||
<div class="px-1">
|
<div class="px-1">
|
||||||
<p class="text-4.5xl leading-none font-bold">{{ $formatNumber(totalItems) }}</p>
|
<p class="text-4.5xl leading-none font-bold">{{ $formatNumber(totalItems) }}</p>
|
||||||
<p class="text-xs md:text-sm text-white/80">{{ $strings.LabelStatsItemsInLibrary }}</p>
|
<p class="text-xs md:text-sm text-white/80">{{ $strings.LabelStatsItemsInLibrary }}</p>
|
||||||
@@ -19,9 +17,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="isBookLibrary" class="flex p-2">
|
<div v-if="isBookLibrary" class="flex p-2">
|
||||||
<svg class="h-14 w-14" viewBox="0 0 24 24">
|
<span class="material-symbols text-5xl py-1">person</span>
|
||||||
<path fill="currentColor" d="M12,4A4,4 0 0,1 16,8A4,4 0 0,1 12,12A4,4 0 0,1 8,8A4,4 0 0,1 12,4M12,6A2,2 0 0,0 10,8A2,2 0 0,0 12,10A2,2 0 0,0 14,8A2,2 0 0,0 12,6M12,13C14.67,13 20,14.33 20,17V20H4V17C4,14.33 9.33,13 12,13M12,14.9C9.03,14.9 5.9,16.36 5.9,17V18.1H18.1V17C18.1,16.36 14.97,14.9 12,14.9Z" />
|
|
||||||
</svg>
|
|
||||||
<div class="px-1">
|
<div class="px-1">
|
||||||
<p class="text-4.5xl leading-none font-bold">{{ $formatNumber(totalAuthors) }}</p>
|
<p class="text-4.5xl leading-none font-bold">{{ $formatNumber(totalAuthors) }}</p>
|
||||||
<p class="text-xs md:text-sm text-white/80">{{ $strings.LabelStatsAuthors }}</p>
|
<p class="text-xs md:text-sm text-white/80">{{ $strings.LabelStatsAuthors }}</p>
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
<div v-if="userCanUpdate" class="mx-1" :class="isHovering ? '' : 'ml-6'">
|
<div v-if="userCanUpdate" class="mx-1" :class="isHovering ? '' : 'ml-6'">
|
||||||
<ui-icon-btn icon="edit" borderless @click="clickEdit" />
|
<ui-icon-btn icon="edit" borderless @click="clickEdit" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="userCanDelete" class="mx-1">
|
<div v-if="userCanUpdate" class="mx-1">
|
||||||
<ui-icon-btn icon="close" borderless @click="removeClick" />
|
<ui-icon-btn icon="close" borderless @click="removeClick" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -79,8 +79,7 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
translateDistance() {
|
translateDistance() {
|
||||||
if (!this.userCanUpdate && !this.userCanDelete) return 'translate-x-0'
|
if (!this.userCanUpdate) return 'translate-x-0'
|
||||||
else if (!this.userCanUpdate || !this.userCanDelete) return '-translate-x-12'
|
|
||||||
return '-translate-x-24'
|
return '-translate-x-24'
|
||||||
},
|
},
|
||||||
media() {
|
media() {
|
||||||
@@ -144,9 +143,6 @@ export default {
|
|||||||
},
|
},
|
||||||
userCanUpdate() {
|
userCanUpdate() {
|
||||||
return this.$store.getters['user/getUserCanUpdate']
|
return this.$store.getters['user/getUserCanUpdate']
|
||||||
},
|
|
||||||
userCanDelete() {
|
|
||||||
return this.$store.getters['user/getUserCanDelete']
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="w-40">
|
<div :class="hasSlotContent ? 'w-auto' : 'w-40'">
|
||||||
<div class="bg-bg border border-gray-500 py-2 px-5 rounded-lg flex items-center flex-col box-shadow-md">
|
<div class="bg-bg border border-gray-500 py-2 px-5 rounded-lg flex items-center flex-col box-shadow-md">
|
||||||
<div class="loader-dots block relative w-20 h-5 mt-2">
|
<div class="loader-dots block relative w-20 h-5 mt-2">
|
||||||
<div class="absolute top-0 mt-1 w-3 h-3 rounded-full bg-green-500"></div>
|
<div class="absolute top-0 mt-1 w-3 h-3 rounded-full bg-green-500"></div>
|
||||||
@@ -7,7 +7,9 @@
|
|||||||
<div class="absolute top-0 mt-1 w-3 h-3 rounded-full bg-green-500"></div>
|
<div class="absolute top-0 mt-1 w-3 h-3 rounded-full bg-green-500"></div>
|
||||||
<div class="absolute top-0 mt-1 w-3 h-3 rounded-full bg-green-500"></div>
|
<div class="absolute top-0 mt-1 w-3 h-3 rounded-full bg-green-500"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-gray-200 text-xs font-light mt-2 text-center">{{ message }}</div>
|
<slot>
|
||||||
|
<div class="text-gray-200 text-xs font-light mt-2 text-center">{{ message }}</div>
|
||||||
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -23,6 +25,9 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
message() {
|
message() {
|
||||||
return this.text || this.$strings.MessagePleaseWait
|
return this.text || this.$strings.MessagePleaseWait
|
||||||
|
},
|
||||||
|
hasSlotContent() {
|
||||||
|
return this.$slots.default && this.$slots.default.length > 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,11 @@
|
|||||||
<div ref="wrapper" class="relative">
|
<div ref="wrapper" class="relative">
|
||||||
<form @submit.prevent="submitForm">
|
<form @submit.prevent="submitForm">
|
||||||
<div ref="inputWrapper" role="list" style="min-height: 36px" class="flex-wrap relative w-full shadow-xs flex items-center border border-gray-600 rounded-sm px-2 py-1" :class="wrapperClass" @click.stop.prevent="clickWrapper" @mouseup.stop.prevent @mousedown.prevent>
|
<div ref="inputWrapper" role="list" style="min-height: 36px" class="flex-wrap relative w-full shadow-xs flex items-center border border-gray-600 rounded-sm px-2 py-1" :class="wrapperClass" @click.stop.prevent="clickWrapper" @mouseup.stop.prevent @mousedown.prevent>
|
||||||
<div v-for="item in selected" :key="item" role="listitem" class="rounded-full px-2 py-1 mx-0.5 my-0.5 text-xs bg-bg flex flex-nowrap break-all items-center relative">
|
<!-- Use index in v-for and key in case the same key exists multiple times -->
|
||||||
|
<div v-for="(item, idx) in selected" :key="item + '-' + idx" role="listitem" class="rounded-full px-2 py-1 mx-0.5 my-0.5 text-xs bg-bg flex flex-nowrap break-all items-center relative">
|
||||||
<div v-if="!disabled" class="w-full h-full rounded-full absolute top-0 left-0 px-1 bg-bg/75 flex items-center justify-end opacity-0 hover:opacity-100" :class="{ 'opacity-100': inputFocused }">
|
<div v-if="!disabled" class="w-full h-full rounded-full absolute top-0 left-0 px-1 bg-bg/75 flex items-center justify-end opacity-0 hover:opacity-100" :class="{ 'opacity-100': inputFocused }">
|
||||||
<button v-if="showEdit" type="button" :aria-label="$strings.ButtonEdit" class="material-symbols text-white hover:text-warning cursor-pointer" style="font-size: 1.1rem" @click.stop="editItem(item)">edit</button>
|
<button v-if="showEdit" type="button" :aria-label="$strings.ButtonEdit" class="material-symbols text-white hover:text-warning cursor-pointer" style="font-size: 1.1rem" @click.stop="editItem(item)">edit</button>
|
||||||
<button type="button" :aria-label="$strings.ButtonRemove" class="material-symbols text-white hover:text-error focus:text-error cursor-pointer" style="font-size: 1.1rem" @click.stop="removeItem(item)" @keydown.enter.stop.prevent="removeItem(item)" @focus="setInputFocused(true)" @blur="setInputFocused(false)" tabindex="0">close</button>
|
<button type="button" :aria-label="$strings.ButtonRemove" class="material-symbols text-white hover:text-error focus:text-error cursor-pointer" style="font-size: 1.1rem" @click.stop="removeItem(item, idx)" @keydown.enter.stop.prevent="removeItem(item, idx)" @focus="setInputFocused(true)" @blur="setInputFocused(false)" tabindex="0">close</button>
|
||||||
</div>
|
</div>
|
||||||
{{ item }}
|
{{ item }}
|
||||||
</div>
|
</div>
|
||||||
@@ -259,8 +260,9 @@ export default {
|
|||||||
}
|
}
|
||||||
this.focus()
|
this.focus()
|
||||||
},
|
},
|
||||||
removeItem(item) {
|
removeItem(item, idx) {
|
||||||
var remaining = this.selected.filter((i) => i !== item)
|
var remaining = this.selected.slice()
|
||||||
|
remaining.splice(idx, 1)
|
||||||
this.$emit('input', remaining)
|
this.$emit('input', remaining)
|
||||||
this.$emit('removedItem', item)
|
this.$emit('removedItem', item)
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
@@ -276,7 +278,7 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
insertNewItem(item) {
|
insertNewItem(item) {
|
||||||
this.selected.push(item)
|
if (!this.selected.includes(item)) this.selected.push(item)
|
||||||
this.$emit('input', this.selected)
|
this.$emit('input', this.selected)
|
||||||
this.$emit('newItem', item)
|
this.$emit('newItem', item)
|
||||||
this.textInput = null
|
this.textInput = null
|
||||||
|
|||||||
@@ -287,7 +287,7 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
insertNewItem(item) {
|
insertNewItem(item) {
|
||||||
this.selected.push(item)
|
if (!this.selected.find((i) => i.name === item.name)) this.selected.push(item)
|
||||||
this.$emit('input', this.selected)
|
this.$emit('input', this.selected)
|
||||||
this.$emit('newItem', item)
|
this.$emit('newItem', item)
|
||||||
this.textInput = null
|
this.textInput = null
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<button :aria-label="isRead ? $strings.MessageMarkAsNotFinished : $strings.MessageMarkAsFinished" class="icon-btn rounded-md flex items-center justify-center h-9 w-9 relative" :class="borderless ? '' : 'bg-primary border border-gray-600'" @click="clickBtn">
|
<button :aria-label="isRead ? $strings.MessageMarkAsNotFinished : $strings.MessageMarkAsFinished" class="icon-btn rounded-md flex items-center justify-center h-9 w-9 relative" :class="borderless ? '' : 'bg-primary border border-gray-600'" @click="clickBtn">
|
||||||
<div class="w-5 h-5 text-white relative">
|
<div class="w-5 h-5 relative">
|
||||||
<svg v-if="isRead" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="rgb(63, 181, 68)">
|
<span v-if="isRead" class="material-symbols fill text-xl text-success">beenhere</span>
|
||||||
<path d="M19 1H5c-1.1 0-1.99.9-1.99 2L3 15.93c0 .69.35 1.3.88 1.66L12 23l8.11-5.41c.53-.36.88-.97.88-1.66L21 3c0-1.1-.9-2-2-2zm-9 15l-5-5 1.41-1.41L10 13.17l7.59-7.59L19 7l-9 9z" />
|
<span v-else class="material-symbols text-xl text-white">beenhere</span>
|
||||||
</svg>
|
|
||||||
<svg v-else xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
|
|
||||||
<path d="M19 1H5c-1.1 0-1.99.9-1.99 2L3 15.93c0 .69.35 1.3.88 1.66L12 23l8.11-5.41c.53-.36.88-.97.88-1.66L21 3c0-1.1-.9-2-2-2zm-7 19.6l-7-4.66V3h14v12.93l-7 4.67zm-2.01-7.42l-2.58-2.59L6 12l4 4 8-8-1.42-1.42z" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div ref="wrapper" class="relative">
|
<div ref="wrapper" class="relative">
|
||||||
<input :id="inputId" :name="inputName" ref="input" v-model="inputValue" :type="actualType" :step="step" :min="min" :readonly="readonly" :disabled="disabled" :placeholder="placeholder" dir="auto" class="rounded-sm bg-primary text-gray-200 focus:bg-bg focus:outline-hidden border h-full w-full" :class="classList" @keyup="keyup" @change="change" @focus="focused" @blur="blurred" />
|
<input :id="inputId" :name="inputName" ref="input" v-model="inputValue" :type="actualType" :step="step" :min="min" :readonly="readonly" :disabled="disabled" :placeholder="placeholder" :autocomplete="autocomplete" dir="auto" class="rounded-sm bg-primary text-gray-200 focus:bg-bg focus:outline-hidden border h-full w-full" :class="classList" @keyup="keyup" @change="change" @focus="focused" @blur="blurred" />
|
||||||
<div v-if="clearable && inputValue" class="absolute top-0 right-0 h-full px-2 flex items-center justify-center">
|
<div v-if="clearable && inputValue" class="absolute top-0 right-0 h-full px-2 flex items-center justify-center">
|
||||||
<span class="material-symbols text-gray-300 cursor-pointer" style="font-size: 1.1rem" @click.stop.prevent="clear">close</span>
|
<span class="material-symbols text-gray-300 cursor-pointer" style="font-size: 1.1rem" @click.stop.prevent="clear">close</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -41,7 +41,8 @@ export default {
|
|||||||
step: [String, Number],
|
step: [String, Number],
|
||||||
min: [String, Number],
|
min: [String, Number],
|
||||||
customInputClass: String,
|
customInputClass: String,
|
||||||
trimWhitespace: Boolean
|
trimWhitespace: Boolean,
|
||||||
|
autocomplete: String
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<em v-if="note" class="font-normal text-xs pl-2">{{ note }}</em>
|
<em v-if="note" class="font-normal text-xs pl-2">{{ note }}</em>
|
||||||
</label>
|
</label>
|
||||||
</slot>
|
</slot>
|
||||||
<ui-text-input :placeholder="placeholder || label" :inputId="identifier" ref="input" v-model="inputValue" :disabled="disabled" :readonly="readonly" :type="type" :min="min" :show-copy="showCopy" class="w-full" :class="inputClass" :trim-whitespace="trimWhitespace" @blur="inputBlurred" />
|
<ui-text-input :placeholder="placeholder || label" :inputId="identifier" ref="input" v-model="inputValue" :disabled="disabled" :readonly="readonly" :type="type" :min="min" :show-copy="showCopy" :autocomplete="autocomplete" class="w-full" :class="inputClass" :trim-whitespace="trimWhitespace" @blur="inputBlurred" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -26,7 +26,8 @@ export default {
|
|||||||
disabled: Boolean,
|
disabled: Boolean,
|
||||||
inputClass: String,
|
inputClass: String,
|
||||||
showCopy: Boolean,
|
showCopy: Boolean,
|
||||||
trimWhitespace: Boolean
|
trimWhitespace: Boolean,
|
||||||
|
autocomplete: String
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {}
|
return {}
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ export default {
|
|||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
disabled: Boolean
|
disabled: Boolean,
|
||||||
|
plaintext: Boolean
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -46,7 +47,11 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
updateText() {
|
updateText() {
|
||||||
if (this.tooltip) {
|
if (this.tooltip) {
|
||||||
this.tooltip.innerHTML = this.text
|
if (this.plaintext) {
|
||||||
|
this.tooltip.textContent = this.text
|
||||||
|
} else {
|
||||||
|
this.tooltip.innerHTML = this.text
|
||||||
|
}
|
||||||
this.setTooltipPosition(this.tooltip)
|
this.setTooltipPosition(this.tooltip)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -58,7 +63,11 @@ export default {
|
|||||||
tooltip.className = 'tooltip-wrapper absolute px-2 py-1 text-white text-xs rounded-sm shadow-lg max-w-xs text-center hidden sm:block'
|
tooltip.className = 'tooltip-wrapper absolute px-2 py-1 text-white text-xs rounded-sm shadow-lg max-w-xs text-center hidden sm:block'
|
||||||
tooltip.style.zIndex = 100
|
tooltip.style.zIndex = 100
|
||||||
tooltip.style.backgroundColor = 'rgba(0,0,0,0.85)'
|
tooltip.style.backgroundColor = 'rgba(0,0,0,0.85)'
|
||||||
tooltip.innerHTML = this.text
|
if (this.plaintext) {
|
||||||
|
tooltip.textContent = this.text
|
||||||
|
} else {
|
||||||
|
tooltip.innerHTML = this.text
|
||||||
|
}
|
||||||
tooltip.addEventListener('mouseover', this.cancelHide)
|
tooltip.addEventListener('mouseover', this.cancelHide)
|
||||||
tooltip.addEventListener('mouseleave', this.hideTooltip)
|
tooltip.addEventListener('mouseleave', this.hideTooltip)
|
||||||
|
|
||||||
|
|||||||
@@ -1,40 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<ui-tooltip :text="$strings.LabelExplicit" direction="top">
|
<ui-tooltip :text="$strings.LabelExplicit" direction="top">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="12px" height="12px" viewBox="0 0 512 512" class="ml-1">
|
<span class="material-symbols fill text-sm ml-1 !block">explicit</span>
|
||||||
<path
|
|
||||||
fill="white"
|
|
||||||
d="M 89.00,40.12
|
|
||||||
C 89.00,40.12 127.00,40.12 127.00,40.12
|
|
||||||
127.00,40.12 198.00,40.12 198.00,40.12
|
|
||||||
198.00,40.12 416.00,40.12 416.00,40.12
|
|
||||||
446.58,40.05 472.95,66.42 473.00,97.00
|
|
||||||
473.00,97.00 473.00,303.00 473.00,303.00
|
|
||||||
473.00,303.00 473.00,418.00 473.00,418.00
|
|
||||||
472.65,447.55 445.06,472.95 416.00,473.00
|
|
||||||
416.00,473.00 210.00,473.00 210.00,473.00
|
|
||||||
210.00,473.00 95.00,473.00 95.00,473.00
|
|
||||||
65.45,472.65 40.05,445.06 40.00,416.00
|
|
||||||
40.00,416.00 40.00,136.00 40.00,136.00
|
|
||||||
40.00,136.00 40.00,109.00 40.00,109.00
|
|
||||||
40.00,109.00 40.00,96.00 40.00,96.00
|
|
||||||
40.07,81.58 46.89,67.14 57.01,57.01
|
|
||||||
61.17,52.86 64.86,50.13 70.00,47.31
|
|
||||||
77.25,43.33 81.02,42.18 89.00,40.12 Z
|
|
||||||
M 337.00,121.00
|
|
||||||
C 337.00,121.00 175.00,121.00 175.00,121.00
|
|
||||||
175.00,121.00 175.00,392.00 175.00,392.00
|
|
||||||
175.00,392.00 337.00,392.00 337.00,392.00
|
|
||||||
337.00,392.00 337.00,349.00 337.00,349.00
|
|
||||||
337.00,349.00 226.00,349.00 226.00,349.00
|
|
||||||
226.00,349.00 226.00,274.00 226.00,274.00
|
|
||||||
226.00,274.00 332.00,274.00 332.00,274.00
|
|
||||||
332.00,274.00 332.00,232.00 332.00,232.00
|
|
||||||
332.00,232.00 226.00,232.00 226.00,232.00
|
|
||||||
226.00,232.00 226.00,164.00 226.00,164.00
|
|
||||||
226.00,164.00 337.00,164.00 337.00,164.00
|
|
||||||
337.00,164.00 337.00,121.00 337.00,121.00 Z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -132,10 +132,10 @@ export default {
|
|||||||
editAuthor(author) {
|
editAuthor(author) {
|
||||||
this.$store.commit('globals/showEditAuthorModal', author)
|
this.$store.commit('globals/showEditAuthorModal', author)
|
||||||
},
|
},
|
||||||
editItem(libraryItem) {
|
editItem(libraryItem, tab = 'details') {
|
||||||
var itemIds = this.items.map((e) => e.id)
|
var itemIds = this.items.map((e) => e.id)
|
||||||
this.$store.commit('setBookshelfBookIds', itemIds)
|
this.$store.commit('setBookshelfBookIds', itemIds)
|
||||||
this.$store.commit('showEditModal', libraryItem)
|
this.$store.commit('showEditModalOnTab', { libraryItem, tab: tab || 'details' })
|
||||||
},
|
},
|
||||||
selectItem(payload) {
|
selectItem(payload) {
|
||||||
this.$emit('selectEntity', payload)
|
this.$emit('selectEntity', payload)
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ export default {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.error('User has no more accessible libraries')
|
console.error('User has no more accessible libraries')
|
||||||
this.$store.commit('libraries/setCurrentLibrary', null)
|
this.$store.commit('libraries/setCurrentLibrary', { id: null })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -371,11 +371,13 @@ export default {
|
|||||||
},
|
},
|
||||||
customMetadataProviderAdded(provider) {
|
customMetadataProviderAdded(provider) {
|
||||||
if (!provider?.id) return
|
if (!provider?.id) return
|
||||||
this.$store.commit('scanners/addCustomMetadataProvider', provider)
|
// Refresh providers cache
|
||||||
|
this.$store.dispatch('scanners/refreshProviders')
|
||||||
},
|
},
|
||||||
customMetadataProviderRemoved(provider) {
|
customMetadataProviderRemoved(provider) {
|
||||||
if (!provider?.id) return
|
if (!provider?.id) return
|
||||||
this.$store.commit('scanners/removeCustomMetadataProvider', provider)
|
// Refresh providers cache
|
||||||
|
this.$store.dispatch('scanners/refreshProviders')
|
||||||
},
|
},
|
||||||
initializeSocket() {
|
initializeSocket() {
|
||||||
if (this.$root.socket) {
|
if (this.$root.socket) {
|
||||||
|
|||||||
@@ -118,8 +118,8 @@ export default {
|
|||||||
propsData: props,
|
propsData: props,
|
||||||
parent: this,
|
parent: this,
|
||||||
created() {
|
created() {
|
||||||
this.$on('edit', (entity) => {
|
this.$on('edit', (entity, tab) => {
|
||||||
if (_this.editEntity) _this.editEntity(entity)
|
if (_this.editEntity) _this.editEntity(entity, tab)
|
||||||
})
|
})
|
||||||
this.$on('select', ({ entity, shiftKey }) => {
|
this.$on('select', ({ entity, shiftKey }) => {
|
||||||
if (_this.selectEntity) _this.selectEntity(entity, shiftKey)
|
if (_this.selectEntity) _this.selectEntity(entity, shiftKey)
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ module.exports = {
|
|||||||
proxy,
|
proxy,
|
||||||
|
|
||||||
io: {
|
io: {
|
||||||
|
server: false,
|
||||||
sockets: [
|
sockets: [
|
||||||
{
|
{
|
||||||
name: 'dev',
|
name: 'dev',
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "audiobookshelf-client",
|
"name": "audiobookshelf-client",
|
||||||
"version": "2.26.1",
|
"version": "3.0.0-beta",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "audiobookshelf-client",
|
"name": "audiobookshelf-client",
|
||||||
"version": "2.26.0",
|
"version": "3.0.0-beta",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nuxtjs/axios": "^5.13.6",
|
"@nuxtjs/axios": "^5.13.6",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "audiobookshelf-client",
|
"name": "audiobookshelf-client",
|
||||||
"version": "2.26.1",
|
"version": "3.0.0-beta",
|
||||||
"buildNumber": 1,
|
"buildNumber": 1,
|
||||||
"description": "Self-hosted audiobook and podcast client",
|
"description": "Self-hosted audiobook and podcast client",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
|
|||||||
+142
-5
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="page-wrapper" class="page p-6 overflow-y-auto relative" :class="streamLibraryItem ? 'streaming' : ''">
|
<div id="page-wrapper" class="page p-6 overflow-y-auto relative" :class="streamLibraryItem ? 'streaming' : ''">
|
||||||
<div class="w-full max-w-xl mx-auto">
|
<div class="w-full max-w-2xl mx-auto">
|
||||||
<h1 class="text-2xl">{{ $strings.HeaderAccount }}</h1>
|
<h1 class="text-2xl">{{ $strings.HeaderAccount }}</h1>
|
||||||
|
|
||||||
<div class="my-4">
|
<div class="my-4">
|
||||||
@@ -69,8 +69,52 @@
|
|||||||
</app-settings-content>
|
</app-settings-content>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="py-4 mt-8 flex">
|
<div v-if="!isGuest">
|
||||||
<ui-btn color="bg-primary flex items-center text-lg" @click="logout"><span class="material-symbols mr-4 icon-text">logout</span>{{ $strings.ButtonLogout }}</ui-btn>
|
<div class="w-full h-px bg-white/10 my-4" />
|
||||||
|
|
||||||
|
<app-settings-content :header-text="$strings.HeaderSessions">
|
||||||
|
<table v-if="authSessions.length" class="tracksTable mt-4 table-fixed w-full">
|
||||||
|
<tr>
|
||||||
|
<th class="text-left">{{ $strings.LabelDeviceInfo }}</th>
|
||||||
|
<th class="text-left hidden sm:table-cell w-36">{{ $strings.LabelIpAddress }}</th>
|
||||||
|
<th class="text-left w-30 sm:w-40">{{ $strings.LabelLastUpdate }}</th>
|
||||||
|
<th class="w-12"></th>
|
||||||
|
</tr>
|
||||||
|
<tr v-for="session in authSessions" :key="session.id">
|
||||||
|
<td class="max-w-0">
|
||||||
|
<div class="flex items-center gap-0.5 min-w-0">
|
||||||
|
<span class="text-sm text-gray-100 truncate min-w-0" :title="session.userAgent">{{ getSessionDeviceLabel(session) }}</span>
|
||||||
|
<ui-tooltip v-if="session.current" direction="top" :text="$strings.LabelCurrent" class="inline-flex shrink-0">
|
||||||
|
<span class="material-symbols text-success text-sm leading-none">check</span>
|
||||||
|
</ui-tooltip>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="hidden sm:table-cell w-36">
|
||||||
|
<p class="text-sm text-gray-100 truncate" :title="session.ipAddress">{{ session.ipAddress || '-' }}</p>
|
||||||
|
</td>
|
||||||
|
<td class="w-30 sm:w-40">
|
||||||
|
<ui-tooltip v-if="session.updatedAt" direction="top" :text="$formatDatetime(session.updatedAt, dateFormat, timeFormat)">
|
||||||
|
<p class="text-xs sm:text-sm text-gray-100">{{ $dateDistanceFromNow(session.updatedAt) }}</p>
|
||||||
|
</ui-tooltip>
|
||||||
|
</td>
|
||||||
|
<td class="w-12">
|
||||||
|
<div class="flex justify-end items-center h-10">
|
||||||
|
<ui-icon-btn icon="delete" borderless :size="8" icon-font-size="1.1rem" :disabled="deletingSessionId === session.id || loadingAuthSessions" @click="deleteAuthSessionClick(session)" />
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<div v-if="authSessionsNumPages > 1" class="flex items-center justify-end py-1">
|
||||||
|
<ui-icon-btn icon="arrow_back_ios_new" :size="7" icon-font-size="1rem" class="mx-1" :disabled="loadingAuthSessions || authSessionsPage === 0" @click="prevAuthSessionsPage" />
|
||||||
|
<p class="text-sm mx-1">{{ $getString('LabelPaginationPageXOfY', [authSessionsPage + 1, authSessionsNumPages]) }}</p>
|
||||||
|
<ui-icon-btn icon="arrow_forward_ios" :size="7" icon-font-size="1rem" class="mx-1" :disabled="loadingAuthSessions || authSessionsPage >= authSessionsNumPages - 1" @click="nextAuthSessionsPage" />
|
||||||
|
</div>
|
||||||
|
</app-settings-content>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="py-4 mt-8 flex flex-wrap gap-2">
|
||||||
|
<ui-btn v-if="!isGuest" color="bg-primary flex items-center text-lg" :disabled="loggingOut" @click="logout(true)"> <span class="material-symbols mr-4 icon-text">devices</span>{{ $strings.ButtonLogoutAllDevices }} </ui-btn>
|
||||||
|
<ui-btn color="bg-primary flex items-center text-lg" :disabled="loggingOut" @click="logout(false)"><span class="material-symbols mr-4 icon-text">logout</span>{{ $strings.ButtonLogout }}</ui-btn>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<modals-emails-user-e-reader-device-modal v-model="showEReaderDeviceModal" :existing-devices="revisedEreaderDevices" :ereader-device="selectedEReaderDevice" @update="ereaderDevicesUpdated" />
|
<modals-emails-user-e-reader-device-modal v-model="showEReaderDeviceModal" :existing-devices="revisedEreaderDevices" :ereader-device="selectedEReaderDevice" @update="ereaderDevicesUpdated" />
|
||||||
@@ -87,6 +131,13 @@ export default {
|
|||||||
newPassword: null,
|
newPassword: null,
|
||||||
confirmPassword: null,
|
confirmPassword: null,
|
||||||
changingPassword: false,
|
changingPassword: false,
|
||||||
|
loggingOut: false,
|
||||||
|
authSessions: [],
|
||||||
|
authSessionsPage: 0,
|
||||||
|
authSessionsNumPages: 0,
|
||||||
|
authSessionsItemsPerPage: 10,
|
||||||
|
loadingAuthSessions: false,
|
||||||
|
deletingSessionId: null,
|
||||||
selectedLanguage: '',
|
selectedLanguage: '',
|
||||||
newEReaderDevice: {
|
newEReaderDevice: {
|
||||||
name: '',
|
name: '',
|
||||||
@@ -129,13 +180,19 @@ export default {
|
|||||||
},
|
},
|
||||||
revisedEreaderDevices() {
|
revisedEreaderDevices() {
|
||||||
return this.ereaderDevices.filter((device) => device.users?.length === 1)
|
return this.ereaderDevices.filter((device) => device.users?.length === 1)
|
||||||
|
},
|
||||||
|
dateFormat() {
|
||||||
|
return this.$store.getters['getServerSetting']('dateFormat')
|
||||||
|
},
|
||||||
|
timeFormat() {
|
||||||
|
return this.$store.getters['getServerSetting']('timeFormat')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
updateLocalLanguage(lang) {
|
updateLocalLanguage(lang) {
|
||||||
this.$setLanguageCode(lang)
|
this.$setLanguageCode(lang)
|
||||||
},
|
},
|
||||||
logout() {
|
logout(allDevices = false) {
|
||||||
// Disconnect from socket
|
// Disconnect from socket
|
||||||
if (this.$root.socket) {
|
if (this.$root.socket) {
|
||||||
console.log('Disconnecting from socket', this.$root.socket.id)
|
console.log('Disconnecting from socket', this.$root.socket.id)
|
||||||
@@ -149,8 +206,10 @@ export default {
|
|||||||
this.$store.commit('libraries/setUserPlaylists', [])
|
this.$store.commit('libraries/setUserPlaylists', [])
|
||||||
this.$store.commit('libraries/setCollections', [])
|
this.$store.commit('libraries/setCollections', [])
|
||||||
|
|
||||||
|
this.loggingOut = true
|
||||||
|
const url = allDevices ? '/logout?allDevices=1' : '/logout'
|
||||||
this.$axios
|
this.$axios
|
||||||
.$post('/logout')
|
.$post(url)
|
||||||
.then((logoutPayload) => {
|
.then((logoutPayload) => {
|
||||||
const redirect_url = logoutPayload.redirect_url
|
const redirect_url = logoutPayload.redirect_url
|
||||||
|
|
||||||
@@ -163,6 +222,9 @@ export default {
|
|||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
})
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loggingOut = false
|
||||||
|
})
|
||||||
},
|
},
|
||||||
resetForm() {
|
resetForm() {
|
||||||
this.password = null
|
this.password = null
|
||||||
@@ -238,11 +300,86 @@ export default {
|
|||||||
},
|
},
|
||||||
ereaderDevicesUpdated(ereaderDevices) {
|
ereaderDevicesUpdated(ereaderDevices) {
|
||||||
this.ereaderDevices = ereaderDevices
|
this.ereaderDevices = ereaderDevices
|
||||||
|
},
|
||||||
|
loadAuthSessions(page = 0) {
|
||||||
|
if (this.loadingAuthSessions) return
|
||||||
|
if (page < 0) return
|
||||||
|
if (this.authSessionsNumPages > 0 && page > this.authSessionsNumPages - 1) return
|
||||||
|
|
||||||
|
this.loadingAuthSessions = true
|
||||||
|
this.$axios
|
||||||
|
.$get(`/api/me/sessions?page=${page}&itemsPerPage=${this.authSessionsItemsPerPage}`)
|
||||||
|
.then((data) => {
|
||||||
|
this.authSessions = data.sessions || []
|
||||||
|
this.authSessionsPage = data.page ?? page
|
||||||
|
this.authSessionsNumPages = data.numPages ?? 0
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Failed to load sessions', error)
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loadingAuthSessions = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
prevAuthSessionsPage() {
|
||||||
|
if (this.authSessionsPage <= 0) return
|
||||||
|
this.loadAuthSessions(this.authSessionsPage - 1)
|
||||||
|
},
|
||||||
|
nextAuthSessionsPage() {
|
||||||
|
if (this.authSessionsPage >= this.authSessionsNumPages - 1) return
|
||||||
|
this.loadAuthSessions(this.authSessionsPage + 1)
|
||||||
|
},
|
||||||
|
deleteAuthSessionClick(session) {
|
||||||
|
this.$store.commit('globals/setConfirmPrompt', {
|
||||||
|
message: this.$getString('MessageConfirmLogoutDevice', [this.getSessionDeviceLabel(session)]),
|
||||||
|
callback: (confirmed) => {
|
||||||
|
if (confirmed) this.deleteAuthSession(session)
|
||||||
|
},
|
||||||
|
type: 'yesNo'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
deleteAuthSession(session) {
|
||||||
|
// Call logout instead for current session
|
||||||
|
if (session.current) {
|
||||||
|
this.logout(false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.deletingSessionId = session.id
|
||||||
|
this.$axios
|
||||||
|
.$delete(`/api/me/sessions/${session.id}`)
|
||||||
|
.then(() => {
|
||||||
|
if (this.authSessions.length === 1 && this.authSessionsPage > 0) {
|
||||||
|
this.loadAuthSessions(this.authSessionsPage - 1)
|
||||||
|
} else {
|
||||||
|
this.loadAuthSessions(this.authSessionsPage)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Failed to delete session', error)
|
||||||
|
this.$toast.error(this.$strings.ToastFailedToDelete)
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.deletingSessionId = null
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getSessionDeviceLabel(session) {
|
||||||
|
const deviceInfo = session.deviceInfo
|
||||||
|
if (!deviceInfo) return session.userAgent || '-'
|
||||||
|
|
||||||
|
const parts = []
|
||||||
|
if (deviceInfo.model) parts.push(deviceInfo.model)
|
||||||
|
if (deviceInfo.osName) parts.push(`${deviceInfo.osName}${deviceInfo.osVersion ? ` ${deviceInfo.osVersion}` : ''}`)
|
||||||
|
if (deviceInfo.browserName) parts.push(deviceInfo.browserName)
|
||||||
|
return parts.join(' / ') || session.userAgent || '-'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.selectedLanguage = this.$languageCodes.current
|
this.selectedLanguage = this.$languageCodes.current
|
||||||
this.ereaderDevices = this.$store.state.libraries.ereaderDevices || []
|
this.ereaderDevices = this.$store.state.libraries.ereaderDevices || []
|
||||||
|
if (!this.isGuest) {
|
||||||
|
this.loadAuthSessions()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -12,24 +12,24 @@
|
|||||||
<p class="text-base font-mono ml-4 hidden md:block">{{ $secondsToTimestamp(mediaDurationRounded) }}</p>
|
<p class="text-base font-mono ml-4 hidden md:block">{{ $secondsToTimestamp(mediaDurationRounded) }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-wrap-reverse lg:flex-nowrap justify-center py-4 px-4">
|
<div class="flex flex-wrap-reverse min-[1120px]:flex-nowrap justify-center py-4 px-4">
|
||||||
<div class="w-full max-w-3xl py-4">
|
<div class="w-full max-w-3xl py-4">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="w-12 hidden lg:block" />
|
<div class="w-12 hidden min-w-[1120px]:block" />
|
||||||
<p class="text-lg mb-4 font-semibold">{{ $strings.HeaderChapters }}</p>
|
<p class="text-lg mb-4 font-semibold">{{ $strings.HeaderChapters }}</p>
|
||||||
<div class="grow" />
|
<div class="grow" />
|
||||||
<ui-checkbox v-model="showSecondInputs" checkbox-bg="primary" small label-class="text-sm text-gray-200 pl-1" :label="$strings.LabelShowSeconds" class="mx-2" />
|
<ui-checkbox v-model="showSecondInputs" checkbox-bg="primary" small label-class="text-sm text-gray-200 pl-1" :label="$strings.LabelShowSeconds" class="mx-2" />
|
||||||
<div class="w-32 hidden lg:block" />
|
<div class="w-32 hidden min-[1120px]:block" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center mb-3 py-1 -mx-1">
|
<div class="flex items-center mb-3 py-1 -mx-1">
|
||||||
<div class="w-12 hidden lg:block" />
|
<div class="w-12 hidden min-[1120px]:block" />
|
||||||
<ui-btn v-if="chapters.length" color="bg-primary" small class="mx-1 whitespace-nowrap" @click.stop="removeAllChaptersClick">{{ $strings.ButtonRemoveAll }}</ui-btn>
|
<ui-btn v-if="chapters.length" color="bg-primary" small class="mx-1 whitespace-nowrap" @click.stop="removeAllChaptersClick">{{ $strings.ButtonRemoveAll }}</ui-btn>
|
||||||
<ui-btn v-if="newChapters.length > 1" :color="showShiftTimes ? 'bg-bg' : 'bg-primary'" class="mx-1 whitespace-nowrap" small @click="showShiftTimes = !showShiftTimes">{{ $strings.ButtonShiftTimes }}</ui-btn>
|
<ui-btn v-if="newChapters.length > 1" :color="showShiftTimes ? 'bg-bg' : 'bg-primary'" class="mx-1 whitespace-nowrap" small @click="showShiftTimes = !showShiftTimes">{{ $strings.ButtonShiftTimes }}</ui-btn>
|
||||||
<ui-btn color="bg-primary" small :class="{ 'mx-1': newChapters.length > 1 }" @click="showFindChaptersModal = true">{{ $strings.ButtonLookup }}</ui-btn>
|
<ui-btn color="bg-primary" small :class="{ 'mx-1': newChapters.length > 1 }" @click="showFindChaptersModal = true">{{ $strings.ButtonLookup }}</ui-btn>
|
||||||
<div class="grow" />
|
<div class="grow" />
|
||||||
<ui-btn v-if="hasChanges" small class="mx-1" @click.stop="resetChapters">{{ $strings.ButtonReset }}</ui-btn>
|
<ui-btn v-if="hasChanges" small class="mx-1" @click.stop="resetChapters">{{ $strings.ButtonReset }}</ui-btn>
|
||||||
<ui-btn v-if="hasChanges" color="bg-success" class="mx-1" :disabled="!hasChanges" small @click="saveChapters">{{ $strings.ButtonSave }}</ui-btn>
|
<ui-btn v-if="hasChanges" color="bg-success" class="mx-1" :disabled="!hasChanges" small @click="saveChapters">{{ $strings.ButtonSave }}</ui-btn>
|
||||||
<div class="w-32 hidden lg:block" />
|
<div class="w-32 hidden min-[1120px]:block" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="overflow-hidden">
|
<div class="overflow-hidden">
|
||||||
@@ -53,54 +53,104 @@
|
|||||||
|
|
||||||
<div class="flex text-xs uppercase text-gray-300 font-semibold mb-2">
|
<div class="flex text-xs uppercase text-gray-300 font-semibold mb-2">
|
||||||
<div class="w-8 min-w-8 md:w-12 md:min-w-12"></div>
|
<div class="w-8 min-w-8 md:w-12 md:min-w-12"></div>
|
||||||
<div class="w-24 min-w-24 md:w-32 md:min-w-32 px-2">{{ $strings.LabelStart }}</div>
|
<div class="w-38 min-w-38 md:w-40 md:min-w-40 px-1 pl-8">{{ $strings.LabelStart }}</div>
|
||||||
<div class="grow px-2">{{ $strings.LabelTitle }}</div>
|
<div class="grow px-1 min-w-54">{{ $strings.LabelTitle }}</div>
|
||||||
|
<div class="w-7 min-w-7 px-1 flex items-center justify-center">
|
||||||
|
<ui-tooltip :text="allChaptersLocked ? $strings.TooltipUnlockAllChapters : $strings.TooltipLockAllChapters" direction="bottom">
|
||||||
|
<button class="w-7 h-7 rounded-full flex items-center justify-center cursor-pointer transition-colors duration-150" :class="allChaptersLocked ? 'text-orange-400 hover:text-orange-300' : 'text-gray-300 hover:text-white'" @click="toggleAllChaptersLock">
|
||||||
|
<span class="material-symbols text-xl">{{ allChaptersLocked ? 'lock' : 'lock_open' }}</span>
|
||||||
|
</button>
|
||||||
|
</ui-tooltip>
|
||||||
|
</div>
|
||||||
<div class="w-32"></div>
|
<div class="w-32"></div>
|
||||||
</div>
|
</div>
|
||||||
<template v-for="chapter in newChapters">
|
<div v-for="chapter in newChapters" :key="chapter.id" class="flex py-1">
|
||||||
<div :key="chapter.id" class="flex py-1">
|
<div class="w-8 min-w-8 md:w-12 md:min-w-12">#{{ chapter.id + 1 }}</div>
|
||||||
<div class="w-8 min-w-8 md:w-12 md:min-w-12">#{{ chapter.id + 1 }}</div>
|
<div class="w-38 min-w-38 md:w-40 md:min-w-40 px-1">
|
||||||
<div class="w-24 min-w-24 md:w-32 md:min-w-32 px-1">
|
<div class="flex items-center gap-1">
|
||||||
<ui-text-input v-if="showSecondInputs" v-model="chapter.start" type="number" class="text-xs" @change="checkChapters" />
|
<ui-tooltip :text="$strings.TooltipSubtractOneSecond" direction="bottom">
|
||||||
<ui-time-picker v-else class="text-xs" v-model="chapter.start" :show-three-digit-hour="mediaDuration >= 360000" @change="checkChapters" />
|
<button
|
||||||
</div>
|
class="w-6 h-6 rounded-full flex items-center justify-center text-gray-300 hover:text-white transform hover:scale-110 duration-150 flex-shrink-0"
|
||||||
<div class="grow px-1">
|
:class="{ 'opacity-50 cursor-not-allowed': chapter.id === 0 && chapter.start - timeIncrementAmount < 0 }"
|
||||||
<ui-text-input v-model="chapter.title" @change="checkChapters" class="text-xs min-w-52" />
|
@click="incrementChapterTime(chapter, -timeIncrementAmount)"
|
||||||
</div>
|
:disabled="chapter.id === 0 && chapter.start - timeIncrementAmount < 0"
|
||||||
<div class="w-32 min-w-32 px-2 py-1">
|
>
|
||||||
<div class="flex items-center">
|
<span class="material-symbols text-sm">remove</span>
|
||||||
<ui-tooltip :text="$strings.MessageRemoveChapter" direction="bottom">
|
</button>
|
||||||
<button v-if="newChapters.length > 1" class="w-7 h-7 rounded-full flex items-center justify-center text-gray-300 hover:text-error transform hover:scale-110 duration-150" @click="removeChapter(chapter)">
|
</ui-tooltip>
|
||||||
<span class="material-symbols text-base">remove</span>
|
|
||||||
</button>
|
|
||||||
</ui-tooltip>
|
|
||||||
|
|
||||||
<ui-tooltip :text="$strings.MessageInsertChapterBelow" direction="bottom">
|
<div class="flex-1 min-w-0">
|
||||||
<button class="w-7 h-7 rounded-full flex items-center justify-center text-gray-300 hover:text-success transform hover:scale-110 duration-150" @click="addChapter(chapter)">
|
<ui-text-input v-if="showSecondInputs" v-model="chapter.start" type="number" class="text-xs" @change="checkChapters" />
|
||||||
<span class="material-symbols text-lg">add</span>
|
<ui-time-picker v-else class="text-xs" v-model="chapter.start" :show-three-digit-hour="mediaDuration >= 360000" @change="checkChapters" />
|
||||||
</button>
|
|
||||||
</ui-tooltip>
|
|
||||||
|
|
||||||
<ui-tooltip :text="selectedChapterId === chapter.id && isPlayingChapter ? $strings.MessagePauseChapter : $strings.MessagePlayChapter" direction="bottom">
|
|
||||||
<button class="w-7 h-7 rounded-full flex items-center justify-center text-gray-300 hover:text-white transform hover:scale-110 duration-150" @click="playChapter(chapter)">
|
|
||||||
<widgets-loading-spinner v-if="selectedChapterId === chapter.id && isLoadingChapter" />
|
|
||||||
<span v-else-if="selectedChapterId === chapter.id && isPlayingChapter" class="material-symbols text-base">pause</span>
|
|
||||||
<span v-else class="material-symbols text-base">play_arrow</span>
|
|
||||||
</button>
|
|
||||||
</ui-tooltip>
|
|
||||||
|
|
||||||
<ui-tooltip v-if="chapter.error" :text="chapter.error" direction="left">
|
|
||||||
<button class="w-7 h-7 rounded-full flex items-center justify-center text-error">
|
|
||||||
<span class="material-symbols text-lg">error_outline</span>
|
|
||||||
</button>
|
|
||||||
</ui-tooltip>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<ui-tooltip :text="$strings.TooltipAddOneSecond" direction="bottom">
|
||||||
|
<button class="w-6 h-6 rounded-full flex items-center justify-center text-gray-300 hover:text-white transform hover:scale-110 duration-150 flex-shrink-0" :class="{ 'opacity-50 cursor-not-allowed': chapter.start + timeIncrementAmount >= mediaDuration }" @click="incrementChapterTime(chapter, timeIncrementAmount)" :disabled="chapter.start + timeIncrementAmount >= mediaDuration">
|
||||||
|
<span class="material-symbols text-sm">add</span>
|
||||||
|
</button>
|
||||||
|
</ui-tooltip>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
<div class="grow px-1">
|
||||||
|
<ui-text-input v-model="chapter.title" @change="checkChapters" class="text-xs min-w-52" />
|
||||||
|
</div>
|
||||||
|
<div class="w-7 min-w-7 px-1 py-1">
|
||||||
|
<div class="flex items-center justify-center">
|
||||||
|
<ui-tooltip :text="lockedChapters.has(chapter.id) ? $strings.TooltipUnlockChapter : $strings.TooltipLockChapter" direction="bottom">
|
||||||
|
<button class="w-7 h-7 rounded-full flex items-center justify-center transform hover:scale-110 duration-150 flex-shrink-0" :class="lockedChapters.has(chapter.id) ? 'text-orange-400 hover:text-orange-300' : 'text-gray-300 hover:text-white'" @click="toggleChapterLock(chapter, $event)">
|
||||||
|
<span class="material-symbols text-base">{{ lockedChapters.has(chapter.id) ? 'lock' : 'lock_open' }}</span>
|
||||||
|
</button>
|
||||||
|
</ui-tooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="w-32 min-w-32 px-2 py-1">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<ui-tooltip :text="$strings.MessageRemoveChapter" direction="bottom">
|
||||||
|
<button v-if="newChapters.length > 1" class="w-7 h-7 rounded-full flex items-center justify-center text-gray-300 hover:text-error transform hover:scale-110 duration-150" @click="removeChapter(chapter)">
|
||||||
|
<span class="material-symbols text-base">delete</span>
|
||||||
|
</button>
|
||||||
|
</ui-tooltip>
|
||||||
|
|
||||||
|
<ui-tooltip :text="$strings.MessageInsertChapterBelow" direction="bottom">
|
||||||
|
<button class="w-7 h-7 rounded-full flex items-center justify-center text-gray-300 hover:text-success transform hover:scale-110 duration-150" @click="addChapter(chapter)">
|
||||||
|
<span class="material-symbols text-lg">add_row_below</span>
|
||||||
|
</button>
|
||||||
|
</ui-tooltip>
|
||||||
|
<ui-tooltip :text="selectedChapterId === chapter.id && isPlayingChapter ? $strings.MessagePauseChapter : $strings.MessagePlayChapter" direction="bottom">
|
||||||
|
<button :disabled="!getAudioTrackForTime(chapter.start)" class="w-7 h-7 rounded-full flex items-center justify-center text-gray-300 hover:text-white transform hover:scale-110 duration-150 disabled:opacity-50 disabled:cursor-not-allowed" @click="playChapter(chapter)">
|
||||||
|
<widgets-loading-spinner v-if="selectedChapterId === chapter.id && isLoadingChapter" />
|
||||||
|
<span v-else-if="selectedChapterId === chapter.id && isPlayingChapter" class="material-symbols text-base">pause</span>
|
||||||
|
<span v-else class="material-symbols text-xl">play_arrow</span>
|
||||||
|
</button>
|
||||||
|
</ui-tooltip>
|
||||||
|
<ui-tooltip v-if="selectedChapterId === chapter.id && (isPlayingChapter || isLoadingChapter)" :text="$strings.TooltipAdjustChapterStart" direction="bottom">
|
||||||
|
<div class="ml-2 text-xs text-gray-300 font-mono min-w-10 cursor-pointer hover:text-white transition-colors duration-150" @click="adjustChapterStartTime(chapter)">{{ elapsedTime }}s</div>
|
||||||
|
</ui-tooltip>
|
||||||
|
<ui-tooltip v-if="chapter.error" :text="chapter.error" plaintext direction="left">
|
||||||
|
<button class="w-7 h-7 rounded-full flex items-center justify-center text-error">
|
||||||
|
<span class="material-symbols text-lg">error_outline</span>
|
||||||
|
</button>
|
||||||
|
</ui-tooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center mt-4 mb-2">
|
||||||
|
<div class="w-8 min-w-8 md:w-12 md:min-w-12"></div>
|
||||||
|
<div class="w-38 min-w-38 md:w-40 md:min-w-40 px-1"></div>
|
||||||
|
<div class="flex items-center gap-2 grow px-1">
|
||||||
|
<ui-text-input v-model="bulkChapterInput" :placeholder="$strings.PlaceholderBulkChapterInput" class="text-xs grow min-w-52" @keyup.enter="handleBulkChapterAdd" />
|
||||||
|
</div>
|
||||||
|
<div class="w-39 min-w-39 px-1 py-1">
|
||||||
|
<ui-tooltip :text="$strings.TooltipAddChapters" direction="bottom" class="inline-block align-middle">
|
||||||
|
<button class="w-5 h-5 rounded-full flex items-center justify-center text-gray-300 hover:text-success transform hover:scale-110 duration-150 flex-shrink-0" :aria-label="$strings.TooltipAddChapters" :class="{ 'opacity-50 cursor-not-allowed': !bulkChapterInput.trim() }" :disabled="!bulkChapterInput.trim()" @click="handleBulkChapterAdd">
|
||||||
|
<span class="material-symbols text-lg">add</span>
|
||||||
|
</button>
|
||||||
|
</ui-tooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="w-full max-w-xl py-4 px-2">
|
<div class="w-full max-w-3xl min-[1120px]:max-w-xl py-4 px-2">
|
||||||
<div class="flex items-center mb-4 py-1">
|
<div class="flex items-center mb-4 py-1">
|
||||||
<p class="text-lg font-semibold">{{ $strings.HeaderAudioTracks }}</p>
|
<p class="text-lg font-semibold">{{ $strings.HeaderAudioTracks }}</p>
|
||||||
<div class="grow" />
|
<div class="grow" />
|
||||||
@@ -110,23 +160,19 @@
|
|||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex text-xs uppercase text-gray-300 font-semibold mb-2">
|
<div class="flex text-xs uppercase text-gray-300 font-semibold mb-2">
|
||||||
<div class="grow">{{ $strings.LabelFilename }}</div>
|
<div class="grow min-[1120px]:max-w-64 xl:max-w-sm">{{ $strings.LabelFilename }}</div>
|
||||||
<div class="w-20">{{ $strings.LabelDuration }}</div>
|
<div class="w-20">{{ $strings.LabelDuration }}</div>
|
||||||
<div class="w-20 hidden md:block text-center">{{ $strings.HeaderChapters }}</div>
|
<div class="w-20 hidden md:block text-center">{{ $strings.HeaderChapters }}</div>
|
||||||
</div>
|
</div>
|
||||||
<template v-for="track in audioTracks">
|
<div v-for="track in audioTracks" :key="track.ino" class="flex items-center py-2" :class="currentTrackIndex === track.index && isPlayingChapter ? 'bg-success/10' : ''">
|
||||||
<div :key="track.ino" class="flex items-center py-2" :class="currentTrackIndex === track.index && isPlayingChapter ? 'bg-success/10' : ''">
|
<div class="pr-2 grow min-[1120px]:max-w-64 xl:max-w-sm">
|
||||||
<div class="grow max-w-[calc(100%-80px)] pr-2">
|
<p class="text-xs truncate">{{ track.metadata.filename }}</p>
|
||||||
<p class="text-xs truncate max-w-sm">{{ track.metadata.filename }}</p>
|
|
||||||
</div>
|
|
||||||
<div class="w-20" style="min-width: 80px">
|
|
||||||
<p class="text-xs font-mono text-gray-200">{{ $secondsToTimestamp(Math.round(track.duration), false, true) }}</p>
|
|
||||||
</div>
|
|
||||||
<div class="w-20 hidden md:flex justify-center" style="min-width: 80px">
|
|
||||||
<span v-if="(track.chapters || []).length" class="material-symbols text-success text-sm">check</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
<div class="w-20" style="min-width: 80px">
|
||||||
|
<p class="text-xs font-mono text-gray-200">{{ $secondsToTimestamp(Math.round(track.duration), false, true) }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="w-20 hidden md:flex justify-center" style="min-width: 80px"><span v-if="(track.chapters || []).length" class="material-symbols text-success text-sm">check</span></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -134,6 +180,7 @@
|
|||||||
<ui-loading-indicator />
|
<ui-loading-indicator />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- audible chapter lookup modal -->
|
||||||
<modals-modal v-model="showFindChaptersModal" name="edit-book" :width="500" :processing="findingChapters">
|
<modals-modal v-model="showFindChaptersModal" name="edit-book" :width="500" :processing="findingChapters">
|
||||||
<template #outer>
|
<template #outer>
|
||||||
<div class="absolute top-0 left-0 p-5 w-2/3 overflow-hidden pointer-events-none">
|
<div class="absolute top-0 left-0 p-5 w-2/3 overflow-hidden pointer-events-none">
|
||||||
@@ -159,12 +206,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="w-full p-4">
|
<div v-else class="w-full p-4">
|
||||||
<div class="flex justify-between mb-4">
|
<div class="flex mb-4">
|
||||||
|
<button class="w-7 h-7 rounded-full flex items-center justify-center text-gray-300 hover:text-white flex-shrink-0" :aria-label="$strings.ButtonBack" @click="resetChapterLookupData">
|
||||||
|
<span class="material-symbols text-lg">arrow_back</span>
|
||||||
|
</button>
|
||||||
<p>
|
<p>
|
||||||
{{ $strings.LabelDurationFound }} <span class="font-semibold">{{ $secondsToTimestamp(chapterData.runtimeLengthSec) }}</span
|
{{ $strings.LabelDurationFound }} <span class="font-semibold">{{ $secondsToTimestamp(chapterData.runtimeLengthSec) }}</span>
|
||||||
><br />
|
<br />
|
||||||
<span class="font-semibold" :class="{ 'text-warning': chapters.length !== chapterData.chapters.length }">{{ chapterData.chapters.length }}</span> {{ $strings.LabelChaptersFound }}
|
<span class="font-semibold" :class="{ 'text-warning': chapters.length !== chapterData.chapters.length }">{{ chapterData.chapters.length }}</span> {{ $strings.LabelChaptersFound }}
|
||||||
</p>
|
</p>
|
||||||
|
<div class="grow" />
|
||||||
<p>
|
<p>
|
||||||
{{ $strings.LabelYourAudiobookDuration }}: <span class="font-semibold">{{ $secondsToTimestamp(mediaDurationRounded) }}</span
|
{{ $strings.LabelYourAudiobookDuration }}: <span class="font-semibold">{{ $secondsToTimestamp(mediaDurationRounded) }}</span
|
||||||
><br />
|
><br />
|
||||||
@@ -198,17 +249,49 @@
|
|||||||
<p class="pl-2">{{ $strings.MessageChapterStartIsAfter }}</p>
|
<p class="pl-2">{{ $strings.MessageChapterStartIsAfter }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center pt-2">
|
<div class="flex items-center pt-2 justify-between">
|
||||||
<ui-btn small color="bg-primary" class="mr-1" @click="applyChapterNamesOnly">{{ $strings.ButtonMapChapterTitles }}</ui-btn>
|
<div class="flex items-center gap-2">
|
||||||
<ui-tooltip :text="$strings.MessageMapChapterTitles" direction="top" class="flex items-center">
|
<ui-btn small color="bg-primary" @click="applyChapterNamesOnly">{{ $strings.ButtonMapChapterTitles }}</ui-btn>
|
||||||
<span class="material-symbols text-xl text-gray-200">info</span>
|
<ui-tooltip :text="$strings.MessageMapChapterTitles" direction="top" class="flex items-center">
|
||||||
</ui-tooltip>
|
<span class="material-symbols text-xl text-gray-200">info</span>
|
||||||
<div class="grow" />
|
</ui-tooltip>
|
||||||
|
</div>
|
||||||
<ui-btn small color="bg-success" @click="applyChapterData">{{ $strings.ButtonApplyChapters }}</ui-btn>
|
<ui-btn small color="bg-success" @click="applyChapterData">{{ $strings.ButtonApplyChapters }}</ui-btn>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</modals-modal>
|
</modals-modal>
|
||||||
|
|
||||||
|
<!-- create bulk chapters modal -->
|
||||||
|
<modals-modal v-model="showBulkChapterModal" name="bulk-chapters" :width="400">
|
||||||
|
<template #outer>
|
||||||
|
<div class="absolute top-0 left-0 p-5 w-2/3 overflow-hidden pointer-events-none">
|
||||||
|
<p class="text-3xl text-white truncate pointer-events-none">{{ $strings.HeaderBulkChapterModal }}</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div class="w-full h-full max-h-full text-sm rounded-lg bg-bg shadow-lg border border-black-300 relative p-6">
|
||||||
|
<div class="flex flex-col space-y-8">
|
||||||
|
<p class="text-base">{{ $strings.MessageBulkChapterPattern }}</p>
|
||||||
|
|
||||||
|
<div v-if="detectedPattern" class="text-sm text-gray-400 bg-gray-800 p-2 rounded">
|
||||||
|
<strong>{{ $strings.LabelDetectedPattern }}</strong> "{{ detectedPattern.before }}{{ formatNumberWithPadding(detectedPattern.startingNumber, detectedPattern) }}{{ detectedPattern.after }}"
|
||||||
|
<br />
|
||||||
|
<strong>{{ $strings.LabelNextChapters }}</strong>
|
||||||
|
"{{ detectedPattern.before }}{{ formatNumberWithPadding(detectedPattern.startingNumber + 1, detectedPattern) }}{{ detectedPattern.after }}", "{{ detectedPattern.before }}{{ formatNumberWithPadding(detectedPattern.startingNumber + 2, detectedPattern) }}{{ detectedPattern.after }}", etc.
|
||||||
|
</div>
|
||||||
|
<div class="flex px-1 items-center">
|
||||||
|
<label class="text-base font-medium">{{ $strings.LabelNumberOfChapters }}</label>
|
||||||
|
<div class="grow" />
|
||||||
|
<ui-text-input v-model="bulkChapterCount" type="number" min="1" max="50" class="w-14" :style="{ height: `2em` }" @keyup.enter="addBulkChapters" />
|
||||||
|
</div>
|
||||||
|
<div class="flex px-1 items-center">
|
||||||
|
<ui-btn small @click="showBulkChapterModal = false">{{ $strings.ButtonCancel }}</ui-btn>
|
||||||
|
<div class="grow" />
|
||||||
|
<ui-btn small color="bg-success" @click="addBulkChapters">{{ $strings.ButtonAddChapters }}</ui-btn>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</modals-modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -265,7 +348,17 @@ export default {
|
|||||||
removeBranding: false,
|
removeBranding: false,
|
||||||
showSecondInputs: false,
|
showSecondInputs: false,
|
||||||
audibleRegions: ['US', 'CA', 'UK', 'AU', 'FR', 'DE', 'JP', 'IT', 'IN', 'ES'],
|
audibleRegions: ['US', 'CA', 'UK', 'AU', 'FR', 'DE', 'JP', 'IT', 'IN', 'ES'],
|
||||||
hasChanges: false
|
hasChanges: false,
|
||||||
|
timeIncrementAmount: 1,
|
||||||
|
elapsedTime: 0,
|
||||||
|
playStartTime: null,
|
||||||
|
elapsedTimeInterval: null,
|
||||||
|
lockedChapters: new Set(),
|
||||||
|
lastSelectedLockIndex: null,
|
||||||
|
bulkChapterInput: '',
|
||||||
|
showBulkChapterModal: false,
|
||||||
|
bulkChapterCount: 1,
|
||||||
|
detectedPattern: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -304,9 +397,18 @@ export default {
|
|||||||
},
|
},
|
||||||
selectedChapterId() {
|
selectedChapterId() {
|
||||||
return this.selectedChapter ? this.selectedChapter.id : null
|
return this.selectedChapter ? this.selectedChapter.id : null
|
||||||
|
},
|
||||||
|
allChaptersLocked() {
|
||||||
|
return this.newChapters.length > 0 && this.newChapters.every((chapter) => this.lockedChapters.has(chapter.id))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
formatNumberWithPadding(number, pattern) {
|
||||||
|
if (!pattern || !pattern.hasLeadingZeros || !pattern.originalPadding) {
|
||||||
|
return number.toString()
|
||||||
|
}
|
||||||
|
return number.toString().padStart(pattern.originalPadding, '0')
|
||||||
|
},
|
||||||
setChaptersFromTracks() {
|
setChaptersFromTracks() {
|
||||||
let currentStartTime = 0
|
let currentStartTime = 0
|
||||||
let index = 0
|
let index = 0
|
||||||
@@ -321,7 +423,7 @@ export default {
|
|||||||
currentStartTime += track.duration
|
currentStartTime += track.duration
|
||||||
}
|
}
|
||||||
this.newChapters = chapters
|
this.newChapters = chapters
|
||||||
|
this.lockedChapters = new Set()
|
||||||
this.checkChapters()
|
this.checkChapters()
|
||||||
},
|
},
|
||||||
toggleRemoveBranding() {
|
toggleRemoveBranding() {
|
||||||
@@ -334,19 +436,22 @@ export default {
|
|||||||
|
|
||||||
const amount = Number(this.shiftAmount)
|
const amount = Number(this.shiftAmount)
|
||||||
|
|
||||||
const lastChapter = this.newChapters[this.newChapters.length - 1]
|
// Check if any unlocked chapters would be affected negatively
|
||||||
if (lastChapter.start + amount > this.mediaDurationRounded) {
|
const unlockedChapters = this.newChapters.filter((chap) => !this.lockedChapters.has(chap.id))
|
||||||
this.$toast.error(this.$strings.ToastChaptersInvalidShiftAmountLast)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.newChapters[1].start + amount <= 0) {
|
if (unlockedChapters.length === 0) {
|
||||||
this.$toast.error(this.$strings.ToastChaptersInvalidShiftAmountStart)
|
this.$toast.warning(this.$strings.ToastChaptersAllLocked)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < this.newChapters.length; i++) {
|
for (let i = 0; i < this.newChapters.length; i++) {
|
||||||
const chap = this.newChapters[i]
|
const chap = this.newChapters[i]
|
||||||
|
|
||||||
|
// Skip locked chapters
|
||||||
|
if (this.lockedChapters.has(chap.id)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
chap.end = Math.min(chap.end + amount, this.mediaDuration)
|
chap.end = Math.min(chap.end + amount, this.mediaDuration)
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
chap.start = Math.max(0, chap.start + amount)
|
chap.start = Math.max(0, chap.start + amount)
|
||||||
@@ -354,6 +459,83 @@ export default {
|
|||||||
}
|
}
|
||||||
this.checkChapters()
|
this.checkChapters()
|
||||||
},
|
},
|
||||||
|
incrementChapterTime(chapter, amount) {
|
||||||
|
if (chapter.id === 0 && chapter.start + amount < 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (chapter.start + amount >= this.mediaDuration) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
chapter.start = Math.max(0, chapter.start + amount)
|
||||||
|
this.checkChapters()
|
||||||
|
},
|
||||||
|
adjustChapterStartTime(chapter) {
|
||||||
|
const newStartTime = chapter.start + this.elapsedTime
|
||||||
|
chapter.start = newStartTime
|
||||||
|
this.checkChapters()
|
||||||
|
this.$toast.success(this.$strings.ToastChapterStartTimeAdjusted.replace('{0}', this.elapsedTime))
|
||||||
|
|
||||||
|
this.destroyAudioEl()
|
||||||
|
},
|
||||||
|
startElapsedTimeTracking() {
|
||||||
|
this.elapsedTime = 0
|
||||||
|
this.playStartTime = Date.now()
|
||||||
|
this.elapsedTimeInterval = setInterval(() => {
|
||||||
|
this.elapsedTime = Math.floor((Date.now() - this.playStartTime) / 1000)
|
||||||
|
}, 100)
|
||||||
|
},
|
||||||
|
stopElapsedTimeTracking() {
|
||||||
|
if (this.elapsedTimeInterval) {
|
||||||
|
clearInterval(this.elapsedTimeInterval)
|
||||||
|
this.elapsedTimeInterval = null
|
||||||
|
}
|
||||||
|
this.elapsedTime = 0
|
||||||
|
this.playStartTime = null
|
||||||
|
},
|
||||||
|
toggleChapterLock(chapter, event) {
|
||||||
|
const chapterId = chapter.id
|
||||||
|
|
||||||
|
if (event.shiftKey && this.lastSelectedLockIndex !== null) {
|
||||||
|
const startIndex = Math.min(this.lastSelectedLockIndex, chapterId)
|
||||||
|
const endIndex = Math.max(this.lastSelectedLockIndex, chapterId)
|
||||||
|
const shouldLock = !this.lockedChapters.has(chapterId)
|
||||||
|
|
||||||
|
for (let i = startIndex; i <= endIndex; i++) {
|
||||||
|
if (shouldLock) {
|
||||||
|
this.lockedChapters.add(i)
|
||||||
|
} else {
|
||||||
|
this.lockedChapters.delete(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this.lockedChapters.has(chapterId)) {
|
||||||
|
this.lockedChapters.delete(chapterId)
|
||||||
|
} else {
|
||||||
|
this.lockedChapters.add(chapterId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.lastSelectedLockIndex = chapterId
|
||||||
|
this.lockedChapters = new Set(this.lockedChapters)
|
||||||
|
},
|
||||||
|
lockAllChapters() {
|
||||||
|
this.newChapters.forEach((chapter) => {
|
||||||
|
this.lockedChapters.add(chapter.id)
|
||||||
|
})
|
||||||
|
this.lockedChapters = new Set(this.lockedChapters)
|
||||||
|
},
|
||||||
|
unlockAllChapters() {
|
||||||
|
this.lockedChapters.clear()
|
||||||
|
this.lockedChapters = new Set(this.lockedChapters)
|
||||||
|
},
|
||||||
|
toggleAllChaptersLock() {
|
||||||
|
if (this.allChaptersLocked) {
|
||||||
|
this.unlockAllChapters()
|
||||||
|
} else {
|
||||||
|
this.lockAllChapters()
|
||||||
|
}
|
||||||
|
},
|
||||||
editItem() {
|
editItem() {
|
||||||
this.$store.commit('showEditModal', this.libraryItem)
|
this.$store.commit('showEditModal', this.libraryItem)
|
||||||
},
|
},
|
||||||
@@ -368,6 +550,10 @@ export default {
|
|||||||
this.checkChapters()
|
this.checkChapters()
|
||||||
},
|
},
|
||||||
removeChapter(chapter) {
|
removeChapter(chapter) {
|
||||||
|
if (this.lockedChapters.has(chapter.id)) {
|
||||||
|
this.$toast.warning(this.$strings.ToastChapterLocked)
|
||||||
|
return
|
||||||
|
}
|
||||||
this.newChapters = this.newChapters.filter((ch) => ch.id !== chapter.id)
|
this.newChapters = this.newChapters.filter((ch) => ch.id !== chapter.id)
|
||||||
this.checkChapters()
|
this.checkChapters()
|
||||||
},
|
},
|
||||||
@@ -408,6 +594,14 @@ export default {
|
|||||||
|
|
||||||
this.hasChanges = hasChanges
|
this.hasChanges = hasChanges
|
||||||
},
|
},
|
||||||
|
getAudioTrackForTime(time) {
|
||||||
|
if (typeof time !== 'number') {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return this.tracks.find((at) => {
|
||||||
|
return time >= at.startOffset && time < at.startOffset + at.duration
|
||||||
|
})
|
||||||
|
},
|
||||||
playChapter(chapter) {
|
playChapter(chapter) {
|
||||||
console.log('Play Chapter', chapter.id)
|
console.log('Play Chapter', chapter.id)
|
||||||
if (this.selectedChapterId === chapter.id) {
|
if (this.selectedChapterId === chapter.id) {
|
||||||
@@ -422,9 +616,12 @@ export default {
|
|||||||
this.destroyAudioEl()
|
this.destroyAudioEl()
|
||||||
}
|
}
|
||||||
|
|
||||||
const audioTrack = this.tracks.find((at) => {
|
const audioTrack = this.getAudioTrackForTime(chapter.start)
|
||||||
return chapter.start >= at.startOffset && chapter.start < at.startOffset + at.duration
|
if (!audioTrack) {
|
||||||
})
|
console.error('No audio track found for chapter', chapter)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
this.selectedChapter = chapter
|
this.selectedChapter = chapter
|
||||||
this.isLoadingChapter = true
|
this.isLoadingChapter = true
|
||||||
|
|
||||||
@@ -451,6 +648,7 @@ export default {
|
|||||||
console.log('Audio playing')
|
console.log('Audio playing')
|
||||||
this.isLoadingChapter = false
|
this.isLoadingChapter = false
|
||||||
this.isPlayingChapter = true
|
this.isPlayingChapter = true
|
||||||
|
this.startElapsedTimeTracking()
|
||||||
})
|
})
|
||||||
audioEl.addEventListener('ended', () => {
|
audioEl.addEventListener('ended', () => {
|
||||||
console.log('Audio ended')
|
console.log('Audio ended')
|
||||||
@@ -473,6 +671,10 @@ export default {
|
|||||||
this.selectedChapter = null
|
this.selectedChapter = null
|
||||||
this.isPlayingChapter = false
|
this.isPlayingChapter = false
|
||||||
this.isLoadingChapter = false
|
this.isLoadingChapter = false
|
||||||
|
this.stopElapsedTimeTracking()
|
||||||
|
},
|
||||||
|
resetChapterLookupData() {
|
||||||
|
this.chapterData = null
|
||||||
},
|
},
|
||||||
saveChapters() {
|
saveChapters() {
|
||||||
this.checkChapters()
|
this.checkChapters()
|
||||||
@@ -506,11 +708,7 @@ export default {
|
|||||||
this.saving = false
|
this.saving = false
|
||||||
if (data.updated) {
|
if (data.updated) {
|
||||||
this.$toast.success(this.$strings.ToastChaptersUpdated)
|
this.$toast.success(this.$strings.ToastChaptersUpdated)
|
||||||
if (this.previousRoute) {
|
this.reloadLibraryItem()
|
||||||
this.$router.push(this.previousRoute)
|
|
||||||
} else {
|
|
||||||
this.$router.push(`/item/${this.libraryItem.id}`)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
this.$toast.info(this.$strings.MessageNoUpdatesWereNecessary)
|
this.$toast.info(this.$strings.MessageNoUpdatesWereNecessary)
|
||||||
}
|
}
|
||||||
@@ -523,7 +721,7 @@ export default {
|
|||||||
},
|
},
|
||||||
applyChapterNamesOnly() {
|
applyChapterNamesOnly() {
|
||||||
this.newChapters.forEach((chapter, index) => {
|
this.newChapters.forEach((chapter, index) => {
|
||||||
if (this.chapterData.chapters[index]) {
|
if (this.chapterData.chapters[index] && !this.lockedChapters.has(chapter.id)) {
|
||||||
chapter.title = this.chapterData.chapters[index].title
|
chapter.title = this.chapterData.chapters[index].title
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -535,7 +733,7 @@ export default {
|
|||||||
},
|
},
|
||||||
applyChapterData() {
|
applyChapterData() {
|
||||||
let index = 0
|
let index = 0
|
||||||
this.newChapters = this.chapterData.chapters
|
const audibleChapters = this.chapterData.chapters
|
||||||
.filter((chap) => chap.startOffsetSec < this.mediaDuration)
|
.filter((chap) => chap.startOffsetSec < this.mediaDuration)
|
||||||
.map((chap) => {
|
.map((chap) => {
|
||||||
return {
|
return {
|
||||||
@@ -545,6 +743,21 @@ export default {
|
|||||||
title: chap.title
|
title: chap.title
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const merged = []
|
||||||
|
let audibleIdx = 0
|
||||||
|
for (let i = 0; i < Math.max(this.newChapters.length, audibleChapters.length); i++) {
|
||||||
|
const isLocked = this.lockedChapters.has(i)
|
||||||
|
if (isLocked && this.newChapters[i]) {
|
||||||
|
merged.push({ ...this.newChapters[i], id: i })
|
||||||
|
} else if (audibleChapters[audibleIdx]) {
|
||||||
|
merged.push({ ...audibleChapters[audibleIdx], id: i })
|
||||||
|
audibleIdx++
|
||||||
|
} else if (this.newChapters[i]) {
|
||||||
|
merged.push({ ...this.newChapters[i], id: i })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.newChapters = merged
|
||||||
this.showFindChaptersModal = false
|
this.showFindChaptersModal = false
|
||||||
this.chapterData = null
|
this.chapterData = null
|
||||||
|
|
||||||
@@ -572,7 +785,7 @@ export default {
|
|||||||
if (data.error) {
|
if (data.error) {
|
||||||
this.asinError = this.$getString(data.stringKey)
|
this.asinError = this.$getString(data.stringKey)
|
||||||
} else {
|
} else {
|
||||||
console.log('Chapter data', data)
|
console.log('Chapter data', { ...data })
|
||||||
this.chapterData = this.removeBranding ? this.removeBrandingFromData(data) : data
|
this.chapterData = this.removeBranding ? this.removeBrandingFromData(data) : data
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -609,6 +822,11 @@ export default {
|
|||||||
data.chapters.pop()
|
data.chapters.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove Branding durations from Runtime totals
|
||||||
|
data.runtimeLengthMs -= introDuration + outroDuration
|
||||||
|
data.runtimeLengthSec = Math.floor(data.runtimeLengthMs / 1000)
|
||||||
|
console.log('Brandless Chapter data', data)
|
||||||
|
|
||||||
return data
|
return data
|
||||||
} catch {
|
} catch {
|
||||||
return data
|
return data
|
||||||
@@ -638,6 +856,7 @@ export default {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
this.lockedChapters = new Set()
|
||||||
this.checkChapters()
|
this.checkChapters()
|
||||||
},
|
},
|
||||||
removeAllChaptersClick() {
|
removeAllChaptersClick() {
|
||||||
@@ -662,11 +881,7 @@ export default {
|
|||||||
.then((data) => {
|
.then((data) => {
|
||||||
if (data.updated) {
|
if (data.updated) {
|
||||||
this.$toast.success(this.$strings.ToastChaptersRemoved)
|
this.$toast.success(this.$strings.ToastChaptersRemoved)
|
||||||
if (this.previousRoute) {
|
this.reloadLibraryItem()
|
||||||
this.$router.push(this.previousRoute)
|
|
||||||
} else {
|
|
||||||
this.$router.push(`/item/${this.libraryItem.id}`)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
this.$toast.info(this.$strings.MessageNoUpdatesWereNecessary)
|
this.$toast.info(this.$strings.MessageNoUpdatesWereNecessary)
|
||||||
}
|
}
|
||||||
@@ -679,6 +894,91 @@ export default {
|
|||||||
this.saving = false
|
this.saving = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
handleBulkChapterAdd() {
|
||||||
|
const input = this.bulkChapterInput.trim()
|
||||||
|
if (!input) return
|
||||||
|
|
||||||
|
const numberMatch = input.match(/(\d+)/)
|
||||||
|
|
||||||
|
if (numberMatch) {
|
||||||
|
// Extract the base pattern and number, preserving zero-padding
|
||||||
|
const originalNumberString = numberMatch[1]
|
||||||
|
const foundNumber = parseInt(originalNumberString)
|
||||||
|
const numberIndex = numberMatch.index
|
||||||
|
const beforeNumber = input.substring(0, numberIndex)
|
||||||
|
const afterNumber = input.substring(numberIndex + originalNumberString.length)
|
||||||
|
|
||||||
|
this.detectedPattern = {
|
||||||
|
before: beforeNumber,
|
||||||
|
after: afterNumber,
|
||||||
|
startingNumber: foundNumber,
|
||||||
|
originalPadding: originalNumberString.length,
|
||||||
|
hasLeadingZeros: originalNumberString.length > 1 && originalNumberString.startsWith('0')
|
||||||
|
}
|
||||||
|
|
||||||
|
this.bulkChapterCount = 1
|
||||||
|
this.showBulkChapterModal = true
|
||||||
|
} else {
|
||||||
|
this.addSingleChapterFromInput(input)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addSingleChapterFromInput(title) {
|
||||||
|
// Find the last chapter to determine where to add the new one
|
||||||
|
const lastChapter = this.newChapters[this.newChapters.length - 1]
|
||||||
|
const newStart = lastChapter ? lastChapter.end : 0
|
||||||
|
const newEnd = Math.min(newStart + 300, this.mediaDuration)
|
||||||
|
|
||||||
|
const newChapter = {
|
||||||
|
id: this.newChapters.length,
|
||||||
|
start: newStart,
|
||||||
|
end: newEnd,
|
||||||
|
title: title
|
||||||
|
}
|
||||||
|
|
||||||
|
this.newChapters.push(newChapter)
|
||||||
|
this.bulkChapterInput = ''
|
||||||
|
this.checkChapters()
|
||||||
|
},
|
||||||
|
|
||||||
|
addBulkChapters() {
|
||||||
|
const count = parseInt(this.bulkChapterCount)
|
||||||
|
if (!count || count < 1 || count > 150) {
|
||||||
|
this.$toast.error(this.$strings.ToastBulkChapterInvalidCount)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const { before, after, startingNumber, originalPadding, hasLeadingZeros } = this.detectedPattern
|
||||||
|
const lastChapter = this.newChapters[this.newChapters.length - 1]
|
||||||
|
const baseStart = lastChapter ? lastChapter.start + 1 : 0
|
||||||
|
|
||||||
|
// Add multiple chapters with the detected pattern
|
||||||
|
for (let i = 0; i < count; i++) {
|
||||||
|
const chapterNumber = startingNumber + i
|
||||||
|
let formattedNumber = chapterNumber.toString()
|
||||||
|
|
||||||
|
// Apply zero-padding if the original had leading zeros
|
||||||
|
if (hasLeadingZeros && originalPadding > 1) {
|
||||||
|
formattedNumber = chapterNumber.toString().padStart(originalPadding, '0')
|
||||||
|
}
|
||||||
|
|
||||||
|
const newStart = baseStart + i
|
||||||
|
const newEnd = Math.min(newStart + i + i, this.mediaDuration)
|
||||||
|
|
||||||
|
const newChapter = {
|
||||||
|
id: this.newChapters.length,
|
||||||
|
start: newStart,
|
||||||
|
end: newEnd,
|
||||||
|
title: `${before}${formattedNumber}${after}`
|
||||||
|
}
|
||||||
|
|
||||||
|
this.newChapters.push(newChapter)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.bulkChapterInput = ''
|
||||||
|
this.showBulkChapterModal = false
|
||||||
|
this.detectedPattern = null
|
||||||
|
this.checkChapters()
|
||||||
|
},
|
||||||
libraryItemUpdated(libraryItem) {
|
libraryItemUpdated(libraryItem) {
|
||||||
if (libraryItem.id === this.libraryItem.id) {
|
if (libraryItem.id === this.libraryItem.id) {
|
||||||
if (!!libraryItem.media.metadata.asin && this.mediaMetadata.asin !== libraryItem.media.metadata.asin) {
|
if (!!libraryItem.media.metadata.asin && this.mediaMetadata.asin !== libraryItem.media.metadata.asin) {
|
||||||
@@ -686,6 +986,18 @@ export default {
|
|||||||
}
|
}
|
||||||
this.libraryItem = libraryItem
|
this.libraryItem = libraryItem
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
reloadLibraryItem() {
|
||||||
|
this.$axios
|
||||||
|
.$get(`/api/items/${this.libraryItem.id}?expanded=1`)
|
||||||
|
.then((data) => {
|
||||||
|
this.libraryItem = data
|
||||||
|
this.initChapters()
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Failed to reload library item', error)
|
||||||
|
this.$toast.error(this.$strings.ToastFailedToLoadData)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex ml-2">
|
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex ml-2">
|
||||||
<a href="https://www.audiobookshelf.org/guides/api-keys" target="_blank" class="inline-flex">
|
<a href="https://audiobookshelf.org/docs/documentation/server-management/api-keys" target="_blank" class="inline-flex">
|
||||||
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
|
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
|
||||||
</a>
|
</a>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
<ui-checkbox v-model="enableOpenIDAuth" checkbox-bg="bg" />
|
<ui-checkbox v-model="enableOpenIDAuth" checkbox-bg="bg" />
|
||||||
<p class="text-lg pl-4">{{ $strings.HeaderOpenIDConnectAuthentication }}</p>
|
<p class="text-lg pl-4">{{ $strings.HeaderOpenIDConnectAuthentication }}</p>
|
||||||
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex ml-2">
|
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex ml-2">
|
||||||
<a href="https://www.audiobookshelf.org/guides/oidc_authentication" target="_blank" class="inline-flex">
|
<a href="https://audiobookshelf.org/docs/documentation/server-management/oidc-authentication" target="_blank" class="inline-flex">
|
||||||
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
|
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
|
||||||
</a>
|
</a>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<app-settings-content :header-text="$strings.HeaderEmailSettings" :description="''">
|
<app-settings-content :header-text="$strings.HeaderEmailSettings" :description="''">
|
||||||
<template #header-items>
|
<template #header-items>
|
||||||
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex ml-2">
|
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex ml-2">
|
||||||
<a href="https://www.audiobookshelf.org/guides/send_to_ereader" target="_blank" class="inline-flex">
|
<a href="https://audiobookshelf.org/docs/documentation/libraries/book-library/ebooks" target="_blank" class="inline-flex">
|
||||||
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
|
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
|
||||||
</a>
|
</a>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
|
|||||||
@@ -131,35 +131,26 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grow py-2">
|
<div class="grow py-2">
|
||||||
<ui-dropdown :label="$strings.LabelSettingsDateFormat" v-model="newServerSettings.dateFormat" :items="dateFormats" small class="max-w-52" @input="(val) => updateSettingsKey('dateFormat', val)" />
|
<ui-dropdown :label="$strings.LabelSettingsDateFormat" v-model="newServerSettings.dateFormat" :items="dateFormats" small class="max-w-72" @input="(val) => updateSettingsKey('dateFormat', val)" />
|
||||||
<p class="text-xs ml-1 text-white/60">{{ $strings.LabelExample }}: {{ dateExample }}</p>
|
<p class="text-xs ml-1 text-white/60">{{ $strings.LabelExample }}: {{ dateExample }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grow py-2">
|
<div class="grow py-2">
|
||||||
<ui-dropdown :label="$strings.LabelSettingsTimeFormat" v-model="newServerSettings.timeFormat" :items="timeFormats" small class="max-w-52" @input="(val) => updateSettingsKey('timeFormat', val)" />
|
<ui-dropdown :label="$strings.LabelSettingsTimeFormat" v-model="newServerSettings.timeFormat" :items="timeFormats" small class="max-w-72" @input="(val) => updateSettingsKey('timeFormat', val)" />
|
||||||
<p class="text-xs ml-1 text-white/60">{{ $strings.LabelExample }}: {{ timeExample }}</p>
|
<p class="text-xs ml-1 text-white/60">{{ $strings.LabelExample }}: {{ timeExample }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="py-2">
|
<div class="py-2">
|
||||||
<ui-dropdown :label="$strings.LabelLanguageDefaultServer" ref="langDropdown" v-model="newServerSettings.language" :items="$languageCodeOptions" small class="max-w-52" @input="updateServerLanguage" />
|
<ui-dropdown :label="$strings.LabelLanguageDefaultServer" ref="langDropdown" v-model="newServerSettings.language" :items="$languageCodeOptions" small class="max-w-72" @input="updateServerLanguage" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- old experimental features -->
|
<div class="pt-4">
|
||||||
<!-- <div class="pt-4">
|
<h2 class="font-semibold">{{ $strings.HeaderSettingsSecurity }}</h2>
|
||||||
<h2 class="font-semibold">{{ $strings.HeaderSettingsExperimental }}</h2>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center py-2">
|
<div class="py-2">
|
||||||
<ui-toggle-switch labeledBy="settings-experimental-features" v-model="showExperimentalFeatures" />
|
<ui-multi-select v-model="newServerSettings.allowedOrigins" :items="newServerSettings.allowedOrigins" :label="$strings.LabelCorsAllowed" class="max-w-72" @input="updateCorsOrigins" />
|
||||||
<ui-tooltip :text="$strings.LabelSettingsExperimentalFeaturesHelp">
|
</div>
|
||||||
<p class="pl-4">
|
|
||||||
<span id="settings-experimental-features">{{ $strings.LabelSettingsExperimentalFeatures }}</span>
|
|
||||||
<a :aria-label="$strings.LabelSettingsExperimentalFeaturesHelp" href="https://github.com/advplyr/audiobookshelf/discussions/75" target="_blank">
|
|
||||||
<span class="material-symbols icon-text">info</span>
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
</ui-tooltip>
|
|
||||||
</div> -->
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</app-settings-content>
|
</app-settings-content>
|
||||||
@@ -256,7 +247,8 @@ export default {
|
|||||||
return this.$store.state.serverSettings
|
return this.$store.state.serverSettings
|
||||||
},
|
},
|
||||||
providers() {
|
providers() {
|
||||||
return this.$store.state.scanners.providers
|
// Use book cover providers for the cover provider dropdown
|
||||||
|
return this.$store.state.scanners.bookCoverProviders || []
|
||||||
},
|
},
|
||||||
dateFormats() {
|
dateFormats() {
|
||||||
return this.$store.state.globals.dateFormats
|
return this.$store.state.globals.dateFormats
|
||||||
@@ -323,6 +315,27 @@ export default {
|
|||||||
updateServerLanguage(val) {
|
updateServerLanguage(val) {
|
||||||
this.updateSettingsKey('language', val)
|
this.updateSettingsKey('language', val)
|
||||||
},
|
},
|
||||||
|
updateCorsOrigins(val) {
|
||||||
|
const validOrigins = []
|
||||||
|
const invalidOrigins = []
|
||||||
|
|
||||||
|
val.forEach((origin) => {
|
||||||
|
const trimmedOrigin = origin.trim().toLowerCase()
|
||||||
|
try {
|
||||||
|
new URL(trimmedOrigin)
|
||||||
|
validOrigins.push(trimmedOrigin)
|
||||||
|
} catch {
|
||||||
|
invalidOrigins.push(trimmedOrigin)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (invalidOrigins.length > 0) {
|
||||||
|
this.$toast.error(this.$strings.ToastInvalidUrls)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.newServerSettings.allowedOrigins = validOrigins
|
||||||
|
this.updateSettingsKey('allowedOrigins', validOrigins)
|
||||||
|
},
|
||||||
updateSettingsKey(key, val) {
|
updateSettingsKey(key, val) {
|
||||||
if (key === 'scannerDisableWatcher') {
|
if (key === 'scannerDisableWatcher') {
|
||||||
this.newServerSettings.scannerDisableWatcher = val
|
this.newServerSettings.scannerDisableWatcher = val
|
||||||
@@ -352,6 +365,7 @@ export default {
|
|||||||
initServerSettings() {
|
initServerSettings() {
|
||||||
this.newServerSettings = this.serverSettings ? { ...this.serverSettings } : {}
|
this.newServerSettings = this.serverSettings ? { ...this.serverSettings } : {}
|
||||||
this.newServerSettings.sortingPrefixes = [...(this.newServerSettings.sortingPrefixes || [])]
|
this.newServerSettings.sortingPrefixes = [...(this.newServerSettings.sortingPrefixes || [])]
|
||||||
|
this.newServerSettings.allowedOrigins = [...(this.newServerSettings.allowedOrigins || [])]
|
||||||
this.scannerEnableWatcher = !this.newServerSettings.scannerDisableWatcher
|
this.scannerEnableWatcher = !this.newServerSettings.scannerDisableWatcher
|
||||||
|
|
||||||
this.homepageUseBookshelfView = this.newServerSettings.homeBookshelfView != this.$constants.BookshelfView.DETAIL
|
this.homepageUseBookshelfView = this.newServerSettings.homeBookshelfView != this.$constants.BookshelfView.DETAIL
|
||||||
@@ -376,8 +390,8 @@ export default {
|
|||||||
},
|
},
|
||||||
purgeItemsCache() {
|
purgeItemsCache() {
|
||||||
const payload = {
|
const payload = {
|
||||||
// message: `This will delete the entire folder at <code>/metadata/cache/items</code>.<br />Are you sure you want to purge items cache?`,
|
|
||||||
message: this.$strings.MessageConfirmPurgeItemsCache,
|
message: this.$strings.MessageConfirmPurgeItemsCache,
|
||||||
|
allowHtml: true,
|
||||||
callback: (confirmed) => {
|
callback: (confirmed) => {
|
||||||
if (confirmed) {
|
if (confirmed) {
|
||||||
this.sendPurgeItemsCache()
|
this.sendPurgeItemsCache()
|
||||||
@@ -403,6 +417,8 @@ export default {
|
|||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.initServerSettings()
|
this.initServerSettings()
|
||||||
|
// Fetch providers if not already loaded (for cover provider dropdown)
|
||||||
|
this.$store.dispatch('scanners/fetchProviders')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #header-items>
|
<template #header-items>
|
||||||
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex ml-2">
|
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex ml-2">
|
||||||
<a href="https://www.audiobookshelf.org/guides/custom-metadata-providers" target="_blank" class="inline-flex">
|
<a href="https://audiobookshelf.org/docs/documentation/community/community-providers" target="_blank" class="inline-flex">
|
||||||
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
|
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
|
||||||
</a>
|
</a>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
|
|||||||
@@ -90,9 +90,9 @@ export default {
|
|||||||
|
|
||||||
let message = this.$getString('MessageConfirmRenameGenre', [this.editingGenre, this.newGenreName])
|
let message = this.$getString('MessageConfirmRenameGenre', [this.editingGenre, this.newGenreName])
|
||||||
if (genreNameExists) {
|
if (genreNameExists) {
|
||||||
message += `<br><span class="text-sm">${this.$strings.MessageConfirmRenameGenreMergeNote}</span>`
|
message += ` ${this.$strings.MessageConfirmRenameGenreMergeNote}`
|
||||||
} else if (genreNameExistsOfDifferentCase) {
|
} else if (genreNameExistsOfDifferentCase) {
|
||||||
message += `<br><span class="text-warning text-sm">${this.$getString('MessageConfirmRenameGenreWarning', [genreNameExistsOfDifferentCase])}</span>`
|
message += ` ${this.$getString('MessageConfirmRenameGenreWarning', [genreNameExistsOfDifferentCase])}`
|
||||||
}
|
}
|
||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
|
|||||||
@@ -86,9 +86,9 @@ export default {
|
|||||||
|
|
||||||
let message = this.$getString('MessageConfirmRenameTag', [this.editingTag, this.newTagName])
|
let message = this.$getString('MessageConfirmRenameTag', [this.editingTag, this.newTagName])
|
||||||
if (tagNameExists) {
|
if (tagNameExists) {
|
||||||
message += `<br><span class="text-sm">${this.$strings.MessageConfirmRenameTagMergeNote}</span>`
|
message += ` ${this.$strings.MessageConfirmRenameTagMergeNote}`
|
||||||
} else if (tagNameExistsOfDifferentCase) {
|
} else if (tagNameExistsOfDifferentCase) {
|
||||||
message += `<br><span class="text-warning text-sm">${this.$getString('MessageConfirmRenameTagWarning', [tagNameExistsOfDifferentCase])}</span>`
|
message += ` ${this.$getString('MessageConfirmRenameTagWarning', [tagNameExistsOfDifferentCase])}`
|
||||||
}
|
}
|
||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<app-settings-content :header-text="$strings.HeaderLibraries">
|
<app-settings-content :header-text="$strings.HeaderLibraries">
|
||||||
<template #header-items>
|
<template #header-items>
|
||||||
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex ml-2">
|
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex ml-2">
|
||||||
<a href="https://www.audiobookshelf.org/guides/library_creation" target="_blank" class="inline-flex">
|
<a href="https://audiobookshelf.org/docs/documentation/libraries/common-content/overview" target="_blank" class="inline-flex">
|
||||||
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
|
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
|
||||||
</a>
|
</a>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<app-settings-content :header-text="$strings.HeaderLogs" :description="$strings.MessageLogsDescription">
|
<app-settings-content :header-text="$strings.HeaderLogs" :description="$strings.MessageLogsDescription">
|
||||||
<template #header-items>
|
<template #header-items>
|
||||||
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex ml-2">
|
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex ml-2">
|
||||||
<a href="https://www.audiobookshelf.org/guides/server_logs" target="_blank" class="inline-flex">
|
<a href="https://audiobookshelf.org/docs/documentation/server-management/server-logs" target="_blank" class="inline-flex">
|
||||||
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
|
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
|
||||||
</a>
|
</a>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<app-settings-content :header-text="$strings.HeaderRSSFeeds">
|
<app-settings-content :header-text="$strings.HeaderRSSFeeds">
|
||||||
<template #header-items>
|
<template #header-items>
|
||||||
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex ml-2">
|
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex ml-2">
|
||||||
<a href="https://www.audiobookshelf.org/guides/rss_feeds" target="_blank" class="inline-flex">
|
<a href="https://audiobookshelf.org/docs/documentation/libraries/common-content/public-shares#rss-feed" target="_blank" class="inline-flex">
|
||||||
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
|
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
|
||||||
</a>
|
</a>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
|
|||||||
@@ -6,80 +6,86 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="listeningSessions.length" class="block max-w-full relative">
|
<div v-if="listeningSessions.length" class="block max-w-full relative">
|
||||||
<table class="userSessionsTable">
|
<div class="overflow-x-auto">
|
||||||
<tr class="bg-primary/40">
|
<table class="userSessionsTable">
|
||||||
<th class="w-6 min-w-6 text-left hidden md:table-cell h-11">
|
<tr class="bg-primary/40">
|
||||||
<ui-checkbox v-model="isAllSelected" :partial="numSelected > 0 && !isAllSelected" small checkbox-bg="bg" />
|
<th class="w-6 min-w-6 text-left hidden md:table-cell h-11">
|
||||||
</th>
|
<ui-checkbox v-model="isAllSelected" :partial="numSelected > 0 && !isAllSelected" small checkbox-bg="bg" />
|
||||||
<th v-if="numSelected" class="grow text-left" :colspan="7">
|
</th>
|
||||||
<div class="flex items-center">
|
<th v-if="numSelected" class="grow text-left" :colspan="7">
|
||||||
<p>{{ $getString('MessageSelected', [numSelected]) }}</p>
|
<div class="flex items-center">
|
||||||
<div class="grow" />
|
<p>{{ $getString('MessageSelected', [numSelected]) }}</p>
|
||||||
<ui-btn small color="bg-error" :loading="deletingSessions" @click.stop="removeSessionsClick">{{ $strings.ButtonRemove }}</ui-btn>
|
<div class="grow" />
|
||||||
</div>
|
<ui-btn small color="bg-error" :loading="deletingSessions" @click.stop="removeSessionsClick">{{ $strings.ButtonRemove }}</ui-btn>
|
||||||
</th>
|
</div>
|
||||||
<th v-if="!numSelected" class="grow sm:grow-0 sm:w-48 sm:max-w-48 text-left group cursor-pointer" @click.stop="sortColumn('displayTitle')">
|
</th>
|
||||||
<div class="inline-flex items-center">
|
<th v-if="!numSelected" class="grow sm:grow-0 sm:w-48 sm:max-w-48 text-left group cursor-pointer" @click.stop="sortColumn('displayTitle')">
|
||||||
{{ $strings.LabelItem }} <span :class="{ 'opacity-0 group-hover:opacity-30': !isSortSelected('displayTitle') }" class="material-symbols text-base pl-px">{{ sortDesc ? 'arrow_drop_down' : 'arrow_drop_up' }}</span>
|
<div class="inline-flex items-center">
|
||||||
</div>
|
{{ $strings.LabelItem }} <span :class="{ 'opacity-0 group-hover:opacity-30': !isSortSelected('displayTitle') }" class="material-symbols text-base pl-px">{{ sortDesc ? 'arrow_drop_down' : 'arrow_drop_up' }}</span>
|
||||||
</th>
|
</div>
|
||||||
<th v-if="!numSelected" class="w-20 min-w-20 text-left hidden md:table-cell">{{ $strings.LabelUser }}</th>
|
</th>
|
||||||
<th v-if="!numSelected" class="w-26 min-w-26 text-left hidden md:table-cell group cursor-pointer" @click.stop="sortColumn('playMethod')">
|
<th v-if="!numSelected" class="w-20 min-w-20 text-left hidden md:table-cell">{{ $strings.LabelUser }}</th>
|
||||||
<div class="inline-flex items-center">
|
<th v-if="!numSelected" class="w-26 min-w-26 text-left hidden md:table-cell group cursor-pointer" @click.stop="sortColumn('playMethod')">
|
||||||
{{ $strings.LabelPlayMethod }} <span :class="{ 'opacity-0 group-hover:opacity-30': !isSortSelected('playMethod') }" class="material-symbols text-base pl-px">{{ sortDesc ? 'arrow_drop_down' : 'arrow_drop_up' }}</span>
|
<div class="inline-flex items-center">
|
||||||
</div>
|
{{ $strings.LabelPlayMethod }} <span :class="{ 'opacity-0 group-hover:opacity-30': !isSortSelected('playMethod') }" class="material-symbols text-base pl-px">{{ sortDesc ? 'arrow_drop_down' : 'arrow_drop_up' }}</span>
|
||||||
</th>
|
</div>
|
||||||
<th v-if="!numSelected" class="w-32 min-w-32 text-left hidden sm:table-cell">{{ $strings.LabelDeviceInfo }}</th>
|
</th>
|
||||||
<th v-if="!numSelected" class="w-24 min-w-24 sm:w-32 sm:min-w-32 group cursor-pointer" @click.stop="sortColumn('timeListening')">
|
<th v-if="!numSelected" class="w-32 min-w-32 text-left hidden sm:table-cell">{{ $strings.LabelDeviceInfo }}</th>
|
||||||
<div class="inline-flex items-center">
|
<th v-if="!numSelected" class="w-24 min-w-24 sm:w-32 sm:min-w-32 group cursor-pointer" @click.stop="sortColumn('timeListening')">
|
||||||
{{ $strings.LabelTimeListened }} <span :class="{ 'opacity-0 group-hover:opacity-30': !isSortSelected('timeListening') }" class="material-symbols text-base pl-px hidden sm:inline-block">{{ sortDesc ? 'arrow_drop_down' : 'arrow_drop_up' }}</span>
|
<div class="inline-flex items-center">
|
||||||
</div>
|
{{ $strings.LabelTimeListened }} <span :class="{ 'opacity-0 group-hover:opacity-30': !isSortSelected('timeListening') }" class="material-symbols text-base pl-px hidden sm:inline-block">{{ sortDesc ? 'arrow_drop_down' : 'arrow_drop_up' }}</span>
|
||||||
</th>
|
</div>
|
||||||
<th v-if="!numSelected" class="w-24 min-w-24 group cursor-pointer" @click.stop="sortColumn('currentTime')">
|
</th>
|
||||||
<div class="inline-flex items-center">
|
<th v-if="!numSelected" class="w-24 min-w-24 group cursor-pointer" @click.stop="sortColumn('currentTime')">
|
||||||
{{ $strings.LabelLastTime }} <span :class="{ 'opacity-0 group-hover:opacity-30': !isSortSelected('currentTime') }" class="material-symbols text-base pl-px hidden sm:inline-block">{{ sortDesc ? 'arrow_drop_down' : 'arrow_drop_up' }}</span>
|
<div class="inline-flex items-center">
|
||||||
</div>
|
{{ $strings.LabelLastTime }} <span :class="{ 'opacity-0 group-hover:opacity-30': !isSortSelected('currentTime') }" class="material-symbols text-base pl-px hidden sm:inline-block">{{ sortDesc ? 'arrow_drop_down' : 'arrow_drop_up' }}</span>
|
||||||
</th>
|
</div>
|
||||||
<th v-if="!numSelected" class="grow hidden sm:table-cell cursor-pointer group" @click.stop="sortColumn('updatedAt')">
|
</th>
|
||||||
<div class="inline-flex items-center">
|
<th v-if="!numSelected" class="grow hidden sm:table-cell cursor-pointer group" @click.stop="sortColumn('updatedAt')">
|
||||||
{{ $strings.LabelLastUpdate }} <span :class="{ 'opacity-0 group-hover:opacity-30': !isSortSelected('updatedAt') }" class="material-symbols text-base pl-px">{{ sortDesc ? 'arrow_drop_down' : 'arrow_drop_up' }}</span>
|
<div class="inline-flex items-center">
|
||||||
</div>
|
{{ $strings.LabelLastUpdate }} <span :class="{ 'opacity-0 group-hover:opacity-30': !isSortSelected('updatedAt') }" class="material-symbols text-base pl-px">{{ sortDesc ? 'arrow_drop_down' : 'arrow_drop_up' }}</span>
|
||||||
</th>
|
</div>
|
||||||
</tr>
|
</th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
<tr v-for="session in listeningSessions" :key="session.id" :class="{ selected: session.selected }" class="cursor-pointer" @click="clickSessionRow(session)">
|
<tr v-for="session in listeningSessions" :key="session.id" :class="{ selected: session.selected }" class="cursor-pointer" @click="clickSessionRow(session)">
|
||||||
<td class="hidden md:table-cell py-1 max-w-6 relative">
|
<td class="hidden md:table-cell py-1 max-w-6 relative">
|
||||||
<ui-checkbox v-model="session.selected" small checkbox-bg="bg" />
|
<ui-checkbox v-model="session.selected" small checkbox-bg="bg" />
|
||||||
<!-- overlay of the checkbox so that the entire box is clickable -->
|
<!-- overlay of the checkbox so that the entire box is clickable -->
|
||||||
<div class="absolute inset-0 w-full h-full" @click.stop="session.selected = !session.selected" />
|
<div class="absolute inset-0 w-full h-full" @click.stop="session.selected = !session.selected" />
|
||||||
</td>
|
</td>
|
||||||
<td class="py-1 grow sm:grow-0 sm:w-48 sm:max-w-48">
|
<td class="py-1 grow sm:grow-0 sm:w-48 sm:max-w-48">
|
||||||
<p class="text-xs text-gray-200 truncate">{{ session.displayTitle }}</p>
|
<p class="text-xs text-gray-200 truncate">{{ session.displayTitle }}</p>
|
||||||
<p class="text-xs text-gray-400 truncate">{{ session.displayAuthor }}</p>
|
<p class="text-xs text-gray-400 truncate">{{ session.displayAuthor }}</p>
|
||||||
</td>
|
</td>
|
||||||
<td class="hidden md:table-cell w-20 min-w-20">
|
<td class="hidden md:table-cell w-20 min-w-20">
|
||||||
<p v-if="filteredUserUsername" class="text-xs">{{ filteredUserUsername }}</p>
|
<p v-if="filteredUserUsername" class="text-xs">{{ filteredUserUsername }}</p>
|
||||||
<p v-else class="text-xs">{{ session.user ? session.user.username : 'N/A' }}</p>
|
<p v-else class="text-xs">{{ session.user ? session.user.username : 'N/A' }}</p>
|
||||||
</td>
|
</td>
|
||||||
<td class="hidden md:table-cell w-26 min-w-26">
|
<td class="hidden md:table-cell w-26 min-w-26">
|
||||||
<p class="text-xs">{{ getPlayMethodName(session.playMethod) }}</p>
|
<p class="text-xs">{{ getPlayMethodName(session.playMethod) }}</p>
|
||||||
</td>
|
</td>
|
||||||
<td class="hidden sm:table-cell max-w-32 min-w-32">
|
<td class="hidden sm:table-cell max-w-32 min-w-32">
|
||||||
<p class="text-xs truncate" v-html="getDeviceInfoString(session.deviceInfo)" />
|
<p class="text-xs truncate">
|
||||||
</td>
|
<template v-for="(line, index) in getDeviceInfoLines(session.deviceInfo)">
|
||||||
<td class="text-center w-24 min-w-24 sm:w-32 sm:min-w-32">
|
<br v-if="index > 0" :key="'br-' + index" />{{ line }}
|
||||||
<p class="text-xs font-mono">{{ $elapsedPrettyLocalized(session.timeListening) }}</p>
|
</template>
|
||||||
</td>
|
</p>
|
||||||
<td class="text-center hover:underline w-24 min-w-24" @click.stop="clickCurrentTime(session)">
|
</td>
|
||||||
<p class="text-xs font-mono">{{ $secondsToTimestamp(session.currentTime) }}</p>
|
<td class="text-center w-24 min-w-24 sm:w-32 sm:min-w-32">
|
||||||
</td>
|
<p class="text-xs font-mono">{{ $elapsedPrettyLocalized(session.timeListening) }}</p>
|
||||||
<td class="text-center hidden sm:table-cell">
|
</td>
|
||||||
<ui-tooltip v-if="session.updatedAt" direction="top" :text="$formatDatetime(session.updatedAt, dateFormat, timeFormat)">
|
<td class="text-center hover:underline w-24 min-w-24" @click.stop="clickCurrentTime(session)">
|
||||||
<p class="text-xs text-gray-200">{{ $dateDistanceFromNow(session.updatedAt) }}</p>
|
<p class="text-xs font-mono">{{ $secondsToTimestamp(session.currentTime) }}</p>
|
||||||
</ui-tooltip>
|
</td>
|
||||||
</td>
|
<td class="text-center hidden sm:table-cell">
|
||||||
</tr>
|
<ui-tooltip v-if="session.updatedAt" direction="top" :text="$formatDatetime(session.updatedAt, dateFormat, timeFormat)">
|
||||||
</table>
|
<p class="text-xs text-gray-200">{{ $dateDistanceFromNow(session.updatedAt) }}</p>
|
||||||
|
</ui-tooltip>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
<!-- table bottom options -->
|
<!-- table bottom options -->
|
||||||
<div class="flex items-center my-2">
|
<div class="flex items-center my-2">
|
||||||
<div class="grow" />
|
<div class="grow" />
|
||||||
@@ -128,7 +134,11 @@
|
|||||||
<p class="text-xs">{{ getPlayMethodName(session.playMethod) }}</p>
|
<p class="text-xs">{{ getPlayMethodName(session.playMethod) }}</p>
|
||||||
</td>
|
</td>
|
||||||
<td class="hidden sm:table-cell max-w-32 min-w-32">
|
<td class="hidden sm:table-cell max-w-32 min-w-32">
|
||||||
<p class="text-xs truncate" v-html="getDeviceInfoString(session.deviceInfo)" />
|
<p class="text-xs truncate">
|
||||||
|
<template v-for="(line, index) in getDeviceInfoLines(session.deviceInfo)">
|
||||||
|
<br v-if="index > 0" :key="'br-' + index" />{{ line }}
|
||||||
|
</template>
|
||||||
|
</p>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<p class="text-xs font-mono">{{ $elapsedPretty(session.timeListening) }}</p>
|
<p class="text-xs font-mono">{{ $elapsedPretty(session.timeListening) }}</p>
|
||||||
@@ -170,7 +180,11 @@
|
|||||||
<p class="text-xs">{{ getPlayMethodName(session.playMethod) }}</p>
|
<p class="text-xs">{{ getPlayMethodName(session.playMethod) }}</p>
|
||||||
</td>
|
</td>
|
||||||
<td class="hidden sm:table-cell max-w-32 min-w-32">
|
<td class="hidden sm:table-cell max-w-32 min-w-32">
|
||||||
<p class="text-xs truncate" v-html="getDeviceInfoString(session.deviceInfo)" />
|
<p class="text-xs truncate">
|
||||||
|
<template v-for="(line, index) in getDeviceInfoLines(session.deviceInfo)">
|
||||||
|
<br v-if="index > 0" :key="'br-' + index" />{{ line }}
|
||||||
|
</template>
|
||||||
|
</p>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center hover:underline" @click.stop="clickCurrentTime(session)">
|
<td class="text-center hover:underline" @click.stop="clickCurrentTime(session)">
|
||||||
<p class="text-xs font-mono">{{ $secondsToTimestamp(session.currentTime) }}</p>
|
<p class="text-xs font-mono">{{ $secondsToTimestamp(session.currentTime) }}</p>
|
||||||
@@ -431,16 +445,16 @@ export default {
|
|||||||
this.selectedSession = session
|
this.selectedSession = session
|
||||||
this.showSessionModal = true
|
this.showSessionModal = true
|
||||||
},
|
},
|
||||||
getDeviceInfoString(deviceInfo) {
|
getDeviceInfoLines(deviceInfo) {
|
||||||
if (!deviceInfo) return ''
|
if (!deviceInfo) return []
|
||||||
var lines = []
|
const lines = []
|
||||||
if (deviceInfo.clientName) lines.push(`${deviceInfo.clientName} ${deviceInfo.clientVersion || ''}`)
|
if (deviceInfo.clientName) lines.push(`${deviceInfo.clientName} ${deviceInfo.clientVersion || ''}`)
|
||||||
if (deviceInfo.osName) lines.push(`${deviceInfo.osName} ${deviceInfo.osVersion}`)
|
if (deviceInfo.osName) lines.push(`${deviceInfo.osName} ${deviceInfo.osVersion}`)
|
||||||
if (deviceInfo.browserName) lines.push(deviceInfo.browserName)
|
if (deviceInfo.browserName) lines.push(deviceInfo.browserName)
|
||||||
|
|
||||||
if (deviceInfo.manufacturer && deviceInfo.model) lines.push(`${deviceInfo.manufacturer} ${deviceInfo.model}`)
|
if (deviceInfo.manufacturer && deviceInfo.model) lines.push(`${deviceInfo.manufacturer} ${deviceInfo.model}`)
|
||||||
if (deviceInfo.sdkVersion) lines.push(`SDK Version: ${deviceInfo.sdkVersion}`)
|
if (deviceInfo.sdkVersion) lines.push(`SDK Version: ${deviceInfo.sdkVersion}`)
|
||||||
return lines.join('<br>')
|
return lines
|
||||||
},
|
},
|
||||||
getPlayMethodName(playMethod) {
|
getPlayMethodName(playMethod) {
|
||||||
if (playMethod === this.$constants.PlayMethod.DIRECTPLAY) return 'Direct Play'
|
if (playMethod === this.$constants.PlayMethod.DIRECTPLAY) return 'Direct Play'
|
||||||
|
|||||||
@@ -13,11 +13,6 @@
|
|||||||
<widgets-online-indicator :value="!!userOnline" />
|
<widgets-online-indicator :value="!!userOnline" />
|
||||||
<h1 class="text-xl pl-2">{{ username }}</h1>
|
<h1 class="text-xl pl-2">{{ username }}</h1>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="legacyToken" class="text-xs space-y-2 mt-4">
|
|
||||||
<ui-text-input-with-label label="Legacy API Token" :value="legacyToken" readonly show-copy />
|
|
||||||
|
|
||||||
<p class="text-warning" v-html="$strings.MessageAuthenticationLegacyTokenWarning" />
|
|
||||||
</div>
|
|
||||||
<div class="w-full h-px bg-white/10 my-2" />
|
<div class="w-full h-px bg-white/10 my-2" />
|
||||||
<div class="py-2">
|
<div class="py-2">
|
||||||
<h1 class="text-lg mb-2 text-white/90 px-2 sm:px-0">{{ $strings.HeaderListeningStats }}</h1>
|
<h1 class="text-lg mb-2 text-white/90 px-2 sm:px-0">{{ $strings.HeaderListeningStats }}</h1>
|
||||||
@@ -102,12 +97,6 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
legacyToken() {
|
|
||||||
return this.user.token
|
|
||||||
},
|
|
||||||
userToken() {
|
|
||||||
return this.user.accessToken
|
|
||||||
},
|
|
||||||
bookCoverAspectRatio() {
|
bookCoverAspectRatio() {
|
||||||
return this.$store.getters['libraries/getBookCoverAspectRatio']
|
return this.$store.getters['libraries/getBookCoverAspectRatio']
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -19,39 +19,45 @@
|
|||||||
<div class="py-2">
|
<div class="py-2">
|
||||||
<h1 class="text-lg mb-2 text-white/90 px-2 sm:px-0">{{ $strings.HeaderListeningSessions }}</h1>
|
<h1 class="text-lg mb-2 text-white/90 px-2 sm:px-0">{{ $strings.HeaderListeningSessions }}</h1>
|
||||||
<div v-if="listeningSessions.length">
|
<div v-if="listeningSessions.length">
|
||||||
<table class="userSessionsTable">
|
<div class="overflow-x-auto">
|
||||||
<tr class="bg-primary/40">
|
<table class="userSessionsTable">
|
||||||
<th class="w-48 min-w-48 text-left">{{ $strings.LabelItem }}</th>
|
<tr class="bg-primary/40">
|
||||||
<th class="w-32 min-w-32 text-left hidden md:table-cell">{{ $strings.LabelPlayMethod }}</th>
|
<th class="w-48 min-w-48 text-left">{{ $strings.LabelItem }}</th>
|
||||||
<th class="w-32 min-w-32 text-left hidden sm:table-cell">{{ $strings.LabelDeviceInfo }}</th>
|
<th class="w-32 min-w-32 text-left hidden md:table-cell">{{ $strings.LabelPlayMethod }}</th>
|
||||||
<th class="w-32 min-w-32">{{ $strings.LabelTimeListened }}</th>
|
<th class="w-32 min-w-32 text-left hidden sm:table-cell">{{ $strings.LabelDeviceInfo }}</th>
|
||||||
<th class="w-16 min-w-16">{{ $strings.LabelLastTime }}</th>
|
<th class="w-32 min-w-32">{{ $strings.LabelTimeListened }}</th>
|
||||||
<th class="grow hidden sm:table-cell">{{ $strings.LabelLastUpdate }}</th>
|
<th class="w-16 min-w-16">{{ $strings.LabelLastTime }}</th>
|
||||||
</tr>
|
<th class="grow hidden sm:table-cell">{{ $strings.LabelLastUpdate }}</th>
|
||||||
<tr v-for="session in listeningSessions" :key="session.id" class="cursor-pointer" @click="showSession(session)">
|
</tr>
|
||||||
<td class="py-1 max-w-48">
|
<tr v-for="session in listeningSessions" :key="session.id" class="cursor-pointer" @click="showSession(session)">
|
||||||
<p class="text-xs text-gray-200 truncate">{{ session.displayTitle }}</p>
|
<td class="py-1 max-w-48">
|
||||||
<p class="text-xs text-gray-400 truncate">{{ session.displayAuthor }}</p>
|
<p class="text-xs text-gray-200 truncate">{{ session.displayTitle }}</p>
|
||||||
|
<p class="text-xs text-gray-400 truncate">{{ session.displayAuthor }}</p>
|
||||||
|
</td>
|
||||||
|
<td class="hidden md:table-cell">
|
||||||
|
<p class="text-xs">{{ getPlayMethodName(session.playMethod) }}</p>
|
||||||
|
</td>
|
||||||
|
<td class="hidden sm:table-cell min-w-32 max-w-32">
|
||||||
|
<p class="text-xs truncate">
|
||||||
|
<template v-for="(line, index) in getDeviceInfoLines(session.deviceInfo)">
|
||||||
|
<br v-if="index > 0" :key="'br-' + index" />{{ line }}
|
||||||
|
</template>
|
||||||
|
</p>
|
||||||
</td>
|
</td>
|
||||||
<td class="hidden md:table-cell">
|
<td class="text-center">
|
||||||
<p class="text-xs">{{ getPlayMethodName(session.playMethod) }}</p>
|
<p class="text-xs font-mono">{{ $elapsedPrettyLocalized(session.timeListening) }}</p>
|
||||||
</td>
|
</td>
|
||||||
<td class="hidden sm:table-cell min-w-32 max-w-32">
|
<td class="text-center hover:underline" @click.stop="clickCurrentTime(session)">
|
||||||
<p class="text-xs truncate" v-html="getDeviceInfoString(session.deviceInfo)" />
|
<p class="text-xs font-mono">{{ $secondsToTimestamp(session.currentTime) }}</p>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">
|
<td class="text-center hidden sm:table-cell">
|
||||||
<p class="text-xs font-mono">{{ $elapsedPrettyLocalized(session.timeListening) }}</p>
|
<ui-tooltip v-if="session.updatedAt" direction="top" :text="$formatDatetime(session.updatedAt, dateFormat, timeFormat)">
|
||||||
</td>
|
<p class="text-xs text-gray-200">{{ $dateDistanceFromNow(session.updatedAt) }}</p>
|
||||||
<td class="text-center hover:underline" @click.stop="clickCurrentTime(session)">
|
</ui-tooltip>
|
||||||
<p class="text-xs font-mono">{{ $secondsToTimestamp(session.currentTime) }}</p>
|
</td>
|
||||||
</td>
|
</tr>
|
||||||
<td class="text-center hidden sm:table-cell">
|
</table>
|
||||||
<ui-tooltip v-if="session.updatedAt" direction="top" :text="$formatDatetime(session.updatedAt, dateFormat, timeFormat)">
|
</div>
|
||||||
<p class="text-xs text-gray-200">{{ $dateDistanceFromNow(session.updatedAt) }}</p>
|
|
||||||
</ui-tooltip>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<div class="flex items-center justify-end py-1">
|
<div class="flex items-center justify-end py-1">
|
||||||
<ui-icon-btn icon="arrow_back_ios_new" :size="7" icon-font-size="1rem" class="mx-1" :disabled="currentPage === 0" @click="prevPage" />
|
<ui-icon-btn icon="arrow_back_ios_new" :size="7" icon-font-size="1rem" class="mx-1" :disabled="currentPage === 0" @click="prevPage" />
|
||||||
<p class="text-sm mx-1">{{ $getString('LabelPaginationPageXOfY', [currentPage + 1, numPages]) }}</p>
|
<p class="text-sm mx-1">{{ $getString('LabelPaginationPageXOfY', [currentPage + 1, numPages]) }}</p>
|
||||||
@@ -191,16 +197,16 @@ export default {
|
|||||||
this.selectedSession = session
|
this.selectedSession = session
|
||||||
this.showSessionModal = true
|
this.showSessionModal = true
|
||||||
},
|
},
|
||||||
getDeviceInfoString(deviceInfo) {
|
getDeviceInfoLines(deviceInfo) {
|
||||||
if (!deviceInfo) return ''
|
if (!deviceInfo) return []
|
||||||
var lines = []
|
const lines = []
|
||||||
if (deviceInfo.clientName) lines.push(`${deviceInfo.clientName} ${deviceInfo.clientVersion || ''}`)
|
if (deviceInfo.clientName) lines.push(`${deviceInfo.clientName} ${deviceInfo.clientVersion || ''}`)
|
||||||
if (deviceInfo.osName) lines.push(`${deviceInfo.osName} ${deviceInfo.osVersion}`)
|
if (deviceInfo.osName) lines.push(`${deviceInfo.osName} ${deviceInfo.osVersion}`)
|
||||||
if (deviceInfo.browserName) lines.push(deviceInfo.browserName)
|
if (deviceInfo.browserName) lines.push(deviceInfo.browserName)
|
||||||
|
|
||||||
if (deviceInfo.manufacturer && deviceInfo.model) lines.push(`${deviceInfo.manufacturer} ${deviceInfo.model}`)
|
if (deviceInfo.manufacturer && deviceInfo.model) lines.push(`${deviceInfo.manufacturer} ${deviceInfo.model}`)
|
||||||
if (deviceInfo.sdkVersion) lines.push(`SDK Version: ${deviceInfo.sdkVersion}`)
|
if (deviceInfo.sdkVersion) lines.push(`SDK Version: ${deviceInfo.sdkVersion}`)
|
||||||
return lines.join('<br>')
|
return lines
|
||||||
},
|
},
|
||||||
getPlayMethodName(playMethod) {
|
getPlayMethodName(playMethod) {
|
||||||
if (playMethod === this.$constants.PlayMethod.DIRECTPLAY) return 'Direct Play'
|
if (playMethod === this.$constants.PlayMethod.DIRECTPLAY) return 'Direct Play'
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex ml-2">
|
<ui-tooltip :text="$strings.LabelClickForMoreInfo" class="inline-flex ml-2">
|
||||||
<a href="https://www.audiobookshelf.org/guides/users" target="_blank" class="inline-flex">
|
<a href="https://audiobookshelf.org/docs/documentation/server-management/user-management" target="_blank" class="inline-flex">
|
||||||
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
|
<span class="material-symbols text-xl w-5 text-gray-200">help_outline</span>
|
||||||
</a>
|
</a>
|
||||||
</ui-tooltip>
|
</ui-tooltip>
|
||||||
|
|||||||
+10
-32
@@ -17,9 +17,9 @@
|
|||||||
|
|
||||||
<form @submit.prevent="submitServerSetup">
|
<form @submit.prevent="submitServerSetup">
|
||||||
<p class="text-lg font-semibold mb-2 pl-1 text-center">Create Root User</p>
|
<p class="text-lg font-semibold mb-2 pl-1 text-center">Create Root User</p>
|
||||||
<ui-text-input-with-label v-model.trim="newRoot.username" label="Username" :disabled="processing" class="w-full mb-3 text-sm" />
|
<ui-text-input-with-label v-model.trim="newRoot.username" label="Username" autocomplete="username" :disabled="processing" class="w-full mb-3 text-sm" />
|
||||||
<ui-text-input-with-label v-model="newRoot.password" label="Password" type="password" :disabled="processing" class="w-full mb-3 text-sm" />
|
<ui-text-input-with-label v-model="newRoot.password" label="Password" type="password" autocomplete="new-password" :disabled="processing" class="w-full mb-3 text-sm" />
|
||||||
<ui-text-input-with-label v-model="confirmPassword" label="Confirm Password" type="password" :disabled="processing" class="w-full mb-3 text-sm" />
|
<ui-text-input-with-label v-model="confirmPassword" label="Confirm Password" type="password" autocomplete="new-password" :disabled="processing" class="w-full mb-3 text-sm" />
|
||||||
|
|
||||||
<p class="text-lg font-semibold mt-6 mb-2 pl-1 text-center">Directory Paths</p>
|
<p class="text-lg font-semibold mt-6 mb-2 pl-1 text-center">Directory Paths</p>
|
||||||
<ui-text-input-with-label v-model="ConfigPath" label="Config Path" disabled class="w-full mb-3 text-sm" />
|
<ui-text-input-with-label v-model="ConfigPath" label="Config Path" disabled class="w-full mb-3 text-sm" />
|
||||||
@@ -40,21 +40,12 @@
|
|||||||
|
|
||||||
<p v-if="error" class="text-error text-center py-2">{{ error }}</p>
|
<p v-if="error" class="text-error text-center py-2">{{ error }}</p>
|
||||||
|
|
||||||
<div v-if="showNewAuthSystemMessage" class="mb-4">
|
|
||||||
<widgets-alert type="warning">
|
|
||||||
<div>
|
|
||||||
<p>{{ $strings.MessageAuthenticationSecurityMessage }}</p>
|
|
||||||
<a v-if="showNewAuthSystemAdminMessage" href="https://github.com/advplyr/audiobookshelf/discussions/4460" target="_blank" class="underline">{{ $strings.LabelMoreInfo }}</a>
|
|
||||||
</div>
|
|
||||||
</widgets-alert>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form v-show="login_local" @submit.prevent="submitForm">
|
<form v-show="login_local" @submit.prevent="submitForm">
|
||||||
<label class="text-xs text-gray-300 uppercase">{{ $strings.LabelUsername }}</label>
|
<label class="text-xs text-gray-300 uppercase">{{ $strings.LabelUsername }}</label>
|
||||||
<ui-text-input v-model.trim="username" :disabled="processing" class="mb-3 w-full" inputName="username" />
|
<ui-text-input v-model.trim="username" autocomplete="username" :disabled="processing" class="mb-3 w-full" inputName="username" />
|
||||||
|
|
||||||
<label class="text-xs text-gray-300 uppercase">{{ $strings.LabelPassword }}</label>
|
<label class="text-xs text-gray-300 uppercase">{{ $strings.LabelPassword }}</label>
|
||||||
<ui-text-input v-model.trim="password" type="password" :disabled="processing" class="w-full mb-3" inputName="password" />
|
<ui-text-input v-model.trim="password" type="password" autocomplete="current-password" :disabled="processing" class="w-full mb-3" inputName="password" />
|
||||||
<div class="w-full flex justify-end py-3">
|
<div class="w-full flex justify-end py-3">
|
||||||
<ui-btn type="submit" :disabled="processing" color="bg-primary" class="leading-none">{{ processing ? 'Checking...' : $strings.ButtonSubmit }}</ui-btn>
|
<ui-btn type="submit" :disabled="processing" color="bg-primary" class="leading-none">{{ processing ? 'Checking...' : $strings.ButtonSubmit }}</ui-btn>
|
||||||
</div>
|
</div>
|
||||||
@@ -94,10 +85,7 @@ export default {
|
|||||||
MetadataPath: '',
|
MetadataPath: '',
|
||||||
login_local: true,
|
login_local: true,
|
||||||
login_openid: false,
|
login_openid: false,
|
||||||
authFormData: null,
|
authFormData: null
|
||||||
// New JWT auth system re-login flags
|
|
||||||
showNewAuthSystemMessage: false,
|
|
||||||
showNewAuthSystemAdminMessage: false
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@@ -189,7 +177,8 @@ export default {
|
|||||||
require('@/plugins/chromecast.js').default(this)
|
require('@/plugins/chromecast.js').default(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$store.commit('libraries/setCurrentLibrary', userDefaultLibraryId)
|
this.$store.commit('libraries/setLastLoad', 0) // Ensure libraries get loaded again when switching users
|
||||||
|
this.$store.commit('libraries/setCurrentLibrary', { id: userDefaultLibraryId })
|
||||||
this.$store.commit('user/setUser', user)
|
this.$store.commit('user/setUser', user)
|
||||||
// Access token only returned from login, not authorize
|
// Access token only returned from login, not authorize
|
||||||
if (user.accessToken) {
|
if (user.accessToken) {
|
||||||
@@ -200,8 +189,6 @@ export default {
|
|||||||
},
|
},
|
||||||
async submitForm() {
|
async submitForm() {
|
||||||
this.error = null
|
this.error = null
|
||||||
this.showNewAuthSystemMessage = false
|
|
||||||
this.showNewAuthSystemAdminMessage = false
|
|
||||||
this.processing = true
|
this.processing = true
|
||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
@@ -237,15 +224,6 @@ export default {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
// Force re-login if user is using an old token with no expiration
|
|
||||||
if (res.user.isOldToken) {
|
|
||||||
this.username = res.user.username
|
|
||||||
this.showNewAuthSystemMessage = true
|
|
||||||
// Admin user sees link to github discussion
|
|
||||||
this.showNewAuthSystemAdminMessage = res.user.type === 'admin' || res.user.type === 'root'
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setUser(res)
|
this.setUser(res)
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
@@ -298,8 +276,8 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (authMethods.includes('openid')) {
|
if (authMethods.includes('openid')) {
|
||||||
// Auto redirect unless query string ?autoLaunch=0
|
// Auto redirect unless query string ?autoLaunch=0 OR when explicity requested through ?autoLaunch=1
|
||||||
if (this.authFormData?.authOpenIDAutoLaunch && this.$route.query?.autoLaunch !== '0') {
|
if ((this.authFormData?.authOpenIDAutoLaunch && this.$route.query?.autoLaunch !== '0') || this.$route.query?.autoLaunch == '1') {
|
||||||
window.location.href = this.openidAuthUri
|
window.location.href = this.openidAuthUri
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -364,6 +364,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const startTime = this.playbackSession.currentTime || 0
|
const startTime = this.playbackSession.currentTime || 0
|
||||||
|
|
||||||
this.localAudioPlayer.set(null, this.audioTracks, false, startTime, false)
|
this.localAudioPlayer.set(null, this.audioTracks, false, startTime, false)
|
||||||
this.localAudioPlayer.on('stateChange', this.playerStateChange.bind(this))
|
this.localAudioPlayer.on('stateChange', this.playerStateChange.bind(this))
|
||||||
this.localAudioPlayer.on('timeupdate', this.playerTimeUpdate.bind(this))
|
this.localAudioPlayer.on('timeupdate', this.playerTimeUpdate.bind(this))
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ export default {
|
|||||||
},
|
},
|
||||||
providers() {
|
providers() {
|
||||||
if (this.selectedLibraryIsPodcast) return this.$store.state.scanners.podcastProviders
|
if (this.selectedLibraryIsPodcast) return this.$store.state.scanners.podcastProviders
|
||||||
return this.$store.state.scanners.providers
|
return this.$store.state.scanners.bookProviders
|
||||||
},
|
},
|
||||||
canFetchMetadata() {
|
canFetchMetadata() {
|
||||||
return !this.selectedLibraryIsPodcast && this.fetchMetadata.enabled
|
return !this.selectedLibraryIsPodcast && this.fetchMetadata.enabled
|
||||||
@@ -297,6 +297,15 @@ export default {
|
|||||||
ref.setUploadStatus(status)
|
ref.setUploadStatus(status)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
updateItemCardProgress(index, progress) {
|
||||||
|
var ref = this.$refs[`itemCard-${index}`]
|
||||||
|
if (ref && ref.length) ref = ref[0]
|
||||||
|
if (!ref) {
|
||||||
|
console.error('Book card ref not found', index, this.$refs)
|
||||||
|
} else {
|
||||||
|
ref.setUploadProgress(progress)
|
||||||
|
}
|
||||||
|
},
|
||||||
async uploadItem(item) {
|
async uploadItem(item) {
|
||||||
var form = new FormData()
|
var form = new FormData()
|
||||||
form.set('title', item.title)
|
form.set('title', item.title)
|
||||||
@@ -312,8 +321,20 @@ export default {
|
|||||||
form.set(`${index++}`, file)
|
form.set(`${index++}`, file)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
onUploadProgress: (progressEvent) => {
|
||||||
|
if (progressEvent.lengthComputable) {
|
||||||
|
const progress = {
|
||||||
|
loaded: progressEvent.loaded,
|
||||||
|
total: progressEvent.total
|
||||||
|
}
|
||||||
|
this.updateItemCardProgress(item.index, progress)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return this.$axios
|
return this.$axios
|
||||||
.$post('/api/upload', form)
|
.$post('/api/upload', form, config)
|
||||||
.then(() => true)
|
.then(() => true)
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed to upload item', error)
|
console.error('Failed to upload item', error)
|
||||||
@@ -394,6 +415,8 @@ export default {
|
|||||||
this.setMetadataProvider()
|
this.setMetadataProvider()
|
||||||
|
|
||||||
this.setDefaultFolder()
|
this.setDefaultFolder()
|
||||||
|
// Fetch providers if not already loaded
|
||||||
|
this.$store.dispatch('scanners/fetchProviders')
|
||||||
window.addEventListener('dragenter', this.dragenter)
|
window.addEventListener('dragenter', this.dragenter)
|
||||||
window.addEventListener('dragleave', this.dragleave)
|
window.addEventListener('dragleave', this.dragleave)
|
||||||
window.addEventListener('dragover', this.dragover)
|
window.addEventListener('dragover', this.dragover)
|
||||||
|
|||||||
@@ -46,7 +46,20 @@ export default class LocalAudioPlayer extends EventEmitter {
|
|||||||
this.player.addEventListener('loadedmetadata', this.evtLoadedMetadata.bind(this))
|
this.player.addEventListener('loadedmetadata', this.evtLoadedMetadata.bind(this))
|
||||||
this.player.addEventListener('timeupdate', this.evtTimeupdate.bind(this))
|
this.player.addEventListener('timeupdate', this.evtTimeupdate.bind(this))
|
||||||
|
|
||||||
var mimeTypes = ['audio/flac', 'audio/mpeg', 'audio/mp4', 'audio/ogg', 'audio/aac', 'audio/x-ms-wma', 'audio/x-aiff', 'audio/webm']
|
var mimeTypes = [
|
||||||
|
'audio/flac',
|
||||||
|
'audio/mpeg',
|
||||||
|
'audio/mp4',
|
||||||
|
'audio/ogg',
|
||||||
|
'audio/aac',
|
||||||
|
'audio/x-ms-wma',
|
||||||
|
'audio/x-aiff',
|
||||||
|
'audio/webm',
|
||||||
|
// `audio/matroska` is the correct mimetype, but the server still uses `audio/x-matroska`
|
||||||
|
// ref: https://www.iana.org/assignments/media-types/media-types.xhtml
|
||||||
|
'audio/matroska',
|
||||||
|
'audio/x-matroska'
|
||||||
|
]
|
||||||
var mimeTypeCanPlayMap = {}
|
var mimeTypeCanPlayMap = {}
|
||||||
mimeTypes.forEach((mt) => {
|
mimeTypes.forEach((mt) => {
|
||||||
var canPlay = this.player.canPlayType(mt)
|
var canPlay = this.player.canPlayType(mt)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ const defaultCode = 'en-us'
|
|||||||
|
|
||||||
const languageCodeMap = {
|
const languageCodeMap = {
|
||||||
ar: { label: 'عربي', dateFnsLocale: 'ar' },
|
ar: { label: 'عربي', dateFnsLocale: 'ar' },
|
||||||
|
be: { label: 'Беларуская', dateFnsLocale: 'be' },
|
||||||
bg: { label: 'Български', dateFnsLocale: 'bg' },
|
bg: { label: 'Български', dateFnsLocale: 'bg' },
|
||||||
bn: { label: 'বাংলা', dateFnsLocale: 'bn' },
|
bn: { label: 'বাংলা', dateFnsLocale: 'bn' },
|
||||||
ca: { label: 'Català', dateFnsLocale: 'ca' },
|
ca: { label: 'Català', dateFnsLocale: 'ca' },
|
||||||
@@ -20,15 +21,19 @@ const languageCodeMap = {
|
|||||||
he: { label: 'עברית', dateFnsLocale: 'he' },
|
he: { label: 'עברית', dateFnsLocale: 'he' },
|
||||||
hr: { label: 'Hrvatski', dateFnsLocale: 'hr' },
|
hr: { label: 'Hrvatski', dateFnsLocale: 'hr' },
|
||||||
it: { label: 'Italiano', dateFnsLocale: 'it' },
|
it: { label: 'Italiano', dateFnsLocale: 'it' },
|
||||||
|
ja: { label: '日本語', dateFnsLocale: 'ja' },
|
||||||
lt: { label: 'Lietuvių', dateFnsLocale: 'lt' },
|
lt: { label: 'Lietuvių', dateFnsLocale: 'lt' },
|
||||||
hu: { label: 'Magyar', dateFnsLocale: 'hu' },
|
hu: { label: 'Magyar', dateFnsLocale: 'hu' },
|
||||||
|
ko: { label: '한국어', dateFnsLocale: 'ko' },
|
||||||
nl: { label: 'Nederlands', dateFnsLocale: 'nl' },
|
nl: { label: 'Nederlands', dateFnsLocale: 'nl' },
|
||||||
no: { label: 'Norsk', dateFnsLocale: 'no' },
|
no: { label: 'Norsk', dateFnsLocale: 'no' },
|
||||||
pl: { label: 'Polski', dateFnsLocale: 'pl' },
|
pl: { label: 'Polski', dateFnsLocale: 'pl' },
|
||||||
'pt-br': { label: 'Português (Brasil)', dateFnsLocale: 'ptBR' },
|
'pt-br': { label: 'Português (Brasil)', dateFnsLocale: 'ptBR' },
|
||||||
ru: { label: 'Русский', dateFnsLocale: 'ru' },
|
ru: { label: 'Русский', dateFnsLocale: 'ru' },
|
||||||
|
sk: { label: 'Slovenčina', dateFnsLocale: 'sk' },
|
||||||
sl: { label: 'Slovenščina', dateFnsLocale: 'sl' },
|
sl: { label: 'Slovenščina', dateFnsLocale: 'sl' },
|
||||||
sv: { label: 'Svenska', dateFnsLocale: 'sv' },
|
sv: { label: 'Svenska', dateFnsLocale: 'sv' },
|
||||||
|
tr: { label: 'Türkçe', dateFnsLocale: 'tr' },
|
||||||
uk: { label: 'Українська', dateFnsLocale: 'uk' },
|
uk: { label: 'Українська', dateFnsLocale: 'uk' },
|
||||||
'vi-vn': { label: 'Tiếng Việt', dateFnsLocale: 'vi' },
|
'vi-vn': { label: 'Tiếng Việt', dateFnsLocale: 'vi' },
|
||||||
'zh-cn': { label: '简体中文 (Simplified Chinese)', dateFnsLocale: 'zhCN' },
|
'zh-cn': { label: '简体中文 (Simplified Chinese)', dateFnsLocale: 'zhCN' },
|
||||||
@@ -46,6 +51,7 @@ const podcastSearchRegionMap = {
|
|||||||
au: { label: 'Australia' },
|
au: { label: 'Australia' },
|
||||||
br: { label: 'Brasil' },
|
br: { label: 'Brasil' },
|
||||||
be: { label: 'België / Belgique / Belgien' },
|
be: { label: 'België / Belgique / Belgien' },
|
||||||
|
by: { label: 'Беларусь' },
|
||||||
cz: { label: 'Česko' },
|
cz: { label: 'Česko' },
|
||||||
dk: { label: 'Danmark' },
|
dk: { label: 'Danmark' },
|
||||||
de: { label: 'Deutschland' },
|
de: { label: 'Deutschland' },
|
||||||
@@ -55,6 +61,7 @@ const podcastSearchRegionMap = {
|
|||||||
hr: { label: 'Hrvatska' },
|
hr: { label: 'Hrvatska' },
|
||||||
il: { label: 'ישראל / إسرائيل' },
|
il: { label: 'ישראל / إسرائيل' },
|
||||||
it: { label: 'Italia' },
|
it: { label: 'Italia' },
|
||||||
|
jp: { label: '日本' },
|
||||||
lu: { label: 'Luxembourg / Luxemburg / Lëtezebuerg' },
|
lu: { label: 'Luxembourg / Luxemburg / Lëtezebuerg' },
|
||||||
hu: { label: 'Magyarország' },
|
hu: { label: 'Magyarország' },
|
||||||
nl: { label: 'Nederland' },
|
nl: { label: 'Nederland' },
|
||||||
@@ -65,6 +72,7 @@ const podcastSearchRegionMap = {
|
|||||||
pt: { label: 'Portugal' },
|
pt: { label: 'Portugal' },
|
||||||
ru: { label: 'Россия' },
|
ru: { label: 'Россия' },
|
||||||
ch: { label: 'Schweiz / Suisse / Svizzera' },
|
ch: { label: 'Schweiz / Suisse / Svizzera' },
|
||||||
|
sk: { label: 'Slovensko' },
|
||||||
se: { label: 'Sverige' },
|
se: { label: 'Sverige' },
|
||||||
vn: { label: 'Việt Nam' },
|
vn: { label: 'Việt Nam' },
|
||||||
ua: { label: 'Україна' },
|
ua: { label: 'Україна' },
|
||||||
|
|||||||
@@ -117,7 +117,6 @@ export const actions = {
|
|||||||
const library = data.library
|
const library = data.library
|
||||||
const filterData = data.filterdata
|
const filterData = data.filterdata
|
||||||
const issues = data.issues || 0
|
const issues = data.issues || 0
|
||||||
const customMetadataProviders = data.customMetadataProviders || []
|
|
||||||
const numUserPlaylists = data.numUserPlaylists
|
const numUserPlaylists = data.numUserPlaylists
|
||||||
|
|
||||||
dispatch('user/checkUpdateLibrarySortFilter', library.mediaType, { root: true })
|
dispatch('user/checkUpdateLibrarySortFilter', library.mediaType, { root: true })
|
||||||
@@ -131,9 +130,7 @@ export const actions = {
|
|||||||
commit('setLibraryIssues', issues)
|
commit('setLibraryIssues', issues)
|
||||||
commit('setLibraryFilterData', filterData)
|
commit('setLibraryFilterData', filterData)
|
||||||
commit('setNumUserPlaylists', numUserPlaylists)
|
commit('setNumUserPlaylists', numUserPlaylists)
|
||||||
commit('scanners/setCustomMetadataProviders', customMetadataProviders, { root: true })
|
commit('setCurrentLibrary', { id: libraryId })
|
||||||
|
|
||||||
commit('setCurrentLibrary', libraryId)
|
|
||||||
return data
|
return data
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
@@ -159,7 +156,7 @@ export const actions = {
|
|||||||
.$get(`/api/libraries`)
|
.$get(`/api/libraries`)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
commit('set', data.libraries)
|
commit('set', data.libraries)
|
||||||
commit('setLastLoad')
|
commit('setLastLoad', new Date())
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed', error)
|
console.error('Failed', error)
|
||||||
@@ -176,14 +173,14 @@ export const mutations = {
|
|||||||
setFoldersLastUpdate(state) {
|
setFoldersLastUpdate(state) {
|
||||||
state.folderLastUpdate = Date.now()
|
state.folderLastUpdate = Date.now()
|
||||||
},
|
},
|
||||||
setLastLoad(state) {
|
setLastLoad(state, date) {
|
||||||
state.lastLoad = Date.now()
|
state.lastLoad = date
|
||||||
},
|
},
|
||||||
setLibraryIssues(state, val) {
|
setLibraryIssues(state, val) {
|
||||||
state.issues = val
|
state.issues = val
|
||||||
},
|
},
|
||||||
setCurrentLibrary(state, val) {
|
setCurrentLibrary(state, { id }) {
|
||||||
state.currentLibraryId = val
|
state.currentLibraryId = id
|
||||||
},
|
},
|
||||||
set(state, libraries) {
|
set(state, libraries) {
|
||||||
state.libraries = libraries
|
state.libraries = libraries
|
||||||
|
|||||||
+50
-116
@@ -1,126 +1,60 @@
|
|||||||
export const state = () => ({
|
export const state = () => ({
|
||||||
providers: [
|
bookProviders: [],
|
||||||
{
|
podcastProviders: [],
|
||||||
text: 'Google Books',
|
bookCoverProviders: [],
|
||||||
value: 'google'
|
podcastCoverProviders: [],
|
||||||
},
|
providersLoaded: false
|
||||||
{
|
|
||||||
text: 'Open Library',
|
|
||||||
value: 'openlibrary'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'iTunes',
|
|
||||||
value: 'itunes'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Audible.com',
|
|
||||||
value: 'audible'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Audible.ca',
|
|
||||||
value: 'audible.ca'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Audible.co.uk',
|
|
||||||
value: 'audible.uk'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Audible.com.au',
|
|
||||||
value: 'audible.au'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Audible.fr',
|
|
||||||
value: 'audible.fr'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Audible.de',
|
|
||||||
value: 'audible.de'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Audible.co.jp',
|
|
||||||
value: 'audible.jp'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Audible.it',
|
|
||||||
value: 'audible.it'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Audible.co.in',
|
|
||||||
value: 'audible.in'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Audible.es',
|
|
||||||
value: 'audible.es'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'FantLab.ru',
|
|
||||||
value: 'fantlab'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
podcastProviders: [
|
|
||||||
{
|
|
||||||
text: 'iTunes',
|
|
||||||
value: 'itunes'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
coverOnlyProviders: [
|
|
||||||
{
|
|
||||||
text: 'AudiobookCovers.com',
|
|
||||||
value: 'audiobookcovers'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
})
|
})
|
||||||
|
|
||||||
export const getters = {
|
export const getters = {
|
||||||
checkBookProviderExists: state => (providerValue) => {
|
checkBookProviderExists: (state) => (providerValue) => {
|
||||||
return state.providers.some(p => p.value === providerValue)
|
return state.bookProviders.some((p) => p.value === providerValue)
|
||||||
},
|
},
|
||||||
checkPodcastProviderExists: state => (providerValue) => {
|
checkPodcastProviderExists: (state) => (providerValue) => {
|
||||||
return state.podcastProviders.some(p => p.value === providerValue)
|
return state.podcastProviders.some((p) => p.value === providerValue)
|
||||||
|
},
|
||||||
|
areProvidersLoaded: (state) => state.providersLoaded
|
||||||
|
}
|
||||||
|
|
||||||
|
export const actions = {
|
||||||
|
async fetchProviders({ commit, state }) {
|
||||||
|
// Only fetch if not already loaded
|
||||||
|
if (state.providersLoaded) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await this.$axios.$get('/api/search/providers')
|
||||||
|
if (response?.providers) {
|
||||||
|
commit('setAllProviders', response.providers)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to fetch providers', error)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async refreshProviders({ commit, state }) {
|
||||||
|
// if providers are not loaded, do nothing - they will be fetched when required (
|
||||||
|
if (!state.providersLoaded) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await this.$axios.$get('/api/search/providers')
|
||||||
|
if (response?.providers) {
|
||||||
|
commit('setAllProviders', response.providers)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to refresh providers', error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const actions = {}
|
|
||||||
|
|
||||||
export const mutations = {
|
export const mutations = {
|
||||||
addCustomMetadataProvider(state, provider) {
|
setAllProviders(state, providers) {
|
||||||
if (provider.mediaType === 'book') {
|
state.bookProviders = providers.books || []
|
||||||
if (state.providers.some(p => p.value === provider.slug)) return
|
state.podcastProviders = providers.podcasts || []
|
||||||
state.providers.push({
|
state.bookCoverProviders = providers.booksCovers || []
|
||||||
text: provider.name,
|
state.podcastCoverProviders = providers.podcasts || [] // Use same as bookCovers since podcasts use iTunes only
|
||||||
value: provider.slug
|
state.providersLoaded = true
|
||||||
})
|
|
||||||
} else {
|
|
||||||
if (state.podcastProviders.some(p => p.value === provider.slug)) return
|
|
||||||
state.podcastProviders.push({
|
|
||||||
text: provider.name,
|
|
||||||
value: provider.slug
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
removeCustomMetadataProvider(state, provider) {
|
|
||||||
if (provider.mediaType === 'book') {
|
|
||||||
state.providers = state.providers.filter(p => p.value !== provider.slug)
|
|
||||||
} else {
|
|
||||||
state.podcastProviders = state.podcastProviders.filter(p => p.value !== provider.slug)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setCustomMetadataProviders(state, providers) {
|
|
||||||
if (!providers?.length) return
|
|
||||||
|
|
||||||
const mediaType = providers[0].mediaType
|
|
||||||
if (mediaType === 'book') {
|
|
||||||
// clear previous values, and add new values to the end
|
|
||||||
state.providers = state.providers.filter((p) => !p.value.startsWith('custom-'))
|
|
||||||
state.providers = [
|
|
||||||
...state.providers,
|
|
||||||
...providers.map((p) => ({
|
|
||||||
text: p.name,
|
|
||||||
value: p.slug
|
|
||||||
}))
|
|
||||||
]
|
|
||||||
} else {
|
|
||||||
// Podcast providers not supported yet
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -92,7 +92,7 @@ export const actions = {
|
|||||||
if (state.settings.orderBy == 'media.duration') {
|
if (state.settings.orderBy == 'media.duration') {
|
||||||
settingsUpdate.orderBy = 'media.numTracks'
|
settingsUpdate.orderBy = 'media.numTracks'
|
||||||
}
|
}
|
||||||
if (state.settings.orderBy == 'media.metadata.publishedYear') {
|
if (state.settings.orderBy == 'media.metadata.publishedYear' || state.settings.orderBy == 'progress') {
|
||||||
settingsUpdate.orderBy = 'media.metadata.title'
|
settingsUpdate.orderBy = 'media.metadata.title'
|
||||||
}
|
}
|
||||||
const invalidFilters = ['series', 'authors', 'narrators', 'publishers', 'publishedDecades', 'languages', 'progress', 'issues', 'ebooks', 'abridged']
|
const invalidFilters = ['series', 'authors', 'narrators', 'publishers', 'publishedDecades', 'languages', 'progress', 'issues', 'ebooks', 'abridged']
|
||||||
@@ -152,7 +152,6 @@ export const actions = {
|
|||||||
.$post('/auth/refresh')
|
.$post('/auth/refresh')
|
||||||
.then(async (response) => {
|
.then(async (response) => {
|
||||||
const newAccessToken = response.user.accessToken
|
const newAccessToken = response.user.accessToken
|
||||||
commit('setUser', response.user)
|
|
||||||
commit('setAccessToken', newAccessToken)
|
commit('setAccessToken', newAccessToken)
|
||||||
// Emit event used to re-authenticate socket in default.vue since $root is not available here
|
// Emit event used to re-authenticate socket in default.vue since $root is not available here
|
||||||
if (this.$eventBus) {
|
if (this.$eventBus) {
|
||||||
|
|||||||
+20
-5
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"ButtonAdd": "إضافة",
|
"ButtonAdd": "إضافة",
|
||||||
|
"ButtonAddApiKey": "إضافة مفتاح واجهة برمجة التطبيقات",
|
||||||
"ButtonAddChapters": "إضافة الفصول",
|
"ButtonAddChapters": "إضافة الفصول",
|
||||||
"ButtonAddDevice": "إضافة جهاز",
|
"ButtonAddDevice": "إضافة جهاز",
|
||||||
"ButtonAddLibrary": "إضافة مكتبة",
|
"ButtonAddLibrary": "إضافة مكتبة",
|
||||||
@@ -20,7 +21,8 @@
|
|||||||
"ButtonChooseAFolder": "اختر المجلد",
|
"ButtonChooseAFolder": "اختر المجلد",
|
||||||
"ButtonChooseFiles": "اختر الملفات",
|
"ButtonChooseFiles": "اختر الملفات",
|
||||||
"ButtonClearFilter": "تصفية الفرز",
|
"ButtonClearFilter": "تصفية الفرز",
|
||||||
"ButtonCloseFeed": "إغلاق",
|
"ButtonClose": "إغلاق",
|
||||||
|
"ButtonCloseFeed": "إغلاق الموجز",
|
||||||
"ButtonCloseSession": "إغلاق الجلسة المفتوحة",
|
"ButtonCloseSession": "إغلاق الجلسة المفتوحة",
|
||||||
"ButtonCollections": "المجموعات",
|
"ButtonCollections": "المجموعات",
|
||||||
"ButtonConfigureScanner": "إعدادات الماسح الضوئي",
|
"ButtonConfigureScanner": "إعدادات الماسح الضوئي",
|
||||||
@@ -119,11 +121,13 @@
|
|||||||
"HeaderAccount": "الحساب",
|
"HeaderAccount": "الحساب",
|
||||||
"HeaderAddCustomMetadataProvider": "إضافة موفر بيانات تعريفية مخصص",
|
"HeaderAddCustomMetadataProvider": "إضافة موفر بيانات تعريفية مخصص",
|
||||||
"HeaderAdvanced": "متقدم",
|
"HeaderAdvanced": "متقدم",
|
||||||
|
"HeaderApiKeys": "مفاتيح API",
|
||||||
"HeaderAppriseNotificationSettings": "إعدادات الإشعارات",
|
"HeaderAppriseNotificationSettings": "إعدادات الإشعارات",
|
||||||
"HeaderAudioTracks": "المقاطع الصوتية",
|
"HeaderAudioTracks": "المقاطع الصوتية",
|
||||||
"HeaderAudiobookTools": "أدوات إدارة ملفات الكتب الصوتية",
|
"HeaderAudiobookTools": "أدوات إدارة ملفات الكتب الصوتية",
|
||||||
"HeaderAuthentication": "المصادقة",
|
"HeaderAuthentication": "المصادقة",
|
||||||
"HeaderBackups": "النسخ الاحتياطية",
|
"HeaderBackups": "النسخ الاحتياطية",
|
||||||
|
"HeaderBulkChapterModal": "أضف فصولاً متعددة",
|
||||||
"HeaderChangePassword": "تغيير كلمة المرور",
|
"HeaderChangePassword": "تغيير كلمة المرور",
|
||||||
"HeaderChapters": "الفصول",
|
"HeaderChapters": "الفصول",
|
||||||
"HeaderChooseAFolder": "اختيار المجلد",
|
"HeaderChooseAFolder": "اختيار المجلد",
|
||||||
@@ -162,6 +166,7 @@
|
|||||||
"HeaderMetadataOrderOfPrecedence": "ترتيب أولوية البيانات الوصفية",
|
"HeaderMetadataOrderOfPrecedence": "ترتيب أولوية البيانات الوصفية",
|
||||||
"HeaderMetadataToEmbed": "البيانات الوصفية المراد تضمينها",
|
"HeaderMetadataToEmbed": "البيانات الوصفية المراد تضمينها",
|
||||||
"HeaderNewAccount": "حساب جديد",
|
"HeaderNewAccount": "حساب جديد",
|
||||||
|
"HeaderNewApiKey": "مفتاح API جديد",
|
||||||
"HeaderNewLibrary": "مكتبة جديدة",
|
"HeaderNewLibrary": "مكتبة جديدة",
|
||||||
"HeaderNotificationCreate": "إنشاء إشعار",
|
"HeaderNotificationCreate": "إنشاء إشعار",
|
||||||
"HeaderNotificationUpdate": "تحديث إشعار",
|
"HeaderNotificationUpdate": "تحديث إشعار",
|
||||||
@@ -195,6 +200,7 @@
|
|||||||
"HeaderSettingsExperimental": "ميزات تجريبية",
|
"HeaderSettingsExperimental": "ميزات تجريبية",
|
||||||
"HeaderSettingsGeneral": "عام",
|
"HeaderSettingsGeneral": "عام",
|
||||||
"HeaderSettingsScanner": "إعدادات المسح",
|
"HeaderSettingsScanner": "إعدادات المسح",
|
||||||
|
"HeaderSettingsSecurity": "الأمان",
|
||||||
"HeaderSettingsWebClient": "عميل الويب",
|
"HeaderSettingsWebClient": "عميل الويب",
|
||||||
"HeaderSleepTimer": "مؤقت النوم",
|
"HeaderSleepTimer": "مؤقت النوم",
|
||||||
"HeaderStatsLargestItems": "أكبر العناصر حجماً",
|
"HeaderStatsLargestItems": "أكبر العناصر حجماً",
|
||||||
@@ -206,6 +212,7 @@
|
|||||||
"HeaderTableOfContents": "جدول المحتويات",
|
"HeaderTableOfContents": "جدول المحتويات",
|
||||||
"HeaderTools": "أدوات",
|
"HeaderTools": "أدوات",
|
||||||
"HeaderUpdateAccount": "تحديث الحساب",
|
"HeaderUpdateAccount": "تحديث الحساب",
|
||||||
|
"HeaderUpdateApiKey": "تحديث مفتاح API",
|
||||||
"HeaderUpdateAuthor": "تحديث المؤلف",
|
"HeaderUpdateAuthor": "تحديث المؤلف",
|
||||||
"HeaderUpdateDetails": "تحديث التفاصيل",
|
"HeaderUpdateDetails": "تحديث التفاصيل",
|
||||||
"HeaderUpdateLibrary": "تحديث المكتبة",
|
"HeaderUpdateLibrary": "تحديث المكتبة",
|
||||||
@@ -235,6 +242,10 @@
|
|||||||
"LabelAllUsersExcludingGuests": "جميع المستخدمين باستثناء الضيوف",
|
"LabelAllUsersExcludingGuests": "جميع المستخدمين باستثناء الضيوف",
|
||||||
"LabelAllUsersIncludingGuests": "جميع المستخدمين بما في ذلك الضيوف",
|
"LabelAllUsersIncludingGuests": "جميع المستخدمين بما في ذلك الضيوف",
|
||||||
"LabelAlreadyInYourLibrary": "موجود بالفعل في مكتبتك",
|
"LabelAlreadyInYourLibrary": "موجود بالفعل في مكتبتك",
|
||||||
|
"LabelApiKeyCreated": "تم إنشاء مفتاح API \"{0}\" بنجاح.",
|
||||||
|
"LabelApiKeyCreatedDescription": "تأكد من نسخ مفتاح API الآن، لن تتمكن من رؤيته مرة أخرى.",
|
||||||
|
"LabelApiKeyUser": "التصرف بالنيابة عن مستخدم",
|
||||||
|
"LabelApiKeyUserDescription": "مفتاح API سيمتلك نفس صلاحيات المستخدم الذي ينوب عنه ، سيظهر بالسجلات وكأن المستخدم قام بالطلب.",
|
||||||
"LabelApiToken": "رمز API",
|
"LabelApiToken": "رمز API",
|
||||||
"LabelAppend": "إلحاق",
|
"LabelAppend": "إلحاق",
|
||||||
"LabelAudioBitrate": "معدل بت الصوت (على سبيل المثال 128 كيلو بايت)",
|
"LabelAudioBitrate": "معدل بت الصوت (على سبيل المثال 128 كيلو بايت)",
|
||||||
@@ -284,6 +295,7 @@
|
|||||||
"LabelContinueListening": "استمرار الاستماع",
|
"LabelContinueListening": "استمرار الاستماع",
|
||||||
"LabelContinueReading": "استمرار القراءة",
|
"LabelContinueReading": "استمرار القراءة",
|
||||||
"LabelContinueSeries": "استمرار المسلسلات",
|
"LabelContinueSeries": "استمرار المسلسلات",
|
||||||
|
"LabelCorsAllowed": "CORS Origins مسموح",
|
||||||
"LabelCover": "الغلاف",
|
"LabelCover": "الغلاف",
|
||||||
"LabelCoverImageURL": "رابط صورة الغلاف",
|
"LabelCoverImageURL": "رابط صورة الغلاف",
|
||||||
"LabelCoverProvider": "مزود الغلاف",
|
"LabelCoverProvider": "مزود الغلاف",
|
||||||
@@ -346,7 +358,7 @@
|
|||||||
"LabelExample": "مثال",
|
"LabelExample": "مثال",
|
||||||
"LabelExpandSeries": "توسيع السلاسل",
|
"LabelExpandSeries": "توسيع السلاسل",
|
||||||
"LabelExpandSubSeries": "توسيع السلاسل الفرعية",
|
"LabelExpandSubSeries": "توسيع السلاسل الفرعية",
|
||||||
"LabelExplicit": "صريح",
|
"LabelExplicit": "محتوى صريح",
|
||||||
"LabelExplicitChecked": "صريح (محدد)",
|
"LabelExplicitChecked": "صريح (محدد)",
|
||||||
"LabelExplicitUnchecked": "غير صريح (غير محدد)",
|
"LabelExplicitUnchecked": "غير صريح (غير محدد)",
|
||||||
"LabelExportOPML": "تصدير OPML",
|
"LabelExportOPML": "تصدير OPML",
|
||||||
@@ -365,7 +377,7 @@
|
|||||||
"LabelFolders": "مجلدات",
|
"LabelFolders": "مجلدات",
|
||||||
"LabelFontBold": "عريض",
|
"LabelFontBold": "عريض",
|
||||||
"LabelFontBoldness": "تعريض الخط",
|
"LabelFontBoldness": "تعريض الخط",
|
||||||
"LabelFontFamily": "عائلة الخط",
|
"LabelFontFamily": "عائلة الخطوط",
|
||||||
"LabelFontItalic": "مائل",
|
"LabelFontItalic": "مائل",
|
||||||
"LabelFontScale": "نطاق الخط",
|
"LabelFontScale": "نطاق الخط",
|
||||||
"LabelFontStrikethrough": "يتوسطه خط",
|
"LabelFontStrikethrough": "يتوسطه خط",
|
||||||
@@ -417,6 +429,9 @@
|
|||||||
"LabelLibraryFilterSublistEmpty": "لا يوجد {0}",
|
"LabelLibraryFilterSublistEmpty": "لا يوجد {0}",
|
||||||
"LabelLibraryItem": "عنصر المكتبة",
|
"LabelLibraryItem": "عنصر المكتبة",
|
||||||
"LabelLibraryName": "اسم المكتبة",
|
"LabelLibraryName": "اسم المكتبة",
|
||||||
|
"LabelLibrarySortByProgress": "المرحلة: الأحدث",
|
||||||
|
"LabelLibrarySortByProgressFinished": "المرحلة: تم الانتهاء",
|
||||||
|
"LabelLibrarySortByProgressStarted": "المرحلة: تم البدء",
|
||||||
"LabelLimit": "حد",
|
"LabelLimit": "حد",
|
||||||
"LabelLineSpacing": "تباعد الأسطر",
|
"LabelLineSpacing": "تباعد الأسطر",
|
||||||
"LabelListenAgain": "الاستماع مجدداً",
|
"LabelListenAgain": "الاستماع مجدداً",
|
||||||
@@ -561,7 +576,7 @@
|
|||||||
"LabelSettingsBookshelfViewHelp": "تصميم يحاكي الواقع مع رفوف خشبية",
|
"LabelSettingsBookshelfViewHelp": "تصميم يحاكي الواقع مع رفوف خشبية",
|
||||||
"LabelSettingsChromecastSupport": "دعم Chromecast",
|
"LabelSettingsChromecastSupport": "دعم Chromecast",
|
||||||
"LabelSettingsDateFormat": "تنسيق التاريخ",
|
"LabelSettingsDateFormat": "تنسيق التاريخ",
|
||||||
"LabelSettingsEnableWatcher": "فحص المكتبات تلقائيًا بحثًا عن تغييرات",
|
"LabelSettingsEnableWatcher": "مراقبة المكتبات تلقائياً بحثاً عن تغييرات",
|
||||||
"LabelSettingsEnableWatcherForLibrary": "فحص المكتبة تلقائيًا بحثًا عن تغييرات",
|
"LabelSettingsEnableWatcherForLibrary": "فحص المكتبة تلقائيًا بحثًا عن تغييرات",
|
||||||
"LabelSettingsEnableWatcherHelp": "يمكّن الإضافة/التحديث التلقائي للعناصر عند اكتشاف تغييرات في الملفات. *يتطلب إعادة تشغيل الخادم",
|
"LabelSettingsEnableWatcherHelp": "يمكّن الإضافة/التحديث التلقائي للعناصر عند اكتشاف تغييرات في الملفات. *يتطلب إعادة تشغيل الخادم",
|
||||||
"LabelSettingsEpubsAllowScriptedContent": "السماح بالمحتوى النصي في ملفات epub",
|
"LabelSettingsEpubsAllowScriptedContent": "السماح بالمحتوى النصي في ملفات epub",
|
||||||
@@ -852,7 +867,7 @@
|
|||||||
"MessageResetChaptersConfirm": "هل أنت متأكد أنك تريد إعادة تعيين الفصول والتراجع عن التغييرات التي أجريتها؟",
|
"MessageResetChaptersConfirm": "هل أنت متأكد أنك تريد إعادة تعيين الفصول والتراجع عن التغييرات التي أجريتها؟",
|
||||||
"MessageRestoreBackupConfirm": "هل أنت متأكد أنك تريد استعادة النسخ الاحتياطي الذي تم إنشاؤه في",
|
"MessageRestoreBackupConfirm": "هل أنت متأكد أنك تريد استعادة النسخ الاحتياطي الذي تم إنشاؤه في",
|
||||||
"MessageRestoreBackupWarning": "ستؤدي استعادة النسخ الاحتياطي إلى الكتابة فوق قاعدة البيانات بأكملها الموجودة في /config وصور الأغلفة في /metadata/items و /metadata/authors.<br /><br /> لا تعدل النسخ الاحتياطية أي ملفات في مجلدات مكتبتك. إذا قمت بتمكين إعدادات الخادم لتخزين صور الأغلفة والبيانات الوصفية في مجلدات مكتبتك، فلن يتم نسخها احتياطيًا أو الكتابة فوقها.<br /><br /> سيتم تحديث جميع العملاء الذين يستخدمون الخادم الخاص بك تلقائيًا.",
|
"MessageRestoreBackupWarning": "ستؤدي استعادة النسخ الاحتياطي إلى الكتابة فوق قاعدة البيانات بأكملها الموجودة في /config وصور الأغلفة في /metadata/items و /metadata/authors.<br /><br /> لا تعدل النسخ الاحتياطية أي ملفات في مجلدات مكتبتك. إذا قمت بتمكين إعدادات الخادم لتخزين صور الأغلفة والبيانات الوصفية في مجلدات مكتبتك، فلن يتم نسخها احتياطيًا أو الكتابة فوقها.<br /><br /> سيتم تحديث جميع العملاء الذين يستخدمون الخادم الخاص بك تلقائيًا.",
|
||||||
"MessageScheduleLibraryScanNote": "بالنسبة لمعظم المستخدمين، يوصى بترك هذه الميزة معطلة وإبقاء إعداد مراقب المجلدات ممكّنًا. سيكتشف مراقب المجلدات تلقائيًا التغييرات في مجلدات مكتبتك. لا يعمل مراقب المجلدات مع كل نظام ملفات (مثل NFS)، لذا يمكن استخدام عمليات فحص المكتبة المجدولة بدلاً من ذلك.",
|
"MessageScheduleLibraryScanNote": "لمعظم المستخدمين، موصى بترك هذه الميزة معطلة وإبقاء ممكّنة الأعداد، ”قم بمراقبة المكتبة تلقائاً للتغييرات“. سوف يقم بالكشف التلقائي عن تغييرات في مجلدات مكتبتك. لو لم يعمل الإعداد، \"قم بمراقبة المكتبة تلقائاً للتغييرات،“مع نظمة ملفاتك المستخدمة (مثل NFS على سبيل المثال)، فأمكِن هذه الميزة.",
|
||||||
"MessageScheduleRunEveryWeekdayAtTime": "تشغيل كل {0} في الساعة {1}",
|
"MessageScheduleRunEveryWeekdayAtTime": "تشغيل كل {0} في الساعة {1}",
|
||||||
"MessageSearchResultsFor": "نتائج البحث عن",
|
"MessageSearchResultsFor": "نتائج البحث عن",
|
||||||
"MessageSelected": "تم تحديد {0}",
|
"MessageSelected": "تم تحديد {0}",
|
||||||
|
|||||||
+726
-172
File diff suppressed because it is too large.
Load diff
+267
-10
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"ButtonAdd": "Създай",
|
"ButtonAdd": "Създай",
|
||||||
|
"ButtonAddApiKey": "Добави API ключ",
|
||||||
"ButtonAddChapters": "Добави Глави",
|
"ButtonAddChapters": "Добави Глави",
|
||||||
"ButtonAddDevice": "Добави Устройство",
|
"ButtonAddDevice": "Добави Устройство",
|
||||||
"ButtonAddLibrary": "Добави Библиотека",
|
"ButtonAddLibrary": "Добави Библиотека",
|
||||||
@@ -20,6 +21,7 @@
|
|||||||
"ButtonChooseAFolder": "Избери Папка",
|
"ButtonChooseAFolder": "Избери Папка",
|
||||||
"ButtonChooseFiles": "Избери Файлове",
|
"ButtonChooseFiles": "Избери Файлове",
|
||||||
"ButtonClearFilter": "Изчисти филтър",
|
"ButtonClearFilter": "Изчисти филтър",
|
||||||
|
"ButtonClose": "Затвори",
|
||||||
"ButtonCloseFeed": "Затвори стената",
|
"ButtonCloseFeed": "Затвори стената",
|
||||||
"ButtonCloseSession": "Затвори отворената сесия",
|
"ButtonCloseSession": "Затвори отворената сесия",
|
||||||
"ButtonCollections": "Колекции",
|
"ButtonCollections": "Колекции",
|
||||||
@@ -119,11 +121,13 @@
|
|||||||
"HeaderAccount": "Профил",
|
"HeaderAccount": "Профил",
|
||||||
"HeaderAddCustomMetadataProvider": "Добави персонализиран доставчик на метаданни",
|
"HeaderAddCustomMetadataProvider": "Добави персонализиран доставчик на метаданни",
|
||||||
"HeaderAdvanced": "Разширени настройки",
|
"HeaderAdvanced": "Разширени настройки",
|
||||||
|
"HeaderApiKeys": "API ключове",
|
||||||
"HeaderAppriseNotificationSettings": "Apprise Notification Опции",
|
"HeaderAppriseNotificationSettings": "Apprise Notification Опции",
|
||||||
"HeaderAudioTracks": "Песни",
|
"HeaderAudioTracks": "Песни",
|
||||||
"HeaderAudiobookTools": "Инструмент за Менижиране на Аудиокниги",
|
"HeaderAudiobookTools": "Инструмент за Менижиране на Аудиокниги",
|
||||||
"HeaderAuthentication": "Аутентикация",
|
"HeaderAuthentication": "Аутентикация",
|
||||||
"HeaderBackups": "Архив",
|
"HeaderBackups": "Архив",
|
||||||
|
"HeaderBulkChapterModal": "Добави няколко глави",
|
||||||
"HeaderChangePassword": "Промяна на Парола",
|
"HeaderChangePassword": "Промяна на Парола",
|
||||||
"HeaderChapters": "Глави",
|
"HeaderChapters": "Глави",
|
||||||
"HeaderChooseAFolder": "Избети Папка",
|
"HeaderChooseAFolder": "Избети Папка",
|
||||||
@@ -162,6 +166,7 @@
|
|||||||
"HeaderMetadataOrderOfPrecedence": "Предимство на Метаданни",
|
"HeaderMetadataOrderOfPrecedence": "Предимство на Метаданни",
|
||||||
"HeaderMetadataToEmbed": "Метаданни за Вграждане",
|
"HeaderMetadataToEmbed": "Метаданни за Вграждане",
|
||||||
"HeaderNewAccount": "Нов Профил",
|
"HeaderNewAccount": "Нов Профил",
|
||||||
|
"HeaderNewApiKey": "Нов API ключ",
|
||||||
"HeaderNewLibrary": "Нова Библиотека",
|
"HeaderNewLibrary": "Нова Библиотека",
|
||||||
"HeaderNotificationCreate": "Създай нотификация",
|
"HeaderNotificationCreate": "Създай нотификация",
|
||||||
"HeaderNotificationUpdate": "Обнови нотификация",
|
"HeaderNotificationUpdate": "Обнови нотификация",
|
||||||
@@ -195,6 +200,7 @@
|
|||||||
"HeaderSettingsExperimental": "Експериментални Функции",
|
"HeaderSettingsExperimental": "Експериментални Функции",
|
||||||
"HeaderSettingsGeneral": "Общи",
|
"HeaderSettingsGeneral": "Общи",
|
||||||
"HeaderSettingsScanner": "Скенер",
|
"HeaderSettingsScanner": "Скенер",
|
||||||
|
"HeaderSettingsSecurity": "Сигурност",
|
||||||
"HeaderSettingsWebClient": "Уеб клиент",
|
"HeaderSettingsWebClient": "Уеб клиент",
|
||||||
"HeaderSleepTimer": "Таймер за заспиване",
|
"HeaderSleepTimer": "Таймер за заспиване",
|
||||||
"HeaderStatsLargestItems": "Най-Големите Елементи",
|
"HeaderStatsLargestItems": "Най-Големите Елементи",
|
||||||
@@ -206,6 +212,7 @@
|
|||||||
"HeaderTableOfContents": "Съдържание",
|
"HeaderTableOfContents": "Съдържание",
|
||||||
"HeaderTools": "Инструменти",
|
"HeaderTools": "Инструменти",
|
||||||
"HeaderUpdateAccount": "Обнови Профил",
|
"HeaderUpdateAccount": "Обнови Профил",
|
||||||
|
"HeaderUpdateApiKey": "Обнови API ключ",
|
||||||
"HeaderUpdateAuthor": "Обнови Автор",
|
"HeaderUpdateAuthor": "Обнови Автор",
|
||||||
"HeaderUpdateDetails": "Обнови Детайли",
|
"HeaderUpdateDetails": "Обнови Детайли",
|
||||||
"HeaderUpdateLibrary": "Обнови Библиотека",
|
"HeaderUpdateLibrary": "Обнови Библиотека",
|
||||||
@@ -230,10 +237,15 @@
|
|||||||
"LabelAddedDate": "Добавено",
|
"LabelAddedDate": "Добавено",
|
||||||
"LabelAdminUsersOnly": "Само за Администратори",
|
"LabelAdminUsersOnly": "Само за Администратори",
|
||||||
"LabelAll": "Всичко",
|
"LabelAll": "Всичко",
|
||||||
|
"LabelAllEpisodesDownloaded": "Всички епизоди са изтеглени",
|
||||||
"LabelAllUsers": "Всички Потребители",
|
"LabelAllUsers": "Всички Потребители",
|
||||||
"LabelAllUsersExcludingGuests": "Всички потребители без гости",
|
"LabelAllUsersExcludingGuests": "Всички потребители без гости",
|
||||||
"LabelAllUsersIncludingGuests": "Всички потребители включително гости",
|
"LabelAllUsersIncludingGuests": "Всички потребители включително гости",
|
||||||
"LabelAlreadyInYourLibrary": "Вече е в твоята библиотека",
|
"LabelAlreadyInYourLibrary": "Вече е в твоята библиотека",
|
||||||
|
"LabelApiKeyCreated": "API ключ \"{0}\" успешно създатен.",
|
||||||
|
"LabelApiKeyCreatedDescription": "Погрижете се да копирате API ключът сега, защото повече няма да можете да го виждате онново.",
|
||||||
|
"LabelApiKeyUser": "Действай от името на потребителя",
|
||||||
|
"LabelApiKeyUserDescription": "Този API ключ ще има същите права като на потребителя за чието име действа. В логовете ще изглежда все едно потребителя прави заявката.",
|
||||||
"LabelApiToken": "АПИ Токен",
|
"LabelApiToken": "АПИ Токен",
|
||||||
"LabelAppend": "Добави",
|
"LabelAppend": "Добави",
|
||||||
"LabelAudioBitrate": "Аудио битрейт (напр. 128k)",
|
"LabelAudioBitrate": "Аудио битрейт (напр. 128k)",
|
||||||
@@ -253,7 +265,7 @@
|
|||||||
"LabelBackToUser": "Обратно към Потребител",
|
"LabelBackToUser": "Обратно към Потребител",
|
||||||
"LabelBackupAudioFiles": "Създай резервно копие на аудио файлове",
|
"LabelBackupAudioFiles": "Създай резервно копие на аудио файлове",
|
||||||
"LabelBackupLocation": "Местоположение на Архив",
|
"LabelBackupLocation": "Местоположение на Архив",
|
||||||
"LabelBackupsEnableAutomaticBackups": "Включи автоматично архивиране",
|
"LabelBackupsEnableAutomaticBackups": "Автоматично архивиране",
|
||||||
"LabelBackupsEnableAutomaticBackupsHelp": "Архиви запазени в /metadata/backups",
|
"LabelBackupsEnableAutomaticBackupsHelp": "Архиви запазени в /metadata/backups",
|
||||||
"LabelBackupsMaxBackupSize": "Максимален размер на архива (в GB) (0 за неограничен)",
|
"LabelBackupsMaxBackupSize": "Максимален размер на архива (в GB) (0 за неограничен)",
|
||||||
"LabelBackupsMaxBackupSizeHelp": "За защита срещу грешки в конфигурацията, архивите ще се провалят ако надхвърлят конфигурирания размер.",
|
"LabelBackupsMaxBackupSizeHelp": "За защита срещу грешки в конфигурацията, архивите ще се провалят ако надхвърлят конфигурирания размер.",
|
||||||
@@ -272,7 +284,7 @@
|
|||||||
"LabelChaptersFound": "намерени глави",
|
"LabelChaptersFound": "намерени глави",
|
||||||
"LabelClickForMoreInfo": "Кликни за повече информация",
|
"LabelClickForMoreInfo": "Кликни за повече информация",
|
||||||
"LabelClickToUseCurrentValue": "Натисни да ползваш сегашната стойност",
|
"LabelClickToUseCurrentValue": "Натисни да ползваш сегашната стойност",
|
||||||
"LabelClosePlayer": "Затвори",
|
"LabelClosePlayer": "Затвори плейъра",
|
||||||
"LabelCodec": "Кодек",
|
"LabelCodec": "Кодек",
|
||||||
"LabelCollapseSeries": "Скрий сериите",
|
"LabelCollapseSeries": "Скрий сериите",
|
||||||
"LabelCollapseSubSeries": "Свий подсерии",
|
"LabelCollapseSubSeries": "Свий подсерии",
|
||||||
@@ -283,6 +295,7 @@
|
|||||||
"LabelContinueListening": "Продължи слушане",
|
"LabelContinueListening": "Продължи слушане",
|
||||||
"LabelContinueReading": "Продължи четене",
|
"LabelContinueReading": "Продължи четене",
|
||||||
"LabelContinueSeries": "Продължи серии",
|
"LabelContinueSeries": "Продължи серии",
|
||||||
|
"LabelCorsAllowed": "Разрешени CORS Origins",
|
||||||
"LabelCover": "Корица",
|
"LabelCover": "Корица",
|
||||||
"LabelCoverImageURL": "URL на Корица",
|
"LabelCoverImageURL": "URL на Корица",
|
||||||
"LabelCoverProvider": "Източник за обложки",
|
"LabelCoverProvider": "Източник за обложки",
|
||||||
@@ -296,6 +309,7 @@
|
|||||||
"LabelDeleteFromFileSystemCheckbox": "Изтрий от файловата система (отмени за да бъдат премахни само от базата данни)",
|
"LabelDeleteFromFileSystemCheckbox": "Изтрий от файловата система (отмени за да бъдат премахни само от базата данни)",
|
||||||
"LabelDescription": "Описание",
|
"LabelDescription": "Описание",
|
||||||
"LabelDeselectAll": "Премахни всички",
|
"LabelDeselectAll": "Премахни всички",
|
||||||
|
"LabelDetectedPattern": "Намерен образец:",
|
||||||
"LabelDevice": "Устройство",
|
"LabelDevice": "Устройство",
|
||||||
"LabelDeviceInfo": "Информация за Устройство",
|
"LabelDeviceInfo": "Информация за Устройство",
|
||||||
"LabelDeviceIsAvailableTo": "Устройството е достъпно за ...",
|
"LabelDeviceIsAvailableTo": "Устройството е достъпно за ...",
|
||||||
@@ -345,7 +359,11 @@
|
|||||||
"LabelExample": "Пример",
|
"LabelExample": "Пример",
|
||||||
"LabelExpandSeries": "Покажи сериите",
|
"LabelExpandSeries": "Покажи сериите",
|
||||||
"LabelExpandSubSeries": "Покажи съб сериите",
|
"LabelExpandSubSeries": "Покажи съб сериите",
|
||||||
"LabelExplicit": "С нецензурно съдържание",
|
"LabelExpired": "Изтекъл",
|
||||||
|
"LabelExpiresAt": "Изтича на",
|
||||||
|
"LabelExpiresInSeconds": "Изтича след (секунди)",
|
||||||
|
"LabelExpiresNever": "Никога",
|
||||||
|
"LabelExplicit": "Експлицитно",
|
||||||
"LabelExplicitChecked": "С нецензурно съдържание (проверено)",
|
"LabelExplicitChecked": "С нецензурно съдържание (проверено)",
|
||||||
"LabelExplicitUnchecked": "Без нецензурно съдържание (непроверено)",
|
"LabelExplicitUnchecked": "Без нецензурно съдържание (непроверено)",
|
||||||
"LabelExportOPML": "Експортирай OPML",
|
"LabelExportOPML": "Експортирай OPML",
|
||||||
@@ -360,6 +378,7 @@
|
|||||||
"LabelFilterByUser": "Филтриране по Потребител",
|
"LabelFilterByUser": "Филтриране по Потребител",
|
||||||
"LabelFindEpisodes": "Намери Епизоди",
|
"LabelFindEpisodes": "Намери Епизоди",
|
||||||
"LabelFinished": "Дата на приключване",
|
"LabelFinished": "Дата на приключване",
|
||||||
|
"LabelFinishedDate": "Приключено на {0}",
|
||||||
"LabelFolder": "Папка",
|
"LabelFolder": "Папка",
|
||||||
"LabelFolders": "Папки",
|
"LabelFolders": "Папки",
|
||||||
"LabelFontBold": "Получерно",
|
"LabelFontBold": "Получерно",
|
||||||
@@ -404,6 +423,7 @@
|
|||||||
"LabelLanguages": "Езици",
|
"LabelLanguages": "Езици",
|
||||||
"LabelLastBookAdded": "Последно Добавена Книга",
|
"LabelLastBookAdded": "Последно Добавена Книга",
|
||||||
"LabelLastBookUpdated": "Последно Обновена Книга",
|
"LabelLastBookUpdated": "Последно Обновена Книга",
|
||||||
|
"LabelLastProgressDate": "Последен прогрес: {0}",
|
||||||
"LabelLastSeen": "Последно Видян",
|
"LabelLastSeen": "Последно Видян",
|
||||||
"LabelLastTime": "Последно Време",
|
"LabelLastTime": "Последно Време",
|
||||||
"LabelLastUpdate": "Последно Обновяване",
|
"LabelLastUpdate": "Последно Обновяване",
|
||||||
@@ -416,6 +436,9 @@
|
|||||||
"LabelLibraryFilterSublistEmpty": "Не {0}",
|
"LabelLibraryFilterSublistEmpty": "Не {0}",
|
||||||
"LabelLibraryItem": "Елемент на Библиотека",
|
"LabelLibraryItem": "Елемент на Библиотека",
|
||||||
"LabelLibraryName": "Име на Библиотека",
|
"LabelLibraryName": "Име на Библиотека",
|
||||||
|
"LabelLibrarySortByProgress": "Прогрес: Последно обновление",
|
||||||
|
"LabelLibrarySortByProgressFinished": "Прогрес: Приключено",
|
||||||
|
"LabelLibrarySortByProgressStarted": "Прогрес: Започнато",
|
||||||
"LabelLimit": "Лимит",
|
"LabelLimit": "Лимит",
|
||||||
"LabelLineSpacing": "Междуредие",
|
"LabelLineSpacing": "Междуредие",
|
||||||
"LabelListenAgain": "Слушай отново",
|
"LabelListenAgain": "Слушай отново",
|
||||||
@@ -424,6 +447,7 @@
|
|||||||
"LabelLogLevelWarn": "Предупреждение",
|
"LabelLogLevelWarn": "Предупреждение",
|
||||||
"LabelLookForNewEpisodesAfterDate": "Търси нови епизоди след дата",
|
"LabelLookForNewEpisodesAfterDate": "Търси нови епизоди след дата",
|
||||||
"LabelLowestPriority": "Най-нисък Приоритет",
|
"LabelLowestPriority": "Най-нисък Приоритет",
|
||||||
|
"LabelMatchConfidence": "Увереност",
|
||||||
"LabelMatchExistingUsersBy": "Съпостави съществуващи потребители по",
|
"LabelMatchExistingUsersBy": "Съпостави съществуващи потребители по",
|
||||||
"LabelMatchExistingUsersByDescription": "Използва се за свързване на съществуващи потребители. След свързване потребителите ще бъдат съпоставени по уникален идентификатор от вашия доставчик на SSO",
|
"LabelMatchExistingUsersByDescription": "Използва се за свързване на съществуващи потребители. След свързване потребителите ще бъдат съпоставени по уникален идентификатор от вашия доставчик на SSO",
|
||||||
"LabelMaxEpisodesToDownload": "Максимален брой епизоди за сваляне. Използвай 0 за неограничен.",
|
"LabelMaxEpisodesToDownload": "Максимален брой епизоди за сваляне. Използвай 0 за неограничен.",
|
||||||
@@ -453,7 +477,9 @@
|
|||||||
"LabelNewestAuthors": "Най-новите автори",
|
"LabelNewestAuthors": "Най-новите автори",
|
||||||
"LabelNewestEpisodes": "Най-новите епизоди",
|
"LabelNewestEpisodes": "Най-новите епизоди",
|
||||||
"LabelNextBackupDate": "Следваща Дата на Архивиране",
|
"LabelNextBackupDate": "Следваща Дата на Архивиране",
|
||||||
|
"LabelNextChapters": "Следващите глави ще бъдат:",
|
||||||
"LabelNextScheduledRun": "Следващо Планирано Изпълнение",
|
"LabelNextScheduledRun": "Следващо Планирано Изпълнение",
|
||||||
|
"LabelNoApiKeys": "Няма API ключове",
|
||||||
"LabelNoCustomMetadataProviders": "Няма потребителски доставчици на метаданни",
|
"LabelNoCustomMetadataProviders": "Няма потребителски доставчици на метаданни",
|
||||||
"LabelNoEpisodesSelected": "Няма избрани епизоди",
|
"LabelNoEpisodesSelected": "Няма избрани епизоди",
|
||||||
"LabelNotFinished": "Не е приключено",
|
"LabelNotFinished": "Не е приключено",
|
||||||
@@ -469,6 +495,7 @@
|
|||||||
"LabelNotificationsMaxQueueSize": "Максимален размер на опашката за известия",
|
"LabelNotificationsMaxQueueSize": "Максимален размер на опашката за известия",
|
||||||
"LabelNotificationsMaxQueueSizeHelp": "Събитията са ограничени до изстрелване на 1 на секунда. Събитията ще бъдат игнорирани ако опашката е на максимален размер. Това предотвратява спамирането на известия.",
|
"LabelNotificationsMaxQueueSizeHelp": "Събитията са ограничени до изстрелване на 1 на секунда. Събитията ще бъдат игнорирани ако опашката е на максимален размер. Това предотвратява спамирането на известия.",
|
||||||
"LabelNumberOfBooks": "Брой на Книги",
|
"LabelNumberOfBooks": "Брой на Книги",
|
||||||
|
"LabelNumberOfChapters": "Брой глави:",
|
||||||
"LabelNumberOfEpisodes": "Брой епизоди",
|
"LabelNumberOfEpisodes": "Брой епизоди",
|
||||||
"LabelOpenIDAdvancedPermsClaimDescription": "Име на OpenID твърдението, което съдържа разширени права за достъп до потребителски действия в приложението, които ще се прилагат за роли, различни от администраторските (<b>ако е конфигурирано</b>). Ако твърдението липсва в отговора, достъпът до ABS ще бъде отказан. Ако липсва една опция, тя ще се третира като <code>false</code>. Уверете се, че твърдението на доставчика на идентичност съответства на очакваната структура:",
|
"LabelOpenIDAdvancedPermsClaimDescription": "Име на OpenID твърдението, което съдържа разширени права за достъп до потребителски действия в приложението, които ще се прилагат за роли, различни от администраторските (<b>ако е конфигурирано</b>). Ако твърдението липсва в отговора, достъпът до ABS ще бъде отказан. Ако липсва една опция, тя ще се третира като <code>false</code>. Уверете се, че твърдението на доставчика на идентичност съответства на очакваната структура:",
|
||||||
"LabelOpenIDClaims": "Оставете следните опции празни, за да деактивирате разширеното присвояване на групи, като автоматично ще бъде присвоена групата 'Потребител'.",
|
"LabelOpenIDClaims": "Оставете следните опции празни, за да деактивирате разширеното присвояване на групи, като автоматично ще бъде присвоена групата 'Потребител'.",
|
||||||
@@ -513,7 +540,7 @@
|
|||||||
"LabelPublishers": "Издателство",
|
"LabelPublishers": "Издателство",
|
||||||
"LabelRSSFeedCustomOwnerEmail": "Персонализиран имейл на собственика",
|
"LabelRSSFeedCustomOwnerEmail": "Персонализиран имейл на собственика",
|
||||||
"LabelRSSFeedCustomOwnerName": "Персонализирано име на собственика",
|
"LabelRSSFeedCustomOwnerName": "Персонализирано име на собственика",
|
||||||
"LabelRSSFeedOpen": "RSS Feed Оптворен",
|
"LabelRSSFeedOpen": "RSS Feed е отворен",
|
||||||
"LabelRSSFeedPreventIndexing": "Предотвратете индексиране",
|
"LabelRSSFeedPreventIndexing": "Предотвратете индексиране",
|
||||||
"LabelRSSFeedSlug": "идентификатор на RSS емисия",
|
"LabelRSSFeedSlug": "идентификатор на RSS емисия",
|
||||||
"LabelRSSFeedURL": "URL на RSS емисия",
|
"LabelRSSFeedURL": "URL на RSS емисия",
|
||||||
@@ -543,6 +570,7 @@
|
|||||||
"LabelSelectAll": "Избери всичко",
|
"LabelSelectAll": "Избери всичко",
|
||||||
"LabelSelectAllEpisodes": "Избери всички епизоди",
|
"LabelSelectAllEpisodes": "Избери всички епизоди",
|
||||||
"LabelSelectEpisodesShowing": "Избери {0} епизоди показани",
|
"LabelSelectEpisodesShowing": "Избери {0} епизоди показани",
|
||||||
|
"LabelSelectUser": "Избери потребител",
|
||||||
"LabelSelectUsers": "Избери Потребители",
|
"LabelSelectUsers": "Избери Потребители",
|
||||||
"LabelSendEbookToDevice": "Изпрати електронна книга до ...",
|
"LabelSendEbookToDevice": "Изпрати електронна книга до ...",
|
||||||
"LabelSequence": "Последователност",
|
"LabelSequence": "Последователност",
|
||||||
@@ -560,8 +588,8 @@
|
|||||||
"LabelSettingsBookshelfViewHelp": "Скеуморфен дизайн с дървени рафтове",
|
"LabelSettingsBookshelfViewHelp": "Скеуморфен дизайн с дървени рафтове",
|
||||||
"LabelSettingsChromecastSupport": "Chromecast поддръжка",
|
"LabelSettingsChromecastSupport": "Chromecast поддръжка",
|
||||||
"LabelSettingsDateFormat": "Формат на Дата",
|
"LabelSettingsDateFormat": "Формат на Дата",
|
||||||
"LabelSettingsEnableWatcher": "Автоматично сканиране на библиотеките за промени",
|
"LabelSettingsEnableWatcher": "Автоматично преглеждане на библиотеките за промени",
|
||||||
"LabelSettingsEnableWatcherForLibrary": "Автоматично сканиране на библиотеката за промени",
|
"LabelSettingsEnableWatcherForLibrary": "Автоматично преглеждане на библиотеката за промени",
|
||||||
"LabelSettingsEnableWatcherHelp": "Включва автоматичното добавяне/обновяване на елементи, когато се открият промени във файловете. *Изисква рестарт на сървъра",
|
"LabelSettingsEnableWatcherHelp": "Включва автоматичното добавяне/обновяване на елементи, когато се открият промени във файловете. *Изисква рестарт на сървъра",
|
||||||
"LabelSettingsEpubsAllowScriptedContent": "Позволи скриптово съдържание в epub-и",
|
"LabelSettingsEpubsAllowScriptedContent": "Позволи скриптово съдържание в epub-и",
|
||||||
"LabelSettingsEpubsAllowScriptedContentHelp": "Позволи epub файловете да изпълняват скриптове. Препоръчително е да бъде изключено освен ако не се доверявате на източника на epub файловете.",
|
"LabelSettingsEpubsAllowScriptedContentHelp": "Позволи epub файловете да изпълняват скриптове. Препоръчително е да бъде изключено освен ако не се доверявате на източника на epub файловете.",
|
||||||
@@ -610,6 +638,7 @@
|
|||||||
"LabelStartTime": "Начално Време",
|
"LabelStartTime": "Начално Време",
|
||||||
"LabelStarted": "Стартирано",
|
"LabelStarted": "Стартирано",
|
||||||
"LabelStartedAt": "Стартирано на",
|
"LabelStartedAt": "Стартирано на",
|
||||||
|
"LabelStartedDate": "Започнато {0}",
|
||||||
"LabelStatsAudioTracks": "Аудио Канали",
|
"LabelStatsAudioTracks": "Аудио Канали",
|
||||||
"LabelStatsAuthors": "Автори",
|
"LabelStatsAuthors": "Автори",
|
||||||
"LabelStatsBestDay": "Най-добър ден",
|
"LabelStatsBestDay": "Най-добър ден",
|
||||||
@@ -639,6 +668,7 @@
|
|||||||
"LabelTheme": "Тема",
|
"LabelTheme": "Тема",
|
||||||
"LabelThemeDark": "Тъмна",
|
"LabelThemeDark": "Тъмна",
|
||||||
"LabelThemeLight": "Светла",
|
"LabelThemeLight": "Светла",
|
||||||
|
"LabelThemeSepia": "Сепия",
|
||||||
"LabelTimeBase": "Времева Основа",
|
"LabelTimeBase": "Времева Основа",
|
||||||
"LabelTimeDurationXHours": "{0} часа",
|
"LabelTimeDurationXHours": "{0} часа",
|
||||||
"LabelTimeDurationXMinutes": "{0} минути",
|
"LabelTimeDurationXMinutes": "{0} минути",
|
||||||
@@ -693,7 +723,11 @@
|
|||||||
"LabelViewPlayerSettings": "Виж настройки на плеъра",
|
"LabelViewPlayerSettings": "Виж настройки на плеъра",
|
||||||
"LabelViewQueue": "Виж Опашка",
|
"LabelViewQueue": "Виж Опашка",
|
||||||
"LabelVolume": "Сила на Звука",
|
"LabelVolume": "Сила на Звука",
|
||||||
|
"LabelWebRedirectURLsDescription": "Разрешете тези URL-и във вашият OAuth доставчик, за да позволите пренасочването обратно към уеб приложението след вход:",
|
||||||
|
"LabelWebRedirectURLsSubfolder": "Подпапка за URL адреси за пренасочване",
|
||||||
"LabelWeekdaysToRun": "Делници за изпълнение",
|
"LabelWeekdaysToRun": "Делници за изпълнение",
|
||||||
|
"LabelXBooks": "{0} книги",
|
||||||
|
"LabelXItems": "{0} елемента",
|
||||||
"LabelYearReviewHide": "Скрий ревю на годината ти",
|
"LabelYearReviewHide": "Скрий ревю на годината ти",
|
||||||
"LabelYearReviewShow": "Виж ревю на годината ти",
|
"LabelYearReviewShow": "Виж ревю на годината ти",
|
||||||
"LabelYourAudiobookDuration": "Продължителност на вашата аудиокнига",
|
"LabelYourAudiobookDuration": "Продължителност на вашата аудиокнига",
|
||||||
@@ -702,41 +736,64 @@
|
|||||||
"LabelYourProgress": "Твоят прогрес",
|
"LabelYourProgress": "Твоят прогрес",
|
||||||
"MessageAddToPlayerQueue": "Добави към опашката на плейъра",
|
"MessageAddToPlayerQueue": "Добави към опашката на плейъра",
|
||||||
"MessageAppriseDescription": "За да ползвате тази функция трябва да имате активна инстанция на <a href=\"https://github.com/caronc/apprise-api\" target=\"_blank\">Apprise API</a> или на друго АПИ което да обработва тези заявки. <br />The Apprise API Url-а трябва дае пълния URL път за изпращане на известията, например, ако вашето АПИ ве подава от <code>http://192.168.1.1:8337</code> трябва да сложитев <code>http://192.168.1.1:8337/notify</code>.",
|
"MessageAppriseDescription": "За да ползвате тази функция трябва да имате активна инстанция на <a href=\"https://github.com/caronc/apprise-api\" target=\"_blank\">Apprise API</a> или на друго АПИ което да обработва тези заявки. <br />The Apprise API Url-а трябва дае пълния URL път за изпращане на известията, например, ако вашето АПИ ве подава от <code>http://192.168.1.1:8337</code> трябва да сложитев <code>http://192.168.1.1:8337/notify</code>.",
|
||||||
|
"MessageAsinCheck": "Уверете се, че използвате ASIN от правилния Audible регион, а не от Amazon.",
|
||||||
|
"MessageAuthenticationLegacyTokenWarning": "Остарелите API токени ще бъдат премахнати в бъдеще. Вместо това използвайте <a href=\"/config/api-keys\">API ключове</a>.",
|
||||||
|
"MessageAuthenticationOIDCChangesRestart": "Рестартирайте сървърът след записването на настройките, за да активирате OIDC промените.",
|
||||||
|
"MessageAuthenticationSecurityMessage": "За осигуряването на по-добра сигурност, автентикацията беше подобрена. Всеки потребител ще трябва да се автентикира наново.",
|
||||||
"MessageBackupsDescription": "Резервните копия включват потребители, напредък на потребителите, подробности за елементите в библиотеката, настройки на сървъра и изображения, съхранени в <code>/metadata/items</code> и <code>/metadata/authors</code>. Резервните копия <strong>не</strong> включват никакви файлове, съхранени в папките на вашата библиотека.",
|
"MessageBackupsDescription": "Резервните копия включват потребители, напредък на потребителите, подробности за елементите в библиотеката, настройки на сървъра и изображения, съхранени в <code>/metadata/items</code> и <code>/metadata/authors</code>. Резервните копия <strong>не</strong> включват никакви файлове, съхранени в папките на вашата библиотека.",
|
||||||
|
"MessageBackupsLocationEditNote": "Забележка: Актуализирането на местоположението за архивиране няма да премести или промени съществуващите архиви",
|
||||||
|
"MessageBackupsLocationNoEditNote": "Забележка: Местоположението за архивиране се задава с помощта на променлива на средата и не може бъде променена от тук.",
|
||||||
|
"MessageBackupsLocationPathEmpty": "Пътят към местоположението за архивиране не може да бъде празен",
|
||||||
|
"MessageBatchEditPopulateMapDetailsAllHelp": "Популирайте активираните полета с данни от всички елементи. Полетата със няколко стоайности ще бъдат обединени",
|
||||||
|
"MessageBatchEditPopulateMapDetailsItemHelp": "Попълнете активираните полета с информация за картата с данни от този елемент",
|
||||||
"MessageBatchQuickMatchDescription": "Бързото Съпоставяне ще опита да добави липсващи корици и метаданни за избраните елементи. Активирайте опциите по-долу, за да позволите на Бързото съпоставяне да презапише съществуващите корици и/или метаданни.",
|
"MessageBatchQuickMatchDescription": "Бързото Съпоставяне ще опита да добави липсващи корици и метаданни за избраните елементи. Активирайте опциите по-долу, за да позволите на Бързото съпоставяне да презапише съществуващите корици и/или метаданни.",
|
||||||
"MessageBookshelfNoCollections": "Все още нямате създадени колекции",
|
"MessageBookshelfNoCollections": "Все още нямате създадени колекции",
|
||||||
|
"MessageBookshelfNoCollectionsHelp": "Колекциите са публични. Всички потребители с достъп до библиотеката ще могат да ги виждат.",
|
||||||
"MessageBookshelfNoRSSFeeds": "Няма отворени RSS feed-ове",
|
"MessageBookshelfNoRSSFeeds": "Няма отворени RSS feed-ове",
|
||||||
"MessageBookshelfNoResultsForFilter": "Няма резултат за филтер \"{0}: {1}\"",
|
"MessageBookshelfNoResultsForFilter": "Няма резултат за филтер \"{0}: {1}\"",
|
||||||
"MessageBookshelfNoResultsForQuery": "Няма резултати от заявката",
|
"MessageBookshelfNoResultsForQuery": "Няма резултати от заявката",
|
||||||
"MessageBookshelfNoSeries": "Нямаш сеЗЙ",
|
"MessageBookshelfNoSeries": "Нямате поредица",
|
||||||
|
"MessageBulkChapterPattern": "Колко глави искате да добавите, използвайки тази схема за номериране?",
|
||||||
"MessageChapterEndIsAfter": "Краят на главата е след края на вашата аудиокнига",
|
"MessageChapterEndIsAfter": "Краят на главата е след края на вашата аудиокнига",
|
||||||
"MessageChapterErrorFirstNotZero": "Първата глава трябва да започва от 0",
|
"MessageChapterErrorFirstNotZero": "Първата глава трябва да започва от 0",
|
||||||
"MessageChapterErrorStartGteDuration": "Началото на главата трябва да бъде по-малко от продължителността на аудиокнигата",
|
"MessageChapterErrorStartGteDuration": "Началото на главата трябва да бъде по-малко от продължителността на аудиокнигата",
|
||||||
"MessageChapterErrorStartLtPrev": "Началото на главата трябва да бъде по-голямо или равно на края на предишната глава",
|
"MessageChapterErrorStartLtPrev": "Началото на главата трябва да бъде по-голямо или равно на края на предишната глава",
|
||||||
"MessageChapterStartIsAfter": "Началото на главата е след края на вашата аудиокнига",
|
"MessageChapterStartIsAfter": "Началото на главата е след края на вашата аудиокнига",
|
||||||
|
"MessageChaptersNotFound": "Главите не са намерени",
|
||||||
"MessageCheckingCron": "Проверяване на cron...",
|
"MessageCheckingCron": "Проверяване на cron...",
|
||||||
"MessageConfirmCloseFeed": "Сигурни ли сте, че искате да затворите този feed?",
|
"MessageConfirmCloseFeed": "Сигурни ли сте, че искате да затворите този feed?",
|
||||||
|
"MessageConfirmDeleteApiKey": "Сигурни ли сте, че искате да изтриете API ключ \"{0}\"?",
|
||||||
"MessageConfirmDeleteBackup": "Сигурни ли сте, че искате да изтриете този архив {0}?",
|
"MessageConfirmDeleteBackup": "Сигурни ли сте, че искате да изтриете този архив {0}?",
|
||||||
|
"MessageConfirmDeleteDevice": "Сигурни ли сте, че искате да изтриете е-четец \"{0}\"?",
|
||||||
"MessageConfirmDeleteFile": "Това ще изтрие файла от файловата Ви система. Сигурни ли сте?",
|
"MessageConfirmDeleteFile": "Това ще изтрие файла от файловата Ви система. Сигурни ли сте?",
|
||||||
"MessageConfirmDeleteLibrary": "Сигурни ли сте, че искате да изтриете за винаги библиотека \"{0}\"?",
|
"MessageConfirmDeleteLibrary": "Сигурни ли сте, че искате да изтриете за винаги библиотека \"{0}\"?",
|
||||||
"MessageConfirmDeleteLibraryItem": "Това ще изтрие елемента от базата данни и файловата Ви система. Сигурни ли сте?",
|
"MessageConfirmDeleteLibraryItem": "Това ще изтрие елемента от базата данни и файловата Ви система. Сигурни ли сте?",
|
||||||
"MessageConfirmDeleteLibraryItems": "Това ще изтрие {0} елемента от базата данни и файловата Ви система. Сигурни ли сте?",
|
"MessageConfirmDeleteLibraryItems": "Това ще изтрие {0} елемента от базата данни и файловата Ви система. Сигурни ли сте?",
|
||||||
|
"MessageConfirmDeleteMetadataProvider": "Сигурни ли сте, че искате да изтриете доставчика нa метаданни \"{0}\"?",
|
||||||
|
"MessageConfirmDeleteNotification": "Сигурни ли сте, че искате да изтриете това уведомление?",
|
||||||
"MessageConfirmDeleteSession": "Сигурни ли сте, че искате да изтриете тази сесия?",
|
"MessageConfirmDeleteSession": "Сигурни ли сте, че искате да изтриете тази сесия?",
|
||||||
|
"MessageConfirmEmbedMetadataInAudioFiles": "Сигурнли ли сте, че искате да вградите метаданните в {0} аудио файла?",
|
||||||
"MessageConfirmForceReScan": "Сигурни ли сте, че искате да принудите повторно сканиране?",
|
"MessageConfirmForceReScan": "Сигурни ли сте, че искате да принудите повторно сканиране?",
|
||||||
"MessageConfirmMarkAllEpisodesFinished": "Сигурни ли сте, че искате да маркирате всички епизоди като завършени?",
|
"MessageConfirmMarkAllEpisodesFinished": "Сигурни ли сте, че искате да маркирате всички епизоди като завършени?",
|
||||||
"MessageConfirmMarkAllEpisodesNotFinished": "Сигурни ли сте, че искате да маркирате всички епизоди като незавършени?",
|
"MessageConfirmMarkAllEpisodesNotFinished": "Сигурни ли сте, че искате да маркирате всички епизоди като незавършени?",
|
||||||
|
"MessageConfirmMarkItemFinished": "Сигурни ли сте, че искате да маркирате \"{0}\" като приключено?",
|
||||||
|
"MessageConfirmMarkItemNotFinished": "Сигурни ли сте, че искате да маркирате \"{0}\" като неприключено?",
|
||||||
"MessageConfirmMarkSeriesFinished": "Сигурни ли сте, че искате да маркирате всички книги в тази серия като завършени?",
|
"MessageConfirmMarkSeriesFinished": "Сигурни ли сте, че искате да маркирате всички книги в тази серия като завършени?",
|
||||||
"MessageConfirmMarkSeriesNotFinished": "Сигурни ли сте, че искате да маркирате всички книги в тази серия като незавършени?",
|
"MessageConfirmMarkSeriesNotFinished": "Сигурни ли сте, че искате да маркирате всички книги в тази серия като незавършени?",
|
||||||
|
"MessageConfirmNotificationTestTrigger": "Пуснете това уведомление с тестови данни?",
|
||||||
"MessageConfirmPurgeCache": "Изчистването на кеша ще изтрие цялата директория в <code>/metadata/cache</code>. <br /><br />Сигурни ли сте, че искате да премахнете директорията на кеша?",
|
"MessageConfirmPurgeCache": "Изчистването на кеша ще изтрие цялата директория в <code>/metadata/cache</code>. <br /><br />Сигурни ли сте, че искате да премахнете директорията на кеша?",
|
||||||
"MessageConfirmPurgeItemsCache": "Изчистването на кеша на елементите ще изтрие цялата директория в <code>/metadata/cache/items</code>. <br />Сигурни ли сте?",
|
"MessageConfirmPurgeItemsCache": "Изчистването на кеша на елементите ще изтрие цялата директория в <code>/metadata/cache/items</code>. <br />Сигурни ли сте?",
|
||||||
"MessageConfirmQuickEmbed": "Внимание! Бързото вграждане няма да архивира вашите аудио файлове. Уверете се, че имате резервно копие на вашите аудио файлове. <br><br>Искате ли да продължите?",
|
"MessageConfirmQuickEmbed": "Внимание! Бързото вграждане няма да архивира вашите аудио файлове. Уверете се, че имате резервно копие на вашите аудио файлове. <br><br>Искате ли да продължите?",
|
||||||
|
"MessageConfirmQuickMatchEpisodes": "Бързото сравняване на епизоди ще презапише детайлите, ако се намери съвпадение. Само не съвпаднали епизоди ще бъдат обновени. Сигурни ли сте?",
|
||||||
"MessageConfirmReScanLibraryItems": "Сигурни ли сте, че искате да сканирате отново {0} елемента?",
|
"MessageConfirmReScanLibraryItems": "Сигурни ли сте, че искате да сканирате отново {0} елемента?",
|
||||||
"MessageConfirmRemoveAllChapters": "Сигурни ли сте, че искате да премахнете всички глави?",
|
"MessageConfirmRemoveAllChapters": "Сигурни ли сте, че искате да премахнете всички глави?",
|
||||||
"MessageConfirmRemoveAuthor": "Сигурни ли сте, че искате да премахнете автор \"{0}\"?",
|
"MessageConfirmRemoveAuthor": "Сигурни ли сте, че искате да премахнете автор \"{0}\"?",
|
||||||
"MessageConfirmRemoveCollection": "Сигурни ли сте, че искате да премахнете колекция \"{0}\"?",
|
"MessageConfirmRemoveCollection": "Сигурни ли сте, че искате да премахнете колекция \"{0}\"?",
|
||||||
"MessageConfirmRemoveEpisode": "Сигурни ли сте, че искате да премахнете епизод \"{0}\"?",
|
"MessageConfirmRemoveEpisode": "Сигурни ли сте, че искате да премахнете епизод \"{0}\"?",
|
||||||
|
"MessageConfirmRemoveEpisodeNote": "Забележка: Това няма да доведе до изтриване на аудио файла, освен ако не активирате опцията \"Твърдо изтриване на файла\"",
|
||||||
"MessageConfirmRemoveEpisodes": "Сигурни ли сте, че искате да премахнете {0} епизода?",
|
"MessageConfirmRemoveEpisodes": "Сигурни ли сте, че искате да премахнете {0} епизода?",
|
||||||
"MessageConfirmRemoveListeningSessions": "Сигурни ли сте, че искате да премахнете {0} слушателски сесии?",
|
"MessageConfirmRemoveListeningSessions": "Сигурни ли сте, че искате да премахнете {0} слушателски сесии?",
|
||||||
|
"MessageConfirmRemoveMetadataFiles": "Сигурни ли сте, че искате да премахнете всичките метаданни. {0} файлове във папките на Вашата библиотека?",
|
||||||
"MessageConfirmRemoveNarrator": "Сигурни ли сте, че искате да премахнете разказвач \"{0}\"?",
|
"MessageConfirmRemoveNarrator": "Сигурни ли сте, че искате да премахнете разказвач \"{0}\"?",
|
||||||
"MessageConfirmRemovePlaylist": "Сигурни ли сте, че искате да премахнете плейлиста \"{0}\"?",
|
"MessageConfirmRemovePlaylist": "Сигурни ли сте, че искате да премахнете плейлиста \"{0}\"?",
|
||||||
"MessageConfirmRenameGenre": "Сигурни ли сте, че искате да преименувате жанра \"{0}\" на \"{1}\" за всички елементи?",
|
"MessageConfirmRenameGenre": "Сигурни ли сте, че искате да преименувате жанра \"{0}\" на \"{1}\" за всички елементи?",
|
||||||
@@ -745,19 +802,27 @@
|
|||||||
"MessageConfirmRenameTag": "Сигурни ли сте, че искате да преименувате таг \"{0}\" на \"{1}\" за всички елементи?",
|
"MessageConfirmRenameTag": "Сигурни ли сте, че искате да преименувате таг \"{0}\" на \"{1}\" за всички елементи?",
|
||||||
"MessageConfirmRenameTagMergeNote": "Забележка: Този таг вече съществува и ще бъде слято.",
|
"MessageConfirmRenameTagMergeNote": "Забележка: Този таг вече съществува и ще бъде слято.",
|
||||||
"MessageConfirmRenameTagWarning": "Внимание! Вече съществува подобен таг с различно писане \"{0}\".",
|
"MessageConfirmRenameTagWarning": "Внимание! Вече съществува подобен таг с различно писане \"{0}\".",
|
||||||
|
"MessageConfirmResetProgress": "Сигурни ли сте, че искате да нулирате прогреса си?",
|
||||||
"MessageConfirmSendEbookToDevice": "Сигурни ли сте, че искате да изпратите {0} електронна книга \"{1}\" до устройство \"{2}\"?",
|
"MessageConfirmSendEbookToDevice": "Сигурни ли сте, че искате да изпратите {0} електронна книга \"{1}\" до устройство \"{2}\"?",
|
||||||
|
"MessageConfirmUnlinkOpenId": "Сигурни ли сте, че искате да отвържете този потребител от OpenID?",
|
||||||
|
"MessageDaysListenedInTheLastYear": "{0} дни слушане през последната година",
|
||||||
"MessageDownloadingEpisode": "Сваля епизод",
|
"MessageDownloadingEpisode": "Сваля епизод",
|
||||||
"MessageDragFilesIntoTrackOrder": "Плъзнете файлове в правилния ред на каналите",
|
"MessageDragFilesIntoTrackOrder": "Плъзнете файлове в правилния ред на каналите",
|
||||||
|
"MessageEmbedFailed": "Вграждането беше неуспешно!",
|
||||||
"MessageEmbedFinished": "Вграждането завърши!",
|
"MessageEmbedFinished": "Вграждането завърши!",
|
||||||
|
"MessageEmbedQueue": "Поставено в опашката за вграждане на метаданни ({0} в опашката)",
|
||||||
"MessageEpisodesQueuedForDownload": "{0} Епизод(и) са сложени за сваляне",
|
"MessageEpisodesQueuedForDownload": "{0} Епизод(и) са сложени за сваляне",
|
||||||
"MessageEreaderDevices": "За да осигурите доставката на е-книги, може да се наложи да добавите горепосочения имейл адрес като валиден подател за всяко устройство, изброено по-долу.",
|
"MessageEreaderDevices": "За да осигурите доставката на е-книги, може да се наложи да добавите горепосочения имейл адрес като валиден подател за всяко устройство, изброено по-долу.",
|
||||||
"MessageFeedURLWillBe": "Адресът на емисията ще бъде {0}",
|
"MessageFeedURLWillBe": "Адресът на емисията ще бъде {0}",
|
||||||
"MessageFetching": "Извличане...",
|
"MessageFetching": "Извличане...",
|
||||||
"MessageForceReScanDescription": "ще сканира всички файлове отново като прясно сканиране. Аудио файлове ID3 тагове, OPF файлове и текстови файлове ще бъдат сканирани като нови.",
|
"MessageForceReScanDescription": "ще сканира всички файлове отново като прясно сканиране. Аудио файлове ID3 тагове, OPF файлове и текстови файлове ще бъдат сканирани като нови.",
|
||||||
|
"MessageHeatmapListeningTimeTooltip": "<strong>{0} слушане</strong> на {1}",
|
||||||
|
"MessageHeatmapNoListeningSessions": "Няма сесии за слушане на {0}",
|
||||||
"MessageImportantNotice": "Важно Съобщение!",
|
"MessageImportantNotice": "Важно Съобщение!",
|
||||||
"MessageInsertChapterBelow": "Вмъкни глава под",
|
"MessageInsertChapterBelow": "Вмъкни глава под",
|
||||||
"MessageItemsSelected": "{0} избрани",
|
"MessageInvalidAsin": "Невалиден ASIN",
|
||||||
"MessageItemsUpdated": "{0} елемента обновени",
|
"MessageItemsSelected": "{0} избрани елемента",
|
||||||
|
"MessageItemsUpdated": "{0} обновени елемента",
|
||||||
"MessageJoinUsOn": "Присъединете се към нас",
|
"MessageJoinUsOn": "Присъединете се към нас",
|
||||||
"MessageLoading": "Зарежда...",
|
"MessageLoading": "Зарежда...",
|
||||||
"MessageLoadingFolders": "Зареждане на Папки...",
|
"MessageLoadingFolders": "Зареждане на Папки...",
|
||||||
@@ -778,6 +843,7 @@
|
|||||||
"MessageNoCollections": "Няма колекции",
|
"MessageNoCollections": "Няма колекции",
|
||||||
"MessageNoCoversFound": "Не са намерени корици",
|
"MessageNoCoversFound": "Не са намерени корици",
|
||||||
"MessageNoDescription": "Няма описание",
|
"MessageNoDescription": "Няма описание",
|
||||||
|
"MessageNoDevices": "Няма устройства",
|
||||||
"MessageNoDownloadsInProgress": "Няма изтегляния в прогрес",
|
"MessageNoDownloadsInProgress": "Няма изтегляния в прогрес",
|
||||||
"MessageNoDownloadsQueued": "Няма изтегляния в опашка",
|
"MessageNoDownloadsQueued": "Няма изтегляния в опашка",
|
||||||
"MessageNoEpisodeMatchesFound": "Няма намерени съвпадения за епизоди",
|
"MessageNoEpisodeMatchesFound": "Няма намерени съвпадения за епизоди",
|
||||||
@@ -791,6 +857,7 @@
|
|||||||
"MessageNoLogs": "Няма логове",
|
"MessageNoLogs": "Няма логове",
|
||||||
"MessageNoMediaProgress": "Няма прогрес на медията",
|
"MessageNoMediaProgress": "Няма прогрес на медията",
|
||||||
"MessageNoNotifications": "Няма известия",
|
"MessageNoNotifications": "Няма известия",
|
||||||
|
"MessageNoPodcastFeed": "Невалиден подкаст: Няма канал",
|
||||||
"MessageNoPodcastsFound": "Няма намерени подкасти",
|
"MessageNoPodcastsFound": "Няма намерени подкасти",
|
||||||
"MessageNoResults": "Няма резултати",
|
"MessageNoResults": "Няма резултати",
|
||||||
"MessageNoSearchResultsFor": "Няма резултати за \"{0}\"",
|
"MessageNoSearchResultsFor": "Няма резултати за \"{0}\"",
|
||||||
@@ -799,13 +866,19 @@
|
|||||||
"MessageNoTasksRunning": "Няма вършещи се задачи",
|
"MessageNoTasksRunning": "Няма вършещи се задачи",
|
||||||
"MessageNoUpdatesWereNecessary": "Няма нужда от обновяване",
|
"MessageNoUpdatesWereNecessary": "Няма нужда от обновяване",
|
||||||
"MessageNoUserPlaylists": "Нямате създадени плейлисти",
|
"MessageNoUserPlaylists": "Нямате създадени плейлисти",
|
||||||
|
"MessageNoUserPlaylistsHelp": "Плейлистите за частни. Само създалият ги потребител ще може да ги вижда.",
|
||||||
"MessageNotYetImplemented": "Още не е изпълнено",
|
"MessageNotYetImplemented": "Още не е изпълнено",
|
||||||
|
"MessageOpmlPreviewNote": "Забележка: Това е преглед на анализирания OPML файл. Действителното заглавие на подкаста ще бъде взето от RSS фийда.",
|
||||||
"MessageOr": "или",
|
"MessageOr": "или",
|
||||||
"MessagePauseChapter": "Пауза на глава",
|
"MessagePauseChapter": "Пауза на глава",
|
||||||
"MessagePlayChapter": "Пусни налчалото на глава",
|
"MessagePlayChapter": "Пусни налчалото на глава",
|
||||||
"MessagePlaylistCreateFromCollection": "Създай плейлист от колекция",
|
"MessagePlaylistCreateFromCollection": "Създай плейлист от колекция",
|
||||||
|
"MessagePleaseWait": "Моля изчакайте...",
|
||||||
"MessagePodcastHasNoRSSFeedForMatching": "Подкастът няма URL адрес на RSS feed за използване за съпоставяне",
|
"MessagePodcastHasNoRSSFeedForMatching": "Подкастът няма URL адрес на RSS feed за използване за съпоставяне",
|
||||||
"MessagePodcastSearchField": "Въведи какво да търся или RSS емисия адрес",
|
"MessagePodcastSearchField": "Въведи какво да търся или RSS емисия адрес",
|
||||||
|
"MessageQuickEmbedInProgress": "Бързото вграждане е в процес на изпълнение",
|
||||||
|
"MessageQuickEmbedQueue": "Поставено в опашката за бързо вграждане ({0} в опашката)",
|
||||||
|
"MessageQuickMatchAllEpisodes": "Бързо Сравняване на Всички Епизоди",
|
||||||
"MessageQuickMatchDescription": "Попълни празните детайли и корици с първия резултат от '{0}'. Не презаписва детайлите, освен ако не е активирана настройката 'Предпочети съвпадащи метаданни' на сървъра.",
|
"MessageQuickMatchDescription": "Попълни празните детайли и корици с първия резултат от '{0}'. Не презаписва детайлите, освен ако не е активирана настройката 'Предпочети съвпадащи метаданни' на сървъра.",
|
||||||
"MessageRemoveChapter": "Премахни глава",
|
"MessageRemoveChapter": "Премахни глава",
|
||||||
"MessageRemoveEpisodes": "Премахни {0} епизод(и)",
|
"MessageRemoveEpisodes": "Премахни {0} епизод(и)",
|
||||||
@@ -815,11 +888,52 @@
|
|||||||
"MessageResetChaptersConfirm": "Сигурни ли сте, че искате да нулирате главите и да отмените промените, които сте направили?",
|
"MessageResetChaptersConfirm": "Сигурни ли сте, че искате да нулирате главите и да отмените промените, които сте направили?",
|
||||||
"MessageRestoreBackupConfirm": "Сигурни ли сте, че искате да възстановите архива създаден на",
|
"MessageRestoreBackupConfirm": "Сигурни ли сте, че искате да възстановите архива създаден на",
|
||||||
"MessageRestoreBackupWarning": "Възстановяването на архив ще презапише цялата база данни, намираща се в /config и кориците в /metadata/items & /metadata/authors.<br /><br />Архивите не променят файловете в папките на вашата библиотека. Ако сте активирали настройките на сървъра за съхранение на корици и метаданни в папките на вашата библиотека, те няма да бъдат архивирани или презаписани.<br /><br />Всички клиенти, използващи вашия сървър, ще бъдат автоматично обновени.",
|
"MessageRestoreBackupWarning": "Възстановяването на архив ще презапише цялата база данни, намираща се в /config и кориците в /metadata/items & /metadata/authors.<br /><br />Архивите не променят файловете в папките на вашата библиотека. Ако сте активирали настройките на сървъра за съхранение на корици и метаданни в папките на вашата библиотека, те няма да бъдат архивирани или презаписани.<br /><br />Всички клиенти, използващи вашия сървър, ще бъдат автоматично обновени.",
|
||||||
|
"MessageScheduleLibraryScanNote": "За повече потребители се препоръчва да оставят този фийчър изключен и да оставят настройката \"Автоматично преглеждане за промени в библиотеката\" включена - тя автоматично ще засече промени в папките на вашата библиотека. Включете тази настройка ако \"Автоматично преглеждане за промени в библиотеката\" не рабови на вашата файлова система (например NFS).",
|
||||||
|
"MessageScheduleRunEveryWeekdayAtTime": "Изпълни всеки {0} в {1}",
|
||||||
"MessageSearchResultsFor": "Резултати от търсенето за",
|
"MessageSearchResultsFor": "Резултати от търсенето за",
|
||||||
"MessageSelected": "{0} избрани",
|
"MessageSelected": "{0} избрани",
|
||||||
|
"MessageSeriesSequenceCannotContainSpaces": "Подредбата в серия не може да съдържа шпации",
|
||||||
"MessageServerCouldNotBeReached": "Сървърът не може да бъде достигнат",
|
"MessageServerCouldNotBeReached": "Сървърът не може да бъде достигнат",
|
||||||
"MessageSetChaptersFromTracksDescription": "Задайте глави, като използвате всеки аудио файл като глава и заглавие на главата като име на аудио файла",
|
"MessageSetChaptersFromTracksDescription": "Задайте глави, като използвате всеки аудио файл като глава и заглавие на главата като име на аудио файла",
|
||||||
|
"MessageShareExpirationWillBe": "Изтичането ще бъде на <strong>{0}</strong>",
|
||||||
|
"MessageShareExpiresIn": "Изтича след {0}",
|
||||||
|
"MessageShareURLWillBe": "URL за споделяне ще бъде <strong>{0}</strong>",
|
||||||
"MessageStartPlaybackAtTime": "Започни възпроизвеждане на \"{0}\" в {1}?",
|
"MessageStartPlaybackAtTime": "Започни възпроизвеждане на \"{0}\" в {1}?",
|
||||||
|
"MessageTaskAudioFileNotWritable": "На Аудио файл \"{0}\" не може да се записва",
|
||||||
|
"MessageTaskCanceledByUser": "Задачата е отказана от потребител",
|
||||||
|
"MessageTaskDownloadingEpisodeDescription": "Изтегляне на епизод \"{0}\"",
|
||||||
|
"MessageTaskEmbeddingMetadata": "Вграждане на метаданни",
|
||||||
|
"MessageTaskEmbeddingMetadataDescription": "Вграждане на метаданни в аудиокнига \"{0}\"",
|
||||||
|
"MessageTaskEncodingM4b": "Кодиране M4B",
|
||||||
|
"MessageTaskEncodingM4bDescription": "Кодиране на аудиокнига \"{0}\" в единичен m4b файл",
|
||||||
|
"MessageTaskFailed": "Неуспешно",
|
||||||
|
"MessageTaskFailedToBackupAudioFile": "Неуспешно създаване на разервно копие на аудио файл \"{0}\"",
|
||||||
|
"MessageTaskFailedToCreateCacheDirectory": "Неуспешно създаване на директория за кеширане",
|
||||||
|
"MessageTaskFailedToEmbedMetadataInFile": "Неуспешно вграждане на метаданни във файл \"{0}\"",
|
||||||
|
"MessageTaskFailedToMergeAudioFiles": "Неуспешно сливане на аудио файловете",
|
||||||
|
"MessageTaskFailedToMoveM4bFile": "Неуспешно преместване на m4b файл",
|
||||||
|
"MessageTaskFailedToWriteMetadataFile": "Неуспешно записване на файла за метаданни",
|
||||||
|
"MessageTaskMatchingBooksInLibrary": "Съответстващи книги в библиотека \"{0}\"",
|
||||||
|
"MessageTaskNoFilesToScan": "Няма файлове за сканиране",
|
||||||
|
"MessageTaskOpmlImport": "OPML импортиране",
|
||||||
|
"MessageTaskOpmlImportDescription": "Създаване на подкасти от {0} RSS хранилки",
|
||||||
|
"MessageTaskOpmlImportFeed": "OPML импортиран фийд",
|
||||||
|
"MessageTaskOpmlImportFeedDescription": "Импортиране на RSS хранилка \"{0}\"",
|
||||||
|
"MessageTaskOpmlImportFeedFailed": "Неуспешно взимане на подкаст фийд",
|
||||||
|
"MessageTaskOpmlImportFeedPodcastDescription": "Създаване на подкаст \"{0}\"",
|
||||||
|
"MessageTaskOpmlImportFeedPodcastExists": "На този път вече съществува подкаст",
|
||||||
|
"MessageTaskOpmlImportFeedPodcastFailed": "Неуспешно създаване на подкаст",
|
||||||
|
"MessageTaskOpmlImportFinished": "Добавени {0} подкаста",
|
||||||
|
"MessageTaskOpmlParseFailed": "Неуспешно анализиране на OPML файла",
|
||||||
|
"MessageTaskOpmlParseFastFail": "Невалиден OPML файл, не беше намерен нито <opml> таг нито <outline> таг",
|
||||||
|
"MessageTaskOpmlParseNoneFound": "Няма намерени канали във OPML файла",
|
||||||
|
"MessageTaskScanItemsAdded": "{0} добавени",
|
||||||
|
"MessageTaskScanItemsMissing": "{0} липсващи",
|
||||||
|
"MessageTaskScanItemsUpdated": "{0} обновени",
|
||||||
|
"MessageTaskScanNoChangesNeeded": "Не са нужни промени",
|
||||||
|
"MessageTaskScanningFileChanges": "Проверка за промени във файловете в \"{0}\"",
|
||||||
|
"MessageTaskScanningLibrary": "Сканиране на \"{0}\" библиотека",
|
||||||
|
"MessageTaskTargetDirectoryNotWritable": "Целевата директория не е достъпна за запис",
|
||||||
"MessageThinking": "Мисля...",
|
"MessageThinking": "Мисля...",
|
||||||
"MessageUploaderItemFailed": "Неуспешно качване",
|
"MessageUploaderItemFailed": "Неуспешно качване",
|
||||||
"MessageUploaderItemSuccess": "Успешно качване!",
|
"MessageUploaderItemSuccess": "Успешно качване!",
|
||||||
@@ -837,43 +951,117 @@
|
|||||||
"NoteUploaderFoldersWithMediaFiles": "Папките с медийни файлове ще бъдат обработени като отделни елементи на библиотеката.",
|
"NoteUploaderFoldersWithMediaFiles": "Папките с медийни файлове ще бъдат обработени като отделни елементи на библиотеката.",
|
||||||
"NoteUploaderOnlyAudioFiles": "Ако качвате само аудио файлове, то всеки аудио файл ще бъде обработен като отделна аудиокнига.",
|
"NoteUploaderOnlyAudioFiles": "Ако качвате само аудио файлове, то всеки аудио файл ще бъде обработен като отделна аудиокнига.",
|
||||||
"NoteUploaderUnsupportedFiles": "Неподдържаните файлове се игнорират. При избор или пускане на папка, други файлове, които не са в папка на елемент, се игнорират.",
|
"NoteUploaderUnsupportedFiles": "Неподдържаните файлове се игнорират. При избор или пускане на папка, други файлове, които не са в папка на елемент, се игнорират.",
|
||||||
|
"NotificationOnBackupCompletedDescription": "Изпълнява се при завършване на създаване на резервно копие",
|
||||||
|
"NotificationOnBackupFailedDescription": "Изпълнява се при неуспешено създаване на резервно копие",
|
||||||
|
"NotificationOnEpisodeDownloadedDescription": "Изпълнява се при автоматично изтегляне на подкаст епизод",
|
||||||
|
"NotificationOnRSSFeedDisabledDescription": "Изпълнява се, когато автоматичното изтегляне на епизодите е деактивирано, поради твърде много неуспешни опити",
|
||||||
|
"NotificationOnRSSFeedFailedDescription": "Пуска се когато заявката за RSS фийд е неуспешна за автоматично сваляне на епизод",
|
||||||
|
"NotificationOnTestDescription": "Event за тестване на системата за нотификации",
|
||||||
|
"PlaceholderBulkChapterInput": "Въведете име на глава или използвайте номериране (прим. 'Епизод 1', 'Глава 10', '1.')",
|
||||||
"PlaceholderNewCollection": "Ново име на колекцията",
|
"PlaceholderNewCollection": "Ново име на колекцията",
|
||||||
"PlaceholderNewFolderPath": "Нов път на папката",
|
"PlaceholderNewFolderPath": "Нов път на папката",
|
||||||
"PlaceholderNewPlaylist": "Ново име на плейлиста",
|
"PlaceholderNewPlaylist": "Ново име на плейлиста",
|
||||||
"PlaceholderSearch": "Търсене...",
|
"PlaceholderSearch": "Търсене...",
|
||||||
"PlaceholderSearchEpisode": "Търсене на Епизоди...",
|
"PlaceholderSearchEpisode": "Търсене на Епизоди...",
|
||||||
|
"StatsAuthorsAdded": "добаврени автори",
|
||||||
|
"StatsBooksAdded": "добавени книги",
|
||||||
|
"StatsBooksAdditional": "Някой от вкючените добавки…",
|
||||||
|
"StatsBooksFinished": "завършени книги",
|
||||||
|
"StatsBooksFinishedThisYear": "Някой от книгите приключени тази година…",
|
||||||
|
"StatsBooksListenedTo": "слушани книги",
|
||||||
|
"StatsCollectionGrewTo": "Твоята книжна колекция израсна до…",
|
||||||
|
"StatsSessions": "сесии",
|
||||||
|
"StatsSpentListening": "прекарано в слушане",
|
||||||
|
"StatsTopAuthor": "ТОП АВТОР",
|
||||||
|
"StatsTopAuthors": "ТОП АВТОРИ",
|
||||||
|
"StatsTopGenre": "ТОП ЖАНР",
|
||||||
|
"StatsTopGenres": "ТОП ЖАНРА",
|
||||||
|
"StatsTopMonth": "ТОП МЕСЕЦ",
|
||||||
|
"StatsTopNarrator": "ТОП РАЗКАЗВАЧ",
|
||||||
|
"StatsTopNarrators": "ТОП РАЗКАЗВАЧИ",
|
||||||
|
"StatsTotalDuration": "С пълно времетраене…",
|
||||||
|
"StatsYearInReview": "ГОДИНАТА В ПРЕГЛЕД",
|
||||||
"ToastAccountUpdateSuccess": "Успешно обновяване на акаунта",
|
"ToastAccountUpdateSuccess": "Успешно обновяване на акаунта",
|
||||||
|
"ToastAppriseUrlRequired": "Трябва да въведете Apprise URL",
|
||||||
|
"ToastAsinRequired": "ASIN-а е задължителен",
|
||||||
"ToastAuthorImageRemoveSuccess": "Авторската снимка е премахната",
|
"ToastAuthorImageRemoveSuccess": "Авторската снимка е премахната",
|
||||||
|
"ToastAuthorNotFound": "Автор \"{0}\" не е намерен",
|
||||||
|
"ToastAuthorRemoveSuccess": "Арторът е премахнат",
|
||||||
|
"ToastAuthorSearchNotFound": "Авторът не е намерен",
|
||||||
"ToastAuthorUpdateMerged": "Обновяване на автора сливано",
|
"ToastAuthorUpdateMerged": "Обновяване на автора сливано",
|
||||||
"ToastAuthorUpdateSuccess": "Автора обновен",
|
"ToastAuthorUpdateSuccess": "Автора обновен",
|
||||||
"ToastAuthorUpdateSuccessNoImageFound": "Автор обновен (не е намерена снимка)",
|
"ToastAuthorUpdateSuccessNoImageFound": "Автор обновен (не е намерена снимка)",
|
||||||
|
"ToastBackupAppliedSuccess": "Архивът е приложен",
|
||||||
"ToastBackupCreateFailed": "Неуспешно създаване на архив",
|
"ToastBackupCreateFailed": "Неуспешно създаване на архив",
|
||||||
"ToastBackupCreateSuccess": "Архивът е създаден",
|
"ToastBackupCreateSuccess": "Архивът е създаден",
|
||||||
"ToastBackupDeleteFailed": "Неуспешно изтриване на архив",
|
"ToastBackupDeleteFailed": "Неуспешно изтриване на архив",
|
||||||
"ToastBackupDeleteSuccess": "Архивът е изтрит",
|
"ToastBackupDeleteSuccess": "Архивът е изтрит",
|
||||||
|
"ToastBackupInvalidMaxKeep": "Невалиден брой за архиви за запазване",
|
||||||
|
"ToastBackupInvalidMaxSize": "Невалиден максимален рамер на архив",
|
||||||
"ToastBackupRestoreFailed": "Неуспешно възстановяване на архив",
|
"ToastBackupRestoreFailed": "Неуспешно възстановяване на архив",
|
||||||
"ToastBackupUploadFailed": "Неуспешно качване на архив",
|
"ToastBackupUploadFailed": "Неуспешно качване на архив",
|
||||||
"ToastBackupUploadSuccess": "Архивът е качен",
|
"ToastBackupUploadSuccess": "Архивът е качен",
|
||||||
|
"ToastBatchApplyDetailsToItemsSuccess": "Детайли приложени на предмети",
|
||||||
|
"ToastBatchDeleteFailed": "Груповото изтриване се провали",
|
||||||
|
"ToastBatchDeleteSuccess": "Успешно групово изтриване",
|
||||||
|
"ToastBatchQuickMatchFailed": "Груповото Бързо Съвпадение се провали!",
|
||||||
|
"ToastBatchQuickMatchStarted": "Груповото Бързо Съвпадение на {0} книги започна!",
|
||||||
"ToastBatchUpdateFailed": "Неуспешно групово актуализиране",
|
"ToastBatchUpdateFailed": "Неуспешно групово актуализиране",
|
||||||
"ToastBatchUpdateSuccess": "Успешно групово актуализиране",
|
"ToastBatchUpdateSuccess": "Успешно групово актуализиране",
|
||||||
"ToastBookmarkCreateFailed": "Неуспешно създаване на отметка",
|
"ToastBookmarkCreateFailed": "Неуспешно създаване на отметка",
|
||||||
"ToastBookmarkCreateSuccess": "Отметката е създадена",
|
"ToastBookmarkCreateSuccess": "Отметката е създадена",
|
||||||
"ToastBookmarkRemoveSuccess": "Отметката е премахната",
|
"ToastBookmarkRemoveSuccess": "Отметката е премахната",
|
||||||
|
"ToastBulkChapterInvalidCount": "Въведете число между 1 и 150",
|
||||||
"ToastCachePurgeFailed": "Неуспешно изчистване на кеша",
|
"ToastCachePurgeFailed": "Неуспешно изчистване на кеша",
|
||||||
"ToastCachePurgeSuccess": "Успешно изчистване на кеша",
|
"ToastCachePurgeSuccess": "Успешно изчистване на кеша",
|
||||||
|
"ToastChapterLocked": "Главата е заключена.",
|
||||||
|
"ToastChapterStartTimeAdjusted": "Начално време на главате е настоено с {0} секунди",
|
||||||
|
"ToastChaptersAllLocked": "Всички глави са заключени. Оключете някой глави за да преместите техните времена.",
|
||||||
"ToastChaptersHaveErrors": "Главите имат грешки",
|
"ToastChaptersHaveErrors": "Главите имат грешки",
|
||||||
|
"ToastChaptersInvalidShiftAmountLast": "Невалидно време за преместване. Началният час на последната глава ще превиши общата продължителност на аудиокнигата.",
|
||||||
|
"ToastChaptersInvalidShiftAmountStart": "Невалидно време за преместване. Първата глава ще има нулева или отрицателна дължина и ще бъде презаписана от втората глава. Увеличете началното време на втората глава.",
|
||||||
"ToastChaptersMustHaveTitles": "Главите трябва да имат заглавия",
|
"ToastChaptersMustHaveTitles": "Главите трябва да имат заглавия",
|
||||||
|
"ToastChaptersRemoved": "Главите са премахнати",
|
||||||
|
"ToastChaptersUpdated": "Главите са актуализирани",
|
||||||
|
"ToastCollectionItemsAddFailed": "Неуспешно добавяне на елемент(и) към колекцията",
|
||||||
"ToastCollectionRemoveSuccess": "Колекцията е премахната",
|
"ToastCollectionRemoveSuccess": "Колекцията е премахната",
|
||||||
"ToastCollectionUpdateSuccess": "Колекцията е обновена",
|
"ToastCollectionUpdateSuccess": "Колекцията е обновена",
|
||||||
|
"ToastConnectionNotAvailable": "Няма връзка. Моля, опитайте отново по-късно",
|
||||||
|
"ToastCoverSearchFailed": "Търсенето на корица е неуспешно",
|
||||||
|
"ToastCoverUpdateFailed": "Обновяването на корицата е неуспешно",
|
||||||
|
"ToastDateTimeInvalidOrIncomplete": "Датата и часът са невалидни или непълни",
|
||||||
"ToastDeleteFileFailed": "Неуспешно изтриване на файла",
|
"ToastDeleteFileFailed": "Неуспешно изтриване на файла",
|
||||||
"ToastDeleteFileSuccess": "Успешно изтриване на файла",
|
"ToastDeleteFileSuccess": "Успешно изтриване на файла",
|
||||||
|
"ToastDeviceAddFailed": "Неуспешно добавяне на устройство",
|
||||||
|
"ToastDeviceNameAlreadyExists": "Вече съществува четец с това име",
|
||||||
|
"ToastDeviceTestEmailFailed": "Неуспешно изпращане на тестов имейл",
|
||||||
|
"ToastDeviceTestEmailSuccess": "Тестовият имейл е изпратен",
|
||||||
|
"ToastEmailSettingsUpdateSuccess": "Имейл настройките са актуализирани",
|
||||||
|
"ToastEncodeCancelFailed": "Неуспешно отменяне на кодирането",
|
||||||
|
"ToastEncodeCancelSucces": "Кодирането е отменено",
|
||||||
|
"ToastEpisodeDownloadQueueClearFailed": "Неуспешно изчистване на опашката",
|
||||||
|
"ToastEpisodeDownloadQueueClearSuccess": "Опашката за изтегляне на епизоди е изчистена",
|
||||||
|
"ToastEpisodeUpdateSuccess": "{0} епизода са актуализирани",
|
||||||
|
"ToastErrorCannotShare": "Не може да се споделя директно от това устройство",
|
||||||
|
"ToastFailedToCreate": "Неуспешно създаване",
|
||||||
|
"ToastFailedToDelete": "Неуспешно изтриване",
|
||||||
"ToastFailedToLoadData": "Неуспешно зареждане на данни",
|
"ToastFailedToLoadData": "Неуспешно зареждане на данни",
|
||||||
|
"ToastFailedToMatch": "Неуспешно съвпадение",
|
||||||
|
"ToastFailedToShare": "Неуспешно споделяне",
|
||||||
|
"ToastFailedToUpdate": "Неуспешно актуализиране",
|
||||||
|
"ToastInvalidImageUrl": "Невалиден URL адрес на изображение",
|
||||||
|
"ToastInvalidMaxEpisodesToDownload": "Невалиден максимален брой епизоди за изтегляне",
|
||||||
|
"ToastInvalidUrl": "Невалиден URL адрес",
|
||||||
|
"ToastInvalidUrls": "Един или повече URL адреси са невалидни",
|
||||||
"ToastItemCoverUpdateSuccess": "Корицата на елемента е обновена",
|
"ToastItemCoverUpdateSuccess": "Корицата на елемента е обновена",
|
||||||
|
"ToastItemDeletedFailed": "Неуспешно изтриване на елемента",
|
||||||
|
"ToastItemDeletedSuccess": "Елементът е изтрит",
|
||||||
"ToastItemDetailsUpdateSuccess": "Детайлите на елемента са обновени",
|
"ToastItemDetailsUpdateSuccess": "Детайлите на елемента са обновени",
|
||||||
"ToastItemMarkedAsFinishedFailed": "Неуспешно маркиране като Завършено",
|
"ToastItemMarkedAsFinishedFailed": "Неуспешно маркиране като Завършено",
|
||||||
"ToastItemMarkedAsFinishedSuccess": "Елементът е маркиран като завършен",
|
"ToastItemMarkedAsFinishedSuccess": "Елементът е маркиран като завършен",
|
||||||
"ToastItemMarkedAsNotFinishedFailed": "Неуспешно маркиране като Незавършено",
|
"ToastItemMarkedAsNotFinishedFailed": "Неуспешно маркиране като Незавършено",
|
||||||
"ToastItemMarkedAsNotFinishedSuccess": "Елементът е маркиран като незавършен",
|
"ToastItemMarkedAsNotFinishedSuccess": "Елементът е маркиран като незавършен",
|
||||||
|
"ToastItemUpdateSuccess": "Елементът е актуализиран",
|
||||||
"ToastLibraryCreateFailed": "Неуспешно създаване на библиотека",
|
"ToastLibraryCreateFailed": "Неуспешно създаване на библиотека",
|
||||||
"ToastLibraryCreateSuccess": "Библиотеката \"{0}\" е създадена",
|
"ToastLibraryCreateSuccess": "Библиотеката \"{0}\" е създадена",
|
||||||
"ToastLibraryDeleteFailed": "Неуспешно изтриване на библиотека",
|
"ToastLibraryDeleteFailed": "Неуспешно изтриване на библиотека",
|
||||||
@@ -881,28 +1069,97 @@
|
|||||||
"ToastLibraryScanFailedToStart": "Неуспешно стартиране на сканиране",
|
"ToastLibraryScanFailedToStart": "Неуспешно стартиране на сканиране",
|
||||||
"ToastLibraryScanStarted": "Сканирането на библиотеката е стартирано",
|
"ToastLibraryScanStarted": "Сканирането на библиотеката е стартирано",
|
||||||
"ToastLibraryUpdateSuccess": "Библиотеката \"{0}\" е обновена",
|
"ToastLibraryUpdateSuccess": "Библиотеката \"{0}\" е обновена",
|
||||||
|
"ToastMatchAllAuthorsFailed": "Неуспешно съвпадение на всички автори",
|
||||||
|
"ToastMetadataFilesRemovedError": "Грешка при премахване на metadata.{0} файлове",
|
||||||
|
"ToastMetadataFilesRemovedNoneFound": "Не са намерени metadata.{0} файлове в библиотеката",
|
||||||
|
"ToastMetadataFilesRemovedNoneRemoved": "Не са премахнати metadata.{0} файлове",
|
||||||
|
"ToastMetadataFilesRemovedSuccess": "Премахнати са {0} файла metadata.{1}",
|
||||||
|
"ToastMustHaveAtLeastOnePath": "Трябва да има поне един път",
|
||||||
|
"ToastNameEmailRequired": "Изискват се име и имейл",
|
||||||
|
"ToastNameRequired": "Изисква се име",
|
||||||
|
"ToastNewApiKeyUserError": "Трябва да изберете потребител",
|
||||||
|
"ToastNewEpisodesFound": "Намерени са {0} нови епизода",
|
||||||
|
"ToastNewUserCreatedFailed": "Неуспешно създаване на акаунт: „{0}“",
|
||||||
|
"ToastNewUserCreatedSuccess": "Създаден е нов акаунт",
|
||||||
|
"ToastNewUserLibraryError": "Трябва да изберете поне една библиотека",
|
||||||
|
"ToastNewUserPasswordError": "Трябва да има парола; само root потребителят може да бъде с празна парола",
|
||||||
|
"ToastNewUserTagError": "Трябва да изберете поне един етикет",
|
||||||
|
"ToastNewUserUsernameError": "Въведете потребителско име",
|
||||||
|
"ToastNoNewEpisodesFound": "Не са намерени нови епизоди",
|
||||||
|
"ToastNoRSSFeed": "Подкастът няма RSS емисия",
|
||||||
|
"ToastNoUpdatesNecessary": "Не са необходими актуализации",
|
||||||
|
"ToastNotificationCreateFailed": "Неуспешно създаване на известие",
|
||||||
|
"ToastNotificationDeleteFailed": "Неуспешно изтриване на известието",
|
||||||
|
"ToastNotificationFailedMaximum": "Максималният брой неуспешни опити трябва да бъде >= 0",
|
||||||
|
"ToastNotificationQueueMaximum": "Максималната опашка за известия трябва да бъде >= 0",
|
||||||
|
"ToastNotificationSettingsUpdateSuccess": "Настройките за известия са актуализирани",
|
||||||
|
"ToastNotificationTestTriggerFailed": "Неуспешно задействане на тестово известие",
|
||||||
|
"ToastNotificationTestTriggerSuccess": "Тестовото известие е задействано",
|
||||||
|
"ToastNotificationUpdateSuccess": "Известието е актуализирано",
|
||||||
"ToastPlaylistCreateFailed": "Неуспешно създаване на плейлист",
|
"ToastPlaylistCreateFailed": "Неуспешно създаване на плейлист",
|
||||||
"ToastPlaylistCreateSuccess": "Плейлистът е създаден",
|
"ToastPlaylistCreateSuccess": "Плейлистът е създаден",
|
||||||
"ToastPlaylistRemoveSuccess": "Плейлистът е премахнат",
|
"ToastPlaylistRemoveSuccess": "Плейлистът е премахнат",
|
||||||
"ToastPlaylistUpdateSuccess": "Плейлистът е обновен",
|
"ToastPlaylistUpdateSuccess": "Плейлистът е обновен",
|
||||||
"ToastPodcastCreateFailed": "Неуспешно създаване на подкаст",
|
"ToastPodcastCreateFailed": "Неуспешно създаване на подкаст",
|
||||||
"ToastPodcastCreateSuccess": "Подкаст успешно създаден",
|
"ToastPodcastCreateSuccess": "Подкаст успешно създаден",
|
||||||
|
"ToastPodcastEpisodeUpdated": "Епизодът е актуализиран",
|
||||||
|
"ToastPodcastGetFeedFailed": "Неуспешно извличане на емисията на подкаста",
|
||||||
|
"ToastPodcastNoEpisodesInFeed": "Не са намерени епизоди в RSS емисията",
|
||||||
|
"ToastPodcastNoRssFeed": "Подкастът няма RSS емисия",
|
||||||
|
"ToastProgressIsNotBeingSynced": "Напредъкът не се синхронизира, рестартирайте възпроизвеждането",
|
||||||
|
"ToastProviderCreatedFailed": "Неуспешно добавяне на доставчик",
|
||||||
|
"ToastProviderCreatedSuccess": "Добавен е нов доставчик",
|
||||||
|
"ToastProviderNameAndUrlRequired": "Изискват се име и URL адрес",
|
||||||
|
"ToastProviderRemoveSuccess": "Доставчикът е премахнат",
|
||||||
"ToastRSSFeedCloseFailed": "Неуспешно затваряне на RSS емисията",
|
"ToastRSSFeedCloseFailed": "Неуспешно затваряне на RSS емисията",
|
||||||
"ToastRSSFeedCloseSuccess": "RSS емисията е затворена",
|
"ToastRSSFeedCloseSuccess": "RSS емисията е затворена",
|
||||||
|
"ToastRemoveFailed": "Неуспешно премахване",
|
||||||
"ToastRemoveItemFromCollectionFailed": "Неуспешно премахване на елемент от колекция",
|
"ToastRemoveItemFromCollectionFailed": "Неуспешно премахване на елемент от колекция",
|
||||||
"ToastRemoveItemFromCollectionSuccess": "Елементът е премахнат от колекция",
|
"ToastRemoveItemFromCollectionSuccess": "Елементът е премахнат от колекция",
|
||||||
|
"ToastRemoveItemsWithIssuesFailed": "Неуспешно премахване на елементите от библиотеката с проблеми",
|
||||||
|
"ToastRemoveItemsWithIssuesSuccess": "Елементите от библиотеката с проблеми са премахнати",
|
||||||
|
"ToastRenameFailed": "Неуспешно преименуване",
|
||||||
|
"ToastRescanFailed": "Повторното сканиране е неуспешно за {0}",
|
||||||
|
"ToastRescanRemoved": "Повторното сканиране завърши: елементът е премахнат",
|
||||||
|
"ToastRescanUpToDate": "Повторното сканиране завърши: елементът вече е актуален",
|
||||||
|
"ToastRescanUpdated": "Повторното сканиране завърши: елементът е актуализиран",
|
||||||
|
"ToastScanFailed": "Неуспешно сканиране на елемент от библиотеката",
|
||||||
|
"ToastSelectAtLeastOneUser": "Изберете поне един потребител",
|
||||||
"ToastSendEbookToDeviceFailed": "Неуспешно изпращане на електронна книга до устройство",
|
"ToastSendEbookToDeviceFailed": "Неуспешно изпращане на електронна книга до устройство",
|
||||||
"ToastSendEbookToDeviceSuccess": "Електронната книга е изпратена до устройство \"{0}\"",
|
"ToastSendEbookToDeviceSuccess": "Електронната книга е изпратена до устройство \"{0}\"",
|
||||||
|
"ToastSeriesSubmitFailedSameName": "Не могат да бъдат добавени два сериала с едно и също име",
|
||||||
"ToastSeriesUpdateFailed": "Неуспешно обновяване на серия",
|
"ToastSeriesUpdateFailed": "Неуспешно обновяване на серия",
|
||||||
"ToastSeriesUpdateSuccess": "Серията е обновена",
|
"ToastSeriesUpdateSuccess": "Серията е обновена",
|
||||||
"ToastServerSettingsUpdateSuccess": "Настройките на сървъра са актуализирани",
|
"ToastServerSettingsUpdateSuccess": "Настройките на сървъра са актуализирани",
|
||||||
|
"ToastSessionCloseFailed": "Неуспешно затваряне на сесията",
|
||||||
"ToastSessionDeleteFailed": "Неуспешно изтриване на сесия",
|
"ToastSessionDeleteFailed": "Неуспешно изтриване на сесия",
|
||||||
"ToastSessionDeleteSuccess": "Сесията е изтрита",
|
"ToastSessionDeleteSuccess": "Сесията е изтрита",
|
||||||
|
"ToastSleepTimerDone": "Таймерът за заспиване приключи... zZzzZz",
|
||||||
|
"ToastSlugMustChange": "Краткият URL (slug) съдържа невалидни символи",
|
||||||
|
"ToastSlugRequired": "Изисква се кратък URL (slug)",
|
||||||
"ToastSocketConnected": "Свързан сокет",
|
"ToastSocketConnected": "Свързан сокет",
|
||||||
"ToastSocketDisconnected": "Сокетът е прекъснат",
|
"ToastSocketDisconnected": "Сокетът е прекъснат",
|
||||||
"ToastSocketFailedToConnect": "Неуспешно свързване на сокет",
|
"ToastSocketFailedToConnect": "Неуспешно свързване на сокет",
|
||||||
"ToastSortingPrefixesEmptyError": "Трябва да има поне 1 префикс за сортиране",
|
"ToastSortingPrefixesEmptyError": "Трябва да има поне 1 префикс за сортиране",
|
||||||
"ToastSortingPrefixesUpdateSuccess": "Префиксите за сортиране са актуализирани ({0} елемента)",
|
"ToastSortingPrefixesUpdateSuccess": "Префиксите за сортиране са актуализирани ({0} елемента)",
|
||||||
|
"ToastTitleRequired": "Изисква се заглавие",
|
||||||
|
"ToastUnknownError": "Неизвестна грешка",
|
||||||
|
"ToastUnlinkOpenIdFailed": "Неуспешно прекъсване на връзката на потребителя с OpenID",
|
||||||
|
"ToastUnlinkOpenIdSuccess": "Връзката на потребителя с OpenID е прекъсната",
|
||||||
|
"ToastUploaderFilepathExistsError": "Файловият път „{0}“ вече съществува на сървъра",
|
||||||
|
"ToastUploaderItemExistsInSubdirectoryError": "Елементът „{0}“ използва поддиректория на пътя за качване.",
|
||||||
"ToastUserDeleteFailed": "Неуспешно изтриване на потребител",
|
"ToastUserDeleteFailed": "Неуспешно изтриване на потребител",
|
||||||
"ToastUserDeleteSuccess": "Потребителят е изтрит"
|
"ToastUserDeleteSuccess": "Потребителят е изтрит",
|
||||||
|
"ToastUserPasswordChangeSuccess": "Паролата е променена успешно",
|
||||||
|
"ToastUserPasswordMismatch": "Паролите не съвпадат",
|
||||||
|
"ToastUserPasswordMustChange": "Новата парола не може да бъде същата като старата",
|
||||||
|
"ToastUserRootRequireName": "Трябва да въведете root потребителско име",
|
||||||
|
"TooltipAddChapters": "Добавяне на глава(и)",
|
||||||
|
"TooltipAddOneSecond": "Добавяне на 1 секунда",
|
||||||
|
"TooltipAdjustChapterStart": "Кликнете за коригиране на началния час",
|
||||||
|
"TooltipLockAllChapters": "Заключване на всички глави",
|
||||||
|
"TooltipLockChapter": "Заключване на глава (Shift+клик за диапазон)",
|
||||||
|
"TooltipSubtractOneSecond": "Изваждане на 1 секунда",
|
||||||
|
"TooltipUnlockAllChapters": "Отключване на всички глави",
|
||||||
|
"TooltipUnlockChapter": "Отключване на глава (Shift+клик за диапазон)"
|
||||||
}
|
}
|
||||||
+103
-9
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"ButtonAdd": "যোগ করুন",
|
"ButtonAdd": "যোগ করুন",
|
||||||
|
"ButtonAddApiKey": "এপিআই কী যোগ করুন",
|
||||||
"ButtonAddChapters": "অধ্যায় যোগ করুন",
|
"ButtonAddChapters": "অধ্যায় যোগ করুন",
|
||||||
"ButtonAddDevice": "ডিভাইস যোগ করুন",
|
"ButtonAddDevice": "ডিভাইস যোগ করুন",
|
||||||
"ButtonAddLibrary": "লাইব্রেরি যোগ করুন",
|
"ButtonAddLibrary": "লাইব্রেরি যোগ করুন",
|
||||||
@@ -10,6 +11,8 @@
|
|||||||
"ButtonApplyChapters": "অধ্যায় প্রয়োগ করুন",
|
"ButtonApplyChapters": "অধ্যায় প্রয়োগ করুন",
|
||||||
"ButtonAuthors": "লেখকগণ",
|
"ButtonAuthors": "লেখকগণ",
|
||||||
"ButtonBack": "পেছনে যান",
|
"ButtonBack": "পেছনে যান",
|
||||||
|
"ButtonBatchEditPopulateFromExisting": "বিদ্যমান থেকে পূরণ করুন",
|
||||||
|
"ButtonBatchEditPopulateMapDetails": "ম্যাপ থেকে পূরণ করুন",
|
||||||
"ButtonBrowseForFolder": "ফোল্ডারের জন্য ব্রাউজ করুন",
|
"ButtonBrowseForFolder": "ফোল্ডারের জন্য ব্রাউজ করুন",
|
||||||
"ButtonCancel": "বাতিল করুন",
|
"ButtonCancel": "বাতিল করুন",
|
||||||
"ButtonCancelEncode": "এনকোড বাতিল করুন",
|
"ButtonCancelEncode": "এনকোড বাতিল করুন",
|
||||||
@@ -18,6 +21,7 @@
|
|||||||
"ButtonChooseAFolder": "একটি ফোল্ডার চয়ন করুন",
|
"ButtonChooseAFolder": "একটি ফোল্ডার চয়ন করুন",
|
||||||
"ButtonChooseFiles": "ফাইল চয়ন করুন",
|
"ButtonChooseFiles": "ফাইল চয়ন করুন",
|
||||||
"ButtonClearFilter": "ফিল্টার পরিষ্কার করুন",
|
"ButtonClearFilter": "ফিল্টার পরিষ্কার করুন",
|
||||||
|
"ButtonClose": "বন্ধ করুন",
|
||||||
"ButtonCloseFeed": "ফিড বন্ধ করুন",
|
"ButtonCloseFeed": "ফিড বন্ধ করুন",
|
||||||
"ButtonCloseSession": "খোলা সেশন বন্ধ করুন",
|
"ButtonCloseSession": "খোলা সেশন বন্ধ করুন",
|
||||||
"ButtonCollections": "সংগ্রহ",
|
"ButtonCollections": "সংগ্রহ",
|
||||||
@@ -42,6 +46,7 @@
|
|||||||
"ButtonLatest": "সর্বশেষ",
|
"ButtonLatest": "সর্বশেষ",
|
||||||
"ButtonLibrary": "লাইব্রেরি",
|
"ButtonLibrary": "লাইব্রেরি",
|
||||||
"ButtonLogout": "লগআউট",
|
"ButtonLogout": "লগআউট",
|
||||||
|
"ButtonLogoutAllDevices": "সব ডিভাইস থেকে লগআউট করুন",
|
||||||
"ButtonLookup": "সন্ধান",
|
"ButtonLookup": "সন্ধান",
|
||||||
"ButtonManageTracks": "ট্র্যাকগুলি পরিচালনা করুন",
|
"ButtonManageTracks": "ট্র্যাকগুলি পরিচালনা করুন",
|
||||||
"ButtonMapChapterTitles": "অধ্যায়ের শিরোনাম ম্যাপ করুন",
|
"ButtonMapChapterTitles": "অধ্যায়ের শিরোনাম ম্যাপ করুন",
|
||||||
@@ -72,7 +77,7 @@
|
|||||||
"ButtonReScan": "পুনরায় স্ক্যান",
|
"ButtonReScan": "পুনরায় স্ক্যান",
|
||||||
"ButtonRead": "পড়ুন",
|
"ButtonRead": "পড়ুন",
|
||||||
"ButtonReadLess": "সংক্ষিপ্ত",
|
"ButtonReadLess": "সংক্ষিপ্ত",
|
||||||
"ButtonReadMore": "বিস্তারিত পড়ুন",
|
"ButtonReadMore": "আরও পড়ুন",
|
||||||
"ButtonRefresh": "রিফ্রেশ",
|
"ButtonRefresh": "রিফ্রেশ",
|
||||||
"ButtonRemove": "মুছে ফেলুন",
|
"ButtonRemove": "মুছে ফেলুন",
|
||||||
"ButtonRemoveAll": "সব মুছে ফেলুন",
|
"ButtonRemoveAll": "সব মুছে ফেলুন",
|
||||||
@@ -117,11 +122,13 @@
|
|||||||
"HeaderAccount": "অ্যাকাউন্ট",
|
"HeaderAccount": "অ্যাকাউন্ট",
|
||||||
"HeaderAddCustomMetadataProvider": "কাস্টম মেটাডেটা সরবরাহকারী যোগ করুন",
|
"HeaderAddCustomMetadataProvider": "কাস্টম মেটাডেটা সরবরাহকারী যোগ করুন",
|
||||||
"HeaderAdvanced": "অ্যাডভান্সড",
|
"HeaderAdvanced": "অ্যাডভান্সড",
|
||||||
|
"HeaderApiKeys": "এপিআই কী সমূহ",
|
||||||
"HeaderAppriseNotificationSettings": "বিজ্ঞপ্তি সেটিংস অবহিত করুন",
|
"HeaderAppriseNotificationSettings": "বিজ্ঞপ্তি সেটিংস অবহিত করুন",
|
||||||
"HeaderAudioTracks": "অডিও ট্র্যাকসগুলো",
|
"HeaderAudioTracks": "অডিও ট্র্যাকসগুলো",
|
||||||
"HeaderAudiobookTools": "অডিওবই ফাইল ম্যানেজমেন্ট টুলস",
|
"HeaderAudiobookTools": "অডিওবই ফাইল ম্যানেজমেন্ট টুলস",
|
||||||
"HeaderAuthentication": "প্রমাণীকরণ",
|
"HeaderAuthentication": "প্রমাণীকরণ",
|
||||||
"HeaderBackups": "ব্যাকআপ",
|
"HeaderBackups": "ব্যাকআপ",
|
||||||
|
"HeaderBulkChapterModal": "একাধিক অধ্যায় যোগ করুন",
|
||||||
"HeaderChangePassword": "পাসওয়ার্ড পরিবর্তন করুন",
|
"HeaderChangePassword": "পাসওয়ার্ড পরিবর্তন করুন",
|
||||||
"HeaderChapters": "অধ্যায়",
|
"HeaderChapters": "অধ্যায়",
|
||||||
"HeaderChooseAFolder": "একটি ফোল্ডার চয়ন করুন",
|
"HeaderChooseAFolder": "একটি ফোল্ডার চয়ন করুন",
|
||||||
@@ -160,6 +167,7 @@
|
|||||||
"HeaderMetadataOrderOfPrecedence": "মেটাডেটা অগ্রাধিকারের ক্রম",
|
"HeaderMetadataOrderOfPrecedence": "মেটাডেটা অগ্রাধিকারের ক্রম",
|
||||||
"HeaderMetadataToEmbed": "এম্বেড করার জন্য মেটাডেটা",
|
"HeaderMetadataToEmbed": "এম্বেড করার জন্য মেটাডেটা",
|
||||||
"HeaderNewAccount": "নতুন অ্যাকাউন্ট",
|
"HeaderNewAccount": "নতুন অ্যাকাউন্ট",
|
||||||
|
"HeaderNewApiKey": "নতুন API কী",
|
||||||
"HeaderNewLibrary": "নতুন লাইব্রেরি",
|
"HeaderNewLibrary": "নতুন লাইব্রেরি",
|
||||||
"HeaderNotificationCreate": "বিজ্ঞপ্তি তৈরি করুন",
|
"HeaderNotificationCreate": "বিজ্ঞপ্তি তৈরি করুন",
|
||||||
"HeaderNotificationUpdate": "বিজ্ঞপ্তি আপডেট করুন",
|
"HeaderNotificationUpdate": "বিজ্ঞপ্তি আপডেট করুন",
|
||||||
@@ -175,6 +183,7 @@
|
|||||||
"HeaderPlaylist": "প্লেলিস্ট",
|
"HeaderPlaylist": "প্লেলিস্ট",
|
||||||
"HeaderPlaylistItems": "প্লেলিস্ট আইটেম",
|
"HeaderPlaylistItems": "প্লেলিস্ট আইটেম",
|
||||||
"HeaderPodcastsToAdd": "যোগ করার জন্য পডকাস্ট",
|
"HeaderPodcastsToAdd": "যোগ করার জন্য পডকাস্ট",
|
||||||
|
"HeaderPresets": "প্রিসেট",
|
||||||
"HeaderPreviewCover": "কভার ্দেখুন",
|
"HeaderPreviewCover": "কভার ্দেখুন",
|
||||||
"HeaderRSSFeedGeneral": "আরএসএস বিবরণ",
|
"HeaderRSSFeedGeneral": "আরএসএস বিবরণ",
|
||||||
"HeaderRSSFeedIsOpen": "আরএসএস ফিড খোলা আছে",
|
"HeaderRSSFeedIsOpen": "আরএসএস ফিড খোলা আছে",
|
||||||
@@ -186,12 +195,14 @@
|
|||||||
"HeaderScheduleEpisodeDownloads": "স্বয়ংক্রিয় পর্ব ডাউনলোডের সময়সূচী নির্ধারন করুন",
|
"HeaderScheduleEpisodeDownloads": "স্বয়ংক্রিয় পর্ব ডাউনলোডের সময়সূচী নির্ধারন করুন",
|
||||||
"HeaderScheduleLibraryScans": "স্বয়ংক্রিয় লাইব্রেরি স্ক্যানের সময়সূচী",
|
"HeaderScheduleLibraryScans": "স্বয়ংক্রিয় লাইব্রেরি স্ক্যানের সময়সূচী",
|
||||||
"HeaderSession": "সেশন",
|
"HeaderSession": "সেশন",
|
||||||
|
"HeaderSessions": "সেশনসমূহ",
|
||||||
"HeaderSetBackupSchedule": "ব্যাকআপ সময়সূচী সেট করুন",
|
"HeaderSetBackupSchedule": "ব্যাকআপ সময়সূচী সেট করুন",
|
||||||
"HeaderSettings": "সেটিংস",
|
"HeaderSettings": "সেটিংস",
|
||||||
"HeaderSettingsDisplay": "প্রদর্শন",
|
"HeaderSettingsDisplay": "প্রদর্শন",
|
||||||
"HeaderSettingsExperimental": "পরীক্ষামূলক ফিচার",
|
"HeaderSettingsExperimental": "পরীক্ষামূলক ফিচার",
|
||||||
"HeaderSettingsGeneral": "সাধারণ",
|
"HeaderSettingsGeneral": "সাধারণ",
|
||||||
"HeaderSettingsScanner": "স্ক্যানার",
|
"HeaderSettingsScanner": "স্ক্যানার",
|
||||||
|
"HeaderSettingsSecurity": "নিরাপত্তা",
|
||||||
"HeaderSettingsWebClient": "ওয়েব ক্লায়েন্ট",
|
"HeaderSettingsWebClient": "ওয়েব ক্লায়েন্ট",
|
||||||
"HeaderSleepTimer": "স্লিপ টাইমার",
|
"HeaderSleepTimer": "স্লিপ টাইমার",
|
||||||
"HeaderStatsLargestItems": "সবচেয়ে বড় আইটেম",
|
"HeaderStatsLargestItems": "সবচেয়ে বড় আইটেম",
|
||||||
@@ -203,6 +214,7 @@
|
|||||||
"HeaderTableOfContents": "বিষয়বস্তুর সারণী",
|
"HeaderTableOfContents": "বিষয়বস্তুর সারণী",
|
||||||
"HeaderTools": "টুলস",
|
"HeaderTools": "টুলস",
|
||||||
"HeaderUpdateAccount": "অ্যাকাউন্ট আপডেট করুন",
|
"HeaderUpdateAccount": "অ্যাকাউন্ট আপডেট করুন",
|
||||||
|
"HeaderUpdateApiKey": "API কী আপডেট করুন",
|
||||||
"HeaderUpdateAuthor": "লেখক আপডেট করুন",
|
"HeaderUpdateAuthor": "লেখক আপডেট করুন",
|
||||||
"HeaderUpdateDetails": "বিশদ আপডেট করুন",
|
"HeaderUpdateDetails": "বিশদ আপডেট করুন",
|
||||||
"HeaderUpdateLibrary": "লাইব্রেরি আপডেট করুন",
|
"HeaderUpdateLibrary": "লাইব্রেরি আপডেট করুন",
|
||||||
@@ -217,6 +229,7 @@
|
|||||||
"LabelAccountTypeAdmin": "প্রশাসন",
|
"LabelAccountTypeAdmin": "প্রশাসন",
|
||||||
"LabelAccountTypeGuest": "অতিথি",
|
"LabelAccountTypeGuest": "অতিথি",
|
||||||
"LabelAccountTypeUser": "ব্যবহারকারী",
|
"LabelAccountTypeUser": "ব্যবহারকারী",
|
||||||
|
"LabelActivities": "কার্যকলাপ",
|
||||||
"LabelActivity": "ক্রিয়াকলাপ",
|
"LabelActivity": "ক্রিয়াকলাপ",
|
||||||
"LabelAddToCollection": "সংগ্রহে যোগ করুন",
|
"LabelAddToCollection": "সংগ্রহে যোগ করুন",
|
||||||
"LabelAddToCollectionBatch": "সংগ্রহে {0}টি বই যোগ করুন",
|
"LabelAddToCollectionBatch": "সংগ্রহে {0}টি বই যোগ করুন",
|
||||||
@@ -226,10 +239,15 @@
|
|||||||
"LabelAddedDate": "যোগ করা হয়েছে {0}",
|
"LabelAddedDate": "যোগ করা হয়েছে {0}",
|
||||||
"LabelAdminUsersOnly": "শুধু অ্যাডমিন ব্যবহারকারী",
|
"LabelAdminUsersOnly": "শুধু অ্যাডমিন ব্যবহারকারী",
|
||||||
"LabelAll": "সব",
|
"LabelAll": "সব",
|
||||||
|
"LabelAllEpisodesDownloaded": "সব পর্ব ডাউনলোড করা হয়েছে",
|
||||||
"LabelAllUsers": "সমস্ত ব্যবহারকারী",
|
"LabelAllUsers": "সমস্ত ব্যবহারকারী",
|
||||||
"LabelAllUsersExcludingGuests": "অতিথি ব্যতীত সকল ব্যবহারকারী",
|
"LabelAllUsersExcludingGuests": "অতিথি ব্যতীত সকল ব্যবহারকারী",
|
||||||
"LabelAllUsersIncludingGuests": "অতিথি সহ সকল ব্যবহারকারী",
|
"LabelAllUsersIncludingGuests": "অতিথি সহ সকল ব্যবহারকারী",
|
||||||
"LabelAlreadyInYourLibrary": "ইতিমধ্যেই আপনার লাইব্রেরিতে রয়েছে",
|
"LabelAlreadyInYourLibrary": "ইতিমধ্যেই আপনার লাইব্রেরিতে রয়েছে",
|
||||||
|
"LabelApiKeyCreated": "API কী \"{0}\" সফলভাবে তৈরি করা হয়েছে।",
|
||||||
|
"LabelApiKeyCreatedDescription": "API কীটি এখনই কপি করে রাখুন, কারণ এটি পরে আর দেখতে পারবেন না।",
|
||||||
|
"LabelApiKeyUser": "ব্যবহারকারীর পক্ষ থেকে কাজ করুন",
|
||||||
|
"LabelApiKeyUserDescription": "এই API কীটি যে ব্যবহারকারীর পক্ষ থেকে কাজ করবে, সেই ব্যবহারকারীর মতোই একই অনুমতি পাবে। লগে এটি এমনভাবে দেখাবে যেন ব্যবহারকারী নিজেই অনুরোধটি করেছেন।",
|
||||||
"LabelApiToken": "API টোকেন",
|
"LabelApiToken": "API টোকেন",
|
||||||
"LabelAppend": "সংযোজন",
|
"LabelAppend": "সংযোজন",
|
||||||
"LabelAudioBitrate": "অডিও বিটরেট (যেমন- 128k)",
|
"LabelAudioBitrate": "অডিও বিটরেট (যেমন- 128k)",
|
||||||
@@ -259,7 +277,7 @@
|
|||||||
"LabelBonus": "উপরিলাভ",
|
"LabelBonus": "উপরিলাভ",
|
||||||
"LabelBooks": "বইগুলো",
|
"LabelBooks": "বইগুলো",
|
||||||
"LabelButtonText": "ঘর পাঠ্য",
|
"LabelButtonText": "ঘর পাঠ্য",
|
||||||
"LabelByAuthor": "দ্বারা {0}",
|
"LabelByAuthor": "{0} অবশ্যই একদম অপরিবর্তিত রাখবে",
|
||||||
"LabelChangePassword": "পাসওয়ার্ড পরিবর্তন করুন",
|
"LabelChangePassword": "পাসওয়ার্ড পরিবর্তন করুন",
|
||||||
"LabelChannels": "চ্যানেল",
|
"LabelChannels": "চ্যানেল",
|
||||||
"LabelChapterCount": "{0} অধ্যায়",
|
"LabelChapterCount": "{0} অধ্যায়",
|
||||||
@@ -279,8 +297,10 @@
|
|||||||
"LabelContinueListening": "শোনা চালিয়ে যান",
|
"LabelContinueListening": "শোনা চালিয়ে যান",
|
||||||
"LabelContinueReading": "পড়া চালিয়ে যান",
|
"LabelContinueReading": "পড়া চালিয়ে যান",
|
||||||
"LabelContinueSeries": "সিরিজ চালিয়ে যান",
|
"LabelContinueSeries": "সিরিজ চালিয়ে যান",
|
||||||
|
"LabelCorsAllowed": "অনুমোদিত CORS অরিজিনসমূহ",
|
||||||
"LabelCover": "কভার",
|
"LabelCover": "কভার",
|
||||||
"LabelCoverImageURL": "ছবির কভারের URL",
|
"LabelCoverImageURL": "ছবির কভারের URL",
|
||||||
|
"LabelCoverProvider": "কভার প্রদানকারী",
|
||||||
"LabelCreatedAt": "তৈরি করা হয়েছে",
|
"LabelCreatedAt": "তৈরি করা হয়েছে",
|
||||||
"LabelCronExpression": "Cron এক্সপ্রেশন",
|
"LabelCronExpression": "Cron এক্সপ্রেশন",
|
||||||
"LabelCurrent": "বর্তমান",
|
"LabelCurrent": "বর্তমান",
|
||||||
@@ -291,6 +311,7 @@
|
|||||||
"LabelDeleteFromFileSystemCheckbox": "ফাইল সিস্টেম থেকে মুছে ফেলুন (শুধু ডাটাবেস থেকে সরাতে টিক চিহ্ন মুক্ত করুন)",
|
"LabelDeleteFromFileSystemCheckbox": "ফাইল সিস্টেম থেকে মুছে ফেলুন (শুধু ডাটাবেস থেকে সরাতে টিক চিহ্ন মুক্ত করুন)",
|
||||||
"LabelDescription": "বিবরণ",
|
"LabelDescription": "বিবরণ",
|
||||||
"LabelDeselectAll": "সমস্ত অনির্বাচিত করুন",
|
"LabelDeselectAll": "সমস্ত অনির্বাচিত করুন",
|
||||||
|
"LabelDetectedPattern": "শনাক্ত করা প্যাটার্ন:",
|
||||||
"LabelDevice": "ডিভাইস",
|
"LabelDevice": "ডিভাইস",
|
||||||
"LabelDeviceInfo": "ডিভাইস তথ্য",
|
"LabelDeviceInfo": "ডিভাইস তথ্য",
|
||||||
"LabelDeviceIsAvailableTo": "ডিভাইস এর জন্য উপলব্ধ...",
|
"LabelDeviceIsAvailableTo": "ডিভাইস এর জন্য উপলব্ধ...",
|
||||||
@@ -340,7 +361,11 @@
|
|||||||
"LabelExample": "উদাহরণ",
|
"LabelExample": "উদাহরণ",
|
||||||
"LabelExpandSeries": "সিরিজ প্রসারিত করুন",
|
"LabelExpandSeries": "সিরিজ প্রসারিত করুন",
|
||||||
"LabelExpandSubSeries": "সাব সিরিজ প্রসারিত করুন",
|
"LabelExpandSubSeries": "সাব সিরিজ প্রসারিত করুন",
|
||||||
"LabelExplicit": "বিশদ",
|
"LabelExpired": "মেয়াদ শেষ হয়েছে",
|
||||||
|
"LabelExpiresAt": "মেয়াদ শেষ হওয়ার সময়",
|
||||||
|
"LabelExpiresInSeconds": "মেয়াদ শেষ হবে (সেকেন্ডে)",
|
||||||
|
"LabelExpiresNever": "কখনোই নয়",
|
||||||
|
"LabelExplicit": "অশ্লীল ভাষা",
|
||||||
"LabelExplicitChecked": "সুস্পষ্ট (পরীক্ষিত)",
|
"LabelExplicitChecked": "সুস্পষ্ট (পরীক্ষিত)",
|
||||||
"LabelExplicitUnchecked": "অস্পষ্ট (অপরিক্ষীত)",
|
"LabelExplicitUnchecked": "অস্পষ্ট (অপরিক্ষীত)",
|
||||||
"LabelExportOPML": "OPML এক্সপোর্ট করুন",
|
"LabelExportOPML": "OPML এক্সপোর্ট করুন",
|
||||||
@@ -355,11 +380,12 @@
|
|||||||
"LabelFilterByUser": "ব্যবহারকারী দ্বারা ফিল্টারকৃত",
|
"LabelFilterByUser": "ব্যবহারকারী দ্বারা ফিল্টারকৃত",
|
||||||
"LabelFindEpisodes": "পর্বগুলো খুঁজুন",
|
"LabelFindEpisodes": "পর্বগুলো খুঁজুন",
|
||||||
"LabelFinished": "সমাপ্ত",
|
"LabelFinished": "সমাপ্ত",
|
||||||
|
"LabelFinishedDate": "{0} সম্পন্ন হয়েছে",
|
||||||
"LabelFolder": "ফোল্ডার",
|
"LabelFolder": "ফোল্ডার",
|
||||||
"LabelFolders": "ফোল্ডারগুলো",
|
"LabelFolders": "ফোল্ডারগুলো",
|
||||||
"LabelFontBold": "বোল্ড",
|
"LabelFontBold": "বোল্ড",
|
||||||
"LabelFontBoldness": "হরফ বোল্ডনেস",
|
"LabelFontBoldness": "হরফ বোল্ডনেস",
|
||||||
"LabelFontFamily": "হরফ পরিবার",
|
"LabelFontFamily": "ফন্টের ধরন",
|
||||||
"LabelFontItalic": "ইটালিক",
|
"LabelFontItalic": "ইটালিক",
|
||||||
"LabelFontScale": "ফন্ট স্কেল",
|
"LabelFontScale": "ফন্ট স্কেল",
|
||||||
"LabelFontStrikethrough": "অবচ্ছেদন রেখা",
|
"LabelFontStrikethrough": "অবচ্ছেদন রেখা",
|
||||||
@@ -389,7 +415,9 @@
|
|||||||
"LabelIntervalEvery6Hours": "প্রতি ৬ ঘন্টায়",
|
"LabelIntervalEvery6Hours": "প্রতি ৬ ঘন্টায়",
|
||||||
"LabelIntervalEveryDay": "প্রতিদিন",
|
"LabelIntervalEveryDay": "প্রতিদিন",
|
||||||
"LabelIntervalEveryHour": "প্রতি ঘন্টা",
|
"LabelIntervalEveryHour": "প্রতি ঘন্টা",
|
||||||
|
"LabelIntervalEveryMinute": "প্রতি মিনিটে",
|
||||||
"LabelInvert": "উল্টানো",
|
"LabelInvert": "উল্টানো",
|
||||||
|
"LabelIpAddress": "IP ঠিকানা",
|
||||||
"LabelItem": "আইটেম",
|
"LabelItem": "আইটেম",
|
||||||
"LabelJumpBackwardAmount": "পিছন দিকে ঝাঁপের পরিমাণ",
|
"LabelJumpBackwardAmount": "পিছন দিকে ঝাঁপের পরিমাণ",
|
||||||
"LabelJumpForwardAmount": "সামনের দিকে ঝাঁপের পরিমাণ",
|
"LabelJumpForwardAmount": "সামনের দিকে ঝাঁপের পরিমাণ",
|
||||||
@@ -398,6 +426,7 @@
|
|||||||
"LabelLanguages": "ভাষাসমূহ",
|
"LabelLanguages": "ভাষাসমূহ",
|
||||||
"LabelLastBookAdded": "শেষ বই যোগ করা হয়েছে",
|
"LabelLastBookAdded": "শেষ বই যোগ করা হয়েছে",
|
||||||
"LabelLastBookUpdated": "শেষ বই আপডেট করা হয়েছে",
|
"LabelLastBookUpdated": "শেষ বই আপডেট করা হয়েছে",
|
||||||
|
"LabelLastProgressDate": "সর্বশেষ অগ্রগতি: {0}",
|
||||||
"LabelLastSeen": "শেষ দেখা",
|
"LabelLastSeen": "শেষ দেখা",
|
||||||
"LabelLastTime": "শেষ বার",
|
"LabelLastTime": "শেষ বার",
|
||||||
"LabelLastUpdate": "শেষ আপডেট",
|
"LabelLastUpdate": "শেষ আপডেট",
|
||||||
@@ -410,6 +439,9 @@
|
|||||||
"LabelLibraryFilterSublistEmpty": "না {0}",
|
"LabelLibraryFilterSublistEmpty": "না {0}",
|
||||||
"LabelLibraryItem": "লাইব্রেরি আইটেম",
|
"LabelLibraryItem": "লাইব্রেরি আইটেম",
|
||||||
"LabelLibraryName": "লাইব্রেরির নাম",
|
"LabelLibraryName": "লাইব্রেরির নাম",
|
||||||
|
"LabelLibrarySortByProgress": "অগ্রগতি: সর্বশেষ আপডেট",
|
||||||
|
"LabelLibrarySortByProgressFinished": "অগ্রগতি: সম্পন্ন",
|
||||||
|
"LabelLibrarySortByProgressStarted": "অগ্রগতি: শুরু হয়েছে",
|
||||||
"LabelLimit": "সীমা",
|
"LabelLimit": "সীমা",
|
||||||
"LabelLineSpacing": "লাইন স্পেসিং",
|
"LabelLineSpacing": "লাইন স্পেসিং",
|
||||||
"LabelListenAgain": "আবার শুনুন",
|
"LabelListenAgain": "আবার শুনুন",
|
||||||
@@ -418,6 +450,7 @@
|
|||||||
"LabelLogLevelWarn": "সতর্ক",
|
"LabelLogLevelWarn": "সতর্ক",
|
||||||
"LabelLookForNewEpisodesAfterDate": "এই তারিখের পরে নতুন পর্বগুলি সন্ধান করুন",
|
"LabelLookForNewEpisodesAfterDate": "এই তারিখের পরে নতুন পর্বগুলি সন্ধান করুন",
|
||||||
"LabelLowestPriority": "সর্বনিম্ন অগ্রাধিকার",
|
"LabelLowestPriority": "সর্বনিম্ন অগ্রাধিকার",
|
||||||
|
"LabelMatchConfidence": "নিশ্চয়তার মাত্রা",
|
||||||
"LabelMatchExistingUsersBy": "বিদ্যমান ব্যবহারকারীদের দ্বারা মিলিত করুন",
|
"LabelMatchExistingUsersBy": "বিদ্যমান ব্যবহারকারীদের দ্বারা মিলিত করুন",
|
||||||
"LabelMatchExistingUsersByDescription": "বিদ্যমান ব্যবহারকারীদের সংযোগ করার জন্য ব্যবহৃত হয়। একবার সংযুক্ত হলে, ব্যবহারকারীদের আপনার SSO প্রদানকারীর থেকে একটি অনন্য আইডি দ্বারা মিলিত হবে",
|
"LabelMatchExistingUsersByDescription": "বিদ্যমান ব্যবহারকারীদের সংযোগ করার জন্য ব্যবহৃত হয়। একবার সংযুক্ত হলে, ব্যবহারকারীদের আপনার SSO প্রদানকারীর থেকে একটি অনন্য আইডি দ্বারা মিলিত হবে",
|
||||||
"LabelMaxEpisodesToDownload": "সর্বাধিক # টি পর্ব ডাউনলোড করা হবে। অসীমের জন্য 0 ব্যবহার করুন।",
|
"LabelMaxEpisodesToDownload": "সর্বাধিক # টি পর্ব ডাউনলোড করা হবে। অসীমের জন্য 0 ব্যবহার করুন।",
|
||||||
@@ -432,7 +465,7 @@
|
|||||||
"LabelMetadataProvider": "মেটাডেটা প্রদানকারী",
|
"LabelMetadataProvider": "মেটাডেটা প্রদানকারী",
|
||||||
"LabelMinute": "মিনিট",
|
"LabelMinute": "মিনিট",
|
||||||
"LabelMinutes": "মিনিটস",
|
"LabelMinutes": "মিনিটস",
|
||||||
"LabelMissing": "নিখোঁজ",
|
"LabelMissing": "অনুপস্থিত",
|
||||||
"LabelMissingEbook": "কোনও ই-বই নেই",
|
"LabelMissingEbook": "কোনও ই-বই নেই",
|
||||||
"LabelMissingSupplementaryEbook": "কোনও সম্পূরক ই-বই নেই",
|
"LabelMissingSupplementaryEbook": "কোনও সম্পূরক ই-বই নেই",
|
||||||
"LabelMobileRedirectURIs": "অনুমোদিত মোবাইল রিডাইরেক্ট URIs",
|
"LabelMobileRedirectURIs": "অনুমোদিত মোবাইল রিডাইরেক্ট URIs",
|
||||||
@@ -447,7 +480,9 @@
|
|||||||
"LabelNewestAuthors": "নতুন লেখক",
|
"LabelNewestAuthors": "নতুন লেখক",
|
||||||
"LabelNewestEpisodes": "নতুনতম পর্ব",
|
"LabelNewestEpisodes": "নতুনতম পর্ব",
|
||||||
"LabelNextBackupDate": "পরবর্তী ব্যাকআপ তারিখ",
|
"LabelNextBackupDate": "পরবর্তী ব্যাকআপ তারিখ",
|
||||||
|
"LabelNextChapters": "পরবর্তী অধ্যায়গুলো হবে:",
|
||||||
"LabelNextScheduledRun": "পরবর্তী নির্ধারিত দৌড়",
|
"LabelNextScheduledRun": "পরবর্তী নির্ধারিত দৌড়",
|
||||||
|
"LabelNoApiKeys": "কোনো API কী নেই",
|
||||||
"LabelNoCustomMetadataProviders": "কোনো কাস্টম মেটাডেটা প্রদানকারী নেই",
|
"LabelNoCustomMetadataProviders": "কোনো কাস্টম মেটাডেটা প্রদানকারী নেই",
|
||||||
"LabelNoEpisodesSelected": "কোন পর্ব নির্বাচন করা হয়নি",
|
"LabelNoEpisodesSelected": "কোন পর্ব নির্বাচন করা হয়নি",
|
||||||
"LabelNotFinished": "সমাপ্ত হয়নি",
|
"LabelNotFinished": "সমাপ্ত হয়নি",
|
||||||
@@ -463,7 +498,8 @@
|
|||||||
"LabelNotificationsMaxQueueSize": "বিজ্ঞপ্তি ইভেন্টের জন্য সর্বোচ্চ সারির আকার",
|
"LabelNotificationsMaxQueueSize": "বিজ্ঞপ্তি ইভেন্টের জন্য সর্বোচ্চ সারির আকার",
|
||||||
"LabelNotificationsMaxQueueSizeHelp": "ইভেন্টগুলি প্রতি সেকেন্ডে ১ বার ইন্ধন করার মধ্যে সীমাবদ্ধ। সারি সর্বাধিক আকারে থাকলে ইভেন্টগুলি উপেক্ষা করা হবে। এটি বিজ্ঞপ্তি স্প্যামিং প্রতিরোধ করে।",
|
"LabelNotificationsMaxQueueSizeHelp": "ইভেন্টগুলি প্রতি সেকেন্ডে ১ বার ইন্ধন করার মধ্যে সীমাবদ্ধ। সারি সর্বাধিক আকারে থাকলে ইভেন্টগুলি উপেক্ষা করা হবে। এটি বিজ্ঞপ্তি স্প্যামিং প্রতিরোধ করে।",
|
||||||
"LabelNumberOfBooks": "বইয়ের সংখ্যা",
|
"LabelNumberOfBooks": "বইয়ের সংখ্যা",
|
||||||
"LabelNumberOfEpisodes": "# টি পর্ব",
|
"LabelNumberOfChapters": "অধ্যায়ের সংখ্যা:",
|
||||||
|
"LabelNumberOfEpisodes": "পর্বের সংখ্যা",
|
||||||
"LabelOpenIDAdvancedPermsClaimDescription": "ওপেনআইডি দাবির নাম যাতে অ্যাপ্লিকেশনের মধ্যে ব্যবহারকারীর ক্রিয়াকলাপের জন্য উন্নত অনুমতি রয়েছে যা অ-প্রশাসক ভূমিকাগুলিতে প্রযোজ্য হবে (<b>যদি কনফিগার করা হয়</b>)। প্রতিক্রিয়া থেকে দাবিটি অনুপস্থিত থাকলে, অ্যাক্সেস করুন ABS-তে অস্বীকার করা হবে। যদি একটি একক বিকল্প অনুপস্থিত থাকে, তাহলে এটিকে <code>false</code> হিসাবে গণ্য করা হবে। নিশ্চিত করুন যে পরিচয় প্রদানকারীর দাবি প্রত্যাশিত কাঠামোর সাথে মেলে:",
|
"LabelOpenIDAdvancedPermsClaimDescription": "ওপেনআইডি দাবির নাম যাতে অ্যাপ্লিকেশনের মধ্যে ব্যবহারকারীর ক্রিয়াকলাপের জন্য উন্নত অনুমতি রয়েছে যা অ-প্রশাসক ভূমিকাগুলিতে প্রযোজ্য হবে (<b>যদি কনফিগার করা হয়</b>)। প্রতিক্রিয়া থেকে দাবিটি অনুপস্থিত থাকলে, অ্যাক্সেস করুন ABS-তে অস্বীকার করা হবে। যদি একটি একক বিকল্প অনুপস্থিত থাকে, তাহলে এটিকে <code>false</code> হিসাবে গণ্য করা হবে। নিশ্চিত করুন যে পরিচয় প্রদানকারীর দাবি প্রত্যাশিত কাঠামোর সাথে মেলে:",
|
||||||
"LabelOpenIDClaims": "অ্যাডভান্সড গ্রুপ এবং পারমিশন অ্যাসাইনমেন্ট নিষ্ক্রিয় করতে নিম্নলিখিত বিকল্পগুলিকে খালি ছেড়ে দিন, তারপর স্বয়ংক্রিয়ভাবে 'ব্যবহারকারী' গ্রুপকে বরাদ্দ করা হবে।",
|
"LabelOpenIDClaims": "অ্যাডভান্সড গ্রুপ এবং পারমিশন অ্যাসাইনমেন্ট নিষ্ক্রিয় করতে নিম্নলিখিত বিকল্পগুলিকে খালি ছেড়ে দিন, তারপর স্বয়ংক্রিয়ভাবে 'ব্যবহারকারী' গ্রুপকে বরাদ্দ করা হবে।",
|
||||||
"LabelOpenIDGroupClaimDescription": "ওপেনআইডি দাবির নাম যাতে ব্যবহারকারীর গোষ্ঠীর একটি তালিকা থাকে। সাধারণত <code>গ্রুপ</code> হিসাবে উল্লেখ করা হয়। <b>কনফিগার করা থাকলে</b>, অ্যাপ্লিকেশনটি স্বয়ংক্রিয়ভাবে এর উপর ভিত্তি করে ব্যবহারকারীর গোষ্ঠীর সদস্যপদ নির্ধারণ করবে, শর্ত এই যে এই গোষ্ঠীগুলি কেস-অসংবেদনশীলভাবে দাবিতে 'অ্যাডমিন', 'ব্যবহারকারী' বা 'অতিথি' নাম দেওয়া হয়৷ দাবিতে একটি তালিকা থাকা উচিত এবং যদি একজন ব্যবহারকারী একাধিক গোষ্ঠীর অন্তর্গত হয় তবে অ্যাপ্লিকেশনটি বরাদ্দ করবে সর্বোচ্চ স্তরের অ্যাক্সেসের সাথে সঙ্গতিপূর্ণ ভূমিকা৷ যদি কোনও গোষ্ঠীর সাথে মেলে না, তবে অ্যাক্সেস অস্বীকার করা হবে।",
|
"LabelOpenIDGroupClaimDescription": "ওপেনআইডি দাবির নাম যাতে ব্যবহারকারীর গোষ্ঠীর একটি তালিকা থাকে। সাধারণত <code>গ্রুপ</code> হিসাবে উল্লেখ করা হয়। <b>কনফিগার করা থাকলে</b>, অ্যাপ্লিকেশনটি স্বয়ংক্রিয়ভাবে এর উপর ভিত্তি করে ব্যবহারকারীর গোষ্ঠীর সদস্যপদ নির্ধারণ করবে, শর্ত এই যে এই গোষ্ঠীগুলি কেস-অসংবেদনশীলভাবে দাবিতে 'অ্যাডমিন', 'ব্যবহারকারী' বা 'অতিথি' নাম দেওয়া হয়৷ দাবিতে একটি তালিকা থাকা উচিত এবং যদি একজন ব্যবহারকারী একাধিক গোষ্ঠীর অন্তর্গত হয় তবে অ্যাপ্লিকেশনটি বরাদ্দ করবে সর্বোচ্চ স্তরের অ্যাক্সেসের সাথে সঙ্গতিপূর্ণ ভূমিকা৷ যদি কোনও গোষ্ঠীর সাথে মেলে না, তবে অ্যাক্সেস অস্বীকার করা হবে।",
|
||||||
@@ -484,6 +520,7 @@
|
|||||||
"LabelPersonalYearReview": "আপনার বছরের পর্যালোচনা ({0})",
|
"LabelPersonalYearReview": "আপনার বছরের পর্যালোচনা ({0})",
|
||||||
"LabelPhotoPathURL": "ছবি পথ/ইউআরএল",
|
"LabelPhotoPathURL": "ছবি পথ/ইউআরএল",
|
||||||
"LabelPlayMethod": "প্লে পদ্ধতি",
|
"LabelPlayMethod": "প্লে পদ্ধতি",
|
||||||
|
"LabelPlaybackRateIncrementDecrement": "প্লেব্যাকের গতি বাড়ানো/কমানোর পরিমাণ",
|
||||||
"LabelPlayerChapterNumberMarker": "{1} এর মধ্যে {0}",
|
"LabelPlayerChapterNumberMarker": "{1} এর মধ্যে {0}",
|
||||||
"LabelPlaylists": "প্লেলিস্ট",
|
"LabelPlaylists": "প্লেলিস্ট",
|
||||||
"LabelPodcast": "পডকাস্ট",
|
"LabelPodcast": "পডকাস্ট",
|
||||||
@@ -506,7 +543,7 @@
|
|||||||
"LabelPublishers": "প্রকাশকরা",
|
"LabelPublishers": "প্রকাশকরা",
|
||||||
"LabelRSSFeedCustomOwnerEmail": "কাস্টম মালিকের ইমেইল",
|
"LabelRSSFeedCustomOwnerEmail": "কাস্টম মালিকের ইমেইল",
|
||||||
"LabelRSSFeedCustomOwnerName": "কাস্টম মালিকের নাম",
|
"LabelRSSFeedCustomOwnerName": "কাস্টম মালিকের নাম",
|
||||||
"LabelRSSFeedOpen": "আরএসএস ফিড খুলুন",
|
"LabelRSSFeedOpen": "RSS ফিড খোলা আছে",
|
||||||
"LabelRSSFeedPreventIndexing": "সূচীকরণ প্রতিরোধ করুন",
|
"LabelRSSFeedPreventIndexing": "সূচীকরণ প্রতিরোধ করুন",
|
||||||
"LabelRSSFeedSlug": "আরএসএস ফিড স্লাগ",
|
"LabelRSSFeedSlug": "আরএসএস ফিড স্লাগ",
|
||||||
"LabelRSSFeedURL": "আরএসএস ফিড ইউআরএল",
|
"LabelRSSFeedURL": "আরএসএস ফিড ইউআরএল",
|
||||||
@@ -523,6 +560,7 @@
|
|||||||
"LabelReleaseDate": "উন্মোচনের তারিখ",
|
"LabelReleaseDate": "উন্মোচনের তারিখ",
|
||||||
"LabelRemoveAllMetadataAbs": "সমস্ত metadata.abs ফাইল সরান",
|
"LabelRemoveAllMetadataAbs": "সমস্ত metadata.abs ফাইল সরান",
|
||||||
"LabelRemoveAllMetadataJson": "সমস্ত metadata.json ফাইল সরান",
|
"LabelRemoveAllMetadataJson": "সমস্ত metadata.json ফাইল সরান",
|
||||||
|
"LabelRemoveAudibleBranding": "অধ্যায়গুলো থেকে Audible-এর ইন্ট্রো ও আউট্রো সরান",
|
||||||
"LabelRemoveCover": "কভার সরান",
|
"LabelRemoveCover": "কভার সরান",
|
||||||
"LabelRemoveMetadataFile": "লাইব্রেরি আইটেম ফোল্ডারে মেটাডেটা ফাইল সরান",
|
"LabelRemoveMetadataFile": "লাইব্রেরি আইটেম ফোল্ডারে মেটাডেটা ফাইল সরান",
|
||||||
"LabelRemoveMetadataFileHelp": "আপনার {0} ফোল্ডারের সমস্ত metadata.json এবং metadata.abs ফাইলগুলি সরান।",
|
"LabelRemoveMetadataFileHelp": "আপনার {0} ফোল্ডারের সমস্ত metadata.json এবং metadata.abs ফাইলগুলি সরান।",
|
||||||
@@ -535,6 +573,7 @@
|
|||||||
"LabelSelectAll": "সব নির্বাচন করুন",
|
"LabelSelectAll": "সব নির্বাচন করুন",
|
||||||
"LabelSelectAllEpisodes": "সমস্ত পর্ব নির্বাচন করুন",
|
"LabelSelectAllEpisodes": "সমস্ত পর্ব নির্বাচন করুন",
|
||||||
"LabelSelectEpisodesShowing": "দেখানো {0}টি পর্ব নির্বাচন করুন",
|
"LabelSelectEpisodesShowing": "দেখানো {0}টি পর্ব নির্বাচন করুন",
|
||||||
|
"LabelSelectUser": "ব্যবহারকারী নির্বাচন করুন",
|
||||||
"LabelSelectUsers": "ব্যবহারকারী নির্বাচন করুন",
|
"LabelSelectUsers": "ব্যবহারকারী নির্বাচন করুন",
|
||||||
"LabelSendEbookToDevice": "ই-বই পাঠান...",
|
"LabelSendEbookToDevice": "ই-বই পাঠান...",
|
||||||
"LabelSequence": "ক্রম",
|
"LabelSequence": "ক্রম",
|
||||||
@@ -552,6 +591,8 @@
|
|||||||
"LabelSettingsBookshelfViewHelp": "কাঠের তাক সহ স্কুমরফিক ডিজাইন",
|
"LabelSettingsBookshelfViewHelp": "কাঠের তাক সহ স্কুমরফিক ডিজাইন",
|
||||||
"LabelSettingsChromecastSupport": "ক্রোমকাস্ট সমর্থন",
|
"LabelSettingsChromecastSupport": "ক্রোমকাস্ট সমর্থন",
|
||||||
"LabelSettingsDateFormat": "তারিখ বিন্যাস",
|
"LabelSettingsDateFormat": "তারিখ বিন্যাস",
|
||||||
|
"LabelSettingsEnableWatcher": "পরিবর্তনের জন্য লাইব্রেরিগুলো স্বয়ংক্রিয়ভাবে পর্যবেক্ষণ করুন",
|
||||||
|
"LabelSettingsEnableWatcherForLibrary": "লাইব্রেরির জন্য ফোল্ডার প্রহরী সক্ষম করুন",
|
||||||
"LabelSettingsEnableWatcherHelp": "ফাইলের পরিবর্তন শনাক্ত হলে আইটেমগুলির স্বয়ংক্রিয় যোগ/আপডেট সক্ষম করবে। *সার্ভার পুনরায় চালু করতে হবে",
|
"LabelSettingsEnableWatcherHelp": "ফাইলের পরিবর্তন শনাক্ত হলে আইটেমগুলির স্বয়ংক্রিয় যোগ/আপডেট সক্ষম করবে। *সার্ভার পুনরায় চালু করতে হবে",
|
||||||
"LabelSettingsEpubsAllowScriptedContent": "ইপাবে স্ক্রিপ্ট করা বিষয়বস্তুর অনুমতি দিন",
|
"LabelSettingsEpubsAllowScriptedContent": "ইপাবে স্ক্রিপ্ট করা বিষয়বস্তুর অনুমতি দিন",
|
||||||
"LabelSettingsEpubsAllowScriptedContentHelp": "ইপাব ফাইলগুলিকে স্ক্রিপ্ট চালানোর অনুমতি দিন। আপনি ইপাব ফাইলগুলির উৎসকে বিশ্বাস না করলে এই সেটিংটি নিষ্ক্রিয় রাখার সুপারিশ করা হলো।",
|
"LabelSettingsEpubsAllowScriptedContentHelp": "ইপাব ফাইলগুলিকে স্ক্রিপ্ট চালানোর অনুমতি দিন। আপনি ইপাব ফাইলগুলির উৎসকে বিশ্বাস না করলে এই সেটিংটি নিষ্ক্রিয় রাখার সুপারিশ করা হলো।",
|
||||||
@@ -569,7 +610,7 @@
|
|||||||
"LabelSettingsOnlyShowLaterBooksInContinueSeries": "কন্টিনিউ সিরিজে আগের বইগুলো এড়িয়ে যান",
|
"LabelSettingsOnlyShowLaterBooksInContinueSeries": "কন্টিনিউ সিরিজে আগের বইগুলো এড়িয়ে যান",
|
||||||
"LabelSettingsOnlyShowLaterBooksInContinueSeriesHelp": "কন্টিনিউ সিরিজের নীড় পেজ শেল্ফ দেখায় যে সিরিজে শুরু হয়নি এমন প্রথম বই যার অন্তত একটি বই শেষ হয়েছে এবং কোনো বই চলছে না। এই সেটিংটি সক্ষম করলে শুরু না হওয়া প্রথম বইটির পরিবর্তে সবচেয়ে দূরের সম্পূর্ণ বই থেকে সিরিজ চলতে থাকবে।",
|
"LabelSettingsOnlyShowLaterBooksInContinueSeriesHelp": "কন্টিনিউ সিরিজের নীড় পেজ শেল্ফ দেখায় যে সিরিজে শুরু হয়নি এমন প্রথম বই যার অন্তত একটি বই শেষ হয়েছে এবং কোনো বই চলছে না। এই সেটিংটি সক্ষম করলে শুরু না হওয়া প্রথম বইটির পরিবর্তে সবচেয়ে দূরের সম্পূর্ণ বই থেকে সিরিজ চলতে থাকবে।",
|
||||||
"LabelSettingsParseSubtitles": "সাবটাইটেল পার্স করুন",
|
"LabelSettingsParseSubtitles": "সাবটাইটেল পার্স করুন",
|
||||||
"LabelSettingsParseSubtitlesHelp": "অডিওবুক ফোল্ডারের নাম থেকে সাবটাইটেল বের করুন৷<br>সাবটাইটেল অবশ্যই \" - \"<br>অর্থাৎ \"বুকের শিরোনাম - এখানে একটি সাবটাইটেল\" এর সাবটাইটেল আছে \"এখানে একটি সাবটাইটেল\"",
|
"LabelSettingsParseSubtitlesHelp": "অডিওবুক ফোল্ডারের নাম থেকে সাবটাইটেল শনাক্ত করুন।<br>সাবটাইটেল অবশ্যই \" - \" দিয়ে আলাদা করা থাকতে হবে।<br>যেমন, \"বইয়ের নাম - একটি সাবটাইটেল\" হলে সাবটাইটেল হবে \"একটি সাবটাইটেল\"",
|
||||||
"LabelSettingsPreferMatchedMetadata": "মিলিত মেটাডেটা পছন্দ করুন",
|
"LabelSettingsPreferMatchedMetadata": "মিলিত মেটাডেটা পছন্দ করুন",
|
||||||
"LabelSettingsPreferMatchedMetadataHelp": "দ্রুত ম্যাচ ব্যবহার করার সময় মিলে যাওয়া ডেটা আইটেমের বিবরণকে ওভাররাইড করবে। ডিফল্টরূপে দ্রুত ম্যাচ শুধুমাত্র অনুপস্থিত বিশদগুলি পূরণ করবে।",
|
"LabelSettingsPreferMatchedMetadataHelp": "দ্রুত ম্যাচ ব্যবহার করার সময় মিলে যাওয়া ডেটা আইটেমের বিবরণকে ওভাররাইড করবে। ডিফল্টরূপে দ্রুত ম্যাচ শুধুমাত্র অনুপস্থিত বিশদগুলি পূরণ করবে।",
|
||||||
"LabelSettingsSkipMatchingBooksWithASIN": "এমন বইগুলি এড়িয়ে যান যেগুলির মধ্যে ইতিমধ্যে একটি ASIN আছে",
|
"LabelSettingsSkipMatchingBooksWithASIN": "এমন বইগুলি এড়িয়ে যান যেগুলির মধ্যে ইতিমধ্যে একটি ASIN আছে",
|
||||||
@@ -595,10 +636,12 @@
|
|||||||
"LabelSlug": "স্লাগ",
|
"LabelSlug": "স্লাগ",
|
||||||
"LabelSortAscending": "আরোহী",
|
"LabelSortAscending": "আরোহী",
|
||||||
"LabelSortDescending": "অবরোহী",
|
"LabelSortDescending": "অবরোহী",
|
||||||
|
"LabelSortPubDate": "প্রকাশের তারিখ অনুযায়ী সাজান",
|
||||||
"LabelStart": "শুরু",
|
"LabelStart": "শুরু",
|
||||||
"LabelStartTime": "শুরুর সময়",
|
"LabelStartTime": "শুরুর সময়",
|
||||||
"LabelStarted": "শুরু হয়েছে",
|
"LabelStarted": "শুরু হয়েছে",
|
||||||
"LabelStartedAt": "এতে শুরু হয়েছে",
|
"LabelStartedAt": "এতে শুরু হয়েছে",
|
||||||
|
"LabelStartedDate": "{0} শুরু হয়েছে",
|
||||||
"LabelStatsAudioTracks": "অডিও ট্র্যাক",
|
"LabelStatsAudioTracks": "অডিও ট্র্যাক",
|
||||||
"LabelStatsAuthors": "লেখক",
|
"LabelStatsAuthors": "লেখক",
|
||||||
"LabelStatsBestDay": "সেরা দিন",
|
"LabelStatsBestDay": "সেরা দিন",
|
||||||
@@ -628,6 +671,7 @@
|
|||||||
"LabelTheme": "থিম",
|
"LabelTheme": "থিম",
|
||||||
"LabelThemeDark": "অন্ধকার",
|
"LabelThemeDark": "অন্ধকার",
|
||||||
"LabelThemeLight": "আলো",
|
"LabelThemeLight": "আলো",
|
||||||
|
"LabelThemeSepia": "সেপিয়া",
|
||||||
"LabelTimeBase": "সময় বেস",
|
"LabelTimeBase": "সময় বেস",
|
||||||
"LabelTimeDurationXHours": "{0} ঘণ্টা",
|
"LabelTimeDurationXHours": "{0} ঘণ্টা",
|
||||||
"LabelTimeDurationXMinutes": "{0} মিনিট",
|
"LabelTimeDurationXMinutes": "{0} মিনিট",
|
||||||
@@ -695,23 +739,33 @@
|
|||||||
"LabelYourProgress": "আপনার অগ্রগতি",
|
"LabelYourProgress": "আপনার অগ্রগতি",
|
||||||
"MessageAddToPlayerQueue": "প্লেয়ার সারিতে যোগ করুন",
|
"MessageAddToPlayerQueue": "প্লেয়ার সারিতে যোগ করুন",
|
||||||
"MessageAppriseDescription": "এই বৈশিষ্ট্যটি ব্যবহার করার জন্য আপনাকে <a href=\"https://github.com/caronc/apprise-api\" target=\"_blank\">Apprise API</a> চালানোর একটি উদাহরণ বা একটি এপিআই পরিচালনা করতে হবে যে একই অনুরোধ পরিচালনা করবে। <br />অ্যাপ্রাইজ এপিআই ইউআরএলটি বিজ্ঞপ্তি পাঠানোর জন্য সম্পূর্ণ ইউআরএল পথ হওয়া উচিত, যেমন, যদি আপনার API ইনস্ট্যান্স <code>http://192.168.1.1:8337</code> এ পরিবেশিত হয় তাহলে আপনি <code> রাখবেন >http://192.168.1.1:8337/notify</code>।",
|
"MessageAppriseDescription": "এই বৈশিষ্ট্যটি ব্যবহার করার জন্য আপনাকে <a href=\"https://github.com/caronc/apprise-api\" target=\"_blank\">Apprise API</a> চালানোর একটি উদাহরণ বা একটি এপিআই পরিচালনা করতে হবে যে একই অনুরোধ পরিচালনা করবে। <br />অ্যাপ্রাইজ এপিআই ইউআরএলটি বিজ্ঞপ্তি পাঠানোর জন্য সম্পূর্ণ ইউআরএল পথ হওয়া উচিত, যেমন, যদি আপনার API ইনস্ট্যান্স <code>http://192.168.1.1:8337</code> এ পরিবেশিত হয় তাহলে আপনি <code> রাখবেন >http://192.168.1.1:8337/notify</code>।",
|
||||||
|
"MessageAsinCheck": "নিশ্চিত করুন যে আপনি Amazon-এর নয়, সঠিক Audible অঞ্চলের ASIN ব্যবহার করছেন।",
|
||||||
|
"MessageAuthenticationLegacyTokenWarning": "পুরোনো API টোকেনগুলো ভবিষ্যতে সরিয়ে দেওয়া হবে। এর পরিবর্তে <a href=\"/config/api-keys\">API কী</a> ব্যবহার করুন।",
|
||||||
|
"MessageAuthenticationOIDCChangesRestart": "OIDC-এর পরিবর্তনগুলো কার্যকর করতে সেভ করার পর সার্ভারটি পুনরায় চালু করুন।",
|
||||||
|
"MessageAuthenticationSecurityMessage": "নিরাপত্তার জন্য অথেনটিকেশন ব্যবস্থা উন্নত করা হয়েছে। সকল ব্যবহারকারীকে আবার লগইন করতে হবে।",
|
||||||
"MessageBackupsDescription": "ব্যাকআপের মধ্যে রয়েছে ব্যবহারকারী, ব্যবহারকারীর অগ্রগতি, লাইব্রেরি আইটেমের বিবরণ, সার্ভার সেটিংস এবং <code>/metadata/items</code> & <code>/metadata/authors</code>-এ সংরক্ষিত ছবি। ব্যাকআপগুলি <strong> আপনার লাইব্রেরি ফোল্ডারে সঞ্চিত কোনো ফাইল >অন্তর্ভুক্ত করবেন না</strong>।",
|
"MessageBackupsDescription": "ব্যাকআপের মধ্যে রয়েছে ব্যবহারকারী, ব্যবহারকারীর অগ্রগতি, লাইব্রেরি আইটেমের বিবরণ, সার্ভার সেটিংস এবং <code>/metadata/items</code> & <code>/metadata/authors</code>-এ সংরক্ষিত ছবি। ব্যাকআপগুলি <strong> আপনার লাইব্রেরি ফোল্ডারে সঞ্চিত কোনো ফাইল >অন্তর্ভুক্ত করবেন না</strong>।",
|
||||||
"MessageBackupsLocationEditNote": "দ্রষ্টব্য: ব্যাকআপ অবস্থান আপডেট করলে বিদ্যমান ব্যাকআপগুলি সরানো বা সংশোধন করা হবে না",
|
"MessageBackupsLocationEditNote": "দ্রষ্টব্য: ব্যাকআপ অবস্থান আপডেট করলে বিদ্যমান ব্যাকআপগুলি সরানো বা সংশোধন করা হবে না",
|
||||||
"MessageBackupsLocationNoEditNote": "দ্রষ্টব্য: ব্যাকআপ অবস্থান একটি পরিবেশ পরিবর্তনশীল মাধ্যমে স্থির করা হয়েছে এবং এখানে পরিবর্তন করা যাবে না।",
|
"MessageBackupsLocationNoEditNote": "দ্রষ্টব্য: ব্যাকআপ অবস্থান একটি পরিবেশ পরিবর্তনশীল মাধ্যমে স্থির করা হয়েছে এবং এখানে পরিবর্তন করা যাবে না।",
|
||||||
"MessageBackupsLocationPathEmpty": "ব্যাকআপ অবস্থানের পথ খালি থাকতে পারবে না",
|
"MessageBackupsLocationPathEmpty": "ব্যাকআপ অবস্থানের পথ খালি থাকতে পারবে না",
|
||||||
|
"MessageBatchEditPopulateMapDetailsAllHelp": "সক্রিয় ফিল্ডগুলো সব আইটেমের তথ্য দিয়ে পূরণ করুন। একাধিক মান থাকা ফিল্ডগুলোর মান একত্রিত করা হবে",
|
||||||
|
"MessageBatchEditPopulateMapDetailsItemHelp": "সক্রিয় ম্যাপের বিস্তারিত ফিল্ডগুলো এই আইটেমের তথ্য দিয়ে পূরণ করুন",
|
||||||
"MessageBatchQuickMatchDescription": "কুইক ম্যাচ নির্বাচিত আইটেমগুলির জন্য অনুপস্থিত কভার এবং মেটাডেটা যোগ করার চেষ্টা করবে। বিদ্যমান কভার এবং/অথবা মেটাডেটা ওভাররাইট করার জন্য দ্রুত ম্যাচকে অনুমতি দিতে নীচের বিকল্পগুলি সক্ষম করুন।",
|
"MessageBatchQuickMatchDescription": "কুইক ম্যাচ নির্বাচিত আইটেমগুলির জন্য অনুপস্থিত কভার এবং মেটাডেটা যোগ করার চেষ্টা করবে। বিদ্যমান কভার এবং/অথবা মেটাডেটা ওভাররাইট করার জন্য দ্রুত ম্যাচকে অনুমতি দিতে নীচের বিকল্পগুলি সক্ষম করুন।",
|
||||||
"MessageBookshelfNoCollections": "আপনি এখনও কোনো সংগ্রহ করেননি",
|
"MessageBookshelfNoCollections": "আপনি এখনও কোনো সংগ্রহ করেননি",
|
||||||
|
"MessageBookshelfNoCollectionsHelp": "কালেকশনগুলো সবার জন্য উন্মুক্ত। লাইব্রেরিতে অ্যাক্সেস থাকা সকল ব্যবহারকারী এগুলো দেখতে পারবেন।",
|
||||||
"MessageBookshelfNoRSSFeeds": "কোনও RSS ফিড খোলা নেই",
|
"MessageBookshelfNoRSSFeeds": "কোনও RSS ফিড খোলা নেই",
|
||||||
"MessageBookshelfNoResultsForFilter": "ফিল্টার \"{0}: {1}\" এর জন্য কোন ফলাফল নেই",
|
"MessageBookshelfNoResultsForFilter": "ফিল্টার \"{0}: {1}\" এর জন্য কোন ফলাফল নেই",
|
||||||
"MessageBookshelfNoResultsForQuery": "প্রশ্নের জন্য কোন ফলাফল নেই",
|
"MessageBookshelfNoResultsForQuery": "প্রশ্নের জন্য কোন ফলাফল নেই",
|
||||||
"MessageBookshelfNoSeries": "আপনার কোনো সিরিজ নেই",
|
"MessageBookshelfNoSeries": "আপনার কোনো সিরিজ নেই",
|
||||||
|
"MessageBulkChapterPattern": "এই নম্বর দেওয়ার ধরন অনুযায়ী আপনি কতটি অধ্যায় যোগ করতে চান?",
|
||||||
"MessageChapterEndIsAfter": "অধ্যায়ের সমাপ্তি আপনার অডিওবুকের শেষে",
|
"MessageChapterEndIsAfter": "অধ্যায়ের সমাপ্তি আপনার অডিওবুকের শেষে",
|
||||||
"MessageChapterErrorFirstNotZero": "প্রথম অধ্যায় 0 এ শুরু হতে হবে",
|
"MessageChapterErrorFirstNotZero": "প্রথম অধ্যায় 0 এ শুরু হতে হবে",
|
||||||
"MessageChapterErrorStartGteDuration": "অবৈধ শুরুর সময় অবশ্যই অডিওবুকের সময়কালের কম হতে হবে",
|
"MessageChapterErrorStartGteDuration": "অবৈধ শুরুর সময় অবশ্যই অডিওবুকের সময়কালের কম হতে হবে",
|
||||||
"MessageChapterErrorStartLtPrev": "অবৈধ শুরুর সময় অবশ্যই আগের অধ্যায় শুরুর সময়ের চেয়ে বেশি বা সমান হতে হবে",
|
"MessageChapterErrorStartLtPrev": "অবৈধ শুরুর সময় অবশ্যই আগের অধ্যায় শুরুর সময়ের চেয়ে বেশি বা সমান হতে হবে",
|
||||||
"MessageChapterStartIsAfter": "আপনার অডিওবুক শেষ হওয়ার পরে অধ্যায় শুরু হয়",
|
"MessageChapterStartIsAfter": "আপনার অডিওবুক শেষ হওয়ার পরে অধ্যায় শুরু হয়",
|
||||||
|
"MessageChaptersNotFound": "কোনো অধ্যায় পাওয়া যায়নি",
|
||||||
"MessageCheckingCron": "ক্রন পরীক্ষা করা হচ্ছে...",
|
"MessageCheckingCron": "ক্রন পরীক্ষা করা হচ্ছে...",
|
||||||
"MessageConfirmCloseFeed": "আপনি কি নিশ্চিত যে আপনি এই ফিডটি বন্ধ করতে চান?",
|
"MessageConfirmCloseFeed": "আপনি কি নিশ্চিত যে আপনি এই ফিডটি বন্ধ করতে চান?",
|
||||||
|
"MessageConfirmDeleteApiKey": "আপনি কি নিশ্চিত যে API কী \"{0}\" মুছে ফেলতে চান?",
|
||||||
"MessageConfirmDeleteBackup": "আপনি কি নিশ্চিত যে আপনি {0} এর ব্যাকআপ মুছে ফেলতে চান?",
|
"MessageConfirmDeleteBackup": "আপনি কি নিশ্চিত যে আপনি {0} এর ব্যাকআপ মুছে ফেলতে চান?",
|
||||||
"MessageConfirmDeleteDevice": "আপনি কি নিশ্চিতভাবে ই-রিডার ডিভাইস \"{0}\" মুছতে চান?",
|
"MessageConfirmDeleteDevice": "আপনি কি নিশ্চিতভাবে ই-রিডার ডিভাইস \"{0}\" মুছতে চান?",
|
||||||
"MessageConfirmDeleteFile": "এটি আপনার ফাইল সিস্টেম থেকে ফাইলটি মুছে দেবে। আপনি কি নিশ্চিত?",
|
"MessageConfirmDeleteFile": "এটি আপনার ফাইল সিস্টেম থেকে ফাইলটি মুছে দেবে। আপনি কি নিশ্চিত?",
|
||||||
@@ -723,6 +777,7 @@
|
|||||||
"MessageConfirmDeleteSession": "আপনি কি নিশ্চিত আপনি এই অধিবেশন মুছে দিতে চান?",
|
"MessageConfirmDeleteSession": "আপনি কি নিশ্চিত আপনি এই অধিবেশন মুছে দিতে চান?",
|
||||||
"MessageConfirmEmbedMetadataInAudioFiles": "আপনি কি {0}টি অডিও ফাইলে মেটাডেটা এম্বেড করার বিষয়ে নিশ্চিত?",
|
"MessageConfirmEmbedMetadataInAudioFiles": "আপনি কি {0}টি অডিও ফাইলে মেটাডেটা এম্বেড করার বিষয়ে নিশ্চিত?",
|
||||||
"MessageConfirmForceReScan": "আপনি কি নিশ্চিত যে আপনি জোর করে পুনরায় স্ক্যান করতে চান?",
|
"MessageConfirmForceReScan": "আপনি কি নিশ্চিত যে আপনি জোর করে পুনরায় স্ক্যান করতে চান?",
|
||||||
|
"MessageConfirmLogoutDevice": "আপনি কি নিশ্চিত যে \"{0}\" থেকে লগআউট করতে চান?",
|
||||||
"MessageConfirmMarkAllEpisodesFinished": "আপনি কি নিশ্চিত যে আপনি সমস্ত পর্ব সমাপ্ত হিসাবে চিহ্নিত করতে চান?",
|
"MessageConfirmMarkAllEpisodesFinished": "আপনি কি নিশ্চিত যে আপনি সমস্ত পর্ব সমাপ্ত হিসাবে চিহ্নিত করতে চান?",
|
||||||
"MessageConfirmMarkAllEpisodesNotFinished": "আপনি কি নিশ্চিত যে আপনি সমস্ত পর্বকে শেষ হয়নি বলে চিহ্নিত করতে চান?",
|
"MessageConfirmMarkAllEpisodesNotFinished": "আপনি কি নিশ্চিত যে আপনি সমস্ত পর্বকে শেষ হয়নি বলে চিহ্নিত করতে চান?",
|
||||||
"MessageConfirmMarkItemFinished": "আপনি কি \"{0}\" কে সমাপ্ত হিসাবে চিহ্নিত করার বিষয়ে নিশ্চিত?",
|
"MessageConfirmMarkItemFinished": "আপনি কি \"{0}\" কে সমাপ্ত হিসাবে চিহ্নিত করার বিষয়ে নিশ্চিত?",
|
||||||
@@ -739,6 +794,7 @@
|
|||||||
"MessageConfirmRemoveAuthor": "আপনি কি নিশ্চিত যে আপনি লেখক \"{0}\" অপসারণ করতে চান?",
|
"MessageConfirmRemoveAuthor": "আপনি কি নিশ্চিত যে আপনি লেখক \"{0}\" অপসারণ করতে চান?",
|
||||||
"MessageConfirmRemoveCollection": "আপনি কি নিশ্চিত যে আপনি সংগ্রহ \"{0}\" সরাতে চান?",
|
"MessageConfirmRemoveCollection": "আপনি কি নিশ্চিত যে আপনি সংগ্রহ \"{0}\" সরাতে চান?",
|
||||||
"MessageConfirmRemoveEpisode": "আপনি কি নিশ্চিত আপনি \"{0}\" পর্বটি সরাতে চান?",
|
"MessageConfirmRemoveEpisode": "আপনি কি নিশ্চিত আপনি \"{0}\" পর্বটি সরাতে চান?",
|
||||||
|
"MessageConfirmRemoveEpisodeNote": "দ্রষ্টব্য: \"Hard delete file\" চালু না করলে অডিও ফাইলটি মুছে ফেলা হবে না",
|
||||||
"MessageConfirmRemoveEpisodes": "আপনি কি নিশ্চিত যে আপনি {0}টি পর্ব সরাতে চান?",
|
"MessageConfirmRemoveEpisodes": "আপনি কি নিশ্চিত যে আপনি {0}টি পর্ব সরাতে চান?",
|
||||||
"MessageConfirmRemoveListeningSessions": "আপনি কি নিশ্চিত যে আপনি {0}টি শোনার সেশন সরাতে চান?",
|
"MessageConfirmRemoveListeningSessions": "আপনি কি নিশ্চিত যে আপনি {0}টি শোনার সেশন সরাতে চান?",
|
||||||
"MessageConfirmRemoveMetadataFiles": "আপনি কি আপনার লাইব্রেরি আইটেম ফোল্ডারে থাকা সমস্ত মেটাডেটা {0} ফাইল মুছে ফেলার বিষয়ে নিশ্চিত?",
|
"MessageConfirmRemoveMetadataFiles": "আপনি কি আপনার লাইব্রেরি আইটেম ফোল্ডারে থাকা সমস্ত মেটাডেটা {0} ফাইল মুছে ফেলার বিষয়ে নিশ্চিত?",
|
||||||
@@ -753,6 +809,7 @@
|
|||||||
"MessageConfirmResetProgress": "আপনি কি আপনার অগ্রগতি রিসেট করার বিষয়ে নিশ্চিত?",
|
"MessageConfirmResetProgress": "আপনি কি আপনার অগ্রগতি রিসেট করার বিষয়ে নিশ্চিত?",
|
||||||
"MessageConfirmSendEbookToDevice": "আপনি কি নিশ্চিত যে আপনি \"{2}\" ডিভাইসে {0} ইবুক \"{1}\" পাঠাতে চান?",
|
"MessageConfirmSendEbookToDevice": "আপনি কি নিশ্চিত যে আপনি \"{2}\" ডিভাইসে {0} ইবুক \"{1}\" পাঠাতে চান?",
|
||||||
"MessageConfirmUnlinkOpenId": "আপনি কি এই ব্যবহারকারীকে ওপেনআইডি থেকে লিঙ্কমুক্ত করার বিষয়ে নিশ্চিত?",
|
"MessageConfirmUnlinkOpenId": "আপনি কি এই ব্যবহারকারীকে ওপেনআইডি থেকে লিঙ্কমুক্ত করার বিষয়ে নিশ্চিত?",
|
||||||
|
"MessageDaysListenedInTheLastYear": "গত এক বছরে {0} দিন শোনা হয়েছে",
|
||||||
"MessageDownloadingEpisode": "ডাউনলোডিং পর্ব",
|
"MessageDownloadingEpisode": "ডাউনলোডিং পর্ব",
|
||||||
"MessageDragFilesIntoTrackOrder": "সঠিক ট্র্যাক অর্ডারে ফাইল টেনে আনুন",
|
"MessageDragFilesIntoTrackOrder": "সঠিক ট্র্যাক অর্ডারে ফাইল টেনে আনুন",
|
||||||
"MessageEmbedFailed": "এম্বেড ব্যর্থ হয়েছে!",
|
"MessageEmbedFailed": "এম্বেড ব্যর্থ হয়েছে!",
|
||||||
@@ -763,8 +820,11 @@
|
|||||||
"MessageFeedURLWillBe": "ফিড URL হবে {0}",
|
"MessageFeedURLWillBe": "ফিড URL হবে {0}",
|
||||||
"MessageFetching": "আনয় হচ্ছে.।",
|
"MessageFetching": "আনয় হচ্ছে.।",
|
||||||
"MessageForceReScanDescription": "সকল ফাইল আবার নতুন স্ক্যানের মত স্ক্যান করবে। অডিও ফাইল ID3 ট্যাগ, OPF ফাইল, এবং টেক্সট ফাইলগুলি নতুন হিসাবে স্ক্যান করা হবে।",
|
"MessageForceReScanDescription": "সকল ফাইল আবার নতুন স্ক্যানের মত স্ক্যান করবে। অডিও ফাইল ID3 ট্যাগ, OPF ফাইল, এবং টেক্সট ফাইলগুলি নতুন হিসাবে স্ক্যান করা হবে।",
|
||||||
|
"MessageHeatmapListeningTimeTooltip": "{1}-এ <strong>{0} জন শুনছেন</strong>",
|
||||||
|
"MessageHeatmapNoListeningSessions": "{0}-এ কোনো শোনার সেশন নেই",
|
||||||
"MessageImportantNotice": "গুরুত্বপূর্ণ বিজ্ঞপ্তি!",
|
"MessageImportantNotice": "গুরুত্বপূর্ণ বিজ্ঞপ্তি!",
|
||||||
"MessageInsertChapterBelow": "নীচে অধ্যায় ঢোকান",
|
"MessageInsertChapterBelow": "নীচে অধ্যায় ঢোকান",
|
||||||
|
"MessageInvalidAsin": "অবৈধ ASIN",
|
||||||
"MessageItemsSelected": "{0}টি আইটেম নির্বাচিত",
|
"MessageItemsSelected": "{0}টি আইটেম নির্বাচিত",
|
||||||
"MessageItemsUpdated": "{0}টি আইটেম আপডেট করা হয়েছে",
|
"MessageItemsUpdated": "{0}টি আইটেম আপডেট করা হয়েছে",
|
||||||
"MessageJoinUsOn": "আমাদের সাথে যোগ দিন",
|
"MessageJoinUsOn": "আমাদের সাথে যোগ দিন",
|
||||||
@@ -810,6 +870,7 @@
|
|||||||
"MessageNoTasksRunning": "কোন টাস্ক চলছে না",
|
"MessageNoTasksRunning": "কোন টাস্ক চলছে না",
|
||||||
"MessageNoUpdatesWereNecessary": "কোন আপডেটের প্রয়োজন ছিল না",
|
"MessageNoUpdatesWereNecessary": "কোন আপডেটের প্রয়োজন ছিল না",
|
||||||
"MessageNoUserPlaylists": "আপনার কোনো প্লেলিস্ট নেই",
|
"MessageNoUserPlaylists": "আপনার কোনো প্লেলিস্ট নেই",
|
||||||
|
"MessageNoUserPlaylistsHelp": "প্লেলিস্টগুলো ব্যক্তিগত। শুধুমাত্র যে ব্যবহারকারী এগুলো তৈরি করেছেন তিনিই সেগুলো দেখতে পারবেন।",
|
||||||
"MessageNotYetImplemented": "এখনও বাস্তবায়িত হয়নি",
|
"MessageNotYetImplemented": "এখনও বাস্তবায়িত হয়নি",
|
||||||
"MessageOpmlPreviewNote": "দ্রষ্টব্য: এটি পার্স করা OPML ফাইলের একটি পূর্বরূপ। প্রকৃত পডকাস্ট শিরোনাম RSS ফিড থেকে নেওয়া হবে।",
|
"MessageOpmlPreviewNote": "দ্রষ্টব্য: এটি পার্স করা OPML ফাইলের একটি পূর্বরূপ। প্রকৃত পডকাস্ট শিরোনাম RSS ফিড থেকে নেওয়া হবে।",
|
||||||
"MessageOr": "বা",
|
"MessageOr": "বা",
|
||||||
@@ -831,8 +892,11 @@
|
|||||||
"MessageResetChaptersConfirm": "আপনি কি নিশ্চিত যে আপনি অধ্যায়গুলি পুনরায় সেট করতে চান এবং আপনার করা পরিবর্তনগুলি পূর্বাবস্থায় ফেরাতে চান?",
|
"MessageResetChaptersConfirm": "আপনি কি নিশ্চিত যে আপনি অধ্যায়গুলি পুনরায় সেট করতে চান এবং আপনার করা পরিবর্তনগুলি পূর্বাবস্থায় ফেরাতে চান?",
|
||||||
"MessageRestoreBackupConfirm": "আপনি কি নিশ্চিত যে আপনি তৈরি করা ব্যাকআপ পুনরুদ্ধার করতে চান",
|
"MessageRestoreBackupConfirm": "আপনি কি নিশ্চিত যে আপনি তৈরি করা ব্যাকআপ পুনরুদ্ধার করতে চান",
|
||||||
"MessageRestoreBackupWarning": "একটি ব্যাকআপ পুনরুদ্ধার করা হলে তা /config-এ অবস্থিত সমগ্র ডাটাবেস ওভাররাইট করবে এবং /metadata/items & /metadata/authors-এ থাকা ছবিগুলিকে কভার করবে৷<br /><br />ব্যাকআপগুলি আপনার লাইব্রেরি ফোল্ডারে কোনো ফাইল পরিবর্তন করে না৷ আপনি যদি আপনার লাইব্রেরি ফোল্ডারে কভার আর্ট এবং মেটাডেটা সংরক্ষণ করতে সার্ভার সেটিংস সক্ষম করে থাকেন তবে সেগুলি ব্যাক আপ বা ওভাররাইট করা হয় না৷<br /><br />আপনার সার্ভার ব্যবহারকারী সমস্ত ক্লায়েন্ট স্বয়ংক্রিয়ভাবে রিফ্রেশ হবে৷",
|
"MessageRestoreBackupWarning": "একটি ব্যাকআপ পুনরুদ্ধার করা হলে তা /config-এ অবস্থিত সমগ্র ডাটাবেস ওভাররাইট করবে এবং /metadata/items & /metadata/authors-এ থাকা ছবিগুলিকে কভার করবে৷<br /><br />ব্যাকআপগুলি আপনার লাইব্রেরি ফোল্ডারে কোনো ফাইল পরিবর্তন করে না৷ আপনি যদি আপনার লাইব্রেরি ফোল্ডারে কভার আর্ট এবং মেটাডেটা সংরক্ষণ করতে সার্ভার সেটিংস সক্ষম করে থাকেন তবে সেগুলি ব্যাক আপ বা ওভাররাইট করা হয় না৷<br /><br />আপনার সার্ভার ব্যবহারকারী সমস্ত ক্লায়েন্ট স্বয়ংক্রিয়ভাবে রিফ্রেশ হবে৷",
|
||||||
|
"MessageScheduleLibraryScanNote": "বেশিরভাগ ব্যবহারকারীর জন্য এই ফিচারটি বন্ধ রেখে \"Automatically watch library for changes\" সেটিংটি চালু রাখার পরামর্শ দেওয়া হয়—এটি আপনার লাইব্রেরি ফোল্ডারের পরিবর্তনগুলো স্বয়ংক্রিয়ভাবে শনাক্ত করবে। আপনার ফাইল সিস্টেমে (যেমন NFS) \"Automatically watch library for changes\" কাজ না করলে এই ফিচারটি চালু করুন।",
|
||||||
|
"MessageScheduleRunEveryWeekdayAtTime": "প্রতি {0} অন্তর {1}-এ চালান",
|
||||||
"MessageSearchResultsFor": "এর জন্য অনুসন্ধান ফলাফল",
|
"MessageSearchResultsFor": "এর জন্য অনুসন্ধান ফলাফল",
|
||||||
"MessageSelected": "{0}টি নির্বাচিত",
|
"MessageSelected": "{0}টি নির্বাচিত",
|
||||||
|
"MessageSeriesSequenceCannotContainSpaces": "সিরিজের ক্রমে স্পেস থাকতে পারবে না",
|
||||||
"MessageServerCouldNotBeReached": "সার্ভারে পৌঁছানো যায়নি",
|
"MessageServerCouldNotBeReached": "সার্ভারে পৌঁছানো যায়নি",
|
||||||
"MessageSetChaptersFromTracksDescription": "প্রতিটি অডিও ফাইলকে অধ্যায় হিসেবে ব্যবহার করে অধ্যায় সেট করুন এবং অডিও ফাইলের নাম হিসেবে অধ্যায়ের শিরোনাম করুন",
|
"MessageSetChaptersFromTracksDescription": "প্রতিটি অডিও ফাইলকে অধ্যায় হিসেবে ব্যবহার করে অধ্যায় সেট করুন এবং অডিও ফাইলের নাম হিসেবে অধ্যায়ের শিরোনাম করুন",
|
||||||
"MessageShareExpirationWillBe": "মেয়াদ শেষ হবে <strong>{0}</strong>",
|
"MessageShareExpirationWillBe": "মেয়াদ শেষ হবে <strong>{0}</strong>",
|
||||||
@@ -894,7 +958,10 @@
|
|||||||
"NotificationOnBackupCompletedDescription": "ব্যাকআপ সম্পূর্ণ হলে ট্রিগার হবে",
|
"NotificationOnBackupCompletedDescription": "ব্যাকআপ সম্পূর্ণ হলে ট্রিগার হবে",
|
||||||
"NotificationOnBackupFailedDescription": "ব্যাকআপ ব্যর্থ হলে ট্রিগার হবে",
|
"NotificationOnBackupFailedDescription": "ব্যাকআপ ব্যর্থ হলে ট্রিগার হবে",
|
||||||
"NotificationOnEpisodeDownloadedDescription": "একটি পডকাস্ট পর্ব স্বয়ংক্রিয়ভাবে ডাউনলোড হলে ট্রিগার হবে",
|
"NotificationOnEpisodeDownloadedDescription": "একটি পডকাস্ট পর্ব স্বয়ংক্রিয়ভাবে ডাউনলোড হলে ট্রিগার হবে",
|
||||||
|
"NotificationOnRSSFeedDisabledDescription": "অনেকবার ডাউনলোডের চেষ্টা ব্যর্থ হওয়ার কারণে স্বয়ংক্রিয় পর্ব ডাউনলোড বন্ধ হয়ে গেলে এটি ট্রিগার হয়",
|
||||||
|
"NotificationOnRSSFeedFailedDescription": "স্বয়ংক্রিয় পর্ব ডাউনলোডের জন্য RSS ফিডের অনুরোধ ব্যর্থ হলে এটি ট্রিগার হয়",
|
||||||
"NotificationOnTestDescription": "বিজ্ঞপ্তি সিস্টেম পরীক্ষার জন্য ইভেন্ট",
|
"NotificationOnTestDescription": "বিজ্ঞপ্তি সিস্টেম পরীক্ষার জন্য ইভেন্ট",
|
||||||
|
"PlaceholderBulkChapterInput": "অধ্যায়ের শিরোনাম লিখুন অথবা নম্বর ব্যবহার করুন (যেমন, 'পর্ব 1', 'অধ্যায় 10', '1.')",
|
||||||
"PlaceholderNewCollection": "নতুন সংগ্রহের নাম",
|
"PlaceholderNewCollection": "নতুন সংগ্রহের নাম",
|
||||||
"PlaceholderNewFolderPath": "নতুন ফোল্ডার পথ",
|
"PlaceholderNewFolderPath": "নতুন ফোল্ডার পথ",
|
||||||
"PlaceholderNewPlaylist": "নতুন প্লেলিস্টের নাম",
|
"PlaceholderNewPlaylist": "নতুন প্লেলিস্টের নাম",
|
||||||
@@ -938,6 +1005,7 @@
|
|||||||
"ToastBackupRestoreFailed": "ব্যাকআপ পুনরুদ্ধার করতে ব্যর্থ",
|
"ToastBackupRestoreFailed": "ব্যাকআপ পুনরুদ্ধার করতে ব্যর্থ",
|
||||||
"ToastBackupUploadFailed": "ব্যাকআপ আপলোড করতে ব্যর্থ",
|
"ToastBackupUploadFailed": "ব্যাকআপ আপলোড করতে ব্যর্থ",
|
||||||
"ToastBackupUploadSuccess": "ব্যাকআপ আপলোড হয়েছে",
|
"ToastBackupUploadSuccess": "ব্যাকআপ আপলোড হয়েছে",
|
||||||
|
"ToastBatchApplyDetailsToItemsSuccess": "আইটেমগুলোতে বিস্তারিত তথ্য প্রয়োগ করা হয়েছে",
|
||||||
"ToastBatchDeleteFailed": "ব্যাচ মুছে ফেলতে ব্যর্থ হয়েছে",
|
"ToastBatchDeleteFailed": "ব্যাচ মুছে ফেলতে ব্যর্থ হয়েছে",
|
||||||
"ToastBatchDeleteSuccess": "ব্যাচ মুছে ফেলা সফল হয়েছে",
|
"ToastBatchDeleteSuccess": "ব্যাচ মুছে ফেলা সফল হয়েছে",
|
||||||
"ToastBatchQuickMatchFailed": "ব্যাচ কুইক ম্যাচ ব্যর্থ!",
|
"ToastBatchQuickMatchFailed": "ব্যাচ কুইক ম্যাচ ব্যর্থ!",
|
||||||
@@ -947,16 +1015,25 @@
|
|||||||
"ToastBookmarkCreateFailed": "বুকমার্ক তৈরি করতে ব্যর্থ",
|
"ToastBookmarkCreateFailed": "বুকমার্ক তৈরি করতে ব্যর্থ",
|
||||||
"ToastBookmarkCreateSuccess": "বুকমার্ক যোগ করা হয়েছে",
|
"ToastBookmarkCreateSuccess": "বুকমার্ক যোগ করা হয়েছে",
|
||||||
"ToastBookmarkRemoveSuccess": "বুকমার্ক সরানো হয়েছে",
|
"ToastBookmarkRemoveSuccess": "বুকমার্ক সরানো হয়েছে",
|
||||||
|
"ToastBulkChapterInvalidCount": "১ থেকে ১৫০-এর মধ্যে একটি সংখ্যা লিখুন",
|
||||||
"ToastCachePurgeFailed": "ক্যাশে পরিষ্কার করতে ব্যর্থ হয়েছে",
|
"ToastCachePurgeFailed": "ক্যাশে পরিষ্কার করতে ব্যর্থ হয়েছে",
|
||||||
"ToastCachePurgeSuccess": "ক্যাশে সফলভাবে পরিষ্কার করা হয়েছে",
|
"ToastCachePurgeSuccess": "ক্যাশে সফলভাবে পরিষ্কার করা হয়েছে",
|
||||||
|
"ToastChapterLocked": "অধ্যায়টি লক করা আছে।",
|
||||||
|
"ToastChapterStartTimeAdjusted": "অধ্যায়ের শুরুর সময় {0} সেকেন্ড সমন্বয় করা হয়েছে",
|
||||||
|
"ToastChaptersAllLocked": "সব অধ্যায় লক করা আছে। সময় পরিবর্তন করতে কিছু অধ্যায় আনলক করুন।",
|
||||||
"ToastChaptersHaveErrors": "অধ্যায়ে ত্রুটি আছে",
|
"ToastChaptersHaveErrors": "অধ্যায়ে ত্রুটি আছে",
|
||||||
|
"ToastChaptersInvalidShiftAmountLast": "সময় সরানোর পরিমাণ সঠিক নয়। এতে শেষ অধ্যায়ের শুরুর সময় এই অডিওবুকের মোট সময়সীমা ছাড়িয়ে যাবে।",
|
||||||
|
"ToastChaptersInvalidShiftAmountStart": "সময় সরানোর পরিমাণ সঠিক নয়। প্রথম অধ্যায়ের দৈর্ঘ্য শূন্য বা ঋণাত্মক হয়ে যাবে এবং দ্বিতীয় অধ্যায়টি এটিকে ওভাররাইট করবে। দ্বিতীয় অধ্যায়ের শুরুর সময় বাড়ান।",
|
||||||
"ToastChaptersMustHaveTitles": "অধ্যায়ের শিরোনাম থাকতে হবে",
|
"ToastChaptersMustHaveTitles": "অধ্যায়ের শিরোনাম থাকতে হবে",
|
||||||
"ToastChaptersRemoved": "অধ্যায়গুলো মুছে ফেলা হয়েছে",
|
"ToastChaptersRemoved": "অধ্যায়গুলো মুছে ফেলা হয়েছে",
|
||||||
"ToastChaptersUpdated": "অধ্যায় আপডেট করা হয়েছে",
|
"ToastChaptersUpdated": "অধ্যায় আপডেট করা হয়েছে",
|
||||||
"ToastCollectionItemsAddFailed": "আইটেম(গুলি) সংগ্রহে যোগ করা ব্যর্থ হয়েছে",
|
"ToastCollectionItemsAddFailed": "আইটেম(গুলি) সংগ্রহে যোগ করা ব্যর্থ হয়েছে",
|
||||||
"ToastCollectionRemoveSuccess": "সংগ্রহ সরানো হয়েছে",
|
"ToastCollectionRemoveSuccess": "সংগ্রহ সরানো হয়েছে",
|
||||||
"ToastCollectionUpdateSuccess": "সংগ্রহ আপডেট করা হয়েছে",
|
"ToastCollectionUpdateSuccess": "সংগ্রহ আপডেট করা হয়েছে",
|
||||||
|
"ToastConnectionNotAvailable": "সংযোগ পাওয়া যাচ্ছে না। অনুগ্রহ করে পরে আবার চেষ্টা করুন",
|
||||||
|
"ToastCoverSearchFailed": "কভার অনুসন্ধান ব্যর্থ হয়েছে",
|
||||||
"ToastCoverUpdateFailed": "কভার আপডেট ব্যর্থ হয়েছে",
|
"ToastCoverUpdateFailed": "কভার আপডেট ব্যর্থ হয়েছে",
|
||||||
|
"ToastDateTimeInvalidOrIncomplete": "তারিখ ও সময় সঠিক নয় অথবা অসম্পূর্ণ",
|
||||||
"ToastDeleteFileFailed": "ফাইল মুছে ফেলতে ব্যর্থ হয়েছে",
|
"ToastDeleteFileFailed": "ফাইল মুছে ফেলতে ব্যর্থ হয়েছে",
|
||||||
"ToastDeleteFileSuccess": "ফাইল মুছে ফেলা হয়েছে",
|
"ToastDeleteFileSuccess": "ফাইল মুছে ফেলা হয়েছে",
|
||||||
"ToastDeviceAddFailed": "ডিভাইস যোগ করতে ব্যর্থ হয়েছে",
|
"ToastDeviceAddFailed": "ডিভাইস যোগ করতে ব্যর্থ হয়েছে",
|
||||||
@@ -970,6 +1047,8 @@
|
|||||||
"ToastEpisodeDownloadQueueClearSuccess": "পর্ব ডাউনলোড সারি পরিষ্কার করা হয়েছে",
|
"ToastEpisodeDownloadQueueClearSuccess": "পর্ব ডাউনলোড সারি পরিষ্কার করা হয়েছে",
|
||||||
"ToastEpisodeUpdateSuccess": "{0}টি পর্ব আপডেট করা হয়েছে",
|
"ToastEpisodeUpdateSuccess": "{0}টি পর্ব আপডেট করা হয়েছে",
|
||||||
"ToastErrorCannotShare": "এই ডিভাইসে স্থানীয়ভাবে শেয়ার করা যাবে না",
|
"ToastErrorCannotShare": "এই ডিভাইসে স্থানীয়ভাবে শেয়ার করা যাবে না",
|
||||||
|
"ToastFailedToCreate": "তৈরি করা যায়নি",
|
||||||
|
"ToastFailedToDelete": "মুছে ফেলা যায়নি",
|
||||||
"ToastFailedToLoadData": "ডেটা লোড করা যায়নি",
|
"ToastFailedToLoadData": "ডেটা লোড করা যায়নি",
|
||||||
"ToastFailedToMatch": "মেলাতে ব্যর্থ হয়েছে",
|
"ToastFailedToMatch": "মেলাতে ব্যর্থ হয়েছে",
|
||||||
"ToastFailedToShare": "শেয়ার করতে ব্যর্থ",
|
"ToastFailedToShare": "শেয়ার করতে ব্যর্থ",
|
||||||
@@ -977,6 +1056,7 @@
|
|||||||
"ToastInvalidImageUrl": "অকার্যকর ছবির ইউআরএল",
|
"ToastInvalidImageUrl": "অকার্যকর ছবির ইউআরএল",
|
||||||
"ToastInvalidMaxEpisodesToDownload": "ডাউনলোড করার জন্য অবৈধ সর্বোচ্চ পর্ব",
|
"ToastInvalidMaxEpisodesToDownload": "ডাউনলোড করার জন্য অবৈধ সর্বোচ্চ পর্ব",
|
||||||
"ToastInvalidUrl": "অকার্যকর ইউআরএল",
|
"ToastInvalidUrl": "অকার্যকর ইউআরএল",
|
||||||
|
"ToastInvalidUrls": "এক বা একাধিক URL সঠিক নয়",
|
||||||
"ToastItemCoverUpdateSuccess": "আইটেম কভার আপডেট করা হয়েছে",
|
"ToastItemCoverUpdateSuccess": "আইটেম কভার আপডেট করা হয়েছে",
|
||||||
"ToastItemDeletedFailed": "আইটেম মুছে ফেলতে ব্যর্থ",
|
"ToastItemDeletedFailed": "আইটেম মুছে ফেলতে ব্যর্থ",
|
||||||
"ToastItemDeletedSuccess": "মুছে ফেলা আইটেম",
|
"ToastItemDeletedSuccess": "মুছে ফেলা আইটেম",
|
||||||
@@ -1001,6 +1081,7 @@
|
|||||||
"ToastMustHaveAtLeastOnePath": "অন্তত একটি পথ থাকতে হবে",
|
"ToastMustHaveAtLeastOnePath": "অন্তত একটি পথ থাকতে হবে",
|
||||||
"ToastNameEmailRequired": "নাম এবং ইমেইল আবশ্যক",
|
"ToastNameEmailRequired": "নাম এবং ইমেইল আবশ্যক",
|
||||||
"ToastNameRequired": "নাম আবশ্যক",
|
"ToastNameRequired": "নাম আবশ্যক",
|
||||||
|
"ToastNewApiKeyUserError": "একজন ব্যবহারকারী নির্বাচন করতে হবে",
|
||||||
"ToastNewEpisodesFound": "{0}টি নতুন পর্ব পাওয়া গেছে",
|
"ToastNewEpisodesFound": "{0}টি নতুন পর্ব পাওয়া গেছে",
|
||||||
"ToastNewUserCreatedFailed": "অ্যাকাউন্ট তৈরি করতে ব্যর্থ: \"{0}\"",
|
"ToastNewUserCreatedFailed": "অ্যাকাউন্ট তৈরি করতে ব্যর্থ: \"{0}\"",
|
||||||
"ToastNewUserCreatedSuccess": "নতুন একাউন্ট তৈরি হয়েছে",
|
"ToastNewUserCreatedSuccess": "নতুন একাউন্ট তৈরি হয়েছে",
|
||||||
@@ -1009,6 +1090,7 @@
|
|||||||
"ToastNewUserTagError": "অন্তত একটি ট্যাগ নির্বাচন করতে হবে",
|
"ToastNewUserTagError": "অন্তত একটি ট্যাগ নির্বাচন করতে হবে",
|
||||||
"ToastNewUserUsernameError": "একটি ব্যবহারকারীর নাম লিখুন",
|
"ToastNewUserUsernameError": "একটি ব্যবহারকারীর নাম লিখুন",
|
||||||
"ToastNoNewEpisodesFound": "কোন নতুন পর্ব পাওয়া যায়নি",
|
"ToastNoNewEpisodesFound": "কোন নতুন পর্ব পাওয়া যায়নি",
|
||||||
|
"ToastNoRSSFeed": "ডকাস্টটির কোনো RSS ফিড নেই",
|
||||||
"ToastNoUpdatesNecessary": "কোন আপডেটের প্রয়োজন নেই",
|
"ToastNoUpdatesNecessary": "কোন আপডেটের প্রয়োজন নেই",
|
||||||
"ToastNotificationCreateFailed": "বিজ্ঞপ্তি তৈরি করতে ব্যর্থ",
|
"ToastNotificationCreateFailed": "বিজ্ঞপ্তি তৈরি করতে ব্যর্থ",
|
||||||
"ToastNotificationDeleteFailed": "বিজ্ঞপ্তি মুছে ফেলতে ব্যর্থ",
|
"ToastNotificationDeleteFailed": "বিজ্ঞপ্তি মুছে ফেলতে ব্যর্থ",
|
||||||
@@ -1024,6 +1106,7 @@
|
|||||||
"ToastPlaylistUpdateSuccess": "প্লেলিস্ট আপডেট করা হয়েছে",
|
"ToastPlaylistUpdateSuccess": "প্লেলিস্ট আপডেট করা হয়েছে",
|
||||||
"ToastPodcastCreateFailed": "পডকাস্ট তৈরি করতে ব্যর্থ",
|
"ToastPodcastCreateFailed": "পডকাস্ট তৈরি করতে ব্যর্থ",
|
||||||
"ToastPodcastCreateSuccess": "পডকাস্ট সফলভাবে তৈরি করা হয়েছে",
|
"ToastPodcastCreateSuccess": "পডকাস্ট সফলভাবে তৈরি করা হয়েছে",
|
||||||
|
"ToastPodcastEpisodeUpdated": "পর্ব আপডেট করা হয়েছে",
|
||||||
"ToastPodcastGetFeedFailed": "পডকাস্ট ফিড পেতে ব্যর্থ হয়েছে",
|
"ToastPodcastGetFeedFailed": "পডকাস্ট ফিড পেতে ব্যর্থ হয়েছে",
|
||||||
"ToastPodcastNoEpisodesInFeed": "আরএসএস ফিডে কোনো পর্ব পাওয়া যায়নি",
|
"ToastPodcastNoEpisodesInFeed": "আরএসএস ফিডে কোনো পর্ব পাওয়া যায়নি",
|
||||||
"ToastPodcastNoRssFeed": "পডকাস্টের কোন আরএসএস ফিড নেই",
|
"ToastPodcastNoRssFeed": "পডকাস্টের কোন আরএসএস ফিড নেই",
|
||||||
@@ -1048,6 +1131,7 @@
|
|||||||
"ToastSelectAtLeastOneUser": "অন্তত একজন ব্যবহারকারী নির্বাচন করুন",
|
"ToastSelectAtLeastOneUser": "অন্তত একজন ব্যবহারকারী নির্বাচন করুন",
|
||||||
"ToastSendEbookToDeviceFailed": "ডিভাইসে ইবুক পাঠাতে ব্যর্থ",
|
"ToastSendEbookToDeviceFailed": "ডিভাইসে ইবুক পাঠাতে ব্যর্থ",
|
||||||
"ToastSendEbookToDeviceSuccess": "ইবুক \"{0}\" ডিভাইসে পাঠানো হয়েছে",
|
"ToastSendEbookToDeviceSuccess": "ইবুক \"{0}\" ডিভাইসে পাঠানো হয়েছে",
|
||||||
|
"ToastSeriesSubmitFailedSameName": "একই নামে দুটি সিরিজ যোগ করা যাবে না",
|
||||||
"ToastSeriesUpdateFailed": "সিরিজ আপডেট ব্যর্থ হয়েছে",
|
"ToastSeriesUpdateFailed": "সিরিজ আপডেট ব্যর্থ হয়েছে",
|
||||||
"ToastSeriesUpdateSuccess": "সিরিজ আপডেট সাফল্য",
|
"ToastSeriesUpdateSuccess": "সিরিজ আপডেট সাফল্য",
|
||||||
"ToastServerSettingsUpdateSuccess": "সার্ভার সেটিংস আপডেট করা হয়েছে",
|
"ToastServerSettingsUpdateSuccess": "সার্ভার সেটিংস আপডেট করা হয়েছে",
|
||||||
@@ -1066,10 +1150,20 @@
|
|||||||
"ToastUnknownError": "অজানা ত্রুটি",
|
"ToastUnknownError": "অজানা ত্রুটি",
|
||||||
"ToastUnlinkOpenIdFailed": "OpenID থেকে ব্যবহারকারীকে আনলিঙ্ক করতে ব্যর্থ হয়েছে",
|
"ToastUnlinkOpenIdFailed": "OpenID থেকে ব্যবহারকারীকে আনলিঙ্ক করতে ব্যর্থ হয়েছে",
|
||||||
"ToastUnlinkOpenIdSuccess": "OpenID থেকে ব্যবহারকারীকে লিঙ্কমুক্ত করা হয়েছে",
|
"ToastUnlinkOpenIdSuccess": "OpenID থেকে ব্যবহারকারীকে লিঙ্কমুক্ত করা হয়েছে",
|
||||||
|
"ToastUploaderFilepathExistsError": "ফাইল পাথ \"{0}\" ইতিমধ্যে সার্ভারে বিদ্যমান",
|
||||||
|
"ToastUploaderItemExistsInSubdirectoryError": "আইটেম \"{0}\" আপলোড পাথের একটি সাবডিরেক্টরি ব্যবহার করছে।",
|
||||||
"ToastUserDeleteFailed": "ব্যবহারকারী মুছতে ব্যর্থ",
|
"ToastUserDeleteFailed": "ব্যবহারকারী মুছতে ব্যর্থ",
|
||||||
"ToastUserDeleteSuccess": "ব্যবহারকারী মুছে ফেলা হয়েছে",
|
"ToastUserDeleteSuccess": "ব্যবহারকারী মুছে ফেলা হয়েছে",
|
||||||
"ToastUserPasswordChangeSuccess": "পাসওয়ার্ড সফলভাবে পরিবর্তন করা হয়েছে",
|
"ToastUserPasswordChangeSuccess": "পাসওয়ার্ড সফলভাবে পরিবর্তন করা হয়েছে",
|
||||||
"ToastUserPasswordMismatch": "পাসওয়ার্ড মিলছে না",
|
"ToastUserPasswordMismatch": "পাসওয়ার্ড মিলছে না",
|
||||||
"ToastUserPasswordMustChange": "নতুন পাসওয়ার্ড পুরানো পাসওয়ার্ডের সাথে মিলতে পারবে না",
|
"ToastUserPasswordMustChange": "নতুন পাসওয়ার্ড পুরানো পাসওয়ার্ডের সাথে মিলতে পারবে না",
|
||||||
"ToastUserRootRequireName": "একটি রুট ব্যবহারকারীর নাম লিখতে হবে"
|
"ToastUserRootRequireName": "একটি রুট ব্যবহারকারীর নাম লিখতে হবে",
|
||||||
|
"TooltipAddChapters": "অধ্যায় যোগ করুন",
|
||||||
|
"TooltipAddOneSecond": "১ সেকেন্ড যোগ করুন",
|
||||||
|
"TooltipAdjustChapterStart": "শুরুর সময় সমন্বয় করতে ক্লিক করুন",
|
||||||
|
"TooltipLockAllChapters": "সব অধ্যায় লক করুন",
|
||||||
|
"TooltipLockChapter": "অধ্যায় লক করুন (একাধিক অধ্যায়ের পরিসর নির্বাচন করতে Shift+ক্লিক করুন)",
|
||||||
|
"TooltipSubtractOneSecond": "১ সেকেন্ড কমান",
|
||||||
|
"TooltipUnlockAllChapters": "সব অধ্যায় আনলক করুন",
|
||||||
|
"TooltipUnlockChapter": "অধ্যায় আনলক করুন (একাধিক অধ্যায়ের পরিসর নির্বাচন করতে Shift+ক্লিক করুন)"
|
||||||
}
|
}
|
||||||
+10
-1
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"ButtonAdd": "Afegeix",
|
"ButtonAdd": "Afegeix",
|
||||||
|
"ButtonAddApiKey": "Afegeix clau API",
|
||||||
"ButtonAddChapters": "Afegeix capítols",
|
"ButtonAddChapters": "Afegeix capítols",
|
||||||
"ButtonAddDevice": "Afegeix un aparell",
|
"ButtonAddDevice": "Afegeix un aparell",
|
||||||
"ButtonAddLibrary": "Afegeix una biblioteca",
|
"ButtonAddLibrary": "Afegeix una biblioteca",
|
||||||
@@ -20,6 +21,7 @@
|
|||||||
"ButtonChooseAFolder": "Trieu una carpeta",
|
"ButtonChooseAFolder": "Trieu una carpeta",
|
||||||
"ButtonChooseFiles": "Trieu fitxers",
|
"ButtonChooseFiles": "Trieu fitxers",
|
||||||
"ButtonClearFilter": "Neteja el filtre",
|
"ButtonClearFilter": "Neteja el filtre",
|
||||||
|
"ButtonClose": "Tanca",
|
||||||
"ButtonCloseFeed": "Tanca el canal",
|
"ButtonCloseFeed": "Tanca el canal",
|
||||||
"ButtonCloseSession": "Tanca la sessió oberta",
|
"ButtonCloseSession": "Tanca la sessió oberta",
|
||||||
"ButtonCollections": "Col·leccions",
|
"ButtonCollections": "Col·leccions",
|
||||||
@@ -119,11 +121,13 @@
|
|||||||
"HeaderAccount": "Compte",
|
"HeaderAccount": "Compte",
|
||||||
"HeaderAddCustomMetadataProvider": "Afegeix un proveïdor de metadades personalitzat",
|
"HeaderAddCustomMetadataProvider": "Afegeix un proveïdor de metadades personalitzat",
|
||||||
"HeaderAdvanced": "Avançat",
|
"HeaderAdvanced": "Avançat",
|
||||||
|
"HeaderApiKeys": "Claus API",
|
||||||
"HeaderAppriseNotificationSettings": "Paràmetres de notificacions Apprise",
|
"HeaderAppriseNotificationSettings": "Paràmetres de notificacions Apprise",
|
||||||
"HeaderAudioTracks": "Pistes d'àudio",
|
"HeaderAudioTracks": "Pistes d'àudio",
|
||||||
"HeaderAudiobookTools": "Eines de gestió de fitxers de l'audiollibre",
|
"HeaderAudiobookTools": "Eines de gestió de fitxers de l'audiollibre",
|
||||||
"HeaderAuthentication": "Autenticació",
|
"HeaderAuthentication": "Autenticació",
|
||||||
"HeaderBackups": "Còpies de Seguretat",
|
"HeaderBackups": "Còpies de Seguretat",
|
||||||
|
"HeaderBulkChapterModal": "Afegeix capítols múltiples",
|
||||||
"HeaderChangePassword": "Canvia Contrasenya",
|
"HeaderChangePassword": "Canvia Contrasenya",
|
||||||
"HeaderChapters": "Capítols",
|
"HeaderChapters": "Capítols",
|
||||||
"HeaderChooseAFolder": "Tria una Carpeta",
|
"HeaderChooseAFolder": "Tria una Carpeta",
|
||||||
@@ -162,6 +166,7 @@
|
|||||||
"HeaderMetadataOrderOfPrecedence": "Ordre de Precedència de Metadades",
|
"HeaderMetadataOrderOfPrecedence": "Ordre de Precedència de Metadades",
|
||||||
"HeaderMetadataToEmbed": "Metadades a Inserir",
|
"HeaderMetadataToEmbed": "Metadades a Inserir",
|
||||||
"HeaderNewAccount": "Nou Compte",
|
"HeaderNewAccount": "Nou Compte",
|
||||||
|
"HeaderNewApiKey": "Nova clau API",
|
||||||
"HeaderNewLibrary": "Nova Biblioteca",
|
"HeaderNewLibrary": "Nova Biblioteca",
|
||||||
"HeaderNotificationCreate": "Crea Notificació",
|
"HeaderNotificationCreate": "Crea Notificació",
|
||||||
"HeaderNotificationUpdate": "Actualització de Notificació",
|
"HeaderNotificationUpdate": "Actualització de Notificació",
|
||||||
@@ -195,6 +200,7 @@
|
|||||||
"HeaderSettingsExperimental": "Funcionalitats experimentals",
|
"HeaderSettingsExperimental": "Funcionalitats experimentals",
|
||||||
"HeaderSettingsGeneral": "Generals",
|
"HeaderSettingsGeneral": "Generals",
|
||||||
"HeaderSettingsScanner": "Escàner",
|
"HeaderSettingsScanner": "Escàner",
|
||||||
|
"HeaderSettingsSecurity": "Seguretat",
|
||||||
"HeaderSettingsWebClient": "Client web",
|
"HeaderSettingsWebClient": "Client web",
|
||||||
"HeaderSleepTimer": "Temporitzador de son",
|
"HeaderSleepTimer": "Temporitzador de son",
|
||||||
"HeaderStatsLargestItems": "Elements més grans",
|
"HeaderStatsLargestItems": "Elements més grans",
|
||||||
@@ -417,6 +423,9 @@
|
|||||||
"LabelLibraryFilterSublistEmpty": "Sense {0}",
|
"LabelLibraryFilterSublistEmpty": "Sense {0}",
|
||||||
"LabelLibraryItem": "Element de Biblioteca",
|
"LabelLibraryItem": "Element de Biblioteca",
|
||||||
"LabelLibraryName": "Nom de Biblioteca",
|
"LabelLibraryName": "Nom de Biblioteca",
|
||||||
|
"LabelLibrarySortByProgress": "Progrés: Última actualització",
|
||||||
|
"LabelLibrarySortByProgressFinished": "Progrés: Finalitzat",
|
||||||
|
"LabelLibrarySortByProgressStarted": "Progrés: Començat",
|
||||||
"LabelLimit": "Límits",
|
"LabelLimit": "Límits",
|
||||||
"LabelLineSpacing": "Interlineat",
|
"LabelLineSpacing": "Interlineat",
|
||||||
"LabelListenAgain": "Escoltar de nou",
|
"LabelListenAgain": "Escoltar de nou",
|
||||||
@@ -439,7 +448,7 @@
|
|||||||
"LabelMetadataProvider": "Proveïdor de metadades",
|
"LabelMetadataProvider": "Proveïdor de metadades",
|
||||||
"LabelMinute": "Minut",
|
"LabelMinute": "Minut",
|
||||||
"LabelMinutes": "Minuts",
|
"LabelMinutes": "Minuts",
|
||||||
"LabelMissing": "Absent",
|
"LabelMissing": "Falta",
|
||||||
"LabelMissingEbook": "No té llibre electrònic",
|
"LabelMissingEbook": "No té llibre electrònic",
|
||||||
"LabelMissingSupplementaryEbook": "No té ebook complementari",
|
"LabelMissingSupplementaryEbook": "No té ebook complementari",
|
||||||
"LabelMobileRedirectURIs": "URI de redirecció mòbil permeses",
|
"LabelMobileRedirectURIs": "URI de redirecció mòbil permeses",
|
||||||
|
|||||||
+79
-20
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"ButtonAdd": "Přidat",
|
"ButtonAdd": "Přidat",
|
||||||
|
"ButtonAddApiKey": "Přidat API klíč",
|
||||||
"ButtonAddChapters": "Přidat kapitoly",
|
"ButtonAddChapters": "Přidat kapitoly",
|
||||||
"ButtonAddDevice": "Přidat zařízení",
|
"ButtonAddDevice": "Přidat zařízení",
|
||||||
"ButtonAddLibrary": "Přidat knihovnu",
|
"ButtonAddLibrary": "Přidat knihovnu",
|
||||||
@@ -10,7 +11,7 @@
|
|||||||
"ButtonApplyChapters": "Aplikovat kapitoly",
|
"ButtonApplyChapters": "Aplikovat kapitoly",
|
||||||
"ButtonAuthors": "Autoři",
|
"ButtonAuthors": "Autoři",
|
||||||
"ButtonBack": "Zpět",
|
"ButtonBack": "Zpět",
|
||||||
"ButtonBatchEditPopulateFromExisting": "Vytvořit z existujících",
|
"ButtonBatchEditPopulateFromExisting": "Předvyplnit z existujících",
|
||||||
"ButtonBatchEditPopulateMapDetails": "Předvyplnit podrobnosti mapování",
|
"ButtonBatchEditPopulateMapDetails": "Předvyplnit podrobnosti mapování",
|
||||||
"ButtonBrowseForFolder": "Vyhledat složku",
|
"ButtonBrowseForFolder": "Vyhledat složku",
|
||||||
"ButtonCancel": "Zrušit",
|
"ButtonCancel": "Zrušit",
|
||||||
@@ -20,6 +21,7 @@
|
|||||||
"ButtonChooseAFolder": "Vybrat složku",
|
"ButtonChooseAFolder": "Vybrat složku",
|
||||||
"ButtonChooseFiles": "Vybrat soubory",
|
"ButtonChooseFiles": "Vybrat soubory",
|
||||||
"ButtonClearFilter": "Vymazat filtr",
|
"ButtonClearFilter": "Vymazat filtr",
|
||||||
|
"ButtonClose": "Zavřít",
|
||||||
"ButtonCloseFeed": "Zavřít kanál",
|
"ButtonCloseFeed": "Zavřít kanál",
|
||||||
"ButtonCloseSession": "Zavřít otevřenou relaci",
|
"ButtonCloseSession": "Zavřít otevřenou relaci",
|
||||||
"ButtonCollections": "Kolekce",
|
"ButtonCollections": "Kolekce",
|
||||||
@@ -44,6 +46,7 @@
|
|||||||
"ButtonLatest": "Nejnovější",
|
"ButtonLatest": "Nejnovější",
|
||||||
"ButtonLibrary": "Knihovna",
|
"ButtonLibrary": "Knihovna",
|
||||||
"ButtonLogout": "Odhlásit",
|
"ButtonLogout": "Odhlásit",
|
||||||
|
"ButtonLogoutAllDevices": "Odhlásit ze všech zařízení",
|
||||||
"ButtonLookup": "Vyhledat",
|
"ButtonLookup": "Vyhledat",
|
||||||
"ButtonManageTracks": "Správa stop",
|
"ButtonManageTracks": "Správa stop",
|
||||||
"ButtonMapChapterTitles": "Mapovat názvy kapitol",
|
"ButtonMapChapterTitles": "Mapovat názvy kapitol",
|
||||||
@@ -59,7 +62,7 @@
|
|||||||
"ButtonPause": "Pozastavit",
|
"ButtonPause": "Pozastavit",
|
||||||
"ButtonPlay": "Přehrát",
|
"ButtonPlay": "Přehrát",
|
||||||
"ButtonPlayAll": "Přehrát vše",
|
"ButtonPlayAll": "Přehrát vše",
|
||||||
"ButtonPlaying": "Hraje",
|
"ButtonPlaying": "Přehrává",
|
||||||
"ButtonPlaylists": "Seznamy skladeb",
|
"ButtonPlaylists": "Seznamy skladeb",
|
||||||
"ButtonPrevious": "Předchozí",
|
"ButtonPrevious": "Předchozí",
|
||||||
"ButtonPreviousChapter": "Předchozí Kapitola",
|
"ButtonPreviousChapter": "Předchozí Kapitola",
|
||||||
@@ -69,7 +72,7 @@
|
|||||||
"ButtonQueueAddItem": "Přidat do fronty",
|
"ButtonQueueAddItem": "Přidat do fronty",
|
||||||
"ButtonQueueRemoveItem": "Odstranit z fronty",
|
"ButtonQueueRemoveItem": "Odstranit z fronty",
|
||||||
"ButtonQuickEmbed": "Rychle Zapsat",
|
"ButtonQuickEmbed": "Rychle Zapsat",
|
||||||
"ButtonQuickEmbedMetadata": "Rychle zapsat Metadata",
|
"ButtonQuickEmbedMetadata": "Rychle Vložit Metadata",
|
||||||
"ButtonQuickMatch": "Rychlé přiřazení",
|
"ButtonQuickMatch": "Rychlé přiřazení",
|
||||||
"ButtonReScan": "Znovu prohledat",
|
"ButtonReScan": "Znovu prohledat",
|
||||||
"ButtonRead": "Číst",
|
"ButtonRead": "Číst",
|
||||||
@@ -119,11 +122,13 @@
|
|||||||
"HeaderAccount": "Účet",
|
"HeaderAccount": "Účet",
|
||||||
"HeaderAddCustomMetadataProvider": "Přidat vlastního poskytovatele metadat",
|
"HeaderAddCustomMetadataProvider": "Přidat vlastního poskytovatele metadat",
|
||||||
"HeaderAdvanced": "Pokročilé",
|
"HeaderAdvanced": "Pokročilé",
|
||||||
|
"HeaderApiKeys": "API klíče",
|
||||||
"HeaderAppriseNotificationSettings": "Nastavení oznámení Apprise",
|
"HeaderAppriseNotificationSettings": "Nastavení oznámení Apprise",
|
||||||
"HeaderAudioTracks": "Zvukové stopy",
|
"HeaderAudioTracks": "Zvukové stopy",
|
||||||
"HeaderAudiobookTools": "Nástroje pro správu souborů audioknih",
|
"HeaderAudiobookTools": "Nástroje pro správu souborů audioknih",
|
||||||
"HeaderAuthentication": "Autentizace",
|
"HeaderAuthentication": "Autentizace",
|
||||||
"HeaderBackups": "Zálohy",
|
"HeaderBackups": "Zálohy",
|
||||||
|
"HeaderBulkChapterModal": "Přidat více kapitol",
|
||||||
"HeaderChangePassword": "Změnit heslo",
|
"HeaderChangePassword": "Změnit heslo",
|
||||||
"HeaderChapters": "Kapitoly",
|
"HeaderChapters": "Kapitoly",
|
||||||
"HeaderChooseAFolder": "Zvolte složku",
|
"HeaderChooseAFolder": "Zvolte složku",
|
||||||
@@ -162,6 +167,7 @@
|
|||||||
"HeaderMetadataOrderOfPrecedence": "Pořadí priorit metadat",
|
"HeaderMetadataOrderOfPrecedence": "Pořadí priorit metadat",
|
||||||
"HeaderMetadataToEmbed": "Metadata k vložení",
|
"HeaderMetadataToEmbed": "Metadata k vložení",
|
||||||
"HeaderNewAccount": "Nový účet",
|
"HeaderNewAccount": "Nový účet",
|
||||||
|
"HeaderNewApiKey": "Nový API klíč",
|
||||||
"HeaderNewLibrary": "Nová knihovna",
|
"HeaderNewLibrary": "Nová knihovna",
|
||||||
"HeaderNotificationCreate": "Vytvořit notifikaci",
|
"HeaderNotificationCreate": "Vytvořit notifikaci",
|
||||||
"HeaderNotificationUpdate": "Aktualizovat notifikaci",
|
"HeaderNotificationUpdate": "Aktualizovat notifikaci",
|
||||||
@@ -189,23 +195,26 @@
|
|||||||
"HeaderScheduleEpisodeDownloads": "Naplánovat automatické stahování epizod",
|
"HeaderScheduleEpisodeDownloads": "Naplánovat automatické stahování epizod",
|
||||||
"HeaderScheduleLibraryScans": "Naplánovat automatické prohledávání knihoven",
|
"HeaderScheduleLibraryScans": "Naplánovat automatické prohledávání knihoven",
|
||||||
"HeaderSession": "Relace",
|
"HeaderSession": "Relace",
|
||||||
|
"HeaderSessions": "Relace",
|
||||||
"HeaderSetBackupSchedule": "Nastavit plán zálohování",
|
"HeaderSetBackupSchedule": "Nastavit plán zálohování",
|
||||||
"HeaderSettings": "Nastavení",
|
"HeaderSettings": "Nastavení",
|
||||||
"HeaderSettingsDisplay": "Zobrazit",
|
"HeaderSettingsDisplay": "Zobrazit",
|
||||||
"HeaderSettingsExperimental": "Experimentální funkce",
|
"HeaderSettingsExperimental": "Experimentální funkce",
|
||||||
"HeaderSettingsGeneral": "Obecné",
|
"HeaderSettingsGeneral": "Obecné",
|
||||||
"HeaderSettingsScanner": "Skener",
|
"HeaderSettingsScanner": "Skener",
|
||||||
|
"HeaderSettingsSecurity": "Zabezpečení",
|
||||||
"HeaderSettingsWebClient": "Webový klient",
|
"HeaderSettingsWebClient": "Webový klient",
|
||||||
"HeaderSleepTimer": "Časovač vypnutí",
|
"HeaderSleepTimer": "Časovač vypnutí",
|
||||||
"HeaderStatsLargestItems": "Největší položky",
|
"HeaderStatsLargestItems": "Největší položky",
|
||||||
"HeaderStatsLongestItems": "Nejdelší položky (hod.)",
|
"HeaderStatsLongestItems": "Nejdelší položky (hod.)",
|
||||||
"HeaderStatsMinutesListeningChart": "Poslech za posledních 7 dní (min)",
|
"HeaderStatsMinutesListeningChart": "Poslech za posledních 7 dní (min)",
|
||||||
"HeaderStatsRecentSessions": "Poslední relace",
|
"HeaderStatsRecentSessions": "Nedávné relace",
|
||||||
"HeaderStatsTop10Authors": "Top 10 autorů",
|
"HeaderStatsTop10Authors": "Top 10 autorů",
|
||||||
"HeaderStatsTop5Genres": "Top 5 žánrů",
|
"HeaderStatsTop5Genres": "Top 5 žánrů",
|
||||||
"HeaderTableOfContents": "Obsah",
|
"HeaderTableOfContents": "Obsah",
|
||||||
"HeaderTools": "Nástroje",
|
"HeaderTools": "Nástroje",
|
||||||
"HeaderUpdateAccount": "Aktualizovat účet",
|
"HeaderUpdateAccount": "Aktualizovat účet",
|
||||||
|
"HeaderUpdateApiKey": "Aktualizovat API klíč",
|
||||||
"HeaderUpdateAuthor": "Aktualizovat autora",
|
"HeaderUpdateAuthor": "Aktualizovat autora",
|
||||||
"HeaderUpdateDetails": "Aktualizovat podrobnosti",
|
"HeaderUpdateDetails": "Aktualizovat podrobnosti",
|
||||||
"HeaderUpdateLibrary": "Aktualizovat knihovnu",
|
"HeaderUpdateLibrary": "Aktualizovat knihovnu",
|
||||||
@@ -235,6 +244,10 @@
|
|||||||
"LabelAllUsersExcludingGuests": "Všichni uživatelé kromě hostů",
|
"LabelAllUsersExcludingGuests": "Všichni uživatelé kromě hostů",
|
||||||
"LabelAllUsersIncludingGuests": "Všichni uživatelé včetně hostů",
|
"LabelAllUsersIncludingGuests": "Všichni uživatelé včetně hostů",
|
||||||
"LabelAlreadyInYourLibrary": "Již ve vaší knihovně",
|
"LabelAlreadyInYourLibrary": "Již ve vaší knihovně",
|
||||||
|
"LabelApiKeyCreated": "API klíč \"{0}\" byl úspěšně vytvořen.",
|
||||||
|
"LabelApiKeyCreatedDescription": "Zkopírujte si API klíč nyní, později již nebude možné jej zobrazit.",
|
||||||
|
"LabelApiKeyUser": "Vydávat se za uživatele",
|
||||||
|
"LabelApiKeyUserDescription": "Tento API klíč bude mít stejná oprávnění jako uživatel za něhož vystupuje. V protokolech to bude vypadat jako kdyby požadavky vytvářel přímo daný uživatel.",
|
||||||
"LabelApiToken": "API Token",
|
"LabelApiToken": "API Token",
|
||||||
"LabelAppend": "Připojit",
|
"LabelAppend": "Připojit",
|
||||||
"LabelAudioBitrate": "Bitový tok zvuku (např. 128k)",
|
"LabelAudioBitrate": "Bitový tok zvuku (např. 128k)",
|
||||||
@@ -284,6 +297,7 @@
|
|||||||
"LabelContinueListening": "Pokračovat v poslechu",
|
"LabelContinueListening": "Pokračovat v poslechu",
|
||||||
"LabelContinueReading": "Pokračovat ve čtení",
|
"LabelContinueReading": "Pokračovat ve čtení",
|
||||||
"LabelContinueSeries": "Pokračovat v sérii",
|
"LabelContinueSeries": "Pokračovat v sérii",
|
||||||
|
"LabelCorsAllowed": "Povolené CORS Origins",
|
||||||
"LabelCover": "Obálka",
|
"LabelCover": "Obálka",
|
||||||
"LabelCoverImageURL": "URL obrázku obálky",
|
"LabelCoverImageURL": "URL obrázku obálky",
|
||||||
"LabelCoverProvider": "Poskytovatel obálky",
|
"LabelCoverProvider": "Poskytovatel obálky",
|
||||||
@@ -297,6 +311,7 @@
|
|||||||
"LabelDeleteFromFileSystemCheckbox": "Smazat ze souborového systému (zrušte zaškrtnutí pro odstranění pouze z databáze)",
|
"LabelDeleteFromFileSystemCheckbox": "Smazat ze souborového systému (zrušte zaškrtnutí pro odstranění pouze z databáze)",
|
||||||
"LabelDescription": "Popis",
|
"LabelDescription": "Popis",
|
||||||
"LabelDeselectAll": "Odznačit vše",
|
"LabelDeselectAll": "Odznačit vše",
|
||||||
|
"LabelDetectedPattern": "Detekovaný vzor:",
|
||||||
"LabelDevice": "Zařízení",
|
"LabelDevice": "Zařízení",
|
||||||
"LabelDeviceInfo": "Informace o zařízení",
|
"LabelDeviceInfo": "Informace o zařízení",
|
||||||
"LabelDeviceIsAvailableTo": "Zařízení je dostupné pro...",
|
"LabelDeviceIsAvailableTo": "Zařízení je dostupné pro...",
|
||||||
@@ -346,7 +361,11 @@
|
|||||||
"LabelExample": "Příklad",
|
"LabelExample": "Příklad",
|
||||||
"LabelExpandSeries": "Rozbalit série",
|
"LabelExpandSeries": "Rozbalit série",
|
||||||
"LabelExpandSubSeries": "Rozbalit podsérie",
|
"LabelExpandSubSeries": "Rozbalit podsérie",
|
||||||
"LabelExplicit": "Explicitně",
|
"LabelExpired": "Expirovaný",
|
||||||
|
"LabelExpiresAt": "Expiruje v",
|
||||||
|
"LabelExpiresInSeconds": "Expiruje za (sekundy)",
|
||||||
|
"LabelExpiresNever": "Nikdy",
|
||||||
|
"LabelExplicit": "Explicitní",
|
||||||
"LabelExplicitChecked": "Explicitní (zaškrtnuto)",
|
"LabelExplicitChecked": "Explicitní (zaškrtnuto)",
|
||||||
"LabelExplicitUnchecked": "Není explicitní (nezaškrtnuto)",
|
"LabelExplicitUnchecked": "Není explicitní (nezaškrtnuto)",
|
||||||
"LabelExportOPML": "Export OPML",
|
"LabelExportOPML": "Export OPML",
|
||||||
@@ -361,21 +380,22 @@
|
|||||||
"LabelFilterByUser": "Filtrovat podle uživatele",
|
"LabelFilterByUser": "Filtrovat podle uživatele",
|
||||||
"LabelFindEpisodes": "Najít epizody",
|
"LabelFindEpisodes": "Najít epizody",
|
||||||
"LabelFinished": "Dokončeno",
|
"LabelFinished": "Dokončeno",
|
||||||
|
"LabelFinishedDate": "Dokončeno {0}",
|
||||||
"LabelFolder": "Složka",
|
"LabelFolder": "Složka",
|
||||||
"LabelFolders": "Složky",
|
"LabelFolders": "Složky",
|
||||||
"LabelFontBold": "Tučně",
|
"LabelFontBold": "Tučně",
|
||||||
"LabelFontBoldness": "Výraznost písma",
|
"LabelFontBoldness": "Výraznost písma",
|
||||||
"LabelFontFamily": "Rodina písem",
|
"LabelFontFamily": "Rodina písem",
|
||||||
"LabelFontItalic": "Kurzíva",
|
"LabelFontItalic": "Kurzíva",
|
||||||
"LabelFontScale": "Měřítko písma",
|
"LabelFontScale": "Velikost písma",
|
||||||
"LabelFontStrikethrough": "Přeškrtnutí",
|
"LabelFontStrikethrough": "Přeškrtnutí",
|
||||||
"LabelFormat": "Formát",
|
"LabelFormat": "Formát",
|
||||||
"LabelFull": "Plné",
|
"LabelFull": "Plné",
|
||||||
"LabelGenre": "Žánr",
|
"LabelGenre": "Žánr",
|
||||||
"LabelGenres": "Žánry",
|
"LabelGenres": "Žánry",
|
||||||
"LabelHardDeleteFile": "Trvale smazat soubor",
|
"LabelHardDeleteFile": "Trvale smazat soubor",
|
||||||
"LabelHasEbook": "Obsahuje elektronickou knihu",
|
"LabelHasEbook": "Má e-knihu",
|
||||||
"LabelHasSupplementaryEbook": "Obsahuje doplňkovou elektronickou knihu",
|
"LabelHasSupplementaryEbook": "Obsahuje doplňkovou e-knihu",
|
||||||
"LabelHideSubtitles": "Skrýt titulky",
|
"LabelHideSubtitles": "Skrýt titulky",
|
||||||
"LabelHighestPriority": "Nejvyšší priorita",
|
"LabelHighestPriority": "Nejvyšší priorita",
|
||||||
"LabelHost": "Hostitel",
|
"LabelHost": "Hostitel",
|
||||||
@@ -397,6 +417,7 @@
|
|||||||
"LabelIntervalEveryHour": "Každou hodinu",
|
"LabelIntervalEveryHour": "Každou hodinu",
|
||||||
"LabelIntervalEveryMinute": "Každou minutu",
|
"LabelIntervalEveryMinute": "Každou minutu",
|
||||||
"LabelInvert": "Invertovat",
|
"LabelInvert": "Invertovat",
|
||||||
|
"LabelIpAddress": "IP Adresa",
|
||||||
"LabelItem": "Položka",
|
"LabelItem": "Položka",
|
||||||
"LabelJumpBackwardAmount": "Přeskočit zpět o",
|
"LabelJumpBackwardAmount": "Přeskočit zpět o",
|
||||||
"LabelJumpForwardAmount": "Přeskočit dopředu o",
|
"LabelJumpForwardAmount": "Přeskočit dopředu o",
|
||||||
@@ -405,6 +426,7 @@
|
|||||||
"LabelLanguages": "Jazyky",
|
"LabelLanguages": "Jazyky",
|
||||||
"LabelLastBookAdded": "Poslední kniha přidána",
|
"LabelLastBookAdded": "Poslední kniha přidána",
|
||||||
"LabelLastBookUpdated": "Poslední kniha aktualizována",
|
"LabelLastBookUpdated": "Poslední kniha aktualizována",
|
||||||
|
"LabelLastProgressDate": "Poslední pokrok: {0}",
|
||||||
"LabelLastSeen": "Naposledy viděno",
|
"LabelLastSeen": "Naposledy viděno",
|
||||||
"LabelLastTime": "Naposledy",
|
"LabelLastTime": "Naposledy",
|
||||||
"LabelLastUpdate": "Poslední aktualizace",
|
"LabelLastUpdate": "Poslední aktualizace",
|
||||||
@@ -417,6 +439,9 @@
|
|||||||
"LabelLibraryFilterSublistEmpty": "Žádné {0}",
|
"LabelLibraryFilterSublistEmpty": "Žádné {0}",
|
||||||
"LabelLibraryItem": "Položka knihovny",
|
"LabelLibraryItem": "Položka knihovny",
|
||||||
"LabelLibraryName": "Název knihovny",
|
"LabelLibraryName": "Název knihovny",
|
||||||
|
"LabelLibrarySortByProgress": "Pokrok: naposledy aktualizováno",
|
||||||
|
"LabelLibrarySortByProgressFinished": "Pokrok: dokončeno",
|
||||||
|
"LabelLibrarySortByProgressStarted": "Pokrok: začato",
|
||||||
"LabelLimit": "Omezit",
|
"LabelLimit": "Omezit",
|
||||||
"LabelLineSpacing": "Řádkování",
|
"LabelLineSpacing": "Řádkování",
|
||||||
"LabelListenAgain": "Poslouchat znovu",
|
"LabelListenAgain": "Poslouchat znovu",
|
||||||
@@ -425,10 +450,11 @@
|
|||||||
"LabelLogLevelWarn": "Varovat",
|
"LabelLogLevelWarn": "Varovat",
|
||||||
"LabelLookForNewEpisodesAfterDate": "Hledat nové epizody po tomto datu",
|
"LabelLookForNewEpisodesAfterDate": "Hledat nové epizody po tomto datu",
|
||||||
"LabelLowestPriority": "Nejnižší priorita",
|
"LabelLowestPriority": "Nejnižší priorita",
|
||||||
|
"LabelMatchConfidence": "Jistota",
|
||||||
"LabelMatchExistingUsersBy": "Přiřadit stávající uživatele podle",
|
"LabelMatchExistingUsersBy": "Přiřadit stávající uživatele podle",
|
||||||
"LabelMatchExistingUsersByDescription": "Slouží k propojení stávajících uživatelů. Po propojení budou uživatelé přiřazeni k jedinečnému ID od poskytovatele SSO",
|
"LabelMatchExistingUsersByDescription": "Slouží k propojení stávajících uživatelů. Po propojení budou uživatelé přiřazeni k jedinečnému ID od poskytovatele SSO",
|
||||||
"LabelMaxEpisodesToDownload": "Maximální # epizod pro stažení. Použijte 0 pro bez omezení.",
|
"LabelMaxEpisodesToDownload": "Maximální # epizod pro stažení. Použijte 0 pro bez omezení.",
|
||||||
"LabelMaxEpisodesToDownloadPerCheck": "Maximální počet nových epizod ke stažení při jedné kontrole",
|
"LabelMaxEpisodesToDownloadPerCheck": "Maximální # nových epizod ke stažení při jedné kontrole",
|
||||||
"LabelMaxEpisodesToKeep": "Maximální počet epizod k zachování",
|
"LabelMaxEpisodesToKeep": "Maximální počet epizod k zachování",
|
||||||
"LabelMaxEpisodesToKeepHelp": "Hodnotou 0 není nastaven žádný maximální limit. Po automatickém stažení nové epizody se odstraní nejstarší epizoda, pokud máte více než X epizod. Při každém novém stažení se odstraní pouze 1 epizoda.",
|
"LabelMaxEpisodesToKeepHelp": "Hodnotou 0 není nastaven žádný maximální limit. Po automatickém stažení nové epizody se odstraní nejstarší epizoda, pokud máte více než X epizod. Při každém novém stažení se odstraní pouze 1 epizoda.",
|
||||||
"LabelMediaPlayer": "Přehrávač médií",
|
"LabelMediaPlayer": "Přehrávač médií",
|
||||||
@@ -454,7 +480,9 @@
|
|||||||
"LabelNewestAuthors": "Nejnovější autoři",
|
"LabelNewestAuthors": "Nejnovější autoři",
|
||||||
"LabelNewestEpisodes": "Nejnovější epizody",
|
"LabelNewestEpisodes": "Nejnovější epizody",
|
||||||
"LabelNextBackupDate": "Datum příští zálohy",
|
"LabelNextBackupDate": "Datum příští zálohy",
|
||||||
|
"LabelNextChapters": "Další kapitola bude:",
|
||||||
"LabelNextScheduledRun": "Další naplánované spuštění",
|
"LabelNextScheduledRun": "Další naplánované spuštění",
|
||||||
|
"LabelNoApiKeys": "Žádné API klíče",
|
||||||
"LabelNoCustomMetadataProviders": "Žádní vlastní poskytovatelé metadat",
|
"LabelNoCustomMetadataProviders": "Žádní vlastní poskytovatelé metadat",
|
||||||
"LabelNoEpisodesSelected": "Nebyly vybrány žádné epizody",
|
"LabelNoEpisodesSelected": "Nebyly vybrány žádné epizody",
|
||||||
"LabelNotFinished": "Nedokončeno",
|
"LabelNotFinished": "Nedokončeno",
|
||||||
@@ -470,6 +498,7 @@
|
|||||||
"LabelNotificationsMaxQueueSize": "Maximální velikost fronty pro oznamovací události",
|
"LabelNotificationsMaxQueueSize": "Maximální velikost fronty pro oznamovací události",
|
||||||
"LabelNotificationsMaxQueueSizeHelp": "Události jsou omezeny na 1 za sekundu. Události budou ignorovány, pokud je fronta v maximální velikosti. Tím se zabrání spamování oznámení.",
|
"LabelNotificationsMaxQueueSizeHelp": "Události jsou omezeny na 1 za sekundu. Události budou ignorovány, pokud je fronta v maximální velikosti. Tím se zabrání spamování oznámení.",
|
||||||
"LabelNumberOfBooks": "Počet knih",
|
"LabelNumberOfBooks": "Počet knih",
|
||||||
|
"LabelNumberOfChapters": "Počet kapitol:",
|
||||||
"LabelNumberOfEpisodes": "Počet epizod",
|
"LabelNumberOfEpisodes": "Počet epizod",
|
||||||
"LabelOpenIDAdvancedPermsClaimDescription": "Název požadavku OpenID, který obsahuje rozšířená oprávnění pro akce uživatele v rámci aplikace, která se budou vztahovat na role, které nejsou administrátory (<b>pokud jsou nakonfigurovány</b>). Pokud požadavek v odpovědi chybí, přístup do systému ABS bude zamítnut. Pokud chybí jediná možnost, bude považována za <code>false</code>. Ujistěte se, že deklarace poskytovatele identity odpovídá očekávané struktuře:",
|
"LabelOpenIDAdvancedPermsClaimDescription": "Název požadavku OpenID, který obsahuje rozšířená oprávnění pro akce uživatele v rámci aplikace, která se budou vztahovat na role, které nejsou administrátory (<b>pokud jsou nakonfigurovány</b>). Pokud požadavek v odpovědi chybí, přístup do systému ABS bude zamítnut. Pokud chybí jediná možnost, bude považována za <code>false</code>. Ujistěte se, že deklarace poskytovatele identity odpovídá očekávané struktuře:",
|
||||||
"LabelOpenIDClaims": "Následující možnosti ponechte prázdné, abyste zakázali pokročilé přiřazování skupin a oprávnění a automatické přiřazení skupiny \"User\".",
|
"LabelOpenIDClaims": "Následující možnosti ponechte prázdné, abyste zakázali pokročilé přiřazování skupin a oprávnění a automatické přiřazení skupiny \"User\".",
|
||||||
@@ -544,6 +573,7 @@
|
|||||||
"LabelSelectAll": "Vybrat vše",
|
"LabelSelectAll": "Vybrat vše",
|
||||||
"LabelSelectAllEpisodes": "Vybrat všechny epizody",
|
"LabelSelectAllEpisodes": "Vybrat všechny epizody",
|
||||||
"LabelSelectEpisodesShowing": "Vyberte {0} epizody, které se zobrazují",
|
"LabelSelectEpisodesShowing": "Vyberte {0} epizody, které se zobrazují",
|
||||||
|
"LabelSelectUser": "Vybrat uživatele",
|
||||||
"LabelSelectUsers": "Vybrat uživatele",
|
"LabelSelectUsers": "Vybrat uživatele",
|
||||||
"LabelSendEbookToDevice": "Odeslat e-knihu do...",
|
"LabelSendEbookToDevice": "Odeslat e-knihu do...",
|
||||||
"LabelSequence": "Sekvence",
|
"LabelSequence": "Sekvence",
|
||||||
@@ -562,7 +592,7 @@
|
|||||||
"LabelSettingsChromecastSupport": "Podpora Chromecastu",
|
"LabelSettingsChromecastSupport": "Podpora Chromecastu",
|
||||||
"LabelSettingsDateFormat": "Formát data",
|
"LabelSettingsDateFormat": "Formát data",
|
||||||
"LabelSettingsEnableWatcher": "Automaticky skenovat změny v knihovnách",
|
"LabelSettingsEnableWatcher": "Automaticky skenovat změny v knihovnách",
|
||||||
"LabelSettingsEnableWatcherForLibrary": "Automaticky skenovat změny v knihovně",
|
"LabelSettingsEnableWatcherForLibrary": "Automaticky sledovat změny v knihovně",
|
||||||
"LabelSettingsEnableWatcherHelp": "Povoluje automatické přidávání/aktualizaci položek, když jsou zjištěny změny souborů. *Vyžaduje restart serveru",
|
"LabelSettingsEnableWatcherHelp": "Povoluje automatické přidávání/aktualizaci položek, když jsou zjištěny změny souborů. *Vyžaduje restart serveru",
|
||||||
"LabelSettingsEpubsAllowScriptedContent": "Povolení skriptovaného obsahu v epubu",
|
"LabelSettingsEpubsAllowScriptedContent": "Povolení skriptovaného obsahu v epubu",
|
||||||
"LabelSettingsEpubsAllowScriptedContentHelp": "Povolení spouštění skriptů v souborech epub. Doporučujeme toto nastavení vypnout, pokud nedůvěřujete zdroji souborů epub.",
|
"LabelSettingsEpubsAllowScriptedContentHelp": "Povolení spouštění skriptů v souborech epub. Doporučujeme toto nastavení vypnout, pokud nedůvěřujete zdroji souborů epub.",
|
||||||
@@ -611,6 +641,7 @@
|
|||||||
"LabelStartTime": "Čas Spuštění",
|
"LabelStartTime": "Čas Spuštění",
|
||||||
"LabelStarted": "Spuštěno",
|
"LabelStarted": "Spuštěno",
|
||||||
"LabelStartedAt": "Spuštěno v",
|
"LabelStartedAt": "Spuštěno v",
|
||||||
|
"LabelStartedDate": "Spuštěno {0}",
|
||||||
"LabelStatsAudioTracks": "Zvukové stopy",
|
"LabelStatsAudioTracks": "Zvukové stopy",
|
||||||
"LabelStatsAuthors": "Autoři",
|
"LabelStatsAuthors": "Autoři",
|
||||||
"LabelStatsBestDay": "Nejlepší den",
|
"LabelStatsBestDay": "Nejlepší den",
|
||||||
@@ -640,6 +671,7 @@
|
|||||||
"LabelTheme": "Téma",
|
"LabelTheme": "Téma",
|
||||||
"LabelThemeDark": "Tmavé",
|
"LabelThemeDark": "Tmavé",
|
||||||
"LabelThemeLight": "Světlé",
|
"LabelThemeLight": "Světlé",
|
||||||
|
"LabelThemeSepia": "Hnědé",
|
||||||
"LabelTimeBase": "Časová základna",
|
"LabelTimeBase": "Časová základna",
|
||||||
"LabelTimeDurationXHours": "{0} hodin",
|
"LabelTimeDurationXHours": "{0} hodin",
|
||||||
"LabelTimeDurationXMinutes": "{0} minut",
|
"LabelTimeDurationXMinutes": "{0} minut",
|
||||||
@@ -708,7 +740,9 @@
|
|||||||
"MessageAddToPlayerQueue": "Přidat do fronty přehrávače",
|
"MessageAddToPlayerQueue": "Přidat do fronty přehrávače",
|
||||||
"MessageAppriseDescription": "Abyste mohli používat tuto funkci, musíte mít spuštěnou instanci <a href=\"https://github.com/caronc/apprise-api\" target=\"_blank\">Apprise API</a> nebo API, které bude zpracovávat stejné požadavky. <br />Adresa URL API Apprise by měla být úplná URL cesta pro odeslání oznámení, např. pokud je vaše instance API obsluhována na adrese <code>http://192.168.1.1:8337</code> pak byste měli zadat <code>http://192.168.1.1:8337/notify</code>.",
|
"MessageAppriseDescription": "Abyste mohli používat tuto funkci, musíte mít spuštěnou instanci <a href=\"https://github.com/caronc/apprise-api\" target=\"_blank\">Apprise API</a> nebo API, které bude zpracovávat stejné požadavky. <br />Adresa URL API Apprise by měla být úplná URL cesta pro odeslání oznámení, např. pokud je vaše instance API obsluhována na adrese <code>http://192.168.1.1:8337</code> pak byste měli zadat <code>http://192.168.1.1:8337/notify</code>.",
|
||||||
"MessageAsinCheck": "Ujistěte se, že používáte ASIN ze správného regionu Audible a ne z Amazonu.",
|
"MessageAsinCheck": "Ujistěte se, že používáte ASIN ze správného regionu Audible a ne z Amazonu.",
|
||||||
|
"MessageAuthenticationLegacyTokenWarning": "Zastaralé API tokeny budou v budoucnu odstraněny. Použijte místo nich <a href=\"/config/api-keys\">API klíče</a>.",
|
||||||
"MessageAuthenticationOIDCChangesRestart": "Po uložení restartujte server, aby se změny OIDC použily.",
|
"MessageAuthenticationOIDCChangesRestart": "Po uložení restartujte server, aby se změny OIDC použily.",
|
||||||
|
"MessageAuthenticationSecurityMessage": "Bezpečnost autentizace byla vylepšena. Všichni uživatelé se musí znovu přihlásit.",
|
||||||
"MessageBackupsDescription": "Zálohy zahrnují uživatele, průběh uživatele, podrobnosti o položkách knihovny, nastavení serveru a obrázky uložené v <code>/metadata/items</code> a <code>/metadata/authors</code>. Zálohy <strong>ne</strong> zahrnují všechny soubory uložené ve složkách knihovny.",
|
"MessageBackupsDescription": "Zálohy zahrnují uživatele, průběh uživatele, podrobnosti o položkách knihovny, nastavení serveru a obrázky uložené v <code>/metadata/items</code> a <code>/metadata/authors</code>. Zálohy <strong>ne</strong> zahrnují všechny soubory uložené ve složkách knihovny.",
|
||||||
"MessageBackupsLocationEditNote": "Poznámka: Změna umístění záloh nepřesune ani nezmění existující zálohy",
|
"MessageBackupsLocationEditNote": "Poznámka: Změna umístění záloh nepřesune ani nezmění existující zálohy",
|
||||||
"MessageBackupsLocationNoEditNote": "Poznámka: Umístění záloh je nastavené z proměnných prostředí a nelze zde změnit.",
|
"MessageBackupsLocationNoEditNote": "Poznámka: Umístění záloh je nastavené z proměnných prostředí a nelze zde změnit.",
|
||||||
@@ -722,6 +756,7 @@
|
|||||||
"MessageBookshelfNoResultsForFilter": "Filtr \"{0}: {1}\"",
|
"MessageBookshelfNoResultsForFilter": "Filtr \"{0}: {1}\"",
|
||||||
"MessageBookshelfNoResultsForQuery": "Žádné výsledky pro dotaz",
|
"MessageBookshelfNoResultsForQuery": "Žádné výsledky pro dotaz",
|
||||||
"MessageBookshelfNoSeries": "Nemáte žádnou sérii",
|
"MessageBookshelfNoSeries": "Nemáte žádnou sérii",
|
||||||
|
"MessageBulkChapterPattern": "Kolik kapitol chcete přidat s tímto vzorem číslování?",
|
||||||
"MessageChapterEndIsAfter": "Konec kapitoly přesahuje konec audioknihy",
|
"MessageChapterEndIsAfter": "Konec kapitoly přesahuje konec audioknihy",
|
||||||
"MessageChapterErrorFirstNotZero": "První kapitola musí začínat na 0",
|
"MessageChapterErrorFirstNotZero": "První kapitola musí začínat na 0",
|
||||||
"MessageChapterErrorStartGteDuration": "Neplatný čas začátku, musí být kratší než doba trvání audioknihy",
|
"MessageChapterErrorStartGteDuration": "Neplatný čas začátku, musí být kratší než doba trvání audioknihy",
|
||||||
@@ -730,6 +765,7 @@
|
|||||||
"MessageChaptersNotFound": "Kapitoly nenalezeny",
|
"MessageChaptersNotFound": "Kapitoly nenalezeny",
|
||||||
"MessageCheckingCron": "Kontrola cronu...",
|
"MessageCheckingCron": "Kontrola cronu...",
|
||||||
"MessageConfirmCloseFeed": "Opravdu chcete zavřít tento kanál?",
|
"MessageConfirmCloseFeed": "Opravdu chcete zavřít tento kanál?",
|
||||||
|
"MessageConfirmDeleteApiKey": "Opravdu chcete vymazat API klíč \"{0}\"?",
|
||||||
"MessageConfirmDeleteBackup": "Opravdu chcete smazat zálohu pro {0}?",
|
"MessageConfirmDeleteBackup": "Opravdu chcete smazat zálohu pro {0}?",
|
||||||
"MessageConfirmDeleteDevice": "Opravdu chcete vymazat zařízení e-reader \"{0}\"?",
|
"MessageConfirmDeleteDevice": "Opravdu chcete vymazat zařízení e-reader \"{0}\"?",
|
||||||
"MessageConfirmDeleteFile": "Tento krok smaže soubor ze souborového systému. Jsi si jisti?",
|
"MessageConfirmDeleteFile": "Tento krok smaže soubor ze souborového systému. Jsi si jisti?",
|
||||||
@@ -741,13 +777,14 @@
|
|||||||
"MessageConfirmDeleteSession": "Opravdu chcete smazat tuto relaci?",
|
"MessageConfirmDeleteSession": "Opravdu chcete smazat tuto relaci?",
|
||||||
"MessageConfirmEmbedMetadataInAudioFiles": "Jste si jisti, že chcete vložit metadata do {0} zvukových souborů?",
|
"MessageConfirmEmbedMetadataInAudioFiles": "Jste si jisti, že chcete vložit metadata do {0} zvukových souborů?",
|
||||||
"MessageConfirmForceReScan": "Opravdu chcete vynutit opětovné prohledání?",
|
"MessageConfirmForceReScan": "Opravdu chcete vynutit opětovné prohledání?",
|
||||||
|
"MessageConfirmLogoutDevice": "Opravdu se chcete odhlásit z \"{0}\"?",
|
||||||
"MessageConfirmMarkAllEpisodesFinished": "Opravdu chcete označit všechny epizody jako dokončené?",
|
"MessageConfirmMarkAllEpisodesFinished": "Opravdu chcete označit všechny epizody jako dokončené?",
|
||||||
"MessageConfirmMarkAllEpisodesNotFinished": "Opravdu chcete označit všechny epizody jako nedokončené?",
|
"MessageConfirmMarkAllEpisodesNotFinished": "Opravdu chcete označit všechny epizody jako nedokončené?",
|
||||||
"MessageConfirmMarkItemFinished": "Opravdu chcete označit \"{0}\" jako dokončené?",
|
"MessageConfirmMarkItemFinished": "Opravdu chcete označit \"{0}\" jako dokončené?",
|
||||||
"MessageConfirmMarkItemNotFinished": "Opravdu chcete označit \"{0}\" jako nedokončené?",
|
"MessageConfirmMarkItemNotFinished": "Opravdu chcete označit \"{0}\" jako nedokončené?",
|
||||||
"MessageConfirmMarkSeriesFinished": "Opravdu chcete označit všechny knihy z této série jako dokončené?",
|
"MessageConfirmMarkSeriesFinished": "Opravdu chcete označit všechny knihy z této série jako dokončené?",
|
||||||
"MessageConfirmMarkSeriesNotFinished": "Opravdu chcete označit všechny knihy z této série jako nedokončené?",
|
"MessageConfirmMarkSeriesNotFinished": "Opravdu chcete označit všechny knihy z této série jako nedokončené?",
|
||||||
"MessageConfirmNotificationTestTrigger": "Spustit toto oznámení s testovacími daty?",
|
"MessageConfirmNotificationTestTrigger": "Vyvolat tuto notifikaci s testovacími daty?",
|
||||||
"MessageConfirmPurgeCache": "Vyčistit mezipaměť odstraní celý adresář na adrese <code>/metadata/cache</code>. <br /><br />Určitě chcete odstranit adresář mezipaměti?",
|
"MessageConfirmPurgeCache": "Vyčistit mezipaměť odstraní celý adresář na adrese <code>/metadata/cache</code>. <br /><br />Určitě chcete odstranit adresář mezipaměti?",
|
||||||
"MessageConfirmPurgeItemsCache": "Vyčištění mezipaměti položek odstraní celý adresář <code>/metadata/cache/items</code>.<br />Jste si jistí?",
|
"MessageConfirmPurgeItemsCache": "Vyčištění mezipaměti položek odstraní celý adresář <code>/metadata/cache/items</code>.<br />Jste si jistí?",
|
||||||
"MessageConfirmQuickEmbed": "Varování! Rychlé vložení nezálohuje vaše zvukové soubory. Ujistěte se, že máte zálohu zvukových souborů. <br><br>Chcete pokračovat?",
|
"MessageConfirmQuickEmbed": "Varování! Rychlé vložení nezálohuje vaše zvukové soubory. Ujistěte se, že máte zálohu zvukových souborů. <br><br>Chcete pokračovat?",
|
||||||
@@ -783,6 +820,8 @@
|
|||||||
"MessageFeedURLWillBe": "URL zdroje bude {0}",
|
"MessageFeedURLWillBe": "URL zdroje bude {0}",
|
||||||
"MessageFetching": "Načítání...",
|
"MessageFetching": "Načítání...",
|
||||||
"MessageForceReScanDescription": "znovu prohledá všechny soubory jako při novém skenování. ID3 tagy zvukových souborů OPF soubory a textové soubory budou skenovány jako nové.",
|
"MessageForceReScanDescription": "znovu prohledá všechny soubory jako při novém skenování. ID3 tagy zvukových souborů OPF soubory a textové soubory budou skenovány jako nové.",
|
||||||
|
"MessageHeatmapListeningTimeTooltip": "<strong>{0} poslechnuto</strong> na {1}",
|
||||||
|
"MessageHeatmapNoListeningSessions": "Žádné relace poslouchání na {0}",
|
||||||
"MessageImportantNotice": "Důležité upozornění!",
|
"MessageImportantNotice": "Důležité upozornění!",
|
||||||
"MessageInsertChapterBelow": "Vložit kapitolu níže",
|
"MessageInsertChapterBelow": "Vložit kapitolu níže",
|
||||||
"MessageInvalidAsin": "Neplatný ASIN",
|
"MessageInvalidAsin": "Neplatný ASIN",
|
||||||
@@ -819,7 +858,7 @@
|
|||||||
"MessageNoItems": "Žádné položky",
|
"MessageNoItems": "Žádné položky",
|
||||||
"MessageNoItemsFound": "Nebyly nalezeny žádné položky",
|
"MessageNoItemsFound": "Nebyly nalezeny žádné položky",
|
||||||
"MessageNoListeningSessions": "Žádné poslechové relace",
|
"MessageNoListeningSessions": "Žádné poslechové relace",
|
||||||
"MessageNoLogs": "Žádné logy",
|
"MessageNoLogs": "Žádné záznamy událostí",
|
||||||
"MessageNoMediaProgress": "Žádný průběh médií",
|
"MessageNoMediaProgress": "Žádný průběh médií",
|
||||||
"MessageNoNotifications": "Žádná oznámení",
|
"MessageNoNotifications": "Žádná oznámení",
|
||||||
"MessageNoPodcastFeed": "Neplatný podcast: Žádný kanál",
|
"MessageNoPodcastFeed": "Neplatný podcast: Žádný kanál",
|
||||||
@@ -849,7 +888,7 @@
|
|||||||
"MessageRemoveEpisodes": "Odstranit {0} epizodu",
|
"MessageRemoveEpisodes": "Odstranit {0} epizodu",
|
||||||
"MessageRemoveFromPlayerQueue": "Odstranit z fronty přehrávače",
|
"MessageRemoveFromPlayerQueue": "Odstranit z fronty přehrávače",
|
||||||
"MessageRemoveUserWarning": "Opravdu chcete trvale smazat uživatele \"{0}\"?",
|
"MessageRemoveUserWarning": "Opravdu chcete trvale smazat uživatele \"{0}\"?",
|
||||||
"MessageReportBugsAndContribute": "Hlásit chyby, žádat o funkce a přispívat",
|
"MessageReportBugsAndContribute": "Nahlašte chyby, vyžádejte si funkce a přispěte na",
|
||||||
"MessageResetChaptersConfirm": "Opravdu chcete resetovat kapitoly a vrátit zpět provedené změny?",
|
"MessageResetChaptersConfirm": "Opravdu chcete resetovat kapitoly a vrátit zpět provedené změny?",
|
||||||
"MessageRestoreBackupConfirm": "Opravdu chcete obnovit zálohu vytvořenou dne",
|
"MessageRestoreBackupConfirm": "Opravdu chcete obnovit zálohu vytvořenou dne",
|
||||||
"MessageRestoreBackupWarning": "Obnovení zálohy přepíše celou databázi umístěnou v /config a obálku obrázků v /metadata/items & /metadata/authors.<br /><br />Backups nezmění žádné soubory ve složkách knihovny. Pokud jste povolili nastavení serveru pro ukládání obrázků obalu a metadat do složek knihovny, nebudou zálohovány ani přepsány.<br /><br />Všichni klienti používající váš server budou automaticky obnoveni.",
|
"MessageRestoreBackupWarning": "Obnovení zálohy přepíše celou databázi umístěnou v /config a obálku obrázků v /metadata/items & /metadata/authors.<br /><br />Backups nezmění žádné soubory ve složkách knihovny. Pokud jste povolili nastavení serveru pro ukládání obrázků obalu a metadat do složek knihovny, nebudou zálohovány ani přepsány.<br /><br />Všichni klienti používající váš server budou automaticky obnoveni.",
|
||||||
@@ -882,7 +921,7 @@
|
|||||||
"MessageTaskNoFilesToScan": "Žádné soubory k prohledání",
|
"MessageTaskNoFilesToScan": "Žádné soubory k prohledání",
|
||||||
"MessageTaskOpmlImport": "Import OPML",
|
"MessageTaskOpmlImport": "Import OPML",
|
||||||
"MessageTaskOpmlImportDescription": "Vytváření podcastů z {0} RSS feedů",
|
"MessageTaskOpmlImportDescription": "Vytváření podcastů z {0} RSS feedů",
|
||||||
"MessageTaskOpmlImportFeed": "Importní zdroj OPML",
|
"MessageTaskOpmlImportFeed": "Import OPML feedu",
|
||||||
"MessageTaskOpmlImportFeedDescription": "Importování RSS feedu \"{0}\"",
|
"MessageTaskOpmlImportFeedDescription": "Importování RSS feedu \"{0}\"",
|
||||||
"MessageTaskOpmlImportFeedFailed": "Nepodařilo se získat kanál podcastu",
|
"MessageTaskOpmlImportFeedFailed": "Nepodařilo se získat kanál podcastu",
|
||||||
"MessageTaskOpmlImportFeedPodcastDescription": "Vytváření podcastu \"{0}\"",
|
"MessageTaskOpmlImportFeedPodcastDescription": "Vytváření podcastu \"{0}\"",
|
||||||
@@ -922,6 +961,7 @@
|
|||||||
"NotificationOnRSSFeedDisabledDescription": "Aktivováno když je automatické stahování pozastaveno z důvodu příliš mnoho neůspěšných pokusů",
|
"NotificationOnRSSFeedDisabledDescription": "Aktivováno když je automatické stahování pozastaveno z důvodu příliš mnoho neůspěšných pokusů",
|
||||||
"NotificationOnRSSFeedFailedDescription": "Aktivováno když selže RSS kanál pro stahování epizod",
|
"NotificationOnRSSFeedFailedDescription": "Aktivováno když selže RSS kanál pro stahování epizod",
|
||||||
"NotificationOnTestDescription": "Akce pro otestování upozorňovacího systému",
|
"NotificationOnTestDescription": "Akce pro otestování upozorňovacího systému",
|
||||||
|
"PlaceholderBulkChapterInput": "Zadejte název kapitoly nebo použije číslování (např. 'Epizoda 1', 'Kapitola 10', '1.')",
|
||||||
"PlaceholderNewCollection": "Nový název kolekce",
|
"PlaceholderNewCollection": "Nový název kolekce",
|
||||||
"PlaceholderNewFolderPath": "Nová cesta ke složce",
|
"PlaceholderNewFolderPath": "Nová cesta ke složce",
|
||||||
"PlaceholderNewPlaylist": "Nový název seznamu přehrávání",
|
"PlaceholderNewPlaylist": "Nový název seznamu přehrávání",
|
||||||
@@ -934,7 +974,7 @@
|
|||||||
"StatsBooksFinishedThisYear": "Některé knihy dokončené tento rok…",
|
"StatsBooksFinishedThisYear": "Některé knihy dokončené tento rok…",
|
||||||
"StatsBooksListenedTo": "knih poslechnuto",
|
"StatsBooksListenedTo": "knih poslechnuto",
|
||||||
"StatsCollectionGrewTo": "Vaše kolekce knih se rozrostla na…",
|
"StatsCollectionGrewTo": "Vaše kolekce knih se rozrostla na…",
|
||||||
"StatsSessions": "sezóna",
|
"StatsSessions": "relace",
|
||||||
"StatsSpentListening": "stráveno posloucháním",
|
"StatsSpentListening": "stráveno posloucháním",
|
||||||
"StatsTopAuthor": "TOP AUTOR",
|
"StatsTopAuthor": "TOP AUTOR",
|
||||||
"StatsTopAuthors": "TOP AUTOŘI",
|
"StatsTopAuthors": "TOP AUTOŘI",
|
||||||
@@ -975,8 +1015,12 @@
|
|||||||
"ToastBookmarkCreateFailed": "Vytvoření záložky se nezdařilo",
|
"ToastBookmarkCreateFailed": "Vytvoření záložky se nezdařilo",
|
||||||
"ToastBookmarkCreateSuccess": "Přidána záložka",
|
"ToastBookmarkCreateSuccess": "Přidána záložka",
|
||||||
"ToastBookmarkRemoveSuccess": "Záložka odstraněna",
|
"ToastBookmarkRemoveSuccess": "Záložka odstraněna",
|
||||||
|
"ToastBulkChapterInvalidCount": "Zadejte číslo mezi 1 a 150",
|
||||||
"ToastCachePurgeFailed": "Nepodařilo se vyčistit mezipaměť",
|
"ToastCachePurgeFailed": "Nepodařilo se vyčistit mezipaměť",
|
||||||
"ToastCachePurgeSuccess": "Vyrovnávací paměť úspěšně vyčištěna",
|
"ToastCachePurgeSuccess": "Vyrovnávací paměť úspěšně vyčištěna",
|
||||||
|
"ToastChapterLocked": "Kapitola je uzamčena.",
|
||||||
|
"ToastChapterStartTimeAdjusted": "Začátek kapitoly posunut o {0} sekund",
|
||||||
|
"ToastChaptersAllLocked": "Všechny kapitoly jsou uzamčeny. Pro posun kapitol některé odemkněte.",
|
||||||
"ToastChaptersHaveErrors": "Kapitoly obsahují chyby",
|
"ToastChaptersHaveErrors": "Kapitoly obsahují chyby",
|
||||||
"ToastChaptersInvalidShiftAmountLast": "Nesprávná délka posunu. Čas začátku poslední kapitoly by přesáhl dobu trvání této audioknihy.",
|
"ToastChaptersInvalidShiftAmountLast": "Nesprávná délka posunu. Čas začátku poslední kapitoly by přesáhl dobu trvání této audioknihy.",
|
||||||
"ToastChaptersInvalidShiftAmountStart": "Nesprávná délka posunu. První kapitola by měla nulovou nebo zápornou délku a byla by přepsána druhou kapitolou. Zvětšete čas začátku druhé kapitoly.",
|
"ToastChaptersInvalidShiftAmountStart": "Nesprávná délka posunu. První kapitola by měla nulovou nebo zápornou délku a byla by přepsána druhou kapitolou. Zvětšete čas začátku druhé kapitoly.",
|
||||||
@@ -986,6 +1030,8 @@
|
|||||||
"ToastCollectionItemsAddFailed": "Přidávání položek do kolekce selhalo",
|
"ToastCollectionItemsAddFailed": "Přidávání položek do kolekce selhalo",
|
||||||
"ToastCollectionRemoveSuccess": "Kolekce odstraněna",
|
"ToastCollectionRemoveSuccess": "Kolekce odstraněna",
|
||||||
"ToastCollectionUpdateSuccess": "Kolekce aktualizována",
|
"ToastCollectionUpdateSuccess": "Kolekce aktualizována",
|
||||||
|
"ToastConnectionNotAvailable": "Připojení není k dispozici. Zkuste to prosím znovu později",
|
||||||
|
"ToastCoverSearchFailed": "Hledání obálky se nezdařilo",
|
||||||
"ToastCoverUpdateFailed": "Aktualizace obálky selhala",
|
"ToastCoverUpdateFailed": "Aktualizace obálky selhala",
|
||||||
"ToastDateTimeInvalidOrIncomplete": "Datum a čas jsou chybné nebo nekompletní",
|
"ToastDateTimeInvalidOrIncomplete": "Datum a čas jsou chybné nebo nekompletní",
|
||||||
"ToastDeleteFileFailed": "Nepodařilo se smazat soubor",
|
"ToastDeleteFileFailed": "Nepodařilo se smazat soubor",
|
||||||
@@ -995,12 +1041,14 @@
|
|||||||
"ToastDeviceTestEmailFailed": "Odeslání testovacího emailu selhalo",
|
"ToastDeviceTestEmailFailed": "Odeslání testovacího emailu selhalo",
|
||||||
"ToastDeviceTestEmailSuccess": "Testovací email byl odeslán",
|
"ToastDeviceTestEmailSuccess": "Testovací email byl odeslán",
|
||||||
"ToastEmailSettingsUpdateSuccess": "Nastavení emailu aktualizována",
|
"ToastEmailSettingsUpdateSuccess": "Nastavení emailu aktualizována",
|
||||||
"ToastEncodeCancelFailed": "Chyba zrušení kódování",
|
"ToastEncodeCancelFailed": "Zrušení encodování selhalo",
|
||||||
"ToastEncodeCancelSucces": "Kódování zrušeno",
|
"ToastEncodeCancelSucces": "Kódování zrušeno",
|
||||||
"ToastEpisodeDownloadQueueClearFailed": "Vyčištění fronty selhalo",
|
"ToastEpisodeDownloadQueueClearFailed": "Vyčištění fronty selhalo",
|
||||||
"ToastEpisodeDownloadQueueClearSuccess": "Fronta stahování epizod je prázdná",
|
"ToastEpisodeDownloadQueueClearSuccess": "Fronta stahování epizod je prázdná",
|
||||||
"ToastEpisodeUpdateSuccess": "{0} epizod aktualizováno",
|
"ToastEpisodeUpdateSuccess": "{0} epizod aktualizováno",
|
||||||
"ToastErrorCannotShare": "Na tomto zařízení nelze nativně sdílet",
|
"ToastErrorCannotShare": "Na tomto zařízení nelze nativně sdílet",
|
||||||
|
"ToastFailedToCreate": "Nepodařilo se vytvořit",
|
||||||
|
"ToastFailedToDelete": "Nepodařilo se odstranit",
|
||||||
"ToastFailedToLoadData": "Nepodařilo se načíst data",
|
"ToastFailedToLoadData": "Nepodařilo se načíst data",
|
||||||
"ToastFailedToMatch": "Nepodařilo se spárovat",
|
"ToastFailedToMatch": "Nepodařilo se spárovat",
|
||||||
"ToastFailedToShare": "Sdílení selhalo",
|
"ToastFailedToShare": "Sdílení selhalo",
|
||||||
@@ -1008,6 +1056,7 @@
|
|||||||
"ToastInvalidImageUrl": "Neplatná URL obrázku",
|
"ToastInvalidImageUrl": "Neplatná URL obrázku",
|
||||||
"ToastInvalidMaxEpisodesToDownload": "Neplatný maximální počet epizod ke stažení",
|
"ToastInvalidMaxEpisodesToDownload": "Neplatný maximální počet epizod ke stažení",
|
||||||
"ToastInvalidUrl": "Neplatná URL",
|
"ToastInvalidUrl": "Neplatná URL",
|
||||||
|
"ToastInvalidUrls": "Alespoň jedna URL je neplatná",
|
||||||
"ToastItemCoverUpdateSuccess": "Obálka předmětu byl aktualizována",
|
"ToastItemCoverUpdateSuccess": "Obálka předmětu byl aktualizována",
|
||||||
"ToastItemDeletedFailed": "Smazání položky selhalo",
|
"ToastItemDeletedFailed": "Smazání položky selhalo",
|
||||||
"ToastItemDeletedSuccess": "Položka smazána",
|
"ToastItemDeletedSuccess": "Položka smazána",
|
||||||
@@ -1032,6 +1081,7 @@
|
|||||||
"ToastMustHaveAtLeastOnePath": "Musí mít minimálně jednu cestu",
|
"ToastMustHaveAtLeastOnePath": "Musí mít minimálně jednu cestu",
|
||||||
"ToastNameEmailRequired": "Jméno a email jsou vyžadovány",
|
"ToastNameEmailRequired": "Jméno a email jsou vyžadovány",
|
||||||
"ToastNameRequired": "Jméno je vyžadováno",
|
"ToastNameRequired": "Jméno je vyžadováno",
|
||||||
|
"ToastNewApiKeyUserError": "Je nutné vybrat uživatele",
|
||||||
"ToastNewEpisodesFound": "{0} nových epizod bylo nalezeno",
|
"ToastNewEpisodesFound": "{0} nových epizod bylo nalezeno",
|
||||||
"ToastNewUserCreatedFailed": "Chyba při vytváření účtu: \"{0}\"",
|
"ToastNewUserCreatedFailed": "Chyba při vytváření účtu: \"{0}\"",
|
||||||
"ToastNewUserCreatedSuccess": "Vytvořen nový účet",
|
"ToastNewUserCreatedSuccess": "Vytvořen nový účet",
|
||||||
@@ -1056,6 +1106,7 @@
|
|||||||
"ToastPlaylistUpdateSuccess": "Seznam přehrávání aktualizován",
|
"ToastPlaylistUpdateSuccess": "Seznam přehrávání aktualizován",
|
||||||
"ToastPodcastCreateFailed": "Vytvoření podcastu se nezdařilo",
|
"ToastPodcastCreateFailed": "Vytvoření podcastu se nezdařilo",
|
||||||
"ToastPodcastCreateSuccess": "Podcast byl úspěšně vytvořen",
|
"ToastPodcastCreateSuccess": "Podcast byl úspěšně vytvořen",
|
||||||
|
"ToastPodcastEpisodeUpdated": "Epizoda aktualizována",
|
||||||
"ToastPodcastGetFeedFailed": "Chyba při získání podcastového feedu",
|
"ToastPodcastGetFeedFailed": "Chyba při získání podcastového feedu",
|
||||||
"ToastPodcastNoEpisodesInFeed": "Žádné epizody nenalezeny v RSS feedu",
|
"ToastPodcastNoEpisodesInFeed": "Žádné epizody nenalezeny v RSS feedu",
|
||||||
"ToastPodcastNoRssFeed": "Podcast nemá RSS feed",
|
"ToastPodcastNoRssFeed": "Podcast nemá RSS feed",
|
||||||
@@ -1084,12 +1135,12 @@
|
|||||||
"ToastSeriesUpdateFailed": "Aktualizace série se nezdařila",
|
"ToastSeriesUpdateFailed": "Aktualizace série se nezdařila",
|
||||||
"ToastSeriesUpdateSuccess": "Aktualizace série byla úspěšná",
|
"ToastSeriesUpdateSuccess": "Aktualizace série byla úspěšná",
|
||||||
"ToastServerSettingsUpdateSuccess": "Nastavení serveru aktualizováno",
|
"ToastServerSettingsUpdateSuccess": "Nastavení serveru aktualizováno",
|
||||||
"ToastSessionCloseFailed": "Chyba při ukončení",
|
"ToastSessionCloseFailed": "Nepodařilo se ukončit relaci",
|
||||||
"ToastSessionDeleteFailed": "Nepodařilo se smazat relaci",
|
"ToastSessionDeleteFailed": "Nepodařilo se smazat relaci",
|
||||||
"ToastSessionDeleteSuccess": "Relace smazána",
|
"ToastSessionDeleteSuccess": "Relace smazána",
|
||||||
"ToastSleepTimerDone": "Uspání knížky ... zZzzZz",
|
"ToastSleepTimerDone": "Uspání knížky ... zZzzZz",
|
||||||
"ToastSlugMustChange": "Slug (URL) obsahuje chybné znaky",
|
"ToastSlugMustChange": "Slug obsahuje chybné znaky",
|
||||||
"ToastSlugRequired": "Slug (URL) je vyžadována",
|
"ToastSlugRequired": "Slug (URL) je vyžadován",
|
||||||
"ToastSocketConnected": "Socket připojen",
|
"ToastSocketConnected": "Socket připojen",
|
||||||
"ToastSocketDisconnected": "Socket odpojen",
|
"ToastSocketDisconnected": "Socket odpojen",
|
||||||
"ToastSocketFailedToConnect": "Socket se nepodařilo připojit",
|
"ToastSocketFailedToConnect": "Socket se nepodařilo připojit",
|
||||||
@@ -1106,5 +1157,13 @@
|
|||||||
"ToastUserPasswordChangeSuccess": "Heslo bylo změněno úspěšně",
|
"ToastUserPasswordChangeSuccess": "Heslo bylo změněno úspěšně",
|
||||||
"ToastUserPasswordMismatch": "Hesla se neschodují",
|
"ToastUserPasswordMismatch": "Hesla se neschodují",
|
||||||
"ToastUserPasswordMustChange": "Nové heslo se musí lišit od předchozího",
|
"ToastUserPasswordMustChange": "Nové heslo se musí lišit od předchozího",
|
||||||
"ToastUserRootRequireName": "Musíte zadat uživatelské jméno root"
|
"ToastUserRootRequireName": "Musíte zadat uživatelské jméno root",
|
||||||
|
"TooltipAddChapters": "Přidat kapitolu/y",
|
||||||
|
"TooltipAddOneSecond": "Přidat 1 sekundu",
|
||||||
|
"TooltipAdjustChapterStart": "Kliknutím upravte začátek",
|
||||||
|
"TooltipLockAllChapters": "Uzamknout všechny kapitoly",
|
||||||
|
"TooltipLockChapter": "Uzamknout kapitolu (Shift+klik pro rozsah)",
|
||||||
|
"TooltipSubtractOneSecond": "Odečíst 1 sekundu",
|
||||||
|
"TooltipUnlockAllChapters": "Odemknout všechny kapitoly",
|
||||||
|
"TooltipUnlockChapter": "Odemknout kapitolu (Shift+klik pro rozsah)"
|
||||||
}
|
}
|
||||||
+327
-269
File diff suppressed because it is too large.
Load diff
+61
-22
@@ -13,9 +13,9 @@
|
|||||||
"ButtonBack": "Zurück",
|
"ButtonBack": "Zurück",
|
||||||
"ButtonBatchEditPopulateFromExisting": "Auffüllen aus vorhandenem",
|
"ButtonBatchEditPopulateFromExisting": "Auffüllen aus vorhandenem",
|
||||||
"ButtonBatchEditPopulateMapDetails": "Kartendetails auffüllen",
|
"ButtonBatchEditPopulateMapDetails": "Kartendetails auffüllen",
|
||||||
"ButtonBrowseForFolder": "Ordnersuche",
|
"ButtonBrowseForFolder": "Ordner auswählen",
|
||||||
"ButtonCancel": "Abbrechen",
|
"ButtonCancel": "Abbrechen",
|
||||||
"ButtonCancelEncode": "Codierung abbrechen",
|
"ButtonCancelEncode": "Konvertierung abbrechen",
|
||||||
"ButtonChangeRootPassword": "Hauptpasswort ändern",
|
"ButtonChangeRootPassword": "Hauptpasswort ändern",
|
||||||
"ButtonCheckAndDownloadNewEpisodes": "Überprüfe & lade neue Episoden herunter",
|
"ButtonCheckAndDownloadNewEpisodes": "Überprüfe & lade neue Episoden herunter",
|
||||||
"ButtonChooseAFolder": "Wähle einen Ordner",
|
"ButtonChooseAFolder": "Wähle einen Ordner",
|
||||||
@@ -46,6 +46,7 @@
|
|||||||
"ButtonLatest": "Neueste",
|
"ButtonLatest": "Neueste",
|
||||||
"ButtonLibrary": "Bibliothek",
|
"ButtonLibrary": "Bibliothek",
|
||||||
"ButtonLogout": "Abmelden",
|
"ButtonLogout": "Abmelden",
|
||||||
|
"ButtonLogoutAllDevices": "Von allen Geräte abmelden",
|
||||||
"ButtonLookup": "Online-Suche",
|
"ButtonLookup": "Online-Suche",
|
||||||
"ButtonManageTracks": "Tracks verwalten",
|
"ButtonManageTracks": "Tracks verwalten",
|
||||||
"ButtonMapChapterTitles": "Kapitelüberschriften zuordnen",
|
"ButtonMapChapterTitles": "Kapitelüberschriften zuordnen",
|
||||||
@@ -55,7 +56,7 @@
|
|||||||
"ButtonNext": "Vor",
|
"ButtonNext": "Vor",
|
||||||
"ButtonNextChapter": "Nächstes Kapitel",
|
"ButtonNextChapter": "Nächstes Kapitel",
|
||||||
"ButtonNextItemInQueue": "Das nächste Element in der Warteschlange",
|
"ButtonNextItemInQueue": "Das nächste Element in der Warteschlange",
|
||||||
"ButtonOk": "Ok",
|
"ButtonOk": "OK",
|
||||||
"ButtonOpenFeed": "Feed öffnen",
|
"ButtonOpenFeed": "Feed öffnen",
|
||||||
"ButtonOpenManager": "Manager öffnen",
|
"ButtonOpenManager": "Manager öffnen",
|
||||||
"ButtonPause": "Pausieren",
|
"ButtonPause": "Pausieren",
|
||||||
@@ -75,7 +76,7 @@
|
|||||||
"ButtonQuickMatch": "Schnellabgleich",
|
"ButtonQuickMatch": "Schnellabgleich",
|
||||||
"ButtonReScan": "Neu scannen",
|
"ButtonReScan": "Neu scannen",
|
||||||
"ButtonRead": "Lesen",
|
"ButtonRead": "Lesen",
|
||||||
"ButtonReadLess": "weniger Anzeigen",
|
"ButtonReadLess": "Weniger Anzeigen",
|
||||||
"ButtonReadMore": "Mehr Anzeigen",
|
"ButtonReadMore": "Mehr Anzeigen",
|
||||||
"ButtonRefresh": "Neu Laden",
|
"ButtonRefresh": "Neu Laden",
|
||||||
"ButtonRemove": "Entfernen",
|
"ButtonRemove": "Entfernen",
|
||||||
@@ -104,7 +105,7 @@
|
|||||||
"ButtonStartM4BEncode": "M4B-Kodierung starten",
|
"ButtonStartM4BEncode": "M4B-Kodierung starten",
|
||||||
"ButtonStartMetadataEmbed": "Metadateneinbettung starten",
|
"ButtonStartMetadataEmbed": "Metadateneinbettung starten",
|
||||||
"ButtonStats": "Statistiken",
|
"ButtonStats": "Statistiken",
|
||||||
"ButtonSubmit": "Ok",
|
"ButtonSubmit": "Absenden",
|
||||||
"ButtonTest": "Test",
|
"ButtonTest": "Test",
|
||||||
"ButtonUnlinkOpenId": "OpenID trennen",
|
"ButtonUnlinkOpenId": "OpenID trennen",
|
||||||
"ButtonUpload": "Hochladen",
|
"ButtonUpload": "Hochladen",
|
||||||
@@ -116,7 +117,7 @@
|
|||||||
"ButtonViewAll": "Alles anzeigen",
|
"ButtonViewAll": "Alles anzeigen",
|
||||||
"ButtonYes": "Ja",
|
"ButtonYes": "Ja",
|
||||||
"ErrorUploadFetchMetadataAPI": "Fehler beim Abrufen der Metadaten",
|
"ErrorUploadFetchMetadataAPI": "Fehler beim Abrufen der Metadaten",
|
||||||
"ErrorUploadFetchMetadataNoResults": "Metadaten konnten nicht abgerufen werden. Versuche den Titel und oder den Autor zu aktualisieren",
|
"ErrorUploadFetchMetadataNoResults": "Metadaten konnten nicht abgerufen werden - versuche den Titel und/oder den Autor zu aktualisieren",
|
||||||
"ErrorUploadLacksTitle": "Es muss ein Titel eingegeben werden",
|
"ErrorUploadLacksTitle": "Es muss ein Titel eingegeben werden",
|
||||||
"HeaderAccount": "Konto",
|
"HeaderAccount": "Konto",
|
||||||
"HeaderAddCustomMetadataProvider": "Benutzerdefinierten Metadatenanbieter hinzufügen",
|
"HeaderAddCustomMetadataProvider": "Benutzerdefinierten Metadatenanbieter hinzufügen",
|
||||||
@@ -127,6 +128,7 @@
|
|||||||
"HeaderAudiobookTools": "Hörbuch-Dateiverwaltungswerkzeuge",
|
"HeaderAudiobookTools": "Hörbuch-Dateiverwaltungswerkzeuge",
|
||||||
"HeaderAuthentication": "Authentifizierung",
|
"HeaderAuthentication": "Authentifizierung",
|
||||||
"HeaderBackups": "Sicherungen",
|
"HeaderBackups": "Sicherungen",
|
||||||
|
"HeaderBulkChapterModal": "Mehrere Kapitel hinzufügen",
|
||||||
"HeaderChangePassword": "Passwort ändern",
|
"HeaderChangePassword": "Passwort ändern",
|
||||||
"HeaderChapters": "Kapitel",
|
"HeaderChapters": "Kapitel",
|
||||||
"HeaderChooseAFolder": "Wähle einen Ordner",
|
"HeaderChooseAFolder": "Wähle einen Ordner",
|
||||||
@@ -137,13 +139,13 @@
|
|||||||
"HeaderCustomMessageOnLogin": "Benutzerdefinierte Nachricht für die Anmeldung",
|
"HeaderCustomMessageOnLogin": "Benutzerdefinierte Nachricht für die Anmeldung",
|
||||||
"HeaderCustomMetadataProviders": "Benutzerdefinierte Metadatenanbieter",
|
"HeaderCustomMetadataProviders": "Benutzerdefinierte Metadatenanbieter",
|
||||||
"HeaderDetails": "Details",
|
"HeaderDetails": "Details",
|
||||||
"HeaderDownloadQueue": "Download Warteschlange",
|
"HeaderDownloadQueue": "Download-Warteschlange",
|
||||||
"HeaderEbookFiles": "E-Buch-Dateien",
|
"HeaderEbookFiles": "Buch-Dateien",
|
||||||
"HeaderEmail": "E-Mail",
|
"HeaderEmail": "E-Mail",
|
||||||
"HeaderEmailSettings": "E-Mail-Einstellungen",
|
"HeaderEmailSettings": "E-Mail-Einstellungen",
|
||||||
"HeaderEpisodes": "Episoden",
|
"HeaderEpisodes": "Episoden",
|
||||||
"HeaderEreaderDevices": "E-Reader Geräte",
|
"HeaderEreaderDevices": "E-Reader Geräte",
|
||||||
"HeaderEreaderSettings": "Einstellungen zum Lesen",
|
"HeaderEreaderSettings": "E-Reader Einstellungen",
|
||||||
"HeaderFiles": "Dateien",
|
"HeaderFiles": "Dateien",
|
||||||
"HeaderFindChapters": "Kapitel suchen",
|
"HeaderFindChapters": "Kapitel suchen",
|
||||||
"HeaderIgnoredFiles": "Ignorierte Dateien",
|
"HeaderIgnoredFiles": "Ignorierte Dateien",
|
||||||
@@ -193,12 +195,14 @@
|
|||||||
"HeaderScheduleEpisodeDownloads": "Automatische Episoden-Downloads planen",
|
"HeaderScheduleEpisodeDownloads": "Automatische Episoden-Downloads planen",
|
||||||
"HeaderScheduleLibraryScans": "Automatische Bibliotheksscans",
|
"HeaderScheduleLibraryScans": "Automatische Bibliotheksscans",
|
||||||
"HeaderSession": "Sitzung",
|
"HeaderSession": "Sitzung",
|
||||||
|
"HeaderSessions": "Sitzungen",
|
||||||
"HeaderSetBackupSchedule": "Zeitplan für die Datensicherung festlegen",
|
"HeaderSetBackupSchedule": "Zeitplan für die Datensicherung festlegen",
|
||||||
"HeaderSettings": "Einstellungen",
|
"HeaderSettings": "Einstellungen",
|
||||||
"HeaderSettingsDisplay": "Anzeige",
|
"HeaderSettingsDisplay": "Anzeige",
|
||||||
"HeaderSettingsExperimental": "Experimentelle Funktionen",
|
"HeaderSettingsExperimental": "Experimentelle Funktionen",
|
||||||
"HeaderSettingsGeneral": "Allgemein",
|
"HeaderSettingsGeneral": "Allgemein",
|
||||||
"HeaderSettingsScanner": "Scanner",
|
"HeaderSettingsScanner": "Scanner",
|
||||||
|
"HeaderSettingsSecurity": "Sicherheit",
|
||||||
"HeaderSettingsWebClient": "Web-Client",
|
"HeaderSettingsWebClient": "Web-Client",
|
||||||
"HeaderSleepTimer": "Sleep-Timer",
|
"HeaderSleepTimer": "Sleep-Timer",
|
||||||
"HeaderStatsLargestItems": "Größte Medien",
|
"HeaderStatsLargestItems": "Größte Medien",
|
||||||
@@ -293,6 +297,7 @@
|
|||||||
"LabelContinueListening": "Weiterhören",
|
"LabelContinueListening": "Weiterhören",
|
||||||
"LabelContinueReading": "Weiterlesen",
|
"LabelContinueReading": "Weiterlesen",
|
||||||
"LabelContinueSeries": "Serien fortsetzen",
|
"LabelContinueSeries": "Serien fortsetzen",
|
||||||
|
"LabelCorsAllowed": "Erlaubte CORS Quellen",
|
||||||
"LabelCover": "Titelbild",
|
"LabelCover": "Titelbild",
|
||||||
"LabelCoverImageURL": "URL des Titelbildes",
|
"LabelCoverImageURL": "URL des Titelbildes",
|
||||||
"LabelCoverProvider": "Titelbildanbieter",
|
"LabelCoverProvider": "Titelbildanbieter",
|
||||||
@@ -306,6 +311,7 @@
|
|||||||
"LabelDeleteFromFileSystemCheckbox": "Löschen von der Festplatte + Datenbank (deaktivieren um nur aus der Datenbank zu entfernen)",
|
"LabelDeleteFromFileSystemCheckbox": "Löschen von der Festplatte + Datenbank (deaktivieren um nur aus der Datenbank zu entfernen)",
|
||||||
"LabelDescription": "Beschreibung",
|
"LabelDescription": "Beschreibung",
|
||||||
"LabelDeselectAll": "Alles abwählen",
|
"LabelDeselectAll": "Alles abwählen",
|
||||||
|
"LabelDetectedPattern": "Erkanntes Muster:",
|
||||||
"LabelDevice": "Gerät",
|
"LabelDevice": "Gerät",
|
||||||
"LabelDeviceInfo": "Geräteinformationen",
|
"LabelDeviceInfo": "Geräteinformationen",
|
||||||
"LabelDeviceIsAvailableTo": "Dem Gerät ist es möglich zu ...",
|
"LabelDeviceIsAvailableTo": "Dem Gerät ist es möglich zu ...",
|
||||||
@@ -327,7 +333,7 @@
|
|||||||
"LabelEmail": "E-Mail",
|
"LabelEmail": "E-Mail",
|
||||||
"LabelEmailSettingsFromAddress": "Sender",
|
"LabelEmailSettingsFromAddress": "Sender",
|
||||||
"LabelEmailSettingsRejectUnauthorized": "Nicht autorisierte Zertifikate ablehnen",
|
"LabelEmailSettingsRejectUnauthorized": "Nicht autorisierte Zertifikate ablehnen",
|
||||||
"LabelEmailSettingsRejectUnauthorizedHelp": "Durch das Deaktivieren der SSL-Zertifikatsüberprüfung kann deine Verbindung Sicherheitsrisiken wie Man-in-the-Middle-Angriffen ausgesetzt sein. Deaktiviere diese Option nur, wenn due die Auswirkungen verstehst und dem E-Mail-Server vertraust, mit dem eine Verbindung hergestellt wird.",
|
"LabelEmailSettingsRejectUnauthorizedHelp": "Durch das Deaktivieren der SSL-Zertifikatsüberprüfung kann deine Verbindung Sicherheitsrisiken wie Man-in-the-Middle-Angriffen ausgesetzt sein. Deaktiviere diese Option nur, wenn du die Auswirkungen verstehst und dem E-Mail-Server vertraust, mit dem eine Verbindung hergestellt wird.",
|
||||||
"LabelEmailSettingsSecure": "Sicher",
|
"LabelEmailSettingsSecure": "Sicher",
|
||||||
"LabelEmailSettingsSecureHelp": "Wenn an, verwendet die Verbindung TLS, wenn du eine Verbindung zum Server herstellst. Bei „aus“ wird TLS verwendet, wenn der Server die STARTTLS-Erweiterung unterstützt. In den meisten Fällen solltest du diesen Wert auf „an“ schalten, wenn du eine Verbindung zu Port 465 herstellst. Für Port 587 oder 25 behalte den Wert „aus“ bei. (von nodemailer.com/smtp/#authentication)",
|
"LabelEmailSettingsSecureHelp": "Wenn an, verwendet die Verbindung TLS, wenn du eine Verbindung zum Server herstellst. Bei „aus“ wird TLS verwendet, wenn der Server die STARTTLS-Erweiterung unterstützt. In den meisten Fällen solltest du diesen Wert auf „an“ schalten, wenn du eine Verbindung zu Port 465 herstellst. Für Port 587 oder 25 behalte den Wert „aus“ bei. (von nodemailer.com/smtp/#authentication)",
|
||||||
"LabelEmailSettingsTestAddress": "Test-Adresse",
|
"LabelEmailSettingsTestAddress": "Test-Adresse",
|
||||||
@@ -374,6 +380,7 @@
|
|||||||
"LabelFilterByUser": "Nach Benutzern filtern",
|
"LabelFilterByUser": "Nach Benutzern filtern",
|
||||||
"LabelFindEpisodes": "Episoden suchen",
|
"LabelFindEpisodes": "Episoden suchen",
|
||||||
"LabelFinished": "Beendet",
|
"LabelFinished": "Beendet",
|
||||||
|
"LabelFinishedDate": "Beendet {0}",
|
||||||
"LabelFolder": "Ordner",
|
"LabelFolder": "Ordner",
|
||||||
"LabelFolders": "Verzeichnisse",
|
"LabelFolders": "Verzeichnisse",
|
||||||
"LabelFontBold": "Fett",
|
"LabelFontBold": "Fett",
|
||||||
@@ -410,6 +417,7 @@
|
|||||||
"LabelIntervalEveryHour": "Jede Stunde",
|
"LabelIntervalEveryHour": "Jede Stunde",
|
||||||
"LabelIntervalEveryMinute": "Jede Minute",
|
"LabelIntervalEveryMinute": "Jede Minute",
|
||||||
"LabelInvert": "Umkehren",
|
"LabelInvert": "Umkehren",
|
||||||
|
"LabelIpAddress": "IP-Adresse",
|
||||||
"LabelItem": "Medium",
|
"LabelItem": "Medium",
|
||||||
"LabelJumpBackwardAmount": "Zurückspringen Zeit",
|
"LabelJumpBackwardAmount": "Zurückspringen Zeit",
|
||||||
"LabelJumpForwardAmount": "Vorwärtsspringen Zeit",
|
"LabelJumpForwardAmount": "Vorwärtsspringen Zeit",
|
||||||
@@ -418,6 +426,7 @@
|
|||||||
"LabelLanguages": "Sprachen",
|
"LabelLanguages": "Sprachen",
|
||||||
"LabelLastBookAdded": "Zuletzt hinzugefügtes Buch",
|
"LabelLastBookAdded": "Zuletzt hinzugefügtes Buch",
|
||||||
"LabelLastBookUpdated": "Zuletzt aktualisiertes Buch",
|
"LabelLastBookUpdated": "Zuletzt aktualisiertes Buch",
|
||||||
|
"LabelLastProgressDate": "Letzter Fortschritt: {0}",
|
||||||
"LabelLastSeen": "Zuletzt gesehen",
|
"LabelLastSeen": "Zuletzt gesehen",
|
||||||
"LabelLastTime": "Letztes Mal",
|
"LabelLastTime": "Letztes Mal",
|
||||||
"LabelLastUpdate": "Letzte Aktualisierung",
|
"LabelLastUpdate": "Letzte Aktualisierung",
|
||||||
@@ -430,6 +439,9 @@
|
|||||||
"LabelLibraryFilterSublistEmpty": "Keine {0}",
|
"LabelLibraryFilterSublistEmpty": "Keine {0}",
|
||||||
"LabelLibraryItem": "Bibliothekseintrag",
|
"LabelLibraryItem": "Bibliothekseintrag",
|
||||||
"LabelLibraryName": "Bibliotheksname",
|
"LabelLibraryName": "Bibliotheksname",
|
||||||
|
"LabelLibrarySortByProgress": "Fortschritt: Letzte Aktualisierung",
|
||||||
|
"LabelLibrarySortByProgressFinished": "Fortschritt: Beendet",
|
||||||
|
"LabelLibrarySortByProgressStarted": "Fortschritt: Gestartet",
|
||||||
"LabelLimit": "Begrenzung",
|
"LabelLimit": "Begrenzung",
|
||||||
"LabelLineSpacing": "Zeilenabstand",
|
"LabelLineSpacing": "Zeilenabstand",
|
||||||
"LabelListenAgain": "Erneut anhören",
|
"LabelListenAgain": "Erneut anhören",
|
||||||
@@ -438,6 +450,7 @@
|
|||||||
"LabelLogLevelWarn": "Warnungen",
|
"LabelLogLevelWarn": "Warnungen",
|
||||||
"LabelLookForNewEpisodesAfterDate": "Suche nach neuen Episoden nach diesem Datum",
|
"LabelLookForNewEpisodesAfterDate": "Suche nach neuen Episoden nach diesem Datum",
|
||||||
"LabelLowestPriority": "Niedrigste Priorität",
|
"LabelLowestPriority": "Niedrigste Priorität",
|
||||||
|
"LabelMatchConfidence": "Vertrauenswert",
|
||||||
"LabelMatchExistingUsersBy": "Zuordnen existierender Benutzer mit",
|
"LabelMatchExistingUsersBy": "Zuordnen existierender Benutzer mit",
|
||||||
"LabelMatchExistingUsersByDescription": "Wird zum Verbinden vorhandener Benutzer verwendet. Sobald die Verbindung hergestellt ist, wird den Benutzern eine eindeutige ID vom SSO-Anbieter zugeordnet",
|
"LabelMatchExistingUsersByDescription": "Wird zum Verbinden vorhandener Benutzer verwendet. Sobald die Verbindung hergestellt ist, wird den Benutzern eine eindeutige ID vom SSO-Anbieter zugeordnet",
|
||||||
"LabelMaxEpisodesToDownload": "Max. Anzahl an Episoden zum Herunterladen, 0 für unbegrenzte Episoden.",
|
"LabelMaxEpisodesToDownload": "Max. Anzahl an Episoden zum Herunterladen, 0 für unbegrenzte Episoden.",
|
||||||
@@ -446,7 +459,7 @@
|
|||||||
"LabelMaxEpisodesToKeepHelp": "0 setzt keine Begrenzung. Wenn eine neue Episode automatisch heruntergeladen wird, wird die älteste Episode gelöscht, wenn du mehr als X Episoden gespeichert hast. Es wird nur eine Episode pro neuem Download gelöscht.",
|
"LabelMaxEpisodesToKeepHelp": "0 setzt keine Begrenzung. Wenn eine neue Episode automatisch heruntergeladen wird, wird die älteste Episode gelöscht, wenn du mehr als X Episoden gespeichert hast. Es wird nur eine Episode pro neuem Download gelöscht.",
|
||||||
"LabelMediaPlayer": "Mediaplayer",
|
"LabelMediaPlayer": "Mediaplayer",
|
||||||
"LabelMediaType": "Medientyp",
|
"LabelMediaType": "Medientyp",
|
||||||
"LabelMetaTag": "Meta Schlagwort",
|
"LabelMetaTag": "Meta Tag",
|
||||||
"LabelMetaTags": "Meta Tags",
|
"LabelMetaTags": "Meta Tags",
|
||||||
"LabelMetadataOrderOfPrecedenceDescription": "Höher priorisierte Quellen für Metadaten überschreiben Metadaten aus Quellen mit niedrigerer Priorität",
|
"LabelMetadataOrderOfPrecedenceDescription": "Höher priorisierte Quellen für Metadaten überschreiben Metadaten aus Quellen mit niedrigerer Priorität",
|
||||||
"LabelMetadataProvider": "Metadatenanbieter",
|
"LabelMetadataProvider": "Metadatenanbieter",
|
||||||
@@ -467,6 +480,7 @@
|
|||||||
"LabelNewestAuthors": "Neueste Autoren",
|
"LabelNewestAuthors": "Neueste Autoren",
|
||||||
"LabelNewestEpisodes": "Neueste Episoden",
|
"LabelNewestEpisodes": "Neueste Episoden",
|
||||||
"LabelNextBackupDate": "Nächstes Sicherungsdatum",
|
"LabelNextBackupDate": "Nächstes Sicherungsdatum",
|
||||||
|
"LabelNextChapters": "Das nächste Kapitel ist:",
|
||||||
"LabelNextScheduledRun": "Nächster planmäßiger Durchlauf",
|
"LabelNextScheduledRun": "Nächster planmäßiger Durchlauf",
|
||||||
"LabelNoApiKeys": "Keine API-Schlüssel vorhanden",
|
"LabelNoApiKeys": "Keine API-Schlüssel vorhanden",
|
||||||
"LabelNoCustomMetadataProviders": "Keine benutzerdefinierten Metadata Anbieter",
|
"LabelNoCustomMetadataProviders": "Keine benutzerdefinierten Metadata Anbieter",
|
||||||
@@ -484,6 +498,7 @@
|
|||||||
"LabelNotificationsMaxQueueSize": "Maximale Größe der Warteschlange für die Benachrichtigungsereignisse",
|
"LabelNotificationsMaxQueueSize": "Maximale Größe der Warteschlange für die Benachrichtigungsereignisse",
|
||||||
"LabelNotificationsMaxQueueSizeHelp": "Es wird nur 1 Ereignis pro Sekunde ausgelöst. Ereignisse werden ignoriert, wenn die Warteschlange die maximale Größe erreicht hat. Dies verhindert Benachrichtigungsspamming.",
|
"LabelNotificationsMaxQueueSizeHelp": "Es wird nur 1 Ereignis pro Sekunde ausgelöst. Ereignisse werden ignoriert, wenn die Warteschlange die maximale Größe erreicht hat. Dies verhindert Benachrichtigungsspamming.",
|
||||||
"LabelNumberOfBooks": "Anzahl der Hörbücher",
|
"LabelNumberOfBooks": "Anzahl der Hörbücher",
|
||||||
|
"LabelNumberOfChapters": "Anzahl an Kapiteln:",
|
||||||
"LabelNumberOfEpisodes": "Anzahl der Episoden",
|
"LabelNumberOfEpisodes": "Anzahl der Episoden",
|
||||||
"LabelOpenIDAdvancedPermsClaimDescription": "Name des OpenID-Claims, der erweiterte Berechtigungen für Benutzeraktionen innerhalb der Anwendung enthält, die auf Nicht-Admin-Rollen angewendet werden (<b>wenn konfiguriert</b>). Wenn der Claim in der Antwort fehlt, wird der Zugang zu ABS verweigert. Fehlt eine einzelne Option, wird sie als <code>false</code> behandelt. Stelle sicher, dass der Claim des Identitätsanbieters der erwarteten Struktur entspricht:",
|
"LabelOpenIDAdvancedPermsClaimDescription": "Name des OpenID-Claims, der erweiterte Berechtigungen für Benutzeraktionen innerhalb der Anwendung enthält, die auf Nicht-Admin-Rollen angewendet werden (<b>wenn konfiguriert</b>). Wenn der Claim in der Antwort fehlt, wird der Zugang zu ABS verweigert. Fehlt eine einzelne Option, wird sie als <code>false</code> behandelt. Stelle sicher, dass der Claim des Identitätsanbieters der erwarteten Struktur entspricht:",
|
||||||
"LabelOpenIDClaims": "Lass die folgenden Optionen leer, um die erweiterte Zuweisung von Gruppen und Berechtigungen zu deaktivieren und automatisch die 'User'-Gruppe zuzuweisen.",
|
"LabelOpenIDClaims": "Lass die folgenden Optionen leer, um die erweiterte Zuweisung von Gruppen und Berechtigungen zu deaktivieren und automatisch die 'User'-Gruppe zuzuweisen.",
|
||||||
@@ -528,7 +543,7 @@
|
|||||||
"LabelPublishers": "Herausgeber",
|
"LabelPublishers": "Herausgeber",
|
||||||
"LabelRSSFeedCustomOwnerEmail": "Benutzerdefinierte Eigentümer-E-Mail",
|
"LabelRSSFeedCustomOwnerEmail": "Benutzerdefinierte Eigentümer-E-Mail",
|
||||||
"LabelRSSFeedCustomOwnerName": "Benutzerdefinierter Name des Eigentümers",
|
"LabelRSSFeedCustomOwnerName": "Benutzerdefinierter Name des Eigentümers",
|
||||||
"LabelRSSFeedOpen": "RSS Feed offen",
|
"LabelRSSFeedOpen": "RSS-Feed offen",
|
||||||
"LabelRSSFeedPreventIndexing": "Indizierung verhindern",
|
"LabelRSSFeedPreventIndexing": "Indizierung verhindern",
|
||||||
"LabelRSSFeedSlug": "RSS-Feed-Schlagwort",
|
"LabelRSSFeedSlug": "RSS-Feed-Schlagwort",
|
||||||
"LabelRSSFeedURL": "RSS-Feed-URL",
|
"LabelRSSFeedURL": "RSS-Feed-URL",
|
||||||
@@ -576,8 +591,8 @@
|
|||||||
"LabelSettingsBookshelfViewHelp": "Skeumorphes Design mit Holzeinlegeböden",
|
"LabelSettingsBookshelfViewHelp": "Skeumorphes Design mit Holzeinlegeböden",
|
||||||
"LabelSettingsChromecastSupport": "Chromecastunterstützung",
|
"LabelSettingsChromecastSupport": "Chromecastunterstützung",
|
||||||
"LabelSettingsDateFormat": "Datumsformat",
|
"LabelSettingsDateFormat": "Datumsformat",
|
||||||
"LabelSettingsEnableWatcher": "Bibliotheken automatisch nach Änderungen durchsuchen",
|
"LabelSettingsEnableWatcher": "Bibliotheken automatisch nach Änderungen überwachen",
|
||||||
"LabelSettingsEnableWatcherForLibrary": "Bibliothek automatisch nach Änderungen durchsuchen",
|
"LabelSettingsEnableWatcherForLibrary": "Bibliothek automatisch auf Änderungen überwachen",
|
||||||
"LabelSettingsEnableWatcherHelp": "Aktiviert das automatische Hinzufügen/Aktualisieren von Elementen, wenn Dateiänderungen erkannt werden. *Erfordert einen Server-Neustart",
|
"LabelSettingsEnableWatcherHelp": "Aktiviert das automatische Hinzufügen/Aktualisieren von Elementen, wenn Dateiänderungen erkannt werden. *Erfordert einen Server-Neustart",
|
||||||
"LabelSettingsEpubsAllowScriptedContent": "Skriptinhalte in Epubs zulassen",
|
"LabelSettingsEpubsAllowScriptedContent": "Skriptinhalte in Epubs zulassen",
|
||||||
"LabelSettingsEpubsAllowScriptedContentHelp": "Erlaube Epub-Dateien, Skripte auszuführen. Es wird empfohlen, diese Einstellung deaktiviert zu lassen, es sei denn, du vertraust der Quelle der Epub-Dateien.",
|
"LabelSettingsEpubsAllowScriptedContentHelp": "Erlaube Epub-Dateien, Skripte auszuführen. Es wird empfohlen, diese Einstellung deaktiviert zu lassen, es sei denn, du vertraust der Quelle der Epub-Dateien.",
|
||||||
@@ -610,7 +625,7 @@
|
|||||||
"LabelSettingsStoreMetadataWithItemHelp": "Standardmäßig werden die Metadaten in /metadata/items gespeichert. Wenn diese Option aktiviert ist, werden die Metadaten als OPF-Datei (Textdatei) in dem gleichen Ordner gespeichert in welchem sich auch das Medium befindet",
|
"LabelSettingsStoreMetadataWithItemHelp": "Standardmäßig werden die Metadaten in /metadata/items gespeichert. Wenn diese Option aktiviert ist, werden die Metadaten als OPF-Datei (Textdatei) in dem gleichen Ordner gespeichert in welchem sich auch das Medium befindet",
|
||||||
"LabelSettingsTimeFormat": "Zeitformat",
|
"LabelSettingsTimeFormat": "Zeitformat",
|
||||||
"LabelShare": "Freigeben",
|
"LabelShare": "Freigeben",
|
||||||
"LabelShareDownloadableHelp": "Erlaubt es einem Nutzer, mit dem Link, die Dateien des Mediums als ZIP herunterzuladen.",
|
"LabelShareDownloadableHelp": "Erlaubt es einem Nutzer, mit dem Link die Dateien des Mediums als ZIP herunterzuladen.",
|
||||||
"LabelShareOpen": "Freigeben",
|
"LabelShareOpen": "Freigeben",
|
||||||
"LabelShareURL": "Freigabe URL",
|
"LabelShareURL": "Freigabe URL",
|
||||||
"LabelShowAll": "Alles anzeigen",
|
"LabelShowAll": "Alles anzeigen",
|
||||||
@@ -626,6 +641,7 @@
|
|||||||
"LabelStartTime": "Startzeit",
|
"LabelStartTime": "Startzeit",
|
||||||
"LabelStarted": "Gestartet",
|
"LabelStarted": "Gestartet",
|
||||||
"LabelStartedAt": "Gestartet am",
|
"LabelStartedAt": "Gestartet am",
|
||||||
|
"LabelStartedDate": "Angefangen am {0}",
|
||||||
"LabelStatsAudioTracks": "Audiodateien",
|
"LabelStatsAudioTracks": "Audiodateien",
|
||||||
"LabelStatsAuthors": "Autoren",
|
"LabelStatsAuthors": "Autoren",
|
||||||
"LabelStatsBestDay": "Bester Tag",
|
"LabelStatsBestDay": "Bester Tag",
|
||||||
@@ -655,6 +671,7 @@
|
|||||||
"LabelTheme": "Farbschema",
|
"LabelTheme": "Farbschema",
|
||||||
"LabelThemeDark": "Dunkel",
|
"LabelThemeDark": "Dunkel",
|
||||||
"LabelThemeLight": "Hell",
|
"LabelThemeLight": "Hell",
|
||||||
|
"LabelThemeSepia": "Sepia",
|
||||||
"LabelTimeBase": "Basiszeit",
|
"LabelTimeBase": "Basiszeit",
|
||||||
"LabelTimeDurationXHours": "{0} Stunden",
|
"LabelTimeDurationXHours": "{0} Stunden",
|
||||||
"LabelTimeDurationXMinutes": "{0} Minuten",
|
"LabelTimeDurationXMinutes": "{0} Minuten",
|
||||||
@@ -696,7 +713,7 @@
|
|||||||
"LabelUploaderDragAndDropFilesOnly": "Dateien per Drag & Drop hierher ziehen",
|
"LabelUploaderDragAndDropFilesOnly": "Dateien per Drag & Drop hierher ziehen",
|
||||||
"LabelUploaderDropFiles": "Dateien löschen",
|
"LabelUploaderDropFiles": "Dateien löschen",
|
||||||
"LabelUploaderItemFetchMetadataHelp": "Automatisches Aktualisieren von Titel, Autor und Serie",
|
"LabelUploaderItemFetchMetadataHelp": "Automatisches Aktualisieren von Titel, Autor und Serie",
|
||||||
"LabelUseAdvancedOptions": "Nutze Erweiterte Optionen",
|
"LabelUseAdvancedOptions": "Erweiterte Optionen verwenden",
|
||||||
"LabelUseChapterTrack": "Kapiteldatei verwenden",
|
"LabelUseChapterTrack": "Kapiteldatei verwenden",
|
||||||
"LabelUseFullTrack": "Gesamte Datei verwenden",
|
"LabelUseFullTrack": "Gesamte Datei verwenden",
|
||||||
"LabelUseZeroForUnlimited": "0 für unbegrenzt",
|
"LabelUseZeroForUnlimited": "0 für unbegrenzt",
|
||||||
@@ -722,7 +739,8 @@
|
|||||||
"LabelYourProgress": "Fortschritt",
|
"LabelYourProgress": "Fortschritt",
|
||||||
"MessageAddToPlayerQueue": "Zur Abspielwarteliste hinzufügen",
|
"MessageAddToPlayerQueue": "Zur Abspielwarteliste hinzufügen",
|
||||||
"MessageAppriseDescription": "Um diese Funktion nutzen zu können, musst du eine Instanz von <a href=\"https://github.com/caronc/apprise-api\" target=\"_blank\">Apprise API</a> laufen haben oder eine API verwenden welche dieselbe Anfragen bearbeiten kann. <br />Die Apprise API Url muss der vollständige URL-Pfad sein, an den die Benachrichtigung gesendet werden soll, z.B. wenn Ihre API-Instanz unter <code>http://192.168.1.1:8337</code> läuft, würdest du <code>http://192.168.1.1:8337/notify</code> eingeben.",
|
"MessageAppriseDescription": "Um diese Funktion nutzen zu können, musst du eine Instanz von <a href=\"https://github.com/caronc/apprise-api\" target=\"_blank\">Apprise API</a> laufen haben oder eine API verwenden welche dieselbe Anfragen bearbeiten kann. <br />Die Apprise API Url muss der vollständige URL-Pfad sein, an den die Benachrichtigung gesendet werden soll, z.B. wenn Ihre API-Instanz unter <code>http://192.168.1.1:8337</code> läuft, würdest du <code>http://192.168.1.1:8337/notify</code> eingeben.",
|
||||||
"MessageAsinCheck": "Stellen Sie sicher, dass Sie die ASIN aus der richtigen Audible Region verwenden, nicht Amazon.",
|
"MessageAsinCheck": "Stelle sicher, dass die ASIN aus der richtigen Audible Region verwendet wird, nicht Amazon.",
|
||||||
|
"MessageAuthenticationLegacyTokenWarning": "Nicht mehr unterstützte API tokens werden in der Zukunft entfernt. Nutze stattdessen <a href=\"/config/api-keys\">API Schlüssel</a>.",
|
||||||
"MessageAuthenticationOIDCChangesRestart": "Nach dem Speichern muss der Server neugestartet werden um die OIDC Änderungen zu übernehmen.",
|
"MessageAuthenticationOIDCChangesRestart": "Nach dem Speichern muss der Server neugestartet werden um die OIDC Änderungen zu übernehmen.",
|
||||||
"MessageAuthenticationSecurityMessage": "Die Anmeldung wurde abgesichert. Benutzersitzungen werden getrennt, alle Benutzer müssen sich erneut anmelden.",
|
"MessageAuthenticationSecurityMessage": "Die Anmeldung wurde abgesichert. Benutzersitzungen werden getrennt, alle Benutzer müssen sich erneut anmelden.",
|
||||||
"MessageBackupsDescription": "In einer Sicherung werden Benutzer, Benutzerfortschritte, Details zu den Bibliotheksobjekten, Servereinstellungen und Bilder welche in <code>/metadata/items</code> & <code>/metadata/authors</code> gespeichert sind gespeichert. Sicherungen enthalten keine Dateien welche in den einzelnen Bibliotheksordnern (Medien-Ordnern) gespeichert sind.",
|
"MessageBackupsDescription": "In einer Sicherung werden Benutzer, Benutzerfortschritte, Details zu den Bibliotheksobjekten, Servereinstellungen und Bilder welche in <code>/metadata/items</code> & <code>/metadata/authors</code> gespeichert sind gespeichert. Sicherungen enthalten keine Dateien welche in den einzelnen Bibliotheksordnern (Medien-Ordnern) gespeichert sind.",
|
||||||
@@ -738,6 +756,7 @@
|
|||||||
"MessageBookshelfNoResultsForFilter": "Keine Ergebnisse für Filter \"{0}: {1}\"",
|
"MessageBookshelfNoResultsForFilter": "Keine Ergebnisse für Filter \"{0}: {1}\"",
|
||||||
"MessageBookshelfNoResultsForQuery": "Keine Ergebnisse für die Abfrage",
|
"MessageBookshelfNoResultsForQuery": "Keine Ergebnisse für die Abfrage",
|
||||||
"MessageBookshelfNoSeries": "Keine Serien vorhanden",
|
"MessageBookshelfNoSeries": "Keine Serien vorhanden",
|
||||||
|
"MessageBulkChapterPattern": "Wie viele Kapitel mit diesem Nummerierungs-Muster sollen hinzugefügt werden?",
|
||||||
"MessageChapterEndIsAfter": "Ungültige Kapitelendzeit: Kapitelende > Mediumende (Kapitelende liegt nach dem Ende des Mediums)",
|
"MessageChapterEndIsAfter": "Ungültige Kapitelendzeit: Kapitelende > Mediumende (Kapitelende liegt nach dem Ende des Mediums)",
|
||||||
"MessageChapterErrorFirstNotZero": "Ungültige Kapitelstartzeit: Das erste Kapitel muss bei 0 beginnen",
|
"MessageChapterErrorFirstNotZero": "Ungültige Kapitelstartzeit: Das erste Kapitel muss bei 0 beginnen",
|
||||||
"MessageChapterErrorStartGteDuration": "Ungültige Kapitelstartzeit: Kapitelanfang > Mediumlänge (Kapitelanfang liegt zeitlich nach dem Ende des Mediums -> Lösung: Kapitelanfang < Mediumlänge)",
|
"MessageChapterErrorStartGteDuration": "Ungültige Kapitelstartzeit: Kapitelanfang > Mediumlänge (Kapitelanfang liegt zeitlich nach dem Ende des Mediums -> Lösung: Kapitelanfang < Mediumlänge)",
|
||||||
@@ -758,6 +777,7 @@
|
|||||||
"MessageConfirmDeleteSession": "Sitzung wird gelöscht! Bist du dir sicher?",
|
"MessageConfirmDeleteSession": "Sitzung wird gelöscht! Bist du dir sicher?",
|
||||||
"MessageConfirmEmbedMetadataInAudioFiles": "Bist du dir sicher, dass die Metadaten in {0} Audiodateien eingebettet werden sollen?",
|
"MessageConfirmEmbedMetadataInAudioFiles": "Bist du dir sicher, dass die Metadaten in {0} Audiodateien eingebettet werden sollen?",
|
||||||
"MessageConfirmForceReScan": "Scanvorgang erzwingen! Bist du dir sicher?",
|
"MessageConfirmForceReScan": "Scanvorgang erzwingen! Bist du dir sicher?",
|
||||||
|
"MessageConfirmLogoutDevice": "Bist du sicher, dass du dich von \"{0}\" abmelden willst?",
|
||||||
"MessageConfirmMarkAllEpisodesFinished": "Alle Episoden werden als abgeschlossen markiert! Bist du dir sicher?",
|
"MessageConfirmMarkAllEpisodesFinished": "Alle Episoden werden als abgeschlossen markiert! Bist du dir sicher?",
|
||||||
"MessageConfirmMarkAllEpisodesNotFinished": "Alle Episoden werden als nicht abgeschlossen markiert! Bist du dir sicher?",
|
"MessageConfirmMarkAllEpisodesNotFinished": "Alle Episoden werden als nicht abgeschlossen markiert! Bist du dir sicher?",
|
||||||
"MessageConfirmMarkItemFinished": "Möchtest du \"{0}\" wirklich als fertig markieren?",
|
"MessageConfirmMarkItemFinished": "Möchtest du \"{0}\" wirklich als fertig markieren?",
|
||||||
@@ -800,6 +820,8 @@
|
|||||||
"MessageFeedURLWillBe": "Feed-URL wird {0} sein",
|
"MessageFeedURLWillBe": "Feed-URL wird {0} sein",
|
||||||
"MessageFetching": "Wird abgerufen …",
|
"MessageFetching": "Wird abgerufen …",
|
||||||
"MessageForceReScanDescription": "Durchsucht alle Dateien erneut, wie bei einem frischen Scan. ID3-Tags von Audiodateien, OPF-Dateien und Textdateien werden neu durchsucht.",
|
"MessageForceReScanDescription": "Durchsucht alle Dateien erneut, wie bei einem frischen Scan. ID3-Tags von Audiodateien, OPF-Dateien und Textdateien werden neu durchsucht.",
|
||||||
|
"MessageHeatmapListeningTimeTooltip": "<strong>{0} gehört</strong> auf {1}",
|
||||||
|
"MessageHeatmapNoListeningSessions": "Keine Hörsitzungen am {0}",
|
||||||
"MessageImportantNotice": "Wichtiger Hinweis!",
|
"MessageImportantNotice": "Wichtiger Hinweis!",
|
||||||
"MessageInsertChapterBelow": "Kapitel unten einfügen",
|
"MessageInsertChapterBelow": "Kapitel unten einfügen",
|
||||||
"MessageInvalidAsin": "Ungültige ASIN",
|
"MessageInvalidAsin": "Ungültige ASIN",
|
||||||
@@ -870,7 +892,7 @@
|
|||||||
"MessageResetChaptersConfirm": "Kapitel und vorgenommenen Änderungen werden zurückgesetzt und rückgängig gemacht! Bist du dir sicher?",
|
"MessageResetChaptersConfirm": "Kapitel und vorgenommenen Änderungen werden zurückgesetzt und rückgängig gemacht! Bist du dir sicher?",
|
||||||
"MessageRestoreBackupConfirm": "Bist du dir sicher, dass du die Sicherung wiederherstellen willst, welche am",
|
"MessageRestoreBackupConfirm": "Bist du dir sicher, dass du die Sicherung wiederherstellen willst, welche am",
|
||||||
"MessageRestoreBackupWarning": "Bei der Wiederherstellung einer Sicherung wird die gesamte Datenbank unter /config und die Titelbilder in /metadata/items und /metadata/authors überschrieben.<br /><br />Bei der Sicherung werden keine Dateien in deinen Bibliotheksordnern verändert. Wenn du die Servereinstellungen aktiviert hast, um Cover und Metadaten in deinen Bibliotheksordnern zu speichern, werden diese nicht gesichert oder überschrieben.<br /><br />Alle Clients, die Ihren Server nutzen, werden automatisch aktualisiert.",
|
"MessageRestoreBackupWarning": "Bei der Wiederherstellung einer Sicherung wird die gesamte Datenbank unter /config und die Titelbilder in /metadata/items und /metadata/authors überschrieben.<br /><br />Bei der Sicherung werden keine Dateien in deinen Bibliotheksordnern verändert. Wenn du die Servereinstellungen aktiviert hast, um Cover und Metadaten in deinen Bibliotheksordnern zu speichern, werden diese nicht gesichert oder überschrieben.<br /><br />Alle Clients, die Ihren Server nutzen, werden automatisch aktualisiert.",
|
||||||
"MessageScheduleLibraryScanNote": "Für die meisten Anwender wird empfohlen, diese Funktion deaktiviert und die Ordnerüberwachung aktiviert zu lassen. Die Ordnerüberwachung wird Änderungen in den Bibliotheksordnern automatisch erkennen. Die Ordnerüberwachung funktioniert nicht mit allen Dateisystemen (wie NFS), hier kann stattdessen die automatischen Bibliothekssuchen verwendet werden.",
|
"MessageScheduleLibraryScanNote": "Für die meisten Benutzer wird empfohlen, diese Funktion deaktiviert und die Einstellung „Bibliothek automatisch auf Änderungen überwachen“ aktiviert zu lassen – dadurch werden Änderungen in Ihren Bibliotheksordnern automatisch erkannt. Aktivieren Sie diese Funktion, wenn „Bibliothek automatisch auf Änderungen überwachen“ für Ihr Dateisystem (wie NFS) nicht funktioniert.",
|
||||||
"MessageScheduleRunEveryWeekdayAtTime": "Immer {0} um {1} ausführen",
|
"MessageScheduleRunEveryWeekdayAtTime": "Immer {0} um {1} ausführen",
|
||||||
"MessageSearchResultsFor": "Suchergebnisse für",
|
"MessageSearchResultsFor": "Suchergebnisse für",
|
||||||
"MessageSelected": "{0} ausgewählt",
|
"MessageSelected": "{0} ausgewählt",
|
||||||
@@ -939,6 +961,7 @@
|
|||||||
"NotificationOnRSSFeedDisabledDescription": "Wird ausgeführt wenn automatische Downloads von Episoden wegen zu vielen fehlgeschlagenen Versuchen deaktiviert sind",
|
"NotificationOnRSSFeedDisabledDescription": "Wird ausgeführt wenn automatische Downloads von Episoden wegen zu vielen fehlgeschlagenen Versuchen deaktiviert sind",
|
||||||
"NotificationOnRSSFeedFailedDescription": "Wird ausgelöst, wenn die RSS-Feed-Anforderung für einen automatischen Episoden-Download fehlschlägt",
|
"NotificationOnRSSFeedFailedDescription": "Wird ausgelöst, wenn die RSS-Feed-Anforderung für einen automatischen Episoden-Download fehlschlägt",
|
||||||
"NotificationOnTestDescription": "Wird ausgeführt wenn das Benachrichtigungssystem getestet wird",
|
"NotificationOnTestDescription": "Wird ausgeführt wenn das Benachrichtigungssystem getestet wird",
|
||||||
|
"PlaceholderBulkChapterInput": "Kapitelbezeichnung eingeben oder Nummerierung verwenden (z.B. 'Episode 1', 'Kapitel 10', '1.')",
|
||||||
"PlaceholderNewCollection": "Neuer Sammlungsname",
|
"PlaceholderNewCollection": "Neuer Sammlungsname",
|
||||||
"PlaceholderNewFolderPath": "Neuer Ordnerpfad",
|
"PlaceholderNewFolderPath": "Neuer Ordnerpfad",
|
||||||
"PlaceholderNewPlaylist": "Neuer Wiedergabelistenname",
|
"PlaceholderNewPlaylist": "Neuer Wiedergabelistenname",
|
||||||
@@ -992,17 +1015,23 @@
|
|||||||
"ToastBookmarkCreateFailed": "Lesezeichen konnte nicht erstellt werden",
|
"ToastBookmarkCreateFailed": "Lesezeichen konnte nicht erstellt werden",
|
||||||
"ToastBookmarkCreateSuccess": "Lesezeichen hinzugefügt",
|
"ToastBookmarkCreateSuccess": "Lesezeichen hinzugefügt",
|
||||||
"ToastBookmarkRemoveSuccess": "Lesezeichen entfernt",
|
"ToastBookmarkRemoveSuccess": "Lesezeichen entfernt",
|
||||||
|
"ToastBulkChapterInvalidCount": "Gebe eine Zahl zwischen 1 und 150 ein",
|
||||||
"ToastCachePurgeFailed": "Cache leeren fehlgeschlagen",
|
"ToastCachePurgeFailed": "Cache leeren fehlgeschlagen",
|
||||||
"ToastCachePurgeSuccess": "Cache geleert",
|
"ToastCachePurgeSuccess": "Cache geleert",
|
||||||
|
"ToastChapterLocked": "Kapitel ist freigegeben.",
|
||||||
|
"ToastChapterStartTimeAdjusted": "Kapitelbeginn um {0} Sekunden angepasst",
|
||||||
|
"ToastChaptersAllLocked": "Alle Kapitel sind gesperrt. Gebe einige Kapitel frei um die Zeiten anzupassen.",
|
||||||
"ToastChaptersHaveErrors": "Kapitel sind fehlerhaft",
|
"ToastChaptersHaveErrors": "Kapitel sind fehlerhaft",
|
||||||
"ToastChaptersInvalidShiftAmountLast": "Die Verschiebung ist nicht möglich, da die Startzeit des letzten Kapitels über die Gesamtdauer dieses Hörbuchs hinausgehen würde.",
|
"ToastChaptersInvalidShiftAmountLast": "Die Verschiebung ist nicht möglich, da die Startzeit des letzten Kapitels über die Gesamtdauer dieses Hörbuchs hinausgehen würde.",
|
||||||
"ToastChaptersInvalidShiftAmountStart": "Ungültige Höhe der Verschiebung. Das erste Kapitel hätte eine Länge von Null oder eine negative Länge und würde vom zweiten Kapitel überschrieben werden. Erhöhen Sie die Startdauer des zweiten Kapitels.",
|
"ToastChaptersInvalidShiftAmountStart": "Ungültige Höhe der Verschiebung. Das erste Kapitel hätte eine Länge von Null oder eine negative Länge und würde vom zweiten Kapitel überschrieben werden. Erhöhe die Startdauer des zweiten Kapitels.",
|
||||||
"ToastChaptersMustHaveTitles": "Kapitel benötigen eindeutige Namen",
|
"ToastChaptersMustHaveTitles": "Kapitel benötigen eindeutige Namen",
|
||||||
"ToastChaptersRemoved": "Kapitel entfernt",
|
"ToastChaptersRemoved": "Kapitel entfernt",
|
||||||
"ToastChaptersUpdated": "Kapitel aktualisiert",
|
"ToastChaptersUpdated": "Kapitel aktualisiert",
|
||||||
"ToastCollectionItemsAddFailed": "Das Hinzufügen von Element(en) zur Sammlung ist fehlgeschlagen",
|
"ToastCollectionItemsAddFailed": "Das Hinzufügen von Element(en) zur Sammlung ist fehlgeschlagen",
|
||||||
"ToastCollectionRemoveSuccess": "Sammlung entfernt",
|
"ToastCollectionRemoveSuccess": "Sammlung entfernt",
|
||||||
"ToastCollectionUpdateSuccess": "Sammlung aktualisiert",
|
"ToastCollectionUpdateSuccess": "Sammlung aktualisiert",
|
||||||
|
"ToastConnectionNotAvailable": "Verbindung nicht möglich. Bitte später erneut versuchen",
|
||||||
|
"ToastCoverSearchFailed": "Cover-Suche fehlgeschlagen",
|
||||||
"ToastCoverUpdateFailed": "Cover-Update fehlgeschlagen",
|
"ToastCoverUpdateFailed": "Cover-Update fehlgeschlagen",
|
||||||
"ToastDateTimeInvalidOrIncomplete": "Datum und Zeit sind ungültig oder unvollständig",
|
"ToastDateTimeInvalidOrIncomplete": "Datum und Zeit sind ungültig oder unvollständig",
|
||||||
"ToastDeleteFileFailed": "Die Datei konnte nicht gelöscht werden",
|
"ToastDeleteFileFailed": "Die Datei konnte nicht gelöscht werden",
|
||||||
@@ -1027,6 +1056,7 @@
|
|||||||
"ToastInvalidImageUrl": "Ungültiger Bild URL",
|
"ToastInvalidImageUrl": "Ungültiger Bild URL",
|
||||||
"ToastInvalidMaxEpisodesToDownload": "Ungültige Max. Anzahl an Episoden zum Herunterladen",
|
"ToastInvalidMaxEpisodesToDownload": "Ungültige Max. Anzahl an Episoden zum Herunterladen",
|
||||||
"ToastInvalidUrl": "Ungültiger URL",
|
"ToastInvalidUrl": "Ungültiger URL",
|
||||||
|
"ToastInvalidUrls": "Eine oder mehrere URLs sind ungültig",
|
||||||
"ToastItemCoverUpdateSuccess": "Titelbild aktualisiert",
|
"ToastItemCoverUpdateSuccess": "Titelbild aktualisiert",
|
||||||
"ToastItemDeletedFailed": "Fehler beim löschen des Artikels",
|
"ToastItemDeletedFailed": "Fehler beim löschen des Artikels",
|
||||||
"ToastItemDeletedSuccess": "Artikel gelöscht",
|
"ToastItemDeletedSuccess": "Artikel gelöscht",
|
||||||
@@ -1076,11 +1106,12 @@
|
|||||||
"ToastPlaylistUpdateSuccess": "Wiedergabeliste aktualisiert",
|
"ToastPlaylistUpdateSuccess": "Wiedergabeliste aktualisiert",
|
||||||
"ToastPodcastCreateFailed": "Podcast konnte nicht erstellt werden",
|
"ToastPodcastCreateFailed": "Podcast konnte nicht erstellt werden",
|
||||||
"ToastPodcastCreateSuccess": "Podcast erstellt",
|
"ToastPodcastCreateSuccess": "Podcast erstellt",
|
||||||
"ToastPodcastGetFeedFailed": "Fehler beim abrufen des Podcast Feeds",
|
"ToastPodcastEpisodeUpdated": "Podcast-Folge aktualisiert",
|
||||||
|
"ToastPodcastGetFeedFailed": "Fehler beim Abrufen des Podcast Feeds",
|
||||||
"ToastPodcastNoEpisodesInFeed": "Keine Episoden in RSS Feed gefunden",
|
"ToastPodcastNoEpisodesInFeed": "Keine Episoden in RSS Feed gefunden",
|
||||||
"ToastPodcastNoRssFeed": "Podcast enthält keinen RSS Feed",
|
"ToastPodcastNoRssFeed": "Podcast enthält keinen RSS Feed",
|
||||||
"ToastProgressIsNotBeingSynced": "Fortschritt wird nicht synchronisiert, Wiedergabe wird neu gestartet",
|
"ToastProgressIsNotBeingSynced": "Fortschritt wird nicht synchronisiert, Wiedergabe wird neu gestartet",
|
||||||
"ToastProviderCreatedFailed": "Fehler beim hinzufügen des Anbieters",
|
"ToastProviderCreatedFailed": "Fehler beim Hinzufügen des Anbieters",
|
||||||
"ToastProviderCreatedSuccess": "Neuer Anbieter hinzugefügt",
|
"ToastProviderCreatedSuccess": "Neuer Anbieter hinzugefügt",
|
||||||
"ToastProviderNameAndUrlRequired": "Name und URL notwendig",
|
"ToastProviderNameAndUrlRequired": "Name und URL notwendig",
|
||||||
"ToastProviderRemoveSuccess": "Anbieter entfernt",
|
"ToastProviderRemoveSuccess": "Anbieter entfernt",
|
||||||
@@ -1126,5 +1157,13 @@
|
|||||||
"ToastUserPasswordChangeSuccess": "Passwort erfolgreich verändert",
|
"ToastUserPasswordChangeSuccess": "Passwort erfolgreich verändert",
|
||||||
"ToastUserPasswordMismatch": "Passwörter stimmen nicht überein",
|
"ToastUserPasswordMismatch": "Passwörter stimmen nicht überein",
|
||||||
"ToastUserPasswordMustChange": "Neues Passwort muss sich von altem Passwort unterscheiden",
|
"ToastUserPasswordMustChange": "Neues Passwort muss sich von altem Passwort unterscheiden",
|
||||||
"ToastUserRootRequireName": "Root Benutzername muss angegeben werden"
|
"ToastUserRootRequireName": "Root Benutzername muss angegeben werden",
|
||||||
|
"TooltipAddChapters": "Kapitel hinzufügen",
|
||||||
|
"TooltipAddOneSecond": "1 Sekunde hinzufügen",
|
||||||
|
"TooltipAdjustChapterStart": "Klicke um die Startzeit anzupassen",
|
||||||
|
"TooltipLockAllChapters": "Alle Kapitel sperren",
|
||||||
|
"TooltipLockChapter": "Kapitel sperren (Shift+Klick für mehrere)",
|
||||||
|
"TooltipSubtractOneSecond": "1 Sekunde abziehen",
|
||||||
|
"TooltipUnlockAllChapters": "Alle Kapitel freigeben",
|
||||||
|
"TooltipUnlockChapter": "Kapitel freigeben (Shift+Klick für mehrere)"
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,348 @@
|
|||||||
|
{
|
||||||
|
"ButtonAdd": "Προσθήκη",
|
||||||
|
"ButtonAddApiKey": "Προσθήκη Κλειδιού API",
|
||||||
|
"ButtonAddChapters": "Προσθήκη Κεφαλαίων",
|
||||||
|
"ButtonAddDevice": "Προσθήκη Συσκευής",
|
||||||
|
"ButtonAddLibrary": "Προσθήκη Βιβλιοθήκης",
|
||||||
|
"ButtonAddPodcasts": "Προσθήκη Podcasts",
|
||||||
|
"ButtonAddUser": "Προσθήκη Χρήστη",
|
||||||
|
"ButtonAddYourFirstLibrary": "Πρόσθεσε την πρώτη σου βιβλιοθήκη",
|
||||||
|
"ButtonApply": "Εφαρμογή",
|
||||||
|
"ButtonApplyChapters": "Εφαρμογή Κεφαλαίων",
|
||||||
|
"ButtonAuthors": "Συγγραφείς",
|
||||||
|
"ButtonBack": "Πίσω",
|
||||||
|
"ButtonBatchEditPopulateFromExisting": "Συμπλήρωση από υπάρχοντα",
|
||||||
|
"ButtonBatchEditPopulateMapDetails": "Συμπλήρωση λεπτομερειών χάρτη",
|
||||||
|
"ButtonBrowseForFolder": "Περιήγηση για Φάκελο",
|
||||||
|
"ButtonCancel": "Ακύρωση",
|
||||||
|
"ButtonCancelEncode": "Ακύρωση Κωδικοποίησης",
|
||||||
|
"ButtonChangeRootPassword": "Αλλαγή Κωδικού Πρόσβασης Root",
|
||||||
|
"ButtonCheckAndDownloadNewEpisodes": "Έλεγχος και Κατέβασμα Νέων Επεισοδίων",
|
||||||
|
"ButtonChooseAFolder": "Επιλογή φακέλου",
|
||||||
|
"ButtonChooseFiles": "Επιλογή αρχείων",
|
||||||
|
"ButtonClearFilter": "Διαγραφή Φίλτρου",
|
||||||
|
"ButtonClose": "Κλείσιμο",
|
||||||
|
"ButtonCloseFeed": "Κλείσιμο Τροφοδοσίας",
|
||||||
|
"ButtonCloseSession": "Κλείσιμο Ανοιχτής Συνεδρίας",
|
||||||
|
"ButtonCollections": "Συλλογές",
|
||||||
|
"ButtonConfigureScanner": "Ρύθμιση Παραμέτρων Σαρωτή",
|
||||||
|
"ButtonCreate": "Δημιουργία",
|
||||||
|
"ButtonCreateBackup": "Δημιουργία Αντιγράφου Ασφαλείας",
|
||||||
|
"ButtonDelete": "Διαγραφή",
|
||||||
|
"ButtonDownloadQueue": "Ουρά",
|
||||||
|
"ButtonEdit": "Επεξεργασία",
|
||||||
|
"ButtonEditChapters": "Επεξεργασία Κεφαλαίων",
|
||||||
|
"ButtonEditPodcast": "Επεξεργασία Podcast",
|
||||||
|
"ButtonEnable": "Ενεργοποίηση",
|
||||||
|
"ButtonForceReScan": "Αναγκαστική Επανάληψη Σάρωσης",
|
||||||
|
"ButtonFullPath": "Πλήρης Διαδρομή",
|
||||||
|
"ButtonHide": "Απόκρυψη",
|
||||||
|
"ButtonHome": "Αρχική",
|
||||||
|
"ButtonIssues": "Θέματα",
|
||||||
|
"ButtonJumpBackward": "Μεταπήδηση Πίσω",
|
||||||
|
"ButtonJumpForward": "Μεταπήδηση Μπροστά",
|
||||||
|
"ButtonLatest": "Τελευταία",
|
||||||
|
"ButtonLibrary": "Βιβλιοθήκη",
|
||||||
|
"ButtonLogout": "Αποσύνδεση",
|
||||||
|
"ButtonLookup": "Εύρεση",
|
||||||
|
"ButtonManageTracks": "Διαχείριση Κομματιών",
|
||||||
|
"ButtonMapChapterTitles": "Χαρτογράφηση Τίτλων Κεφαλαίων",
|
||||||
|
"ButtonMatchAllAuthors": "Αντιστοίχιση Όλων των Συγγραφέων",
|
||||||
|
"ButtonMatchBooks": "Αντιστοίχιση Βιβλίων",
|
||||||
|
"ButtonNevermind": "Άστο",
|
||||||
|
"ButtonNext": "Επόμενο",
|
||||||
|
"ButtonNextChapter": "Επόμενο Κεφάλαιο",
|
||||||
|
"ButtonNextItemInQueue": "Επόμενο Αντικείμενο στην Ουρά",
|
||||||
|
"ButtonOk": "Εντάξει",
|
||||||
|
"ButtonOpenFeed": "Άνοιγμα Τροφοδοσίας",
|
||||||
|
"ButtonOpenManager": "Άνοιγμα Διαχειριστή",
|
||||||
|
"ButtonPause": "Παύση",
|
||||||
|
"ButtonPlay": "Αναπαραγωγή",
|
||||||
|
"ButtonPlayAll": "Αναπαραγωγή Όλων",
|
||||||
|
"ButtonPlaying": "Αναπαράγεται",
|
||||||
|
"ButtonPlaylists": "Λίστες Αναπαραγωγής",
|
||||||
|
"ButtonPrevious": "Προηγούμενο",
|
||||||
|
"ButtonPreviousChapter": "Προηγούμενο Κεφάλαιο",
|
||||||
|
"ButtonProbeAudioFile": "Ανάλυση Αρχείου Ήχου",
|
||||||
|
"ButtonPurgeAllCache": "Εκκαθάριση Όλης της Προσωρινής Μνήμης",
|
||||||
|
"ButtonPurgeItemsCache": "Εκκαθάριση της Μνήμης Αντικειμένων",
|
||||||
|
"ButtonQueueAddItem": "Προσθήκη στην ουρά",
|
||||||
|
"ButtonQueueRemoveItem": "Αφαίρεση απ'την ουρά",
|
||||||
|
"ButtonQuickEmbed": "Γρήγορη Ενσωμάτωση",
|
||||||
|
"ButtonQuickEmbedMetadata": "Γρήγορη Ενσωμάτωση Μεταδεδομένων",
|
||||||
|
"ButtonQuickMatch": "Γρήγορη Αντιστοίχηση",
|
||||||
|
"ButtonReScan": "Επανασάρωση",
|
||||||
|
"ButtonRead": "Ανάγνωση",
|
||||||
|
"ButtonReadLess": "Ανάγνωση λιγότερων",
|
||||||
|
"ButtonReadMore": "Διάβασε περισσότερα",
|
||||||
|
"ButtonRefresh": "Ανανέωση",
|
||||||
|
"ButtonRemove": "Αφαίρεση",
|
||||||
|
"ButtonRemoveAll": "Αφαίρεση Όλων",
|
||||||
|
"ButtonRemoveAllLibraryItems": "Αφαίρεση Όλων των Αντικειμέων Βιβλιοθήκης",
|
||||||
|
"ButtonRemoveFromContinueListening": "Αφαίρεση από τη Συνέχεια Ακρόασης",
|
||||||
|
"ButtonRemoveFromContinueReading": "Αφαίρεση από τη Συνέχεια Ανάγνωσης",
|
||||||
|
"ButtonRemoveSeriesFromContinueSeries": "Αφαίρεση Σειράς από τη Συνέχεια Σειράς",
|
||||||
|
"ButtonReset": "Επαναφορά",
|
||||||
|
"ButtonResetToDefault": "Επαναφορά στις προεπιλογές",
|
||||||
|
"ButtonRestore": "Επαναφορά",
|
||||||
|
"ButtonSave": "Αποθήκευση",
|
||||||
|
"ButtonSaveAndClose": "Αποθήκευση και Κλείσιμο",
|
||||||
|
"ButtonSaveTracklist": "Αποθήκευση Λίστας Κομματιών",
|
||||||
|
"ButtonScan": "Σάρψση",
|
||||||
|
"ButtonScanLibrary": "Σάρωση Βιβλιοθήκης",
|
||||||
|
"ButtonScrollLeft": "Κύλιση Αριστερά",
|
||||||
|
"ButtonScrollRight": "Κύλιση Δεξιά",
|
||||||
|
"ButtonSearch": "Αναζήτηση",
|
||||||
|
"ButtonSelectFolderPath": "Επιλογή Διαδρομής Φακέλου",
|
||||||
|
"ButtonSeries": "Σειρά",
|
||||||
|
"ButtonSetChaptersFromTracks": "Ορισμός κεφαλαίων από τα κομμάτια",
|
||||||
|
"ButtonShare": "Κοινοποίηση",
|
||||||
|
"ButtonShiftTimes": "Χρόνοι Μετακίνησης",
|
||||||
|
"ButtonShow": "Εμφάνιση",
|
||||||
|
"ButtonStartM4BEncode": "Έναρξη Κωδικοποίησης M4B",
|
||||||
|
"ButtonStartMetadataEmbed": "Έναρξη Ενσωμάτωσης Μεταδεδομένων",
|
||||||
|
"ButtonStats": "Στατιστικά",
|
||||||
|
"ButtonSubmit": "Υποβολή",
|
||||||
|
"ButtonTest": "Δοκιμή",
|
||||||
|
"ButtonUnlinkOpenId": "Αποσύνδεση OpenID",
|
||||||
|
"ButtonUpload": "Μεταφόρτωση",
|
||||||
|
"ButtonUploadBackup": "Μεταφόρτωση Αντιγράφου Ασφαλείας",
|
||||||
|
"ButtonUploadCover": "Μεταφόρτωση Εξωφύλλου",
|
||||||
|
"ButtonUploadOPMLFile": "Μεταφόρτωση Αρχείου OPML",
|
||||||
|
"ButtonUserDelete": "Διαγραφή Χρήστη {0}",
|
||||||
|
"ButtonUserEdit": "Επεξεργασίας χρήστη {0}",
|
||||||
|
"ButtonViewAll": "Εμφάνιση Όλων",
|
||||||
|
"ButtonYes": "Ναι",
|
||||||
|
"ErrorUploadFetchMetadataAPI": "Σφάλμα κατά την ανάκτηση μεταδεδομένων",
|
||||||
|
"ErrorUploadFetchMetadataNoResults": "Δεν ήταν δυνατή η ανάκτηση των μεταδεδομένων - δοκιμάστε να ενημερώσετε τον τίτλο και/ή τον συγγραφέα",
|
||||||
|
"ErrorUploadLacksTitle": "Πρέπει να έχει τίτλο",
|
||||||
|
"HeaderAccount": "Λογαριασμός",
|
||||||
|
"HeaderAddCustomMetadataProvider": "Προσθήκη Προσαρμοσμένου Παρόχου Μεταδεδομένων",
|
||||||
|
"HeaderAdvanced": "Για Προχωρημένους",
|
||||||
|
"HeaderApiKeys": "Κλειδιά API",
|
||||||
|
"HeaderAppriseNotificationSettings": "Ρυθμίσεις Ειδοποιήσεων Apprise",
|
||||||
|
"HeaderAudioTracks": "Κομμάτια Ήχου",
|
||||||
|
"HeaderAudiobookTools": "Εργαλεία Διαχείρισης Αρχείων Audiobooks",
|
||||||
|
"HeaderAuthentication": "Αυθεντικοποίηση",
|
||||||
|
"HeaderBackups": "Αντίγραφα Ασφαλείας",
|
||||||
|
"HeaderBulkChapterModal": "Προσθήκη Πολλαπλών Κεφαλαίων",
|
||||||
|
"HeaderChangePassword": "Αλλαγή Κωδικού Πρόσβασης",
|
||||||
|
"HeaderChapters": "Κεφάλαια",
|
||||||
|
"HeaderChooseAFolder": "Επιλογή Φακέλου",
|
||||||
|
"HeaderCollection": "Συλλογή",
|
||||||
|
"HeaderCollectionItems": "Αντικείμενα Συλλογής",
|
||||||
|
"HeaderCover": "Εξώφυλλο",
|
||||||
|
"HeaderCurrentDownloads": "Τρέχουσες Λήψεις",
|
||||||
|
"HeaderDetails": "Λεπτομέρειες",
|
||||||
|
"HeaderDownloadQueue": "Ουρά Λήψης",
|
||||||
|
"HeaderEbookFiles": "Αρχεία του βιβλίου",
|
||||||
|
"HeaderEmail": "Ηλεκτρονικό ταχυδρομείο",
|
||||||
|
"HeaderEmailSettings": "Ρυθμίσεις ηλεκτρονικού ταχυδρομείου",
|
||||||
|
"HeaderEpisodes": "Επεισόδια",
|
||||||
|
"HeaderEreaderSettings": "Ρυθμίσεις Ereader",
|
||||||
|
"HeaderFiles": "Αρχεία",
|
||||||
|
"HeaderFindChapters": "Εύρεση Κεφαλαίων",
|
||||||
|
"HeaderItemFiles": "Αρχεία Αντικειμένων",
|
||||||
|
"HeaderLastListeningSession": "Τελευταία Συνεδρία Ακρόασης",
|
||||||
|
"HeaderLatestEpisodes": "Τελευταία Επεισόδια",
|
||||||
|
"HeaderLibraries": "Βιβλιοθήκες",
|
||||||
|
"HeaderLibraryFiles": "Αρχεία Βιβλιοθήκης",
|
||||||
|
"HeaderLibraryStats": "Στατιστικά Βιβλιοθήκης",
|
||||||
|
"HeaderListeningSessions": "Συνεδρίες Ακρόασης",
|
||||||
|
"HeaderListeningStats": "Στατιστικά Ακρόασης",
|
||||||
|
"HeaderLogin": "Σύνδεση",
|
||||||
|
"HeaderMatch": "Ταύτιση",
|
||||||
|
"HeaderNewAccount": "Νέος Λογαριασμός",
|
||||||
|
"HeaderNewApiKey": "Νέο Κλειδί API",
|
||||||
|
"HeaderNewLibrary": "Νέα Βιβλιοθήκη",
|
||||||
|
"HeaderNotificationCreate": "Δημιουργία Ειδοποίησης",
|
||||||
|
"HeaderNotificationUpdate": "Ενημέρωση Ειδοποίησης",
|
||||||
|
"HeaderNotifications": "Ειδοποιήσεις",
|
||||||
|
"HeaderOpenRSSFeed": "Άνοιγμα Τροφοδοσίας RSS",
|
||||||
|
"HeaderOtherFiles": "Άλλα Αρχεία",
|
||||||
|
"HeaderPermissions": "Δικαιώματα",
|
||||||
|
"HeaderPlayerSettings": "Ρυθμίσεις Αναπαραγωγής",
|
||||||
|
"HeaderPlaylist": "Λίστα Αναπαραγωγής",
|
||||||
|
"HeaderPlaylistItems": "Αντικείμενα Λίστας Αναπαραγωγής",
|
||||||
|
"HeaderPresets": "Προεπιλογές",
|
||||||
|
"HeaderRSSFeedGeneral": "Λεπτομέρειες RSS",
|
||||||
|
"HeaderRSSFeedIsOpen": "Η Τροφοδοσία RSS είναι Ανοιχτή",
|
||||||
|
"HeaderRemoveEpisode": "Αφαίρεση Επεισοδίου",
|
||||||
|
"HeaderSession": "Συνεδρία",
|
||||||
|
"HeaderSetBackupSchedule": "Ορισμός Προγράμματος Αντιγράφων Ασφαλείας",
|
||||||
|
"HeaderSettings": "Ρυθμίσεις",
|
||||||
|
"HeaderSettingsDisplay": "Προβολή",
|
||||||
|
"HeaderSettingsGeneral": "Γενικά",
|
||||||
|
"HeaderSettingsSecurity": "Ασφάλεια",
|
||||||
|
"HeaderSleepTimer": "Χρονοδιακόπτης Ύπνου",
|
||||||
|
"HeaderStatsLargestItems": "Μεγαλύτερα Αντικείμενα",
|
||||||
|
"HeaderStatsLongestItems": "Μεγαλύτερα Αντικείμενα (ώρες)",
|
||||||
|
"HeaderStatsMinutesListeningChart": "Λεπτά Ακρόασης (τελευταίες 7 ημέρες)",
|
||||||
|
"HeaderStatsRecentSessions": "Πρόσφατες Συνεδρίες",
|
||||||
|
"HeaderStatsTop10Authors": "10 Κορυφαίου Συγγραφείς",
|
||||||
|
"HeaderStatsTop5Genres": "5 Κορυφαία Είδη",
|
||||||
|
"HeaderTableOfContents": "Πίνακας Περιεχομένων",
|
||||||
|
"HeaderTools": "Εργαλεία",
|
||||||
|
"HeaderUpdateAccount": "Ενημέρωση Λογαριασμού",
|
||||||
|
"HeaderUpdateApiKey": "Ενημέρωση Κλειδιού API",
|
||||||
|
"HeaderUpdateAuthor": "Ενημέρωση Συγγραφέα",
|
||||||
|
"HeaderUpdateDetails": "Ενημέρωση Λεπτομερειεών",
|
||||||
|
"HeaderUpdateLibrary": "Ενημέρωση Βιβλιοθήκης",
|
||||||
|
"HeaderUsers": "Χρήστες",
|
||||||
|
"HeaderYourStats": "Τα Στατιστικά Σας",
|
||||||
|
"LabelAbridged": "Συνοπτικό",
|
||||||
|
"LabelAccessibleBy": "Προσβάσιμο από",
|
||||||
|
"LabelAccountType": "Τύπος Λογαριασμού",
|
||||||
|
"LabelAccountTypeAdmin": "Διαχειριστής",
|
||||||
|
"LabelAccountTypeGuest": "Επισκέπτης",
|
||||||
|
"LabelAccountTypeUser": "Χρήστης",
|
||||||
|
"LabelAddToCollection": "Προσθήκη σε Συλλογή",
|
||||||
|
"LabelAddToCollectionBatch": "Προσθήκη {0} Βιβλίων στην Συλλογή",
|
||||||
|
"LabelAddToPlaylist": "Προσθήκη στην Λίστα Αναπαραγωγής",
|
||||||
|
"LabelAddedAt": "Προστέθηκε Στις",
|
||||||
|
"LabelAddedDate": "Προστέθηκε {0}",
|
||||||
|
"LabelAll": "Όλα",
|
||||||
|
"LabelAllEpisodesDownloaded": "Όλα τα επεισόδια λήφθηκαν",
|
||||||
|
"LabelAllUsers": "Όλοι οι Χρήστες",
|
||||||
|
"LabelAlreadyInYourLibrary": "Υπάρχει ήδη στην βιβλιοθήκη",
|
||||||
|
"LabelAudioChannels": "Κανάλια Ήχου (1 ή 2)",
|
||||||
|
"LabelAuthor": "Συγγραφέας",
|
||||||
|
"LabelAuthorFirstLast": "Συγγραφέας (Όνομα Επώνυμο)",
|
||||||
|
"LabelAuthorLastFirst": "Συγγραφέας (Επώνυμο, Όνομα)",
|
||||||
|
"LabelAuthors": "Συγγραφείς",
|
||||||
|
"LabelAutoDownloadEpisodes": "Αυτόματο Κατέβασμα Επεισοδίων",
|
||||||
|
"LabelAutoLaunch": "Αυτόματη Εκκίνηση",
|
||||||
|
"LabelBackupLocation": "Τοποθεσία Αντιγράφου Ασφαλείας",
|
||||||
|
"LabelBackupsEnableAutomaticBackups": "Αυτόματα αντίγραφα ασφαλείας",
|
||||||
|
"LabelBackupsNumberToKeep": "Αριθμός αντιγράφων ασφαλείας προς διατήρηση",
|
||||||
|
"LabelBooks": "Βιβλία",
|
||||||
|
"LabelButtonText": "Κείμενο Κουμπιού",
|
||||||
|
"LabelByAuthor": "κατά {0}",
|
||||||
|
"LabelChangePassword": "Αλλαγή Κωδικού Πρόσβασης",
|
||||||
|
"LabelChannels": "Κανάλια",
|
||||||
|
"LabelChapterCount": "{0} Κεφάλαια",
|
||||||
|
"LabelChapterTitle": "Τίτλος Κεφαλαίου",
|
||||||
|
"LabelChapters": "Κεφάλαια",
|
||||||
|
"LabelChaptersFound": "κεφάλαια βρέθηκαν",
|
||||||
|
"LabelClosePlayer": "Κλείσιμο αναπαραγωγής",
|
||||||
|
"LabelCollapseSeries": "Σύμπτυξη Σειράς",
|
||||||
|
"LabelCollection": "Συλλογή",
|
||||||
|
"LabelCollections": "Συλλογές",
|
||||||
|
"LabelComplete": "Ολοκλήρωση",
|
||||||
|
"LabelConfirmPassword": "Επιβεβαίωση Κωδικού Πρόσβασης",
|
||||||
|
"LabelContinueListening": "Συνέχεια Ακρόασης",
|
||||||
|
"LabelContinueReading": "Συνέχεια Ανάγνωσης",
|
||||||
|
"LabelContinueSeries": "Συνέχεια Σειράς",
|
||||||
|
"LabelCover": "Εξώφυλλο",
|
||||||
|
"LabelCoverImageURL": "URL Εικόνας Εξωφύλλου",
|
||||||
|
"LabelCoverProvider": "Πάροχος Εξωφύλλου",
|
||||||
|
"LabelCreatedAt": "Δημιουρήθηκε Στις",
|
||||||
|
"LabelCurrent": "Τρέχων",
|
||||||
|
"LabelCurrently": "Τρέχων:",
|
||||||
|
"LabelDays": "Ημέρες",
|
||||||
|
"LabelDescription": "Περιγραφή",
|
||||||
|
"LabelDevice": "Συσκευή",
|
||||||
|
"LabelDeviceInfo": "Πληροφορίες Συσκευής",
|
||||||
|
"LabelDiscover": "Ανακάλυψη",
|
||||||
|
"LabelDownload": "Λήψη",
|
||||||
|
"LabelDownloadNEpisodes": "Λήψη {0} επεισοδίων",
|
||||||
|
"LabelDuration": "Διάρκεια",
|
||||||
|
"LabelDurationComparisonExactMatch": "(ακριβής ταύτιση)",
|
||||||
|
"LabelEbook": "Ηλεκτρονικό βιβλίο",
|
||||||
|
"LabelEbooks": "Ηλεκτρονικά βιβλία",
|
||||||
|
"LabelEdit": "Επεξεργασία",
|
||||||
|
"LabelEmail": "Ηλεκτρονικό ταχυδρομείο",
|
||||||
|
"LabelEmailSettingsFromAddress": "Από διεύθυνση",
|
||||||
|
"LabelEmailSettingsSecure": "Ασφαλές",
|
||||||
|
"LabelEmailSettingsTestAddress": "Δοκιμή διεύθυνσης",
|
||||||
|
"LabelEmbeddedCover": "Ενσωματωμένο Εξώφυλλο",
|
||||||
|
"LabelEnable": "Ενεργοποίηση",
|
||||||
|
"LabelEnd": "Τέλος",
|
||||||
|
"LabelEndOfChapter": "Τέλος Κεφαλαίου",
|
||||||
|
"LabelEpisode": "Επεισόδιο",
|
||||||
|
"LabelExplicit": "Άσεμνο περιεχόμενο",
|
||||||
|
"LabelFeedURL": "URL ροής",
|
||||||
|
"LabelFile": "Αρχείο",
|
||||||
|
"LabelFileBirthtime": "Ώρα δημιουργίας αρχείου",
|
||||||
|
"LabelFileModified": "Τροποποιημένο αρχείο",
|
||||||
|
"LabelFilename": "Όνομα Αρχείου",
|
||||||
|
"LabelFinished": "Ολοκληρώθηκε",
|
||||||
|
"LabelFolder": "Φάκελος",
|
||||||
|
"LabelFontBoldness": "Ένταση γραμματοσειράς",
|
||||||
|
"LabelFontFamily": "Οικογένεια Γραμματοσειράς",
|
||||||
|
"LabelFontScale": "Μέγεθος γραμματοσειράς",
|
||||||
|
"LabelGenre": "Λογοτεχνικό Είδος",
|
||||||
|
"LabelGenres": "Λογοτεχνικά Είδη",
|
||||||
|
"LabelHasEbook": "Έχει βιβλίο",
|
||||||
|
"LabelHasSupplementaryEbook": "Διαθέτει συμπληρωματικό ηλεκτρονικό βιβλίο",
|
||||||
|
"LabelHost": "Διακομιστής",
|
||||||
|
"LabelInProgress": "Σε Εξέλιξη",
|
||||||
|
"LabelIncomplete": "Ελειπής",
|
||||||
|
"LabelLanguage": "Γλώσσα",
|
||||||
|
"LabelLayout": "Διάταξη",
|
||||||
|
"LabelLayoutSinglePage": "Μονή Σελίδα",
|
||||||
|
"LabelLibrarySortByProgress": "Πρόοδος: Τελευταία ενημέρωση",
|
||||||
|
"LabelLibrarySortByProgressFinished": "Πρόοδος: Ολοκληρώθηκε",
|
||||||
|
"LabelLibrarySortByProgressStarted": "Πρόοδος: Έναρξη",
|
||||||
|
"LabelLineSpacing": "Διάστημα γραμμών",
|
||||||
|
"LabelListenAgain": "Επανάληψη Ακρόασης",
|
||||||
|
"LabelMediaType": "Τύπος Πολυμέσων",
|
||||||
|
"LabelMissing": "Λείπει η ετικέτα",
|
||||||
|
"LabelMore": "Περισσότερα",
|
||||||
|
"LabelMoreInfo": "Περισσότερες Πληροφορίες",
|
||||||
|
"LabelName": "Όνομα",
|
||||||
|
"LabelNarrator": "Αφηγητής",
|
||||||
|
"LabelNarrators": "Αφηγητές",
|
||||||
|
"LabelNewestAuthors": "Πρόσφατοι Συγγραφείς",
|
||||||
|
"LabelNewestEpisodes": "Πρόσφατα Επεισόδια",
|
||||||
|
"LabelNotFinished": "Δεν έχει ολοκληρωθεί",
|
||||||
|
"LabelNotStarted": "Δεν Έχει Ξεκινήσει",
|
||||||
|
"LabelNumberOfEpisodes": "# Επεισοδίων",
|
||||||
|
"LabelPassword": "Κωδικός Πρόσβασης",
|
||||||
|
"LabelPath": "Διαδρομή",
|
||||||
|
"LabelPodcast": "Πόντκαστ",
|
||||||
|
"LabelPodcasts": "Πόντκαστ",
|
||||||
|
"LabelProgress": "Πρόοδος",
|
||||||
|
"LabelPubDate": "Ημερομηνία έκδοσης",
|
||||||
|
"LabelPublishYear": "Χρονολογία Έκδοσης",
|
||||||
|
"LabelPublishedDate": "Εκδόθηκε {0}",
|
||||||
|
"LabelRandomly": "Τυχαία",
|
||||||
|
"LabelRead": "Ανάγνωση",
|
||||||
|
"LabelReadAgain": "Ανάγνωση Ξανά",
|
||||||
|
"LabelRecentSeries": "Πρόσφατη Σειρά",
|
||||||
|
"LabelRecentlyAdded": "Προστέθηκαν Πρόσφατα",
|
||||||
|
"LabelSeries": "Σειρά",
|
||||||
|
"LabelSetEbookAsPrimary": "Ορισμός ως πρωτεύων",
|
||||||
|
"LabelShowAll": "Εμφάνιση Όλων",
|
||||||
|
"LabelSize": "Μέγεθος",
|
||||||
|
"LabelSleepTimer": "Χρονοδιακόπτης Ύπνου",
|
||||||
|
"LabelStart": "Έναρξη",
|
||||||
|
"LabelStatsBestDay": "Καλύτερη Ημέρα",
|
||||||
|
"LabelStatsDailyAverage": "Ημερήσιος Μέσος Όρος",
|
||||||
|
"LabelStatsDays": "Ημέρες",
|
||||||
|
"LabelStatsDaysListened": "Ημέρες Ακρόασης",
|
||||||
|
"LabelStatsInARow": "Σε σειρά",
|
||||||
|
"LabelStatsItemsFinished": "Ολοκληρωμένα Αντικείμενα",
|
||||||
|
"LabelStatsMinutes": "λεπτά",
|
||||||
|
"LabelStatsMinutesListening": "Λεπτά Ακρόασης",
|
||||||
|
"LabelStatsWeekListening": "Εβδομαδιαία Ακρόαση",
|
||||||
|
"LabelTheme": "Θέμα",
|
||||||
|
"LabelThemeDark": "Σκοτεινό",
|
||||||
|
"LabelThemeLight": "Φωτεινό",
|
||||||
|
"LabelTimeRemaining": "{0} απομένουν",
|
||||||
|
"LabelTitle": "Τίτλος",
|
||||||
|
"LabelTracks": "Κομμάτια",
|
||||||
|
"LabelType": "Τύπος",
|
||||||
|
"LabelUnknown": "Άγνωστο",
|
||||||
|
"LabelUser": "Χρήστης",
|
||||||
|
"LabelUsername": "Όνομα Χρήστη",
|
||||||
|
"LabelYourProgress": "Η Πρόοδος Σας",
|
||||||
|
"MessageDownloadingEpisode": "Λήψη επεισοδίου",
|
||||||
|
"MessageEreaderDevices": "Για να διασφαλίσετε την παράδοση των ηλεκτρονικών βιβλίων, ίσως χρειαστεί να προσθέσετε την παραπάνω διεύθυνση ηλεκτρονικού ταχυδρομείου ως έγκυρο αποστολέα για κάθε συσκευή που αναγράφεται παρακάτω.",
|
||||||
|
"MessageLoading": "Φόρτωση...",
|
||||||
|
"MessageMarkAsFinished": "Σήμανση ως Ολοκληρωμένο",
|
||||||
|
"MessageNoItemsFound": "Δεν βρέθηκαν αντικείμενα",
|
||||||
|
"MessageNoUserPlaylists": "Δεν έχετε λίστες αναπαραγωγής",
|
||||||
|
"ToastEmailSettingsUpdateSuccess": "Ενημερώθηκαν οι ρυθμίσεις ηλεκτρονικού ταχυδρομείου",
|
||||||
|
"ToastNameEmailRequired": "Το όνομα και η διεύθυνση ηλεκτρονικού ταχυδρομείου είναι υποχρεωτικά"
|
||||||
|
}
|
||||||
@@ -46,6 +46,7 @@
|
|||||||
"ButtonLatest": "Latest",
|
"ButtonLatest": "Latest",
|
||||||
"ButtonLibrary": "Library",
|
"ButtonLibrary": "Library",
|
||||||
"ButtonLogout": "Logout",
|
"ButtonLogout": "Logout",
|
||||||
|
"ButtonLogoutAllDevices": "Logout All Devices",
|
||||||
"ButtonLookup": "Lookup",
|
"ButtonLookup": "Lookup",
|
||||||
"ButtonManageTracks": "Manage Tracks",
|
"ButtonManageTracks": "Manage Tracks",
|
||||||
"ButtonMapChapterTitles": "Map Chapter Titles",
|
"ButtonMapChapterTitles": "Map Chapter Titles",
|
||||||
@@ -127,6 +128,7 @@
|
|||||||
"HeaderAudiobookTools": "Audiobook File Management Tools",
|
"HeaderAudiobookTools": "Audiobook File Management Tools",
|
||||||
"HeaderAuthentication": "Authentication",
|
"HeaderAuthentication": "Authentication",
|
||||||
"HeaderBackups": "Backups",
|
"HeaderBackups": "Backups",
|
||||||
|
"HeaderBulkChapterModal": "Add Multiple Chapters",
|
||||||
"HeaderChangePassword": "Change Password",
|
"HeaderChangePassword": "Change Password",
|
||||||
"HeaderChapters": "Chapters",
|
"HeaderChapters": "Chapters",
|
||||||
"HeaderChooseAFolder": "Choose a Folder",
|
"HeaderChooseAFolder": "Choose a Folder",
|
||||||
@@ -193,12 +195,14 @@
|
|||||||
"HeaderScheduleEpisodeDownloads": "Schedule Automatic Episode Downloads",
|
"HeaderScheduleEpisodeDownloads": "Schedule Automatic Episode Downloads",
|
||||||
"HeaderScheduleLibraryScans": "Schedule Automatic Library Scans",
|
"HeaderScheduleLibraryScans": "Schedule Automatic Library Scans",
|
||||||
"HeaderSession": "Session",
|
"HeaderSession": "Session",
|
||||||
|
"HeaderSessions": "Sessions",
|
||||||
"HeaderSetBackupSchedule": "Set Backup Schedule",
|
"HeaderSetBackupSchedule": "Set Backup Schedule",
|
||||||
"HeaderSettings": "Settings",
|
"HeaderSettings": "Settings",
|
||||||
"HeaderSettingsDisplay": "Display",
|
"HeaderSettingsDisplay": "Display",
|
||||||
"HeaderSettingsExperimental": "Experimental Features",
|
"HeaderSettingsExperimental": "Experimental Features",
|
||||||
"HeaderSettingsGeneral": "General",
|
"HeaderSettingsGeneral": "General",
|
||||||
"HeaderSettingsScanner": "Scanner",
|
"HeaderSettingsScanner": "Scanner",
|
||||||
|
"HeaderSettingsSecurity": "Security",
|
||||||
"HeaderSettingsWebClient": "Web Client",
|
"HeaderSettingsWebClient": "Web Client",
|
||||||
"HeaderSleepTimer": "Sleep Timer",
|
"HeaderSleepTimer": "Sleep Timer",
|
||||||
"HeaderStatsLargestItems": "Largest Items",
|
"HeaderStatsLargestItems": "Largest Items",
|
||||||
@@ -293,6 +297,7 @@
|
|||||||
"LabelContinueListening": "Continue Listening",
|
"LabelContinueListening": "Continue Listening",
|
||||||
"LabelContinueReading": "Continue Reading",
|
"LabelContinueReading": "Continue Reading",
|
||||||
"LabelContinueSeries": "Continue Series",
|
"LabelContinueSeries": "Continue Series",
|
||||||
|
"LabelCorsAllowed": "Allowed CORS Origins",
|
||||||
"LabelCover": "Cover",
|
"LabelCover": "Cover",
|
||||||
"LabelCoverImageURL": "Cover Image URL",
|
"LabelCoverImageURL": "Cover Image URL",
|
||||||
"LabelCoverProvider": "Cover Provider",
|
"LabelCoverProvider": "Cover Provider",
|
||||||
@@ -306,6 +311,7 @@
|
|||||||
"LabelDeleteFromFileSystemCheckbox": "Delete from file system (uncheck to only remove from database)",
|
"LabelDeleteFromFileSystemCheckbox": "Delete from file system (uncheck to only remove from database)",
|
||||||
"LabelDescription": "Description",
|
"LabelDescription": "Description",
|
||||||
"LabelDeselectAll": "Deselect All",
|
"LabelDeselectAll": "Deselect All",
|
||||||
|
"LabelDetectedPattern": "Detected pattern:",
|
||||||
"LabelDevice": "Device",
|
"LabelDevice": "Device",
|
||||||
"LabelDeviceInfo": "Device Info",
|
"LabelDeviceInfo": "Device Info",
|
||||||
"LabelDeviceIsAvailableTo": "Device is available to...",
|
"LabelDeviceIsAvailableTo": "Device is available to...",
|
||||||
@@ -374,6 +380,7 @@
|
|||||||
"LabelFilterByUser": "Filter by User",
|
"LabelFilterByUser": "Filter by User",
|
||||||
"LabelFindEpisodes": "Find Episodes",
|
"LabelFindEpisodes": "Find Episodes",
|
||||||
"LabelFinished": "Finished",
|
"LabelFinished": "Finished",
|
||||||
|
"LabelFinishedDate": "Finished {0}",
|
||||||
"LabelFolder": "Folder",
|
"LabelFolder": "Folder",
|
||||||
"LabelFolders": "Folders",
|
"LabelFolders": "Folders",
|
||||||
"LabelFontBold": "Bold",
|
"LabelFontBold": "Bold",
|
||||||
@@ -410,6 +417,7 @@
|
|||||||
"LabelIntervalEveryHour": "Every hour",
|
"LabelIntervalEveryHour": "Every hour",
|
||||||
"LabelIntervalEveryMinute": "Every minute",
|
"LabelIntervalEveryMinute": "Every minute",
|
||||||
"LabelInvert": "Invert",
|
"LabelInvert": "Invert",
|
||||||
|
"LabelIpAddress": "IP Address",
|
||||||
"LabelItem": "Item",
|
"LabelItem": "Item",
|
||||||
"LabelJumpBackwardAmount": "Jump backward amount",
|
"LabelJumpBackwardAmount": "Jump backward amount",
|
||||||
"LabelJumpForwardAmount": "Jump forward amount",
|
"LabelJumpForwardAmount": "Jump forward amount",
|
||||||
@@ -418,6 +426,7 @@
|
|||||||
"LabelLanguages": "Languages",
|
"LabelLanguages": "Languages",
|
||||||
"LabelLastBookAdded": "Last Book Added",
|
"LabelLastBookAdded": "Last Book Added",
|
||||||
"LabelLastBookUpdated": "Last Book Updated",
|
"LabelLastBookUpdated": "Last Book Updated",
|
||||||
|
"LabelLastProgressDate": "Last progress: {0}",
|
||||||
"LabelLastSeen": "Last Seen",
|
"LabelLastSeen": "Last Seen",
|
||||||
"LabelLastTime": "Last Time",
|
"LabelLastTime": "Last Time",
|
||||||
"LabelLastUpdate": "Last Update",
|
"LabelLastUpdate": "Last Update",
|
||||||
@@ -430,6 +439,9 @@
|
|||||||
"LabelLibraryFilterSublistEmpty": "No {0}",
|
"LabelLibraryFilterSublistEmpty": "No {0}",
|
||||||
"LabelLibraryItem": "Library Item",
|
"LabelLibraryItem": "Library Item",
|
||||||
"LabelLibraryName": "Library Name",
|
"LabelLibraryName": "Library Name",
|
||||||
|
"LabelLibrarySortByProgress": "Progress: Last Updated",
|
||||||
|
"LabelLibrarySortByProgressFinished": "Progress: Finished",
|
||||||
|
"LabelLibrarySortByProgressStarted": "Progress: Started",
|
||||||
"LabelLimit": "Limit",
|
"LabelLimit": "Limit",
|
||||||
"LabelLineSpacing": "Line spacing",
|
"LabelLineSpacing": "Line spacing",
|
||||||
"LabelListenAgain": "Listen Again",
|
"LabelListenAgain": "Listen Again",
|
||||||
@@ -438,6 +450,7 @@
|
|||||||
"LabelLogLevelWarn": "Warn",
|
"LabelLogLevelWarn": "Warn",
|
||||||
"LabelLookForNewEpisodesAfterDate": "Look for new episodes after this date",
|
"LabelLookForNewEpisodesAfterDate": "Look for new episodes after this date",
|
||||||
"LabelLowestPriority": "Lowest Priority",
|
"LabelLowestPriority": "Lowest Priority",
|
||||||
|
"LabelMatchConfidence": "Confidence",
|
||||||
"LabelMatchExistingUsersBy": "Match existing users by",
|
"LabelMatchExistingUsersBy": "Match existing users by",
|
||||||
"LabelMatchExistingUsersByDescription": "Used for connecting existing users. Once connected, users will be matched by a unique id from your SSO provider",
|
"LabelMatchExistingUsersByDescription": "Used for connecting existing users. Once connected, users will be matched by a unique id from your SSO provider",
|
||||||
"LabelMaxEpisodesToDownload": "Max # of episodes to download. Use 0 for unlimited.",
|
"LabelMaxEpisodesToDownload": "Max # of episodes to download. Use 0 for unlimited.",
|
||||||
@@ -467,6 +480,7 @@
|
|||||||
"LabelNewestAuthors": "Newest Authors",
|
"LabelNewestAuthors": "Newest Authors",
|
||||||
"LabelNewestEpisodes": "Newest Episodes",
|
"LabelNewestEpisodes": "Newest Episodes",
|
||||||
"LabelNextBackupDate": "Next backup date",
|
"LabelNextBackupDate": "Next backup date",
|
||||||
|
"LabelNextChapters": "Next chapters will be:",
|
||||||
"LabelNextScheduledRun": "Next scheduled run",
|
"LabelNextScheduledRun": "Next scheduled run",
|
||||||
"LabelNoApiKeys": "No API keys",
|
"LabelNoApiKeys": "No API keys",
|
||||||
"LabelNoCustomMetadataProviders": "No custom metadata providers",
|
"LabelNoCustomMetadataProviders": "No custom metadata providers",
|
||||||
@@ -484,6 +498,7 @@
|
|||||||
"LabelNotificationsMaxQueueSize": "Max queue size for notification events",
|
"LabelNotificationsMaxQueueSize": "Max queue size for notification events",
|
||||||
"LabelNotificationsMaxQueueSizeHelp": "Events are limited to firing 1 per second. Events will be ignored if the queue is at max size. This prevents notification spamming.",
|
"LabelNotificationsMaxQueueSizeHelp": "Events are limited to firing 1 per second. Events will be ignored if the queue is at max size. This prevents notification spamming.",
|
||||||
"LabelNumberOfBooks": "Number of Books",
|
"LabelNumberOfBooks": "Number of Books",
|
||||||
|
"LabelNumberOfChapters": "Number of chapters:",
|
||||||
"LabelNumberOfEpisodes": "# of Episodes",
|
"LabelNumberOfEpisodes": "# of Episodes",
|
||||||
"LabelOpenIDAdvancedPermsClaimDescription": "Name of the OpenID claim that contains advanced permissions for user actions within the application which will apply to non-admin roles (<b>if configured</b>). If the claim is missing from the response, access to ABS will be denied. If a single option is missing, it will be treated as <code>false</code>. Ensure the identity provider's claim matches the expected structure:",
|
"LabelOpenIDAdvancedPermsClaimDescription": "Name of the OpenID claim that contains advanced permissions for user actions within the application which will apply to non-admin roles (<b>if configured</b>). If the claim is missing from the response, access to ABS will be denied. If a single option is missing, it will be treated as <code>false</code>. Ensure the identity provider's claim matches the expected structure:",
|
||||||
"LabelOpenIDClaims": "Leave the following options empty to disable advanced group and permissions assignment, automatically assigning 'User' group then.",
|
"LabelOpenIDClaims": "Leave the following options empty to disable advanced group and permissions assignment, automatically assigning 'User' group then.",
|
||||||
@@ -576,8 +591,8 @@
|
|||||||
"LabelSettingsBookshelfViewHelp": "Skeumorphic design with wooden shelves",
|
"LabelSettingsBookshelfViewHelp": "Skeumorphic design with wooden shelves",
|
||||||
"LabelSettingsChromecastSupport": "Chromecast support",
|
"LabelSettingsChromecastSupport": "Chromecast support",
|
||||||
"LabelSettingsDateFormat": "Date Format",
|
"LabelSettingsDateFormat": "Date Format",
|
||||||
"LabelSettingsEnableWatcher": "Automatically scan libraries for changes",
|
"LabelSettingsEnableWatcher": "Automatically watch libraries for changes",
|
||||||
"LabelSettingsEnableWatcherForLibrary": "Automatically scan library for changes",
|
"LabelSettingsEnableWatcherForLibrary": "Automatically watch library for changes",
|
||||||
"LabelSettingsEnableWatcherHelp": "Enables the automatic adding/updating of items when file changes are detected. *Requires server restart",
|
"LabelSettingsEnableWatcherHelp": "Enables the automatic adding/updating of items when file changes are detected. *Requires server restart",
|
||||||
"LabelSettingsEpubsAllowScriptedContent": "Allow scripted content in epubs",
|
"LabelSettingsEpubsAllowScriptedContent": "Allow scripted content in epubs",
|
||||||
"LabelSettingsEpubsAllowScriptedContentHelp": "Allow epub files to execute scripts. It is recommended to keep this setting disabled unless you trust the source of the epub files.",
|
"LabelSettingsEpubsAllowScriptedContentHelp": "Allow epub files to execute scripts. It is recommended to keep this setting disabled unless you trust the source of the epub files.",
|
||||||
@@ -626,6 +641,7 @@
|
|||||||
"LabelStartTime": "Start Time",
|
"LabelStartTime": "Start Time",
|
||||||
"LabelStarted": "Started",
|
"LabelStarted": "Started",
|
||||||
"LabelStartedAt": "Started At",
|
"LabelStartedAt": "Started At",
|
||||||
|
"LabelStartedDate": "Started {0}",
|
||||||
"LabelStatsAudioTracks": "Audio Tracks",
|
"LabelStatsAudioTracks": "Audio Tracks",
|
||||||
"LabelStatsAuthors": "Authors",
|
"LabelStatsAuthors": "Authors",
|
||||||
"LabelStatsBestDay": "Best Day",
|
"LabelStatsBestDay": "Best Day",
|
||||||
@@ -655,6 +671,7 @@
|
|||||||
"LabelTheme": "Theme",
|
"LabelTheme": "Theme",
|
||||||
"LabelThemeDark": "Dark",
|
"LabelThemeDark": "Dark",
|
||||||
"LabelThemeLight": "Light",
|
"LabelThemeLight": "Light",
|
||||||
|
"LabelThemeSepia": "Sepia",
|
||||||
"LabelTimeBase": "Time Base",
|
"LabelTimeBase": "Time Base",
|
||||||
"LabelTimeDurationXHours": "{0} hours",
|
"LabelTimeDurationXHours": "{0} hours",
|
||||||
"LabelTimeDurationXMinutes": "{0} minutes",
|
"LabelTimeDurationXMinutes": "{0} minutes",
|
||||||
@@ -739,6 +756,7 @@
|
|||||||
"MessageBookshelfNoResultsForFilter": "No results for filter \"{0}: {1}\"",
|
"MessageBookshelfNoResultsForFilter": "No results for filter \"{0}: {1}\"",
|
||||||
"MessageBookshelfNoResultsForQuery": "No results for query",
|
"MessageBookshelfNoResultsForQuery": "No results for query",
|
||||||
"MessageBookshelfNoSeries": "You have no series",
|
"MessageBookshelfNoSeries": "You have no series",
|
||||||
|
"MessageBulkChapterPattern": "How many chapters would you like to add with this numbering pattern?",
|
||||||
"MessageChapterEndIsAfter": "Chapter end is after the end of your audiobook",
|
"MessageChapterEndIsAfter": "Chapter end is after the end of your audiobook",
|
||||||
"MessageChapterErrorFirstNotZero": "First chapter must start at 0",
|
"MessageChapterErrorFirstNotZero": "First chapter must start at 0",
|
||||||
"MessageChapterErrorStartGteDuration": "Invalid start time must be less than audiobook duration",
|
"MessageChapterErrorStartGteDuration": "Invalid start time must be less than audiobook duration",
|
||||||
@@ -759,6 +777,7 @@
|
|||||||
"MessageConfirmDeleteSession": "Are you sure you want to delete this session?",
|
"MessageConfirmDeleteSession": "Are you sure you want to delete this session?",
|
||||||
"MessageConfirmEmbedMetadataInAudioFiles": "Are you sure you want to embed metadata in {0} audio files?",
|
"MessageConfirmEmbedMetadataInAudioFiles": "Are you sure you want to embed metadata in {0} audio files?",
|
||||||
"MessageConfirmForceReScan": "Are you sure you want to force re-scan?",
|
"MessageConfirmForceReScan": "Are you sure you want to force re-scan?",
|
||||||
|
"MessageConfirmLogoutDevice": "Are you sure you want to log out of \"{0}\"?",
|
||||||
"MessageConfirmMarkAllEpisodesFinished": "Are you sure you want to mark all episodes as finished?",
|
"MessageConfirmMarkAllEpisodesFinished": "Are you sure you want to mark all episodes as finished?",
|
||||||
"MessageConfirmMarkAllEpisodesNotFinished": "Are you sure you want to mark all episodes as not finished?",
|
"MessageConfirmMarkAllEpisodesNotFinished": "Are you sure you want to mark all episodes as not finished?",
|
||||||
"MessageConfirmMarkItemFinished": "Are you sure you want to mark \"{0}\" as finished?",
|
"MessageConfirmMarkItemFinished": "Are you sure you want to mark \"{0}\" as finished?",
|
||||||
@@ -801,6 +820,8 @@
|
|||||||
"MessageFeedURLWillBe": "Feed URL will be {0}",
|
"MessageFeedURLWillBe": "Feed URL will be {0}",
|
||||||
"MessageFetching": "Fetching...",
|
"MessageFetching": "Fetching...",
|
||||||
"MessageForceReScanDescription": "will scan all files again like a fresh scan. Audio file ID3 tags, OPF files, and text files will be scanned as new.",
|
"MessageForceReScanDescription": "will scan all files again like a fresh scan. Audio file ID3 tags, OPF files, and text files will be scanned as new.",
|
||||||
|
"MessageHeatmapListeningTimeTooltip": "<strong>{0} listening</strong> on {1}",
|
||||||
|
"MessageHeatmapNoListeningSessions": "No listening sessions on {0}",
|
||||||
"MessageImportantNotice": "Important Notice!",
|
"MessageImportantNotice": "Important Notice!",
|
||||||
"MessageInsertChapterBelow": "Insert chapter below",
|
"MessageInsertChapterBelow": "Insert chapter below",
|
||||||
"MessageInvalidAsin": "Invalid ASIN",
|
"MessageInvalidAsin": "Invalid ASIN",
|
||||||
@@ -871,7 +892,7 @@
|
|||||||
"MessageResetChaptersConfirm": "Are you sure you want to reset chapters and undo the changes you made?",
|
"MessageResetChaptersConfirm": "Are you sure you want to reset chapters and undo the changes you made?",
|
||||||
"MessageRestoreBackupConfirm": "Are you sure you want to restore the backup created on",
|
"MessageRestoreBackupConfirm": "Are you sure you want to restore the backup created on",
|
||||||
"MessageRestoreBackupWarning": "Restoring a backup will overwrite the entire database located at /config and cover images in /metadata/items & /metadata/authors.<br /><br />Backups do not modify any files in your library folders. If you have enabled server settings to store cover art and metadata in your library folders then those are not backed up or overwritten.<br /><br />All clients using your server will be automatically refreshed.",
|
"MessageRestoreBackupWarning": "Restoring a backup will overwrite the entire database located at /config and cover images in /metadata/items & /metadata/authors.<br /><br />Backups do not modify any files in your library folders. If you have enabled server settings to store cover art and metadata in your library folders then those are not backed up or overwritten.<br /><br />All clients using your server will be automatically refreshed.",
|
||||||
"MessageScheduleLibraryScanNote": "For most users, it is recommended to leave this feature disabled and keep the folder watcher setting enabled. The folder watcher will automatically detect changes in your library folders. The folder watcher doesn't work for every file system (like NFS) so scheduled library scans can be used instead.",
|
"MessageScheduleLibraryScanNote": "For most users, it is recommended to leave this feature disabled and keep the \"Automatically watch library for changes\" setting enabled - it will automatically detect changes in your library folders. Enable this feature if \"Automatically watch library for changes\" does not work for your file system (like NFS).",
|
||||||
"MessageScheduleRunEveryWeekdayAtTime": "Run every {0} at {1}",
|
"MessageScheduleRunEveryWeekdayAtTime": "Run every {0} at {1}",
|
||||||
"MessageSearchResultsFor": "Search results for",
|
"MessageSearchResultsFor": "Search results for",
|
||||||
"MessageSelected": "{0} selected",
|
"MessageSelected": "{0} selected",
|
||||||
@@ -940,6 +961,7 @@
|
|||||||
"NotificationOnRSSFeedDisabledDescription": "Triggered when automatic episode downloads are disabled due to too many failed attempts",
|
"NotificationOnRSSFeedDisabledDescription": "Triggered when automatic episode downloads are disabled due to too many failed attempts",
|
||||||
"NotificationOnRSSFeedFailedDescription": "Triggered when the RSS feed request fails for an automatic episode download",
|
"NotificationOnRSSFeedFailedDescription": "Triggered when the RSS feed request fails for an automatic episode download",
|
||||||
"NotificationOnTestDescription": "Event for testing the notification system",
|
"NotificationOnTestDescription": "Event for testing the notification system",
|
||||||
|
"PlaceholderBulkChapterInput": "Enter chapter title or use numbering (e.g., 'Episode 1', 'Chapter 10', '1.')",
|
||||||
"PlaceholderNewCollection": "New collection name",
|
"PlaceholderNewCollection": "New collection name",
|
||||||
"PlaceholderNewFolderPath": "New folder path",
|
"PlaceholderNewFolderPath": "New folder path",
|
||||||
"PlaceholderNewPlaylist": "New playlist name",
|
"PlaceholderNewPlaylist": "New playlist name",
|
||||||
@@ -993,8 +1015,12 @@
|
|||||||
"ToastBookmarkCreateFailed": "Failed to create bookmark",
|
"ToastBookmarkCreateFailed": "Failed to create bookmark",
|
||||||
"ToastBookmarkCreateSuccess": "Bookmark added",
|
"ToastBookmarkCreateSuccess": "Bookmark added",
|
||||||
"ToastBookmarkRemoveSuccess": "Bookmark removed",
|
"ToastBookmarkRemoveSuccess": "Bookmark removed",
|
||||||
|
"ToastBulkChapterInvalidCount": "Enter a number between 1 and 150",
|
||||||
"ToastCachePurgeFailed": "Failed to purge cache",
|
"ToastCachePurgeFailed": "Failed to purge cache",
|
||||||
"ToastCachePurgeSuccess": "Cache purged successfully",
|
"ToastCachePurgeSuccess": "Cache purged successfully",
|
||||||
|
"ToastChapterLocked": "Chapter is locked.",
|
||||||
|
"ToastChapterStartTimeAdjusted": "Chapter start time adjusted by {0} seconds",
|
||||||
|
"ToastChaptersAllLocked": "All chapters are locked. Unlock some chapters to shift their times.",
|
||||||
"ToastChaptersHaveErrors": "Chapters have errors",
|
"ToastChaptersHaveErrors": "Chapters have errors",
|
||||||
"ToastChaptersInvalidShiftAmountLast": "Invalid shift amount. The last chapter start time would extend beyond the duration of this audiobook.",
|
"ToastChaptersInvalidShiftAmountLast": "Invalid shift amount. The last chapter start time would extend beyond the duration of this audiobook.",
|
||||||
"ToastChaptersInvalidShiftAmountStart": "Invalid shift amount. The first chapter would have zero or negative length and would be overwritten by the second chapter. Increase the start duration of second chapter.",
|
"ToastChaptersInvalidShiftAmountStart": "Invalid shift amount. The first chapter would have zero or negative length and would be overwritten by the second chapter. Increase the start duration of second chapter.",
|
||||||
@@ -1004,6 +1030,8 @@
|
|||||||
"ToastCollectionItemsAddFailed": "Item(s) added to collection failed",
|
"ToastCollectionItemsAddFailed": "Item(s) added to collection failed",
|
||||||
"ToastCollectionRemoveSuccess": "Collection removed",
|
"ToastCollectionRemoveSuccess": "Collection removed",
|
||||||
"ToastCollectionUpdateSuccess": "Collection updated",
|
"ToastCollectionUpdateSuccess": "Collection updated",
|
||||||
|
"ToastConnectionNotAvailable": "Connection not available. Please try again later",
|
||||||
|
"ToastCoverSearchFailed": "Cover search failed",
|
||||||
"ToastCoverUpdateFailed": "Cover update failed",
|
"ToastCoverUpdateFailed": "Cover update failed",
|
||||||
"ToastDateTimeInvalidOrIncomplete": "Date and time is invalid or incomplete",
|
"ToastDateTimeInvalidOrIncomplete": "Date and time is invalid or incomplete",
|
||||||
"ToastDeleteFileFailed": "Failed to delete file",
|
"ToastDeleteFileFailed": "Failed to delete file",
|
||||||
@@ -1028,6 +1056,7 @@
|
|||||||
"ToastInvalidImageUrl": "Invalid image URL",
|
"ToastInvalidImageUrl": "Invalid image URL",
|
||||||
"ToastInvalidMaxEpisodesToDownload": "Invalid max episodes to download",
|
"ToastInvalidMaxEpisodesToDownload": "Invalid max episodes to download",
|
||||||
"ToastInvalidUrl": "Invalid URL",
|
"ToastInvalidUrl": "Invalid URL",
|
||||||
|
"ToastInvalidUrls": "One or more URLs are invalid",
|
||||||
"ToastItemCoverUpdateSuccess": "Item cover updated",
|
"ToastItemCoverUpdateSuccess": "Item cover updated",
|
||||||
"ToastItemDeletedFailed": "Failed to delete item",
|
"ToastItemDeletedFailed": "Failed to delete item",
|
||||||
"ToastItemDeletedSuccess": "Deleted item",
|
"ToastItemDeletedSuccess": "Deleted item",
|
||||||
@@ -1077,6 +1106,7 @@
|
|||||||
"ToastPlaylistUpdateSuccess": "Playlist updated",
|
"ToastPlaylistUpdateSuccess": "Playlist updated",
|
||||||
"ToastPodcastCreateFailed": "Failed to create podcast",
|
"ToastPodcastCreateFailed": "Failed to create podcast",
|
||||||
"ToastPodcastCreateSuccess": "Podcast created successfully",
|
"ToastPodcastCreateSuccess": "Podcast created successfully",
|
||||||
|
"ToastPodcastEpisodeUpdated": "Episode updated",
|
||||||
"ToastPodcastGetFeedFailed": "Failed to get podcast feed",
|
"ToastPodcastGetFeedFailed": "Failed to get podcast feed",
|
||||||
"ToastPodcastNoEpisodesInFeed": "No episodes found in RSS feed",
|
"ToastPodcastNoEpisodesInFeed": "No episodes found in RSS feed",
|
||||||
"ToastPodcastNoRssFeed": "Podcast does not have an RSS feed",
|
"ToastPodcastNoRssFeed": "Podcast does not have an RSS feed",
|
||||||
@@ -1127,5 +1157,13 @@
|
|||||||
"ToastUserPasswordChangeSuccess": "Password changed successfully",
|
"ToastUserPasswordChangeSuccess": "Password changed successfully",
|
||||||
"ToastUserPasswordMismatch": "Passwords do not match",
|
"ToastUserPasswordMismatch": "Passwords do not match",
|
||||||
"ToastUserPasswordMustChange": "New password cannot match old password",
|
"ToastUserPasswordMustChange": "New password cannot match old password",
|
||||||
"ToastUserRootRequireName": "Must enter a root username"
|
"ToastUserRootRequireName": "Must enter a root username",
|
||||||
|
"TooltipAddChapters": "Add chapter(s)",
|
||||||
|
"TooltipAddOneSecond": "Add 1 second",
|
||||||
|
"TooltipAdjustChapterStart": "Click to adjust start time",
|
||||||
|
"TooltipLockAllChapters": "Lock all chapters",
|
||||||
|
"TooltipLockChapter": "Lock chapter (Shift+click for range)",
|
||||||
|
"TooltipSubtractOneSecond": "Subtract 1 second",
|
||||||
|
"TooltipUnlockAllChapters": "Unlock all chapters",
|
||||||
|
"TooltipUnlockChapter": "Unlock chapter (Shift+click for range)"
|
||||||
}
|
}
|
||||||
+160
-98
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"ButtonAdd": "Añadir",
|
"ButtonAdd": "Añadir",
|
||||||
|
"ButtonAddApiKey": "Añadir clave API",
|
||||||
"ButtonAddChapters": "Añadir capítulos",
|
"ButtonAddChapters": "Añadir capítulos",
|
||||||
"ButtonAddDevice": "Añadir dispositivo",
|
"ButtonAddDevice": "Añadir dispositivo",
|
||||||
"ButtonAddLibrary": "Añadir biblioteca",
|
"ButtonAddLibrary": "Añadir biblioteca",
|
||||||
@@ -19,9 +20,10 @@
|
|||||||
"ButtonCheckAndDownloadNewEpisodes": "Comprobar y descargar episodios nuevos",
|
"ButtonCheckAndDownloadNewEpisodes": "Comprobar y descargar episodios nuevos",
|
||||||
"ButtonChooseAFolder": "Elegir una carpeta",
|
"ButtonChooseAFolder": "Elegir una carpeta",
|
||||||
"ButtonChooseFiles": "Elegir archivos",
|
"ButtonChooseFiles": "Elegir archivos",
|
||||||
"ButtonClearFilter": "Quitar filtros",
|
"ButtonClearFilter": "Vaciar filtro",
|
||||||
|
"ButtonClose": "Cerrar",
|
||||||
"ButtonCloseFeed": "Cerrar suministro",
|
"ButtonCloseFeed": "Cerrar suministro",
|
||||||
"ButtonCloseSession": "Cerrar la sesión abierta",
|
"ButtonCloseSession": "Cerrar sesión abierta",
|
||||||
"ButtonCollections": "Colecciones",
|
"ButtonCollections": "Colecciones",
|
||||||
"ButtonConfigureScanner": "Configurar Escáner",
|
"ButtonConfigureScanner": "Configurar Escáner",
|
||||||
"ButtonCreate": "Crear",
|
"ButtonCreate": "Crear",
|
||||||
@@ -31,27 +33,28 @@
|
|||||||
"ButtonEdit": "Editar",
|
"ButtonEdit": "Editar",
|
||||||
"ButtonEditChapters": "Editar capítulos",
|
"ButtonEditChapters": "Editar capítulos",
|
||||||
"ButtonEditPodcast": "Editar pódcast",
|
"ButtonEditPodcast": "Editar pódcast",
|
||||||
"ButtonEnable": "Permitir",
|
"ButtonEnable": "Habilitar",
|
||||||
"ButtonFireAndFail": "Ejecutado y fallido",
|
"ButtonFireAndFail": "Ejecutado y fallido",
|
||||||
"ButtonFireOnTest": "Activar evento de prueba",
|
"ButtonFireOnTest": "Activar evento de prueba",
|
||||||
"ButtonForceReScan": "Forzar Re-Escaneo",
|
"ButtonForceReScan": "Forzar Re-Escaneo",
|
||||||
"ButtonFullPath": "Ruta completa",
|
"ButtonFullPath": "Ruta completa",
|
||||||
"ButtonHide": "Ocultar",
|
"ButtonHide": "Ocultar",
|
||||||
"ButtonHome": "Inicio",
|
"ButtonHome": "Inicio",
|
||||||
"ButtonIssues": "Problemas",
|
"ButtonIssues": "Incidencias",
|
||||||
"ButtonJumpBackward": "Retroceder",
|
"ButtonJumpBackward": "Retroceder",
|
||||||
"ButtonJumpForward": "Adelantar",
|
"ButtonJumpForward": "Adelantar",
|
||||||
"ButtonLatest": "Más recientes",
|
"ButtonLatest": "Más recientes",
|
||||||
"ButtonLibrary": "Biblioteca",
|
"ButtonLibrary": "Biblioteca",
|
||||||
"ButtonLogout": "Salir",
|
"ButtonLogout": "Cerrar Sesión",
|
||||||
"ButtonLookup": "Buscar",
|
"ButtonLogoutAllDevices": "Cerrar sesión en todos los dispositivos",
|
||||||
|
"ButtonLookup": "Averiguar",
|
||||||
"ButtonManageTracks": "Gestionar pistas",
|
"ButtonManageTracks": "Gestionar pistas",
|
||||||
"ButtonMapChapterTitles": "Asignar Títulos a Capítulos",
|
"ButtonMapChapterTitles": "Asignar Títulos a Capítulos",
|
||||||
"ButtonMatchAllAuthors": "Encontrar Todos los Autores",
|
"ButtonMatchAllAuthors": "Encontrar Todos los Autores",
|
||||||
"ButtonMatchBooks": "Encontrar Libros",
|
"ButtonMatchBooks": "Cotejar Libros",
|
||||||
"ButtonNevermind": "Olvidar",
|
"ButtonNevermind": "Olvidar",
|
||||||
"ButtonNext": "Siguiente",
|
"ButtonNext": "Siguiente",
|
||||||
"ButtonNextChapter": "Siguiente Capítulo",
|
"ButtonNextChapter": "Siguiente capítulo",
|
||||||
"ButtonNextItemInQueue": "El siguiente elemento en cola",
|
"ButtonNextItemInQueue": "El siguiente elemento en cola",
|
||||||
"ButtonOk": "Aceptar",
|
"ButtonOk": "Aceptar",
|
||||||
"ButtonOpenFeed": "Abrir suministro",
|
"ButtonOpenFeed": "Abrir suministro",
|
||||||
@@ -62,26 +65,26 @@
|
|||||||
"ButtonPlaying": "Reproduciendo",
|
"ButtonPlaying": "Reproduciendo",
|
||||||
"ButtonPlaylists": "Listas de reproducción",
|
"ButtonPlaylists": "Listas de reproducción",
|
||||||
"ButtonPrevious": "Anterior",
|
"ButtonPrevious": "Anterior",
|
||||||
"ButtonPreviousChapter": "Capítulo Anterior",
|
"ButtonPreviousChapter": "Capítulo anterior",
|
||||||
"ButtonProbeAudioFile": "Examinar archivo de audio",
|
"ButtonProbeAudioFile": "Sonda del archivo de audio",
|
||||||
"ButtonPurgeAllCache": "Purgar toda la antememoria",
|
"ButtonPurgeAllCache": "Purgar toda la caché",
|
||||||
"ButtonPurgeItemsCache": "Purgar antememoria de elementos",
|
"ButtonPurgeItemsCache": "Purgar caché de elementos",
|
||||||
"ButtonQueueAddItem": "Añadir a la cola",
|
"ButtonQueueAddItem": "Añadir a cola",
|
||||||
"ButtonQueueRemoveItem": "Quitar de la cola",
|
"ButtonQueueRemoveItem": "Quitar de cola",
|
||||||
"ButtonQuickEmbed": "Inserción rápida",
|
"ButtonQuickEmbed": "Inserción rápida",
|
||||||
"ButtonQuickEmbedMetadata": "Agregue metadatos rápidamente",
|
"ButtonQuickEmbedMetadata": "Empotrar metadatos rápidamente",
|
||||||
"ButtonQuickMatch": "Encontrar Rápido",
|
"ButtonQuickMatch": "Cotejo Rápido",
|
||||||
"ButtonReScan": "Re-Escanear",
|
"ButtonReScan": "Re-Escanear",
|
||||||
"ButtonRead": "Leer",
|
"ButtonRead": "Leer",
|
||||||
"ButtonReadLess": "Leer menos",
|
"ButtonReadLess": "Leer menos",
|
||||||
"ButtonReadMore": "Leer más",
|
"ButtonReadMore": "Leer más",
|
||||||
"ButtonRefresh": "Actualizar",
|
"ButtonRefresh": "Recargar",
|
||||||
"ButtonRemove": "Quitar",
|
"ButtonRemove": "Quitar",
|
||||||
"ButtonRemoveAll": "Quitar todo",
|
"ButtonRemoveAll": "Quitar todo",
|
||||||
"ButtonRemoveAllLibraryItems": "Quitar todos los elementos de la biblioteca",
|
"ButtonRemoveAllLibraryItems": "Quitar todos los elementos de la biblioteca",
|
||||||
"ButtonRemoveFromContinueListening": "Quitar de Continuar escuchando",
|
"ButtonRemoveFromContinueListening": "Quitar desde Escucha Continua",
|
||||||
"ButtonRemoveFromContinueReading": "Quitar de Continuar leyendo",
|
"ButtonRemoveFromContinueReading": "Quitar desde Continuar Leyendo",
|
||||||
"ButtonRemoveSeriesFromContinueSeries": "Quitar serie de Continuar serie",
|
"ButtonRemoveSeriesFromContinueSeries": "Quitar Series desde Series Continuas",
|
||||||
"ButtonReset": "Restablecer",
|
"ButtonReset": "Restablecer",
|
||||||
"ButtonResetToDefault": "Restaurar valores predeterminados",
|
"ButtonResetToDefault": "Restaurar valores predeterminados",
|
||||||
"ButtonRestore": "Restaurar",
|
"ButtonRestore": "Restaurar",
|
||||||
@@ -90,45 +93,47 @@
|
|||||||
"ButtonSaveTracklist": "Guardar lista de pistas",
|
"ButtonSaveTracklist": "Guardar lista de pistas",
|
||||||
"ButtonScan": "Escanear",
|
"ButtonScan": "Escanear",
|
||||||
"ButtonScanLibrary": "Escanear biblioteca",
|
"ButtonScanLibrary": "Escanear biblioteca",
|
||||||
"ButtonScrollLeft": "Desplazarse hacia la izquierda",
|
"ButtonScrollLeft": "Desplazarse a la izquierda",
|
||||||
"ButtonScrollRight": "Desplazarse hacia la derecha",
|
"ButtonScrollRight": "Desplazarse a la derecha",
|
||||||
"ButtonSearch": "Buscar",
|
"ButtonSearch": "Buscar",
|
||||||
"ButtonSelectFolderPath": "Seleccionar ruta de carpeta",
|
"ButtonSelectFolderPath": "Seleccionar ruta de carpeta",
|
||||||
"ButtonSeries": "Series",
|
"ButtonSeries": "Series",
|
||||||
"ButtonSetChaptersFromTracks": "Seleccionar Capítulos Según las Pistas",
|
"ButtonSetChaptersFromTracks": "Establecer capítulos según las pistas",
|
||||||
"ButtonShare": "Compartir",
|
"ButtonShare": "Compartir",
|
||||||
"ButtonShiftTimes": "Desplazar Tiempos",
|
"ButtonShiftTimes": "Veces de Desplazo",
|
||||||
"ButtonShow": "Mostrar",
|
"ButtonShow": "Mostrar",
|
||||||
"ButtonStartM4BEncode": "Iniciar Codificación M4B",
|
"ButtonStartM4BEncode": "Iniciar Codificación M4B",
|
||||||
"ButtonStartMetadataEmbed": "Iniciar la Inserción de Metadata",
|
"ButtonStartMetadataEmbed": "Iniciar Inserción de Metadatos",
|
||||||
"ButtonStats": "Estadísticas",
|
"ButtonStats": "Estadísticas",
|
||||||
"ButtonSubmit": "Enviar",
|
"ButtonSubmit": "Entregar",
|
||||||
"ButtonTest": "Prueba",
|
"ButtonTest": "Prueba",
|
||||||
"ButtonUnlinkOpenId": "Desvincular OpenID",
|
"ButtonUnlinkOpenId": "Desenlazar OpenID",
|
||||||
"ButtonUpload": "Cargar",
|
"ButtonUpload": "Subir",
|
||||||
"ButtonUploadBackup": "Cargar respaldo",
|
"ButtonUploadBackup": "Subir Respaldo",
|
||||||
"ButtonUploadCover": "Cargar cubierta",
|
"ButtonUploadCover": "Subir Cubierta",
|
||||||
"ButtonUploadOPMLFile": "Cargar archivo OPML",
|
"ButtonUploadOPMLFile": "Subir archivo OPML",
|
||||||
"ButtonUserDelete": "Eliminar usuario {0}",
|
"ButtonUserDelete": "Eliminar usuario {0}",
|
||||||
"ButtonUserEdit": "Editar usuario {0}",
|
"ButtonUserEdit": "Editar usuario {0}",
|
||||||
"ButtonViewAll": "Ver todo",
|
"ButtonViewAll": "Ver todo",
|
||||||
"ButtonYes": "Sí",
|
"ButtonYes": "Sí",
|
||||||
"ErrorUploadFetchMetadataAPI": "Error al recuperar los metadatos",
|
"ErrorUploadFetchMetadataAPI": "Error al recuperar los metadatos",
|
||||||
"ErrorUploadFetchMetadataNoResults": "No se pudieron recuperar los metadatos; pruebe a actualizar el título o autor",
|
"ErrorUploadFetchMetadataNoResults": "No se pudieron recuperar los metadatos; pruebe a actualizar el título y/o autor",
|
||||||
"ErrorUploadLacksTitle": "Debe tener título",
|
"ErrorUploadLacksTitle": "Debe tener un título",
|
||||||
"HeaderAccount": "Cuenta",
|
"HeaderAccount": "Cuenta",
|
||||||
"HeaderAddCustomMetadataProvider": "Añadir proveedor de metadatos personalizado",
|
"HeaderAddCustomMetadataProvider": "Añadir proveedor de metadatos personalizado",
|
||||||
"HeaderAdvanced": "Avanzado",
|
"HeaderAdvanced": "Avanzado",
|
||||||
"HeaderAppriseNotificationSettings": "Configuración de notificaciones de Apprise",
|
"HeaderApiKeys": "Claves API",
|
||||||
"HeaderAudioTracks": "Pistas de audio",
|
"HeaderAppriseNotificationSettings": "Ajustes de notificaciones de Apprise",
|
||||||
|
"HeaderAudioTracks": "Pistas de Audio",
|
||||||
"HeaderAudiobookTools": "Herramientas de Gestión de Archivos de Audiolibro",
|
"HeaderAudiobookTools": "Herramientas de Gestión de Archivos de Audiolibro",
|
||||||
"HeaderAuthentication": "Autenticación",
|
"HeaderAuthentication": "Autenticación",
|
||||||
"HeaderBackups": "Respaldos",
|
"HeaderBackups": "Respaldos",
|
||||||
"HeaderChangePassword": "Cambiar contraseña",
|
"HeaderBulkChapterModal": "Añadir Múltiples Capítulos",
|
||||||
|
"HeaderChangePassword": "Cambiar Contraseña",
|
||||||
"HeaderChapters": "Capítulos",
|
"HeaderChapters": "Capítulos",
|
||||||
"HeaderChooseAFolder": "Escoger una Carpeta",
|
"HeaderChooseAFolder": "Escoger una Carpeta",
|
||||||
"HeaderCollection": "Colección",
|
"HeaderCollection": "Colección",
|
||||||
"HeaderCollectionItems": "Elementos en la colección",
|
"HeaderCollectionItems": "Elementos de colección",
|
||||||
"HeaderCover": "Cubierta",
|
"HeaderCover": "Cubierta",
|
||||||
"HeaderCurrentDownloads": "Descargas actuales",
|
"HeaderCurrentDownloads": "Descargas actuales",
|
||||||
"HeaderCustomMessageOnLogin": "Mensaje personalizado al acceder",
|
"HeaderCustomMessageOnLogin": "Mensaje personalizado al acceder",
|
||||||
@@ -136,48 +141,49 @@
|
|||||||
"HeaderDetails": "Detalles",
|
"HeaderDetails": "Detalles",
|
||||||
"HeaderDownloadQueue": "Cola de descargas",
|
"HeaderDownloadQueue": "Cola de descargas",
|
||||||
"HeaderEbookFiles": "Archivos de libros digitales",
|
"HeaderEbookFiles": "Archivos de libros digitales",
|
||||||
"HeaderEmail": "Correo electrónico",
|
"HeaderEmail": "Correo-e",
|
||||||
"HeaderEmailSettings": "Configuración de correo electrónico",
|
"HeaderEmailSettings": "Ajustes de correo-e",
|
||||||
"HeaderEpisodes": "Episodios",
|
"HeaderEpisodes": "Episodios",
|
||||||
"HeaderEreaderDevices": "Dispositivos Ereader",
|
"HeaderEreaderDevices": "Dispositivos Lector-e",
|
||||||
"HeaderEreaderSettings": "Configuración del lector",
|
"HeaderEreaderSettings": "Ajustes del Lector-e",
|
||||||
"HeaderFiles": "Archivos",
|
"HeaderFiles": "Archivos",
|
||||||
"HeaderFindChapters": "Buscar capítulos",
|
"HeaderFindChapters": "Buscar capítulos",
|
||||||
"HeaderIgnoredFiles": "Archivos ignorados",
|
"HeaderIgnoredFiles": "Archivos ignorados",
|
||||||
"HeaderItemFiles": "Archivos de elementos",
|
"HeaderItemFiles": "Archivos del elemento",
|
||||||
"HeaderItemMetadataUtils": "Utilidades de metadatos de elementos",
|
"HeaderItemMetadataUtils": "Utilidades de metadatos del elemento",
|
||||||
"HeaderLastListeningSession": "Última sesión de escucha",
|
"HeaderLastListeningSession": "Última sesión de escucha",
|
||||||
"HeaderLatestEpisodes": "Episodios más recientes",
|
"HeaderLatestEpisodes": "Episodios más recientes",
|
||||||
"HeaderLibraries": "Bibliotecas",
|
"HeaderLibraries": "Bibliotecas",
|
||||||
"HeaderLibraryFiles": "Archivos de biblioteca",
|
"HeaderLibraryFiles": "Archivos de biblioteca",
|
||||||
"HeaderLibraryStats": "Estadísticas de biblioteca",
|
"HeaderLibraryStats": "Estadísticas de biblioteca",
|
||||||
"HeaderListeningSessions": "Sesión",
|
"HeaderListeningSessions": "Sesiones Listadas",
|
||||||
"HeaderListeningStats": "Estadísticas de Tiempo Escuchado",
|
"HeaderListeningStats": "Estadísticas de Tiempo Escuchado",
|
||||||
"HeaderLogin": "Acceder",
|
"HeaderLogin": "Inicio de Sesión",
|
||||||
"HeaderLogs": "Registros",
|
"HeaderLogs": "Bitácoras",
|
||||||
"HeaderManageGenres": "Gestionar géneros",
|
"HeaderManageGenres": "Gestionar géneros",
|
||||||
"HeaderManageTags": "Gestionar etiquetas",
|
"HeaderManageTags": "Gestionar etiquetas",
|
||||||
"HeaderMapDetails": "Asignar Detalles",
|
"HeaderMapDetails": "Asignar Detalles",
|
||||||
"HeaderMatch": "Encontrar",
|
"HeaderMatch": "Coincidir",
|
||||||
"HeaderMetadataOrderOfPrecedence": "Orden de precedencia de metadatos",
|
"HeaderMetadataOrderOfPrecedence": "Orden de precedencia de metadatos",
|
||||||
"HeaderMetadataToEmbed": "Metadatos para Insertar",
|
"HeaderMetadataToEmbed": "Metadatos para empotrar",
|
||||||
"HeaderNewAccount": "Cuenta nueva",
|
"HeaderNewAccount": "Crear Cuenta",
|
||||||
|
"HeaderNewApiKey": "Nueva clave API",
|
||||||
"HeaderNewLibrary": "Biblioteca nueva",
|
"HeaderNewLibrary": "Biblioteca nueva",
|
||||||
"HeaderNotificationCreate": "Crear notificación",
|
"HeaderNotificationCreate": "Crear Notificación",
|
||||||
"HeaderNotificationUpdate": "Notificación de actualización",
|
"HeaderNotificationUpdate": "Notificación de Actualización",
|
||||||
"HeaderNotifications": "Notificaciones",
|
"HeaderNotifications": "Notificaciones",
|
||||||
"HeaderOpenIDConnectAuthentication": "Autenticación OpenID Connect",
|
"HeaderOpenIDConnectAuthentication": "Autenticación OpenID Connect",
|
||||||
"HeaderOpenListeningSessions": "Sesiones públicas de escucha",
|
"HeaderOpenListeningSessions": "Abrir escucha de sesiones",
|
||||||
"HeaderOpenRSSFeed": "Abrir suministro RSS",
|
"HeaderOpenRSSFeed": "Abrir suministro RSS",
|
||||||
"HeaderOtherFiles": "Otros archivos",
|
"HeaderOtherFiles": "Otros archivos",
|
||||||
"HeaderPasswordAuthentication": "Autenticación por contraseña",
|
"HeaderPasswordAuthentication": "Autenticación por contraseña",
|
||||||
"HeaderPermissions": "Permisos",
|
"HeaderPermissions": "Permisos",
|
||||||
"HeaderPlayerQueue": "Cola del reproductor",
|
"HeaderPlayerQueue": "Cola del reproductor",
|
||||||
"HeaderPlayerSettings": "Configuración del reproductor",
|
"HeaderPlayerSettings": "Ajustes del reproductor",
|
||||||
"HeaderPlaylist": "Lista de reproducción",
|
"HeaderPlaylist": "Lista de reproducción",
|
||||||
"HeaderPlaylistItems": "Elementos de lista de reproducción",
|
"HeaderPlaylistItems": "Elementos de lista de reproducción",
|
||||||
"HeaderPodcastsToAdd": "Pódcast para añadir",
|
"HeaderPodcastsToAdd": "Pódcast para añadir",
|
||||||
"HeaderPresets": "Preconfiguraciones",
|
"HeaderPresets": "Preajustes",
|
||||||
"HeaderPreviewCover": "Previsualizar cubierta",
|
"HeaderPreviewCover": "Previsualizar cubierta",
|
||||||
"HeaderRSSFeedGeneral": "Detalles de RSS",
|
"HeaderRSSFeedGeneral": "Detalles de RSS",
|
||||||
"HeaderRSSFeedIsOpen": "El suministro RSS está abierto",
|
"HeaderRSSFeedIsOpen": "El suministro RSS está abierto",
|
||||||
@@ -186,17 +192,19 @@
|
|||||||
"HeaderRemoveEpisodes": "Quitar {0} episodios",
|
"HeaderRemoveEpisodes": "Quitar {0} episodios",
|
||||||
"HeaderSavedMediaProgress": "Guardar Progreso de Multimedia",
|
"HeaderSavedMediaProgress": "Guardar Progreso de Multimedia",
|
||||||
"HeaderSchedule": "Horario",
|
"HeaderSchedule": "Horario",
|
||||||
"HeaderScheduleEpisodeDownloads": "Programar descargas automáticas de episodios",
|
"HeaderScheduleEpisodeDownloads": "Planificador de auto‐descargas de episodios",
|
||||||
"HeaderScheduleLibraryScans": "Programar Escaneo Automático de Biblioteca",
|
"HeaderScheduleLibraryScans": "Planificar Auto‐Escaneo de Biblioteca",
|
||||||
"HeaderSession": "Sesión",
|
"HeaderSession": "Sesión",
|
||||||
"HeaderSetBackupSchedule": "Programar Respaldo",
|
"HeaderSessions": "Sesiones",
|
||||||
"HeaderSettings": "Configuración",
|
"HeaderSetBackupSchedule": "Establecer Planificación de Respaldo",
|
||||||
|
"HeaderSettings": "Ajustes",
|
||||||
"HeaderSettingsDisplay": "Interfaz",
|
"HeaderSettingsDisplay": "Interfaz",
|
||||||
"HeaderSettingsExperimental": "Funcionalidades experimentales",
|
"HeaderSettingsExperimental": "Características experimentales",
|
||||||
"HeaderSettingsGeneral": "Generales",
|
"HeaderSettingsGeneral": "Generales",
|
||||||
"HeaderSettingsScanner": "Escáner",
|
"HeaderSettingsScanner": "Escáner",
|
||||||
|
"HeaderSettingsSecurity": "Seguridad",
|
||||||
"HeaderSettingsWebClient": "Cliente web",
|
"HeaderSettingsWebClient": "Cliente web",
|
||||||
"HeaderSleepTimer": "Temporizador de apagado",
|
"HeaderSleepTimer": "Cronómetro de dormida",
|
||||||
"HeaderStatsLargestItems": "Elementos más grandes",
|
"HeaderStatsLargestItems": "Elementos más grandes",
|
||||||
"HeaderStatsLongestItems": "Elementos más extensos (h)",
|
"HeaderStatsLongestItems": "Elementos más extensos (h)",
|
||||||
"HeaderStatsMinutesListeningChart": "Minutos escuchando (últimos 7 días)",
|
"HeaderStatsMinutesListeningChart": "Minutos escuchando (últimos 7 días)",
|
||||||
@@ -206,6 +214,7 @@
|
|||||||
"HeaderTableOfContents": "Sumario",
|
"HeaderTableOfContents": "Sumario",
|
||||||
"HeaderTools": "Herramientas",
|
"HeaderTools": "Herramientas",
|
||||||
"HeaderUpdateAccount": "Actualizar cuenta",
|
"HeaderUpdateAccount": "Actualizar cuenta",
|
||||||
|
"HeaderUpdateApiKey": "Actualizar clave API",
|
||||||
"HeaderUpdateAuthor": "Actualizar autor",
|
"HeaderUpdateAuthor": "Actualizar autor",
|
||||||
"HeaderUpdateDetails": "Actualizar detalles",
|
"HeaderUpdateDetails": "Actualizar detalles",
|
||||||
"HeaderUpdateLibrary": "Actualizar biblioteca",
|
"HeaderUpdateLibrary": "Actualizar biblioteca",
|
||||||
@@ -226,25 +235,29 @@
|
|||||||
"LabelAddToCollectionBatch": "Añadir {0} libros a colección",
|
"LabelAddToCollectionBatch": "Añadir {0} libros a colección",
|
||||||
"LabelAddToPlaylist": "Añadir a lista de reproducción",
|
"LabelAddToPlaylist": "Añadir a lista de reproducción",
|
||||||
"LabelAddToPlaylistBatch": "Añadir {0} elementos a lista de reproducción",
|
"LabelAddToPlaylistBatch": "Añadir {0} elementos a lista de reproducción",
|
||||||
"LabelAddedAt": "Añadido",
|
"LabelAddedAt": "Añadido en",
|
||||||
"LabelAddedDate": "{0} Añadido",
|
"LabelAddedDate": "Añadido {0}",
|
||||||
"LabelAdminUsersOnly": "Solamente usuarios administradores",
|
"LabelAdminUsersOnly": "Solamente usuarios administradores",
|
||||||
"LabelAll": "Todos",
|
"LabelAll": "Todos",
|
||||||
"LabelAllEpisodesDownloaded": "Todos los episodios descargados",
|
"LabelAllEpisodesDownloaded": "Todos los episodios descargados",
|
||||||
"LabelAllUsers": "Todos los usuarios",
|
"LabelAllUsers": "Todos los usuarios",
|
||||||
"LabelAllUsersExcludingGuests": "Todos los usuarios excepto invitados",
|
"LabelAllUsersExcludingGuests": "Todos los usuarios excepto invitados",
|
||||||
"LabelAllUsersIncludingGuests": "Todos los usuarios e invitados",
|
"LabelAllUsersIncludingGuests": "Todos los usuarios e invitados",
|
||||||
"LabelAlreadyInYourLibrary": "Ya existe en la Biblioteca",
|
"LabelAlreadyInYourLibrary": "Ya dentro de tu biblioteca",
|
||||||
"LabelApiToken": "Token de la API",
|
"LabelApiKeyCreated": "La clave de API “{0}” se ha creado correctamente.",
|
||||||
|
"LabelApiKeyCreatedDescription": "Asegúrate de copiar la clave de API ahora, no la volverás a ver otra vez.",
|
||||||
|
"LabelApiKeyUser": "Actuar en nombre del usuario",
|
||||||
|
"LabelApiKeyUserDescription": "Esta clave de API tendrá los mismos permisos que el usuario al que representa. En los registros se verá como si la solicitud la hubiera hecho el usuario directamente.",
|
||||||
|
"LabelApiToken": "Vale del API",
|
||||||
"LabelAppend": "Adjuntar",
|
"LabelAppend": "Adjuntar",
|
||||||
"LabelAudioBitrate": "Tasa de bits del audio (por ejemplo, 128k)",
|
"LabelAudioBitrate": "Tasa de bit del audio (p.ej., 128k)",
|
||||||
"LabelAudioChannels": "Canales de audio (1 o 2)",
|
"LabelAudioChannels": "Canales de audio (1 o 2)",
|
||||||
"LabelAudioCodec": "Códec de audio",
|
"LabelAudioCodec": "Códec de audio",
|
||||||
"LabelAuthor": "Autor",
|
"LabelAuthor": "Autor",
|
||||||
"LabelAuthorFirstLast": "Autor (Nombre Apellido)",
|
"LabelAuthorFirstLast": "Autor (Nombre Apellido)",
|
||||||
"LabelAuthorLastFirst": "Autor (Apellido, Nombre)",
|
"LabelAuthorLastFirst": "Autor (Apellido, Nombre)",
|
||||||
"LabelAuthors": "Autores",
|
"LabelAuthors": "Autores",
|
||||||
"LabelAutoDownloadEpisodes": "Descargar episodios automáticamente",
|
"LabelAutoDownloadEpisodes": "Auto‐Descargar episodios",
|
||||||
"LabelAutoFetchMetadata": "Recuperar metadatos automáticamente",
|
"LabelAutoFetchMetadata": "Recuperar metadatos automáticamente",
|
||||||
"LabelAutoFetchMetadataHelp": "Obtiene metadatos de título, autor y serie para agilizar la carga. Es posible que haya que cotejar metadatos adicionales después de la carga.",
|
"LabelAutoFetchMetadataHelp": "Obtiene metadatos de título, autor y serie para agilizar la carga. Es posible que haya que cotejar metadatos adicionales después de la carga.",
|
||||||
"LabelAutoLaunch": "Lanzamiento automático",
|
"LabelAutoLaunch": "Lanzamiento automático",
|
||||||
@@ -275,15 +288,16 @@
|
|||||||
"LabelClickToUseCurrentValue": "Pulse para utilizar el valor actual",
|
"LabelClickToUseCurrentValue": "Pulse para utilizar el valor actual",
|
||||||
"LabelClosePlayer": "Cerrar reproductor",
|
"LabelClosePlayer": "Cerrar reproductor",
|
||||||
"LabelCodec": "Codec",
|
"LabelCodec": "Codec",
|
||||||
"LabelCollapseSeries": "Colapsar serie",
|
"LabelCollapseSeries": "Colapsar Series",
|
||||||
"LabelCollapseSubSeries": "Contraer la subserie",
|
"LabelCollapseSubSeries": "Contraer la subserie",
|
||||||
"LabelCollection": "Colección",
|
"LabelCollection": "Colección",
|
||||||
"LabelCollections": "Colecciones",
|
"LabelCollections": "Colecciones",
|
||||||
"LabelComplete": "Completo",
|
"LabelComplete": "Completo",
|
||||||
"LabelConfirmPassword": "Confirmar contraseña",
|
"LabelConfirmPassword": "Confirmar contraseña",
|
||||||
"LabelContinueListening": "Seguir escuchando",
|
"LabelContinueListening": "Seguir Escuchando",
|
||||||
"LabelContinueReading": "Continuar leyendo",
|
"LabelContinueReading": "Continuar leyendo",
|
||||||
"LabelContinueSeries": "Continuar series",
|
"LabelContinueSeries": "Continuar series",
|
||||||
|
"LabelCorsAllowed": "Orígenes CORS Permitidos",
|
||||||
"LabelCover": "Cubierta",
|
"LabelCover": "Cubierta",
|
||||||
"LabelCoverImageURL": "URL de imagen de cubierta",
|
"LabelCoverImageURL": "URL de imagen de cubierta",
|
||||||
"LabelCoverProvider": "Proveedor de cubiertas",
|
"LabelCoverProvider": "Proveedor de cubiertas",
|
||||||
@@ -297,6 +311,7 @@
|
|||||||
"LabelDeleteFromFileSystemCheckbox": "Eliminar del sistema de archivos (desmarque para quitar de la base de datos solamente)",
|
"LabelDeleteFromFileSystemCheckbox": "Eliminar del sistema de archivos (desmarque para quitar de la base de datos solamente)",
|
||||||
"LabelDescription": "Descripción",
|
"LabelDescription": "Descripción",
|
||||||
"LabelDeselectAll": "Deseleccionar Todos",
|
"LabelDeselectAll": "Deseleccionar Todos",
|
||||||
|
"LabelDetectedPattern": "Patrón detectado:",
|
||||||
"LabelDevice": "Dispositivo",
|
"LabelDevice": "Dispositivo",
|
||||||
"LabelDeviceInfo": "Información del dispositivo",
|
"LabelDeviceInfo": "Información del dispositivo",
|
||||||
"LabelDeviceIsAvailableTo": "El dispositivo está disponible para...",
|
"LabelDeviceIsAvailableTo": "El dispositivo está disponible para...",
|
||||||
@@ -312,14 +327,14 @@
|
|||||||
"LabelDurationComparisonLonger": "({0} más largo)",
|
"LabelDurationComparisonLonger": "({0} más largo)",
|
||||||
"LabelDurationComparisonShorter": "({0} más corto)",
|
"LabelDurationComparisonShorter": "({0} más corto)",
|
||||||
"LabelDurationFound": "Duración Comprobada:",
|
"LabelDurationFound": "Duración Comprobada:",
|
||||||
"LabelEbook": "Libro electrónico",
|
"LabelEbook": "Libro-e",
|
||||||
"LabelEbooks": "Libros electrónicos",
|
"LabelEbooks": "Libros-e",
|
||||||
"LabelEdit": "Editar",
|
"LabelEdit": "Editar",
|
||||||
"LabelEmail": "Correo electrónico",
|
"LabelEmail": "Correo electrónico",
|
||||||
"LabelEmailSettingsFromAddress": "Remitente",
|
"LabelEmailSettingsFromAddress": "Remitente",
|
||||||
"LabelEmailSettingsRejectUnauthorized": "Rechazar certificados no autorizados",
|
"LabelEmailSettingsRejectUnauthorized": "Rechazar certificados no autorizados",
|
||||||
"LabelEmailSettingsRejectUnauthorizedHelp": "Desactivar la validación de certificados SSL puede exponer su conexión a riesgos de seguridad, como los ataques por intermediario. Desactive esta opción solo si conoce las implicaciones y confía en el servidor de correo al que se conecta.",
|
"LabelEmailSettingsRejectUnauthorizedHelp": "Desactivar la validación de certificados SSL puede exponer su conexión a riesgos de seguridad, como los ataques por intermediario. Desactive esta opción solo si conoce las implicaciones y confía en el servidor de correo al que se conecta.",
|
||||||
"LabelEmailSettingsSecure": "Seguridad",
|
"LabelEmailSettingsSecure": "Seguro",
|
||||||
"LabelEmailSettingsSecureHelp": "Si está activado, se usará TLS para conectarse al servidor. Si está apagado, se usará TLS si su servidor tiene soporte para la extensión STARTTLS. En la mayoría de los casos, puede dejar esta opción activada si se está conectando al puerto 465. Apáguela en el caso de usar los puertos 587 o 25. (de nodemailer.com/smtp/#authentication)",
|
"LabelEmailSettingsSecureHelp": "Si está activado, se usará TLS para conectarse al servidor. Si está apagado, se usará TLS si su servidor tiene soporte para la extensión STARTTLS. En la mayoría de los casos, puede dejar esta opción activada si se está conectando al puerto 465. Apáguela en el caso de usar los puertos 587 o 25. (de nodemailer.com/smtp/#authentication)",
|
||||||
"LabelEmailSettingsTestAddress": "Probar dirección",
|
"LabelEmailSettingsTestAddress": "Probar dirección",
|
||||||
"LabelEmbeddedCover": "Cubierta incrustada",
|
"LabelEmbeddedCover": "Cubierta incrustada",
|
||||||
@@ -346,6 +361,10 @@
|
|||||||
"LabelExample": "Ejemplo",
|
"LabelExample": "Ejemplo",
|
||||||
"LabelExpandSeries": "Ampliar serie",
|
"LabelExpandSeries": "Ampliar serie",
|
||||||
"LabelExpandSubSeries": "Expandir la subserie",
|
"LabelExpandSubSeries": "Expandir la subserie",
|
||||||
|
"LabelExpired": "Expirado",
|
||||||
|
"LabelExpiresAt": "Expira El",
|
||||||
|
"LabelExpiresInSeconds": "Expira en (segundos)",
|
||||||
|
"LabelExpiresNever": "Nunca",
|
||||||
"LabelExplicit": "Explícito",
|
"LabelExplicit": "Explícito",
|
||||||
"LabelExplicitChecked": "Explícito (marcado)",
|
"LabelExplicitChecked": "Explícito (marcado)",
|
||||||
"LabelExplicitUnchecked": "No Explícito (sin marcar)",
|
"LabelExplicitUnchecked": "No Explícito (sin marcar)",
|
||||||
@@ -360,11 +379,12 @@
|
|||||||
"LabelFilename": "Nombre del archivo",
|
"LabelFilename": "Nombre del archivo",
|
||||||
"LabelFilterByUser": "Filtrar por Usuario",
|
"LabelFilterByUser": "Filtrar por Usuario",
|
||||||
"LabelFindEpisodes": "Buscar Episodio",
|
"LabelFindEpisodes": "Buscar Episodio",
|
||||||
"LabelFinished": "Terminado",
|
"LabelFinished": "Finalizado",
|
||||||
|
"LabelFinishedDate": "Finalizado {0}",
|
||||||
"LabelFolder": "Carpeta",
|
"LabelFolder": "Carpeta",
|
||||||
"LabelFolders": "Carpetas",
|
"LabelFolders": "Carpetas",
|
||||||
"LabelFontBold": "Negrilla",
|
"LabelFontBold": "Negrilla",
|
||||||
"LabelFontBoldness": "Peso tipográfico",
|
"LabelFontBoldness": "Tipográfico sin Negrita",
|
||||||
"LabelFontFamily": "Familia tipográfica",
|
"LabelFontFamily": "Familia tipográfica",
|
||||||
"LabelFontItalic": "Itálica",
|
"LabelFontItalic": "Itálica",
|
||||||
"LabelFontScale": "Escala de letra",
|
"LabelFontScale": "Escala de letra",
|
||||||
@@ -374,8 +394,8 @@
|
|||||||
"LabelGenre": "Género",
|
"LabelGenre": "Género",
|
||||||
"LabelGenres": "Géneros",
|
"LabelGenres": "Géneros",
|
||||||
"LabelHardDeleteFile": "Eliminar Definitivamente",
|
"LabelHardDeleteFile": "Eliminar Definitivamente",
|
||||||
"LabelHasEbook": "Tiene un libro",
|
"LabelHasEbook": "Tiene libro-e",
|
||||||
"LabelHasSupplementaryEbook": "Tiene un libro complementario",
|
"LabelHasSupplementaryEbook": "Tiene un libro-e suplementario",
|
||||||
"LabelHideSubtitles": "Ocultar subtítulos",
|
"LabelHideSubtitles": "Ocultar subtítulos",
|
||||||
"LabelHighestPriority": "Mayor prioridad",
|
"LabelHighestPriority": "Mayor prioridad",
|
||||||
"LabelHost": "Anfitrión",
|
"LabelHost": "Anfitrión",
|
||||||
@@ -397,6 +417,7 @@
|
|||||||
"LabelIntervalEveryHour": "Cada hora",
|
"LabelIntervalEveryHour": "Cada hora",
|
||||||
"LabelIntervalEveryMinute": "Cada minuto",
|
"LabelIntervalEveryMinute": "Cada minuto",
|
||||||
"LabelInvert": "Invertir",
|
"LabelInvert": "Invertir",
|
||||||
|
"LabelIpAddress": "Dirección IP",
|
||||||
"LabelItem": "Elemento",
|
"LabelItem": "Elemento",
|
||||||
"LabelJumpBackwardAmount": "Cantidad de saltos hacia atrás",
|
"LabelJumpBackwardAmount": "Cantidad de saltos hacia atrás",
|
||||||
"LabelJumpForwardAmount": "Cantidad de saltos hacia adelante",
|
"LabelJumpForwardAmount": "Cantidad de saltos hacia adelante",
|
||||||
@@ -405,6 +426,7 @@
|
|||||||
"LabelLanguages": "Idiomas",
|
"LabelLanguages": "Idiomas",
|
||||||
"LabelLastBookAdded": "Último libro añadido",
|
"LabelLastBookAdded": "Último libro añadido",
|
||||||
"LabelLastBookUpdated": "Último libro actualizado",
|
"LabelLastBookUpdated": "Último libro actualizado",
|
||||||
|
"LabelLastProgressDate": "Último progreso: {0}",
|
||||||
"LabelLastSeen": "Última Vez Visto",
|
"LabelLastSeen": "Última Vez Visto",
|
||||||
"LabelLastTime": "Última Vez",
|
"LabelLastTime": "Última Vez",
|
||||||
"LabelLastUpdate": "Última Actualización",
|
"LabelLastUpdate": "Última Actualización",
|
||||||
@@ -417,6 +439,9 @@
|
|||||||
"LabelLibraryFilterSublistEmpty": "Sin {0}",
|
"LabelLibraryFilterSublistEmpty": "Sin {0}",
|
||||||
"LabelLibraryItem": "Elemento de Biblioteca",
|
"LabelLibraryItem": "Elemento de Biblioteca",
|
||||||
"LabelLibraryName": "Nombre de Biblioteca",
|
"LabelLibraryName": "Nombre de Biblioteca",
|
||||||
|
"LabelLibrarySortByProgress": "Progreso: Último actualizado",
|
||||||
|
"LabelLibrarySortByProgressFinished": "Progreso: Finalizado",
|
||||||
|
"LabelLibrarySortByProgressStarted": "Progreso: Iniciado",
|
||||||
"LabelLimit": "Limites",
|
"LabelLimit": "Limites",
|
||||||
"LabelLineSpacing": "Interlineado",
|
"LabelLineSpacing": "Interlineado",
|
||||||
"LabelListenAgain": "Volver a escuchar",
|
"LabelListenAgain": "Volver a escuchar",
|
||||||
@@ -425,6 +450,7 @@
|
|||||||
"LabelLogLevelWarn": "Advertencia",
|
"LabelLogLevelWarn": "Advertencia",
|
||||||
"LabelLookForNewEpisodesAfterDate": "Buscar Nuevos Episodios a partir de esta Fecha",
|
"LabelLookForNewEpisodesAfterDate": "Buscar Nuevos Episodios a partir de esta Fecha",
|
||||||
"LabelLowestPriority": "Menor prioridad",
|
"LabelLowestPriority": "Menor prioridad",
|
||||||
|
"LabelMatchConfidence": "Confidencia",
|
||||||
"LabelMatchExistingUsersBy": "Emparejar a los usuarios existentes por",
|
"LabelMatchExistingUsersBy": "Emparejar a los usuarios existentes por",
|
||||||
"LabelMatchExistingUsersByDescription": "Se utiliza para conectar usuarios existentes. Una vez conectados, los usuarios serán emparejados por un identificador único de su proveedor de SSO",
|
"LabelMatchExistingUsersByDescription": "Se utiliza para conectar usuarios existentes. Una vez conectados, los usuarios serán emparejados por un identificador único de su proveedor de SSO",
|
||||||
"LabelMaxEpisodesToDownload": "Número máximo # de episodios para descargar. Usa 0 para descargar una cantidad ilimitada.",
|
"LabelMaxEpisodesToDownload": "Número máximo # de episodios para descargar. Usa 0 para descargar una cantidad ilimitada.",
|
||||||
@@ -443,7 +469,7 @@
|
|||||||
"LabelMissingEbook": "No tiene libro electrónico",
|
"LabelMissingEbook": "No tiene libro electrónico",
|
||||||
"LabelMissingSupplementaryEbook": "No tiene libro electrónico suplementario",
|
"LabelMissingSupplementaryEbook": "No tiene libro electrónico suplementario",
|
||||||
"LabelMobileRedirectURIs": "URIs de redirección a móviles permitidos",
|
"LabelMobileRedirectURIs": "URIs de redirección a móviles permitidos",
|
||||||
"LabelMobileRedirectURIsDescription": "Esta es una lista blanca de URI de redireccionamiento válidos para aplicaciones móviles. El predeterminado es <code> audiobookshelf</code> , que puede eliminar o complementar con URI adicionales para la integración de aplicaciones de terceros. Usando un asterisco (<code> *</code> ) como única entrada que permite cualquier URI.",
|
"LabelMobileRedirectURIsDescription": "Esta es una lista en blanco de las URI de re‐direccionamiento válidos para aplicaciones móviles. El predeterminado es <code>audiobookshelf</code> , que puede retirar o sustituir con las URI adicionales para la integración de aplicaciones de terceros. Usando un asterisco (<code>*</code> ) como única entrada que permite cualquier URI.",
|
||||||
"LabelMore": "Más",
|
"LabelMore": "Más",
|
||||||
"LabelMoreInfo": "Más información",
|
"LabelMoreInfo": "Más información",
|
||||||
"LabelName": "Nombre",
|
"LabelName": "Nombre",
|
||||||
@@ -454,10 +480,12 @@
|
|||||||
"LabelNewestAuthors": "Autores más nuevos",
|
"LabelNewestAuthors": "Autores más nuevos",
|
||||||
"LabelNewestEpisodes": "Episodios más nuevos",
|
"LabelNewestEpisodes": "Episodios más nuevos",
|
||||||
"LabelNextBackupDate": "Fecha del siguiente respaldo",
|
"LabelNextBackupDate": "Fecha del siguiente respaldo",
|
||||||
|
"LabelNextChapters": "Los próximos capítulos serán:",
|
||||||
"LabelNextScheduledRun": "Próxima ejecución programada",
|
"LabelNextScheduledRun": "Próxima ejecución programada",
|
||||||
|
"LabelNoApiKeys": "Sin claves API",
|
||||||
"LabelNoCustomMetadataProviders": "Sin proveedores de metadatos personalizados",
|
"LabelNoCustomMetadataProviders": "Sin proveedores de metadatos personalizados",
|
||||||
"LabelNoEpisodesSelected": "Ningún Episodio Seleccionado",
|
"LabelNoEpisodesSelected": "Ningún Episodio Seleccionado",
|
||||||
"LabelNotFinished": "No terminado",
|
"LabelNotFinished": "No finalizado",
|
||||||
"LabelNotStarted": "Sin iniciar",
|
"LabelNotStarted": "Sin iniciar",
|
||||||
"LabelNotes": "Notas",
|
"LabelNotes": "Notas",
|
||||||
"LabelNotificationAppriseURL": "URL(s) de Apprise",
|
"LabelNotificationAppriseURL": "URL(s) de Apprise",
|
||||||
@@ -470,7 +498,8 @@
|
|||||||
"LabelNotificationsMaxQueueSize": "Tamaño máximo de la cola de notificaciones",
|
"LabelNotificationsMaxQueueSize": "Tamaño máximo de la cola de notificaciones",
|
||||||
"LabelNotificationsMaxQueueSizeHelp": "Las notificaciones están limitadas a 1 por segundo. Las notificaciones serán ignoradas si llegan al numero máximo de cola para prevenir spam de eventos.",
|
"LabelNotificationsMaxQueueSizeHelp": "Las notificaciones están limitadas a 1 por segundo. Las notificaciones serán ignoradas si llegan al numero máximo de cola para prevenir spam de eventos.",
|
||||||
"LabelNumberOfBooks": "Número de libros",
|
"LabelNumberOfBooks": "Número de libros",
|
||||||
"LabelNumberOfEpisodes": "N.º de episodios",
|
"LabelNumberOfChapters": "Número de capítulos:",
|
||||||
|
"LabelNumberOfEpisodes": "Nº de episodios",
|
||||||
"LabelOpenIDAdvancedPermsClaimDescription": "Nombre de la notificación de OpenID que contiene permisos avanzados para acciones de usuario dentro de la aplicación que se aplicarán a roles que no sean de administrador (<b>si están configurados</b>). Si el reclamo no aparece en la respuesta, se denegará el acceso a ABS. Si falta una sola opción, se tratará como <code>falsa</code>. Asegúrese de que la notificación del proveedor de identidades coincida con la estructura esperada:",
|
"LabelOpenIDAdvancedPermsClaimDescription": "Nombre de la notificación de OpenID que contiene permisos avanzados para acciones de usuario dentro de la aplicación que se aplicarán a roles que no sean de administrador (<b>si están configurados</b>). Si el reclamo no aparece en la respuesta, se denegará el acceso a ABS. Si falta una sola opción, se tratará como <code>falsa</code>. Asegúrese de que la notificación del proveedor de identidades coincida con la estructura esperada:",
|
||||||
"LabelOpenIDClaims": "Deje las siguientes opciones vacías para desactivar la asignación avanzada de grupos y permisos, lo que asignaría de manera automática al grupo «Usuario».",
|
"LabelOpenIDClaims": "Deje las siguientes opciones vacías para desactivar la asignación avanzada de grupos y permisos, lo que asignaría de manera automática al grupo «Usuario».",
|
||||||
"LabelOpenIDGroupClaimDescription": "Nombre de la declaración OpenID que contiene una lista de grupos del usuario. Comúnmente conocidos como <code>grupos</code>. <b>Si se configura</b>, la aplicación asignará automáticamente roles en función de la pertenencia a grupos del usuario, siempre que estos grupos se denominen \"admin\", \"user\" o \"guest\" en la notificación. La solicitud debe contener una lista, y si un usuario pertenece a varios grupos, la aplicación asignará el rol correspondiente al mayor nivel de acceso. Si ningún grupo coincide, se denegará el acceso.",
|
"LabelOpenIDGroupClaimDescription": "Nombre de la declaración OpenID que contiene una lista de grupos del usuario. Comúnmente conocidos como <code>grupos</code>. <b>Si se configura</b>, la aplicación asignará automáticamente roles en función de la pertenencia a grupos del usuario, siempre que estos grupos se denominen \"admin\", \"user\" o \"guest\" en la notificación. La solicitud debe contener una lista, y si un usuario pertenece a varios grupos, la aplicación asignará el rol correspondiente al mayor nivel de acceso. Si ningún grupo coincide, se denegará el acceso.",
|
||||||
@@ -500,7 +529,7 @@
|
|||||||
"LabelPodcasts": "Pódcast",
|
"LabelPodcasts": "Pódcast",
|
||||||
"LabelPort": "Puerto",
|
"LabelPort": "Puerto",
|
||||||
"LabelPrefixesToIgnore": "Prefijos para ignorar (no distingue entre mayúsculas y minúsculas)",
|
"LabelPrefixesToIgnore": "Prefijos para ignorar (no distingue entre mayúsculas y minúsculas)",
|
||||||
"LabelPreventIndexing": "Evite que los directorios de pódcast de iTunes y Google indicen su suministro",
|
"LabelPreventIndexing": "Evite que los directorios de pódcast de iTunes y Google indexen su suministro",
|
||||||
"LabelPrimaryEbook": "Libro electrónico principal",
|
"LabelPrimaryEbook": "Libro electrónico principal",
|
||||||
"LabelProgress": "Progreso",
|
"LabelProgress": "Progreso",
|
||||||
"LabelProvider": "Proveedor",
|
"LabelProvider": "Proveedor",
|
||||||
@@ -512,11 +541,11 @@
|
|||||||
"LabelPublishedDecades": "Décadas publicadas",
|
"LabelPublishedDecades": "Décadas publicadas",
|
||||||
"LabelPublisher": "Editor",
|
"LabelPublisher": "Editor",
|
||||||
"LabelPublishers": "Editores",
|
"LabelPublishers": "Editores",
|
||||||
"LabelRSSFeedCustomOwnerEmail": "Correo electrónico de dueño personalizado",
|
"LabelRSSFeedCustomOwnerEmail": "Correo-e de propietario personalizado",
|
||||||
"LabelRSSFeedCustomOwnerName": "Nombre de dueño personalizado",
|
"LabelRSSFeedCustomOwnerName": "Nombre de propietario personalizado",
|
||||||
"LabelRSSFeedOpen": "Suministro RSS abierto",
|
"LabelRSSFeedOpen": "Fuente RSS Abierta",
|
||||||
"LabelRSSFeedPreventIndexing": "Evitar indización",
|
"LabelRSSFeedPreventIndexing": "Evitar indización",
|
||||||
"LabelRSSFeedSlug": "«Slug» de suministro RSS",
|
"LabelRSSFeedSlug": "Ficha de suministro RSS",
|
||||||
"LabelRSSFeedURL": "URL de suministro RSS",
|
"LabelRSSFeedURL": "URL de suministro RSS",
|
||||||
"LabelRandomly": "Aleatorio",
|
"LabelRandomly": "Aleatorio",
|
||||||
"LabelReAddSeriesToContinueListening": "Volver a agregar la serie para continuar escuchándola",
|
"LabelReAddSeriesToContinueListening": "Volver a agregar la serie para continuar escuchándola",
|
||||||
@@ -544,11 +573,12 @@
|
|||||||
"LabelSelectAll": "Seleccionar todo",
|
"LabelSelectAll": "Seleccionar todo",
|
||||||
"LabelSelectAllEpisodes": "Seleccionar todos los episodios",
|
"LabelSelectAllEpisodes": "Seleccionar todos los episodios",
|
||||||
"LabelSelectEpisodesShowing": "Seleccionar los {0} episodios visibles",
|
"LabelSelectEpisodesShowing": "Seleccionar los {0} episodios visibles",
|
||||||
|
"LabelSelectUser": "Seleccionar usuario",
|
||||||
"LabelSelectUsers": "Seleccionar usuarios",
|
"LabelSelectUsers": "Seleccionar usuarios",
|
||||||
"LabelSendEbookToDevice": "Enviar libro electrónico a...",
|
"LabelSendEbookToDevice": "Enviar libro electrónico a...",
|
||||||
"LabelSequence": "Secuencia",
|
"LabelSequence": "Secuencia",
|
||||||
"LabelSerial": "En serie",
|
"LabelSerial": "En serie",
|
||||||
"LabelSeries": "Serie",
|
"LabelSeries": "Series",
|
||||||
"LabelSeriesName": "Nombre de la serie",
|
"LabelSeriesName": "Nombre de la serie",
|
||||||
"LabelSeriesProgress": "Progreso de la serie",
|
"LabelSeriesProgress": "Progreso de la serie",
|
||||||
"LabelServerLogLevel": "Nivel de registro del servidor",
|
"LabelServerLogLevel": "Nivel de registro del servidor",
|
||||||
@@ -561,8 +591,8 @@
|
|||||||
"LabelSettingsBookshelfViewHelp": "Diseño Esqueuomorfo con Estantes de Madera",
|
"LabelSettingsBookshelfViewHelp": "Diseño Esqueuomorfo con Estantes de Madera",
|
||||||
"LabelSettingsChromecastSupport": "Compatibilidad con Chromecast",
|
"LabelSettingsChromecastSupport": "Compatibilidad con Chromecast",
|
||||||
"LabelSettingsDateFormat": "Formato de Fecha",
|
"LabelSettingsDateFormat": "Formato de Fecha",
|
||||||
"LabelSettingsEnableWatcher": "Buscar cambios automáticamente en las bibliotecas",
|
"LabelSettingsEnableWatcher": "Vigilar automáticamente los cambios en bibliotecas",
|
||||||
"LabelSettingsEnableWatcherForLibrary": "Buscar cambios automáticamente en la biblioteca",
|
"LabelSettingsEnableWatcherForLibrary": "Vigilar automáticamente los cambios de biblioteca",
|
||||||
"LabelSettingsEnableWatcherHelp": "Permite agregar/actualizar elementos automáticamente cuando se detectan cambios en los archivos. *Requiere reiniciar el servidor",
|
"LabelSettingsEnableWatcherHelp": "Permite agregar/actualizar elementos automáticamente cuando se detectan cambios en los archivos. *Requiere reiniciar el servidor",
|
||||||
"LabelSettingsEpubsAllowScriptedContent": "Permitir scripts en epubs",
|
"LabelSettingsEpubsAllowScriptedContent": "Permitir scripts en epubs",
|
||||||
"LabelSettingsEpubsAllowScriptedContentHelp": "Permitir que los archivos epub ejecuten scripts. Se recomienda mantener esta opción desactivada a menos que confíe en el origen de los archivos epub.",
|
"LabelSettingsEpubsAllowScriptedContentHelp": "Permitir que los archivos epub ejecuten scripts. Se recomienda mantener esta opción desactivada a menos que confíe en el origen de los archivos epub.",
|
||||||
@@ -595,14 +625,14 @@
|
|||||||
"LabelSettingsStoreMetadataWithItemHelp": "Por defecto, los archivos de metadatos se almacenan en /metadata/items. Si habilita esta opción, los archivos de metadatos se guardarán en la carpeta de elementos de su biblioteca",
|
"LabelSettingsStoreMetadataWithItemHelp": "Por defecto, los archivos de metadatos se almacenan en /metadata/items. Si habilita esta opción, los archivos de metadatos se guardarán en la carpeta de elementos de su biblioteca",
|
||||||
"LabelSettingsTimeFormat": "Formato de Tiempo",
|
"LabelSettingsTimeFormat": "Formato de Tiempo",
|
||||||
"LabelShare": "Compartir",
|
"LabelShare": "Compartir",
|
||||||
"LabelShareDownloadableHelp": "Permite a quienes posean el enlace de compartición descargar un archivo ZIP del elemento de la biblioteca.",
|
"LabelShareDownloadableHelp": "Permite a quienes posean el enlace de compartición descargar un archivo zip del elemento de la biblioteca.",
|
||||||
"LabelShareOpen": "abrir un recurso compartido",
|
"LabelShareOpen": "abrir un recurso compartido",
|
||||||
"LabelShareURL": "Compartir la URL",
|
"LabelShareURL": "Compartir la URL",
|
||||||
"LabelShowAll": "Mostrar todo",
|
"LabelShowAll": "Mostrar todo",
|
||||||
"LabelShowSeconds": "Mostrar segundos",
|
"LabelShowSeconds": "Mostrar segundos",
|
||||||
"LabelShowSubtitles": "Mostrar subtítulos",
|
"LabelShowSubtitles": "Mostrar subtítulos",
|
||||||
"LabelSize": "Tamaño",
|
"LabelSize": "Tamaño",
|
||||||
"LabelSleepTimer": "Temporizador de apagado",
|
"LabelSleepTimer": "Temporizador de dormida",
|
||||||
"LabelSlug": "Slug",
|
"LabelSlug": "Slug",
|
||||||
"LabelSortAscending": "Ascendente",
|
"LabelSortAscending": "Ascendente",
|
||||||
"LabelSortDescending": "Descendente",
|
"LabelSortDescending": "Descendente",
|
||||||
@@ -611,6 +641,7 @@
|
|||||||
"LabelStartTime": "Tiempo de Inicio",
|
"LabelStartTime": "Tiempo de Inicio",
|
||||||
"LabelStarted": "Iniciado",
|
"LabelStarted": "Iniciado",
|
||||||
"LabelStartedAt": "Iniciado En",
|
"LabelStartedAt": "Iniciado En",
|
||||||
|
"LabelStartedDate": "Iniciado {0}",
|
||||||
"LabelStatsAudioTracks": "Pistas de Audio",
|
"LabelStatsAudioTracks": "Pistas de Audio",
|
||||||
"LabelStatsAuthors": "Autores",
|
"LabelStatsAuthors": "Autores",
|
||||||
"LabelStatsBestDay": "Mejor día",
|
"LabelStatsBestDay": "Mejor día",
|
||||||
@@ -640,6 +671,7 @@
|
|||||||
"LabelTheme": "Tema",
|
"LabelTheme": "Tema",
|
||||||
"LabelThemeDark": "Oscuro",
|
"LabelThemeDark": "Oscuro",
|
||||||
"LabelThemeLight": "Claro",
|
"LabelThemeLight": "Claro",
|
||||||
|
"LabelThemeSepia": "Sepia",
|
||||||
"LabelTimeBase": "Tiempo Base",
|
"LabelTimeBase": "Tiempo Base",
|
||||||
"LabelTimeDurationXHours": "{0} horas",
|
"LabelTimeDurationXHours": "{0} horas",
|
||||||
"LabelTimeDurationXMinutes": "{0} minutos",
|
"LabelTimeDurationXMinutes": "{0} minutos",
|
||||||
@@ -708,8 +740,10 @@
|
|||||||
"MessageAddToPlayerQueue": "Agregar a fila del Reproductor",
|
"MessageAddToPlayerQueue": "Agregar a fila del Reproductor",
|
||||||
"MessageAppriseDescription": "Para usar esta función deberás tener <a href=\"https://github.com/caronc/apprise-api\" target=\"_blank\">la API de Apprise</a> corriendo o una API que maneje los mismos resultados. <br/>La URL de la API de Apprise debe tener la misma ruta de archivos que donde se envían las notificaciones. Por ejemplo: si su API esta en <code>http://192.168.1.1:8337</code> entonces pondría <code>http://192.168.1.1:8337/notify</code>.",
|
"MessageAppriseDescription": "Para usar esta función deberás tener <a href=\"https://github.com/caronc/apprise-api\" target=\"_blank\">la API de Apprise</a> corriendo o una API que maneje los mismos resultados. <br/>La URL de la API de Apprise debe tener la misma ruta de archivos que donde se envían las notificaciones. Por ejemplo: si su API esta en <code>http://192.168.1.1:8337</code> entonces pondría <code>http://192.168.1.1:8337/notify</code>.",
|
||||||
"MessageAsinCheck": "Cerciórese de usar el ASIN de la región correcta de Audible, no de Amazon.",
|
"MessageAsinCheck": "Cerciórese de usar el ASIN de la región correcta de Audible, no de Amazon.",
|
||||||
|
"MessageAuthenticationLegacyTokenWarning": "Los vales de API heredados serán retirados en el futuro. Utilice las <a href=\"/config/api-keys\">claves de API</a> en su lugar.",
|
||||||
"MessageAuthenticationOIDCChangesRestart": "Reinicie el servidor tras el guardado para aplicar los cambios de OIDC.",
|
"MessageAuthenticationOIDCChangesRestart": "Reinicie el servidor tras el guardado para aplicar los cambios de OIDC.",
|
||||||
"MessageBackupsDescription": "Los respaldos incluyen: usuarios, el progreso del los usuarios, los detalles de los elementos de la biblioteca, la configuración del servidor y las imágenes en <code>/metadata/items</code> y <code>/metadata/authors</code>. Los Respaldos <strong>NO</strong> incluyen ningún archivo guardado en la carpeta de tu biblioteca.",
|
"MessageAuthenticationSecurityMessage": "La autenticación ha sido mejorada para seguridad. Todos los usuarios requieren reiniciar sesión.",
|
||||||
|
"MessageBackupsDescription": "Los respaldos incluyen: usuarios, el progreso del los usuarios, los detalles de los elementos de la biblioteca, la configuración del servidor y las imágenes en <code>/metadata/items</code> y <code>/metadata/authors</code>. Los Respaldos <strong>no</strong> incluyen ningún archivo guardado en la carpeta de tu biblioteca.",
|
||||||
"MessageBackupsLocationEditNote": "Nota: actualizar la ubicación de la copia de respaldo no moverá ni modificará los respaldos existentes",
|
"MessageBackupsLocationEditNote": "Nota: actualizar la ubicación de la copia de respaldo no moverá ni modificará los respaldos existentes",
|
||||||
"MessageBackupsLocationNoEditNote": "Nota: la ubicación de la copia de respaldo se establece a través de una variable de entorno y no se puede cambiar aquí.",
|
"MessageBackupsLocationNoEditNote": "Nota: la ubicación de la copia de respaldo se establece a través de una variable de entorno y no se puede cambiar aquí.",
|
||||||
"MessageBackupsLocationPathEmpty": "La ruta de la copia de seguridad no puede estar vacía",
|
"MessageBackupsLocationPathEmpty": "La ruta de la copia de seguridad no puede estar vacía",
|
||||||
@@ -722,6 +756,7 @@
|
|||||||
"MessageBookshelfNoResultsForFilter": "El filtro «{0}: {1}» no produjo ningún resultado",
|
"MessageBookshelfNoResultsForFilter": "El filtro «{0}: {1}» no produjo ningún resultado",
|
||||||
"MessageBookshelfNoResultsForQuery": "No hay resultados para la consulta",
|
"MessageBookshelfNoResultsForQuery": "No hay resultados para la consulta",
|
||||||
"MessageBookshelfNoSeries": "No tiene ninguna serie",
|
"MessageBookshelfNoSeries": "No tiene ninguna serie",
|
||||||
|
"MessageBulkChapterPattern": "¿Cuántos capítulos desea añadir con este patrón de numeración?",
|
||||||
"MessageChapterEndIsAfter": "El final del capítulo es después del final de tu audiolibro",
|
"MessageChapterEndIsAfter": "El final del capítulo es después del final de tu audiolibro",
|
||||||
"MessageChapterErrorFirstNotZero": "El primer capítulo debe iniciar en 0",
|
"MessageChapterErrorFirstNotZero": "El primer capítulo debe iniciar en 0",
|
||||||
"MessageChapterErrorStartGteDuration": "El tiempo de inicio no es válido: debe ser inferior a la duración del audiolibro",
|
"MessageChapterErrorStartGteDuration": "El tiempo de inicio no es válido: debe ser inferior a la duración del audiolibro",
|
||||||
@@ -730,6 +765,7 @@
|
|||||||
"MessageChaptersNotFound": "Capítulos no encontrados",
|
"MessageChaptersNotFound": "Capítulos no encontrados",
|
||||||
"MessageCheckingCron": "Revisando cron...",
|
"MessageCheckingCron": "Revisando cron...",
|
||||||
"MessageConfirmCloseFeed": "¿Confirma que quiere cerrar este suministro?",
|
"MessageConfirmCloseFeed": "¿Confirma que quiere cerrar este suministro?",
|
||||||
|
"MessageConfirmDeleteApiKey": "¿Está seguro que desea eliminar la clave API «{0}»?",
|
||||||
"MessageConfirmDeleteBackup": "¿Confirma que quiere eliminar el respaldo de {0}?",
|
"MessageConfirmDeleteBackup": "¿Confirma que quiere eliminar el respaldo de {0}?",
|
||||||
"MessageConfirmDeleteDevice": "¿Confirma que quiere eliminar el lector electrónico «{0}»?",
|
"MessageConfirmDeleteDevice": "¿Confirma que quiere eliminar el lector electrónico «{0}»?",
|
||||||
"MessageConfirmDeleteFile": "Esto eliminará el archivo del sistema de archivos. ¿Quiere continuar?",
|
"MessageConfirmDeleteFile": "Esto eliminará el archivo del sistema de archivos. ¿Quiere continuar?",
|
||||||
@@ -741,6 +777,7 @@
|
|||||||
"MessageConfirmDeleteSession": "¿Confirma que quiere eliminar esta sesión?",
|
"MessageConfirmDeleteSession": "¿Confirma que quiere eliminar esta sesión?",
|
||||||
"MessageConfirmEmbedMetadataInAudioFiles": "¿Confirma que quiere incrustar metadatos en {0} archivos de audio?",
|
"MessageConfirmEmbedMetadataInAudioFiles": "¿Confirma que quiere incrustar metadatos en {0} archivos de audio?",
|
||||||
"MessageConfirmForceReScan": "¿Confirma que quiere forzar un reescaneo?",
|
"MessageConfirmForceReScan": "¿Confirma que quiere forzar un reescaneo?",
|
||||||
|
"MessageConfirmLogoutDevice": "¿Seguro que quieres cerrar la sesión de «{0}»?",
|
||||||
"MessageConfirmMarkAllEpisodesFinished": "¿Confirma que quiere marcar todos los episodios como terminados?",
|
"MessageConfirmMarkAllEpisodesFinished": "¿Confirma que quiere marcar todos los episodios como terminados?",
|
||||||
"MessageConfirmMarkAllEpisodesNotFinished": "¿Confirma que quiere marcar todos los episodios como no terminados?",
|
"MessageConfirmMarkAllEpisodesNotFinished": "¿Confirma que quiere marcar todos los episodios como no terminados?",
|
||||||
"MessageConfirmMarkItemFinished": "¿Confirma que quiere marcar «{0}» como terminado?",
|
"MessageConfirmMarkItemFinished": "¿Confirma que quiere marcar «{0}» como terminado?",
|
||||||
@@ -748,8 +785,8 @@
|
|||||||
"MessageConfirmMarkSeriesFinished": "¿Confirma que quiere marcar todos los libros de esta serie como terminados?",
|
"MessageConfirmMarkSeriesFinished": "¿Confirma que quiere marcar todos los libros de esta serie como terminados?",
|
||||||
"MessageConfirmMarkSeriesNotFinished": "¿Confirma que quiere marcar todos los libros de esta serie como no terminados?",
|
"MessageConfirmMarkSeriesNotFinished": "¿Confirma que quiere marcar todos los libros de esta serie como no terminados?",
|
||||||
"MessageConfirmNotificationTestTrigger": "¿Activar esta notificación con datos de prueba?",
|
"MessageConfirmNotificationTestTrigger": "¿Activar esta notificación con datos de prueba?",
|
||||||
"MessageConfirmPurgeCache": "Purgar la antememoria eliminará el directorio completo ubicado en <code>/metadata/cache</code>. <br /><br />¿Confirma que quiere eliminar el directorio de antememoria?",
|
"MessageConfirmPurgeCache": "La purga del caché eliminará el directorio completo en <code>/metadata/cache</code>. <br /><br />¿Confirma que desea quitar el directorio de caché?",
|
||||||
"MessageConfirmPurgeItemsCache": "Purgar la antememoria de elementos eliminará el directorio completo ubicado en <code>/metadata/cache/items</code>.<br />¿Lo confirma?",
|
"MessageConfirmPurgeItemsCache": "Purgar el caché de elementos eliminará el directorio completo ubicado en <code>/metadata/cache/items</code>.<br />¿Lo confirma?",
|
||||||
"MessageConfirmQuickEmbed": "Atención: la incrustación rápida no realiza copias de respaldo a ninguno de sus archivos de audio. Cerciórese de haber realizado una copia de los mismos previamente. <br><br>¿Quiere continuar?",
|
"MessageConfirmQuickEmbed": "Atención: la incrustación rápida no realiza copias de respaldo a ninguno de sus archivos de audio. Cerciórese de haber realizado una copia de los mismos previamente. <br><br>¿Quiere continuar?",
|
||||||
"MessageConfirmQuickMatchEpisodes": "El reconocimiento rápido de extensiones sobrescribirá los detalles si se encuentra una coincidencia. Se actualizarán las extensiones no reconocidas. ¿Quiere continuar?",
|
"MessageConfirmQuickMatchEpisodes": "El reconocimiento rápido de extensiones sobrescribirá los detalles si se encuentra una coincidencia. Se actualizarán las extensiones no reconocidas. ¿Quiere continuar?",
|
||||||
"MessageConfirmReScanLibraryItems": "¿Confirma que quiere volver a analizar {0} elementos?",
|
"MessageConfirmReScanLibraryItems": "¿Confirma que quiere volver a analizar {0} elementos?",
|
||||||
@@ -757,6 +794,7 @@
|
|||||||
"MessageConfirmRemoveAuthor": "¿Confirma que quiere quitar el autor «{0}»?",
|
"MessageConfirmRemoveAuthor": "¿Confirma que quiere quitar el autor «{0}»?",
|
||||||
"MessageConfirmRemoveCollection": "¿Confirma que quiere quitar la colección «{0}»?",
|
"MessageConfirmRemoveCollection": "¿Confirma que quiere quitar la colección «{0}»?",
|
||||||
"MessageConfirmRemoveEpisode": "¿Confirma que quiere quitar el episodio «{0}»?",
|
"MessageConfirmRemoveEpisode": "¿Confirma que quiere quitar el episodio «{0}»?",
|
||||||
|
"MessageConfirmRemoveEpisodeNote": "Nota: Esto no borra el archivo de audio a menos que se active la opción \"Borrado definitivo del archivo\"",
|
||||||
"MessageConfirmRemoveEpisodes": "¿Confirma que quiere quitar {0} episodios?",
|
"MessageConfirmRemoveEpisodes": "¿Confirma que quiere quitar {0} episodios?",
|
||||||
"MessageConfirmRemoveListeningSessions": "¿Confirma que quiere quitar {0} sesiones de escucha?",
|
"MessageConfirmRemoveListeningSessions": "¿Confirma que quiere quitar {0} sesiones de escucha?",
|
||||||
"MessageConfirmRemoveMetadataFiles": "¿Confirma que quiere quitar todos los archivos metadata.{0} en las carpetas de elementos de su biblioteca?",
|
"MessageConfirmRemoveMetadataFiles": "¿Confirma que quiere quitar todos los archivos metadata.{0} en las carpetas de elementos de su biblioteca?",
|
||||||
@@ -774,14 +812,16 @@
|
|||||||
"MessageDaysListenedInTheLastYear": "{0} días escuchados el año pasado",
|
"MessageDaysListenedInTheLastYear": "{0} días escuchados el año pasado",
|
||||||
"MessageDownloadingEpisode": "Descargando episodio",
|
"MessageDownloadingEpisode": "Descargando episodio",
|
||||||
"MessageDragFilesIntoTrackOrder": "Arrastre los archivos al orden correcto de las pistas",
|
"MessageDragFilesIntoTrackOrder": "Arrastre los archivos al orden correcto de las pistas",
|
||||||
"MessageEmbedFailed": "Falló la incrustación.",
|
"MessageEmbedFailed": "Incorporación incorrecta.",
|
||||||
"MessageEmbedFinished": "Finalizó la incrustación.",
|
"MessageEmbedFinished": "Incorporación finalizada.",
|
||||||
"MessageEmbedQueue": "En cola para incrustar metadatos ({0} en cola)",
|
"MessageEmbedQueue": "En cola para incrustar metadatos ({0} en cola)",
|
||||||
"MessageEpisodesQueuedForDownload": "{0} episodio(s) en cola para descargar",
|
"MessageEpisodesQueuedForDownload": "{0} episodio(s) en cola para descargar",
|
||||||
"MessageEreaderDevices": "Para garantizar la entrega de libros electrónicos, es posible que tenga que agregar la dirección de correo electrónico anterior como remitente válido para cada dispositivo enumerado a continuación.",
|
"MessageEreaderDevices": "Para garantizar la entrega de libros electrónicos, es posible que tenga que agregar la dirección de correo electrónico anterior como remitente válido para cada dispositivo enumerado a continuación.",
|
||||||
"MessageFeedURLWillBe": "El URL del suministro será {0}",
|
"MessageFeedURLWillBe": "El URL del suministro será {0}",
|
||||||
"MessageFetching": "Recuperando...",
|
"MessageFetching": "Recuperando...",
|
||||||
"MessageForceReScanDescription": "Escaneará todos los archivos como un nuevo escaneo. Archivos de audio con etiquetas ID3, archivos OPF y archivos de texto serán escaneados como nuevos.",
|
"MessageForceReScanDescription": "Escaneará todos los archivos como un nuevo escaneo. Archivos de audio con etiquetas ID3, archivos OPF y archivos de texto serán escaneados como nuevos.",
|
||||||
|
"MessageHeatmapListeningTimeTooltip": "<strong>{0} escuchando</strong> en {1}",
|
||||||
|
"MessageHeatmapNoListeningSessions": "No enumera sesiones en {0}",
|
||||||
"MessageImportantNotice": "¡Notificación importante!",
|
"MessageImportantNotice": "¡Notificación importante!",
|
||||||
"MessageInsertChapterBelow": "Insertar capítulo debajo",
|
"MessageInsertChapterBelow": "Insertar capítulo debajo",
|
||||||
"MessageInvalidAsin": "ASIN no válido",
|
"MessageInvalidAsin": "ASIN no válido",
|
||||||
@@ -814,7 +854,7 @@
|
|||||||
"MessageNoEpisodes": "Ningún episodio",
|
"MessageNoEpisodes": "Ningún episodio",
|
||||||
"MessageNoFoldersAvailable": "Ninguna carpeta disponible",
|
"MessageNoFoldersAvailable": "Ninguna carpeta disponible",
|
||||||
"MessageNoGenres": "Ningún género",
|
"MessageNoGenres": "Ningún género",
|
||||||
"MessageNoIssues": "Ningún número",
|
"MessageNoIssues": "Sin incidencias",
|
||||||
"MessageNoItems": "Ningún elemento",
|
"MessageNoItems": "Ningún elemento",
|
||||||
"MessageNoItemsFound": "Ningún elemento encontrado",
|
"MessageNoItemsFound": "Ningún elemento encontrado",
|
||||||
"MessageNoListeningSessions": "Ninguna sesión de escucha",
|
"MessageNoListeningSessions": "Ninguna sesión de escucha",
|
||||||
@@ -852,7 +892,7 @@
|
|||||||
"MessageResetChaptersConfirm": "¿Confirma que quiere deshacer los cambios y restablecer los capítulos a su estado original?",
|
"MessageResetChaptersConfirm": "¿Confirma que quiere deshacer los cambios y restablecer los capítulos a su estado original?",
|
||||||
"MessageRestoreBackupConfirm": "¿Confirma que quiere restaurar el respaldo creado el",
|
"MessageRestoreBackupConfirm": "¿Confirma que quiere restaurar el respaldo creado el",
|
||||||
"MessageRestoreBackupWarning": "Restaurar sobrescribirá toda la base de datos localizada en /config y las imágenes de portadas en /metadata/items y /metadata/authors.<br /><br />El respaldo no modifica ningún archivo en las carpetas de su biblioteca. Si ha habilitado la opción del servidor para almacenar portadas y metadata en las carpetas de su biblioteca, esos archivos no se respaldan o sobrescriben.<br /><br />Todos los clientes que usen su servidor se actualizarán automáticamente.",
|
"MessageRestoreBackupWarning": "Restaurar sobrescribirá toda la base de datos localizada en /config y las imágenes de portadas en /metadata/items y /metadata/authors.<br /><br />El respaldo no modifica ningún archivo en las carpetas de su biblioteca. Si ha habilitado la opción del servidor para almacenar portadas y metadata en las carpetas de su biblioteca, esos archivos no se respaldan o sobrescriben.<br /><br />Todos los clientes que usen su servidor se actualizarán automáticamente.",
|
||||||
"MessageScheduleLibraryScanNote": "Para la mayoría de los usuarios, se recomienda dejar esta función desactivada y mantener activada la configuración del observador de carpetas. El observador de carpetas detectará automáticamente los cambios en las carpetas de la biblioteca. El observador de carpetas no funciona para todos los sistemas de archivos (como NFS), por lo que se pueden utilizar exploraciones programadas de la biblioteca en su lugar.",
|
"MessageScheduleLibraryScanNote": "Para muchos usuarios, es recomendado dejar esta característica inhabilitada y mantener habilitados los ajustes de la «Vigía automática de cambio de biblioteca»: detectará automáticamente los cambios en sus carpetas de bibliotecas. Habilitar esta características si «Vigía automática de cambio de biblioteca» no funciona en su sistema de archivo (como NFS).",
|
||||||
"MessageScheduleRunEveryWeekdayAtTime": "Ejecutar cada {0} a las {1}",
|
"MessageScheduleRunEveryWeekdayAtTime": "Ejecutar cada {0} a las {1}",
|
||||||
"MessageSearchResultsFor": "Resultados de la búsqueda de",
|
"MessageSearchResultsFor": "Resultados de la búsqueda de",
|
||||||
"MessageSelected": "{0} seleccionado(s)",
|
"MessageSelected": "{0} seleccionado(s)",
|
||||||
@@ -918,7 +958,10 @@
|
|||||||
"NotificationOnBackupCompletedDescription": "Se activa cuando se completa una copia de seguridad",
|
"NotificationOnBackupCompletedDescription": "Se activa cuando se completa una copia de seguridad",
|
||||||
"NotificationOnBackupFailedDescription": "Se activa cuando falla una copia de seguridad",
|
"NotificationOnBackupFailedDescription": "Se activa cuando falla una copia de seguridad",
|
||||||
"NotificationOnEpisodeDownloadedDescription": "Se activa cuando se descarga automáticamente un episodio de un podcast",
|
"NotificationOnEpisodeDownloadedDescription": "Se activa cuando se descarga automáticamente un episodio de un podcast",
|
||||||
|
"NotificationOnRSSFeedDisabledDescription": "Se activa cuando las descargas automáticas de episodios se desactivan debido a varios intentos fallidos",
|
||||||
|
"NotificationOnRSSFeedFailedDescription": "Se activa cuando la solicitud a la fuente RSS falla durante una descarga automática de episodio",
|
||||||
"NotificationOnTestDescription": "Evento para probar el sistema de notificaciones",
|
"NotificationOnTestDescription": "Evento para probar el sistema de notificaciones",
|
||||||
|
"PlaceholderBulkChapterInput": "Ingrese título de capítulo o use numeración (ej. 'Episodio 1', 'Capítulo 10', '1.')",
|
||||||
"PlaceholderNewCollection": "Nuevo nombre de la colección",
|
"PlaceholderNewCollection": "Nuevo nombre de la colección",
|
||||||
"PlaceholderNewFolderPath": "Nueva ruta de carpeta",
|
"PlaceholderNewFolderPath": "Nueva ruta de carpeta",
|
||||||
"PlaceholderNewPlaylist": "Nuevo nombre de la lista de reproducción",
|
"PlaceholderNewPlaylist": "Nuevo nombre de la lista de reproducción",
|
||||||
@@ -972,8 +1015,12 @@
|
|||||||
"ToastBookmarkCreateFailed": "No se pudo crear el marcador",
|
"ToastBookmarkCreateFailed": "No se pudo crear el marcador",
|
||||||
"ToastBookmarkCreateSuccess": "Marcador añadido",
|
"ToastBookmarkCreateSuccess": "Marcador añadido",
|
||||||
"ToastBookmarkRemoveSuccess": "Marcador eliminado",
|
"ToastBookmarkRemoveSuccess": "Marcador eliminado",
|
||||||
|
"ToastBulkChapterInvalidCount": "Por favor ingrese un número válido entre 1 y 150",
|
||||||
"ToastCachePurgeFailed": "No se pudo purgar la antememoria",
|
"ToastCachePurgeFailed": "No se pudo purgar la antememoria",
|
||||||
"ToastCachePurgeSuccess": "Se purgó la antememoria correctamente",
|
"ToastCachePurgeSuccess": "Se purgó la antememoria correctamente",
|
||||||
|
"ToastChapterLocked": "El capítulo está bloqueado.",
|
||||||
|
"ToastChapterStartTimeAdjusted": "El capítulo inicia el tiempo ajustado en {0} segundos",
|
||||||
|
"ToastChaptersAllLocked": "Todos los capítulos están bloqueados. Desbloquee algunos capítulos para cambiar sus tiempos.",
|
||||||
"ToastChaptersHaveErrors": "Los capítulos tienen errores",
|
"ToastChaptersHaveErrors": "Los capítulos tienen errores",
|
||||||
"ToastChaptersInvalidShiftAmountLast": "Cantidad de desplazamiento no válida. La hora de inicio del último capítulo se extendería más allá de la duración de este audiolibro.",
|
"ToastChaptersInvalidShiftAmountLast": "Cantidad de desplazamiento no válida. La hora de inicio del último capítulo se extendería más allá de la duración de este audiolibro.",
|
||||||
"ToastChaptersInvalidShiftAmountStart": "Cantidad de desplazamiento no válida. El primer capítulo tendría una duración cero o negativa y lo sobrescribiría el segundo capítulo. Aumente la duración inicial del segundo capítulo.",
|
"ToastChaptersInvalidShiftAmountStart": "Cantidad de desplazamiento no válida. El primer capítulo tendría una duración cero o negativa y lo sobrescribiría el segundo capítulo. Aumente la duración inicial del segundo capítulo.",
|
||||||
@@ -983,6 +1030,8 @@
|
|||||||
"ToastCollectionItemsAddFailed": "Artículo(s) añadido(s) a la colección fallido(s)",
|
"ToastCollectionItemsAddFailed": "Artículo(s) añadido(s) a la colección fallido(s)",
|
||||||
"ToastCollectionRemoveSuccess": "Colección quitada",
|
"ToastCollectionRemoveSuccess": "Colección quitada",
|
||||||
"ToastCollectionUpdateSuccess": "Colección actualizada",
|
"ToastCollectionUpdateSuccess": "Colección actualizada",
|
||||||
|
"ToastConnectionNotAvailable": "Conexión no disponible. Intenta de nuevo más tarde",
|
||||||
|
"ToastCoverSearchFailed": "Cobertura de búsqueda incorrecta",
|
||||||
"ToastCoverUpdateFailed": "Error al actualizar la cubierta",
|
"ToastCoverUpdateFailed": "Error al actualizar la cubierta",
|
||||||
"ToastDateTimeInvalidOrIncomplete": "Fecha y hora no válidas o incompletas",
|
"ToastDateTimeInvalidOrIncomplete": "Fecha y hora no válidas o incompletas",
|
||||||
"ToastDeleteFileFailed": "Falló la eliminación del archivo",
|
"ToastDeleteFileFailed": "Falló la eliminación del archivo",
|
||||||
@@ -998,6 +1047,8 @@
|
|||||||
"ToastEpisodeDownloadQueueClearSuccess": "Se borró la cola de descargas de los episodios",
|
"ToastEpisodeDownloadQueueClearSuccess": "Se borró la cola de descargas de los episodios",
|
||||||
"ToastEpisodeUpdateSuccess": "{0} episodio(s) actualizado(s)",
|
"ToastEpisodeUpdateSuccess": "{0} episodio(s) actualizado(s)",
|
||||||
"ToastErrorCannotShare": "No se puede compartir de forma nativa en este dispositivo",
|
"ToastErrorCannotShare": "No se puede compartir de forma nativa en este dispositivo",
|
||||||
|
"ToastFailedToCreate": "Ha fallado al crear",
|
||||||
|
"ToastFailedToDelete": "Ha fallado al eliminar",
|
||||||
"ToastFailedToLoadData": "Error al cargar data",
|
"ToastFailedToLoadData": "Error al cargar data",
|
||||||
"ToastFailedToMatch": "Error al emparejar",
|
"ToastFailedToMatch": "Error al emparejar",
|
||||||
"ToastFailedToShare": "Error al compartir",
|
"ToastFailedToShare": "Error al compartir",
|
||||||
@@ -1005,6 +1056,7 @@
|
|||||||
"ToastInvalidImageUrl": "URL de la imagen no válida",
|
"ToastInvalidImageUrl": "URL de la imagen no válida",
|
||||||
"ToastInvalidMaxEpisodesToDownload": "Número máximo de episodios para descargar no válidos",
|
"ToastInvalidMaxEpisodesToDownload": "Número máximo de episodios para descargar no válidos",
|
||||||
"ToastInvalidUrl": "URL no válida",
|
"ToastInvalidUrl": "URL no válida",
|
||||||
|
"ToastInvalidUrls": "Una o más URL son inválidas",
|
||||||
"ToastItemCoverUpdateSuccess": "Cubierta del elemento actualizada",
|
"ToastItemCoverUpdateSuccess": "Cubierta del elemento actualizada",
|
||||||
"ToastItemDeletedFailed": "Error al eliminar el elemento",
|
"ToastItemDeletedFailed": "Error al eliminar el elemento",
|
||||||
"ToastItemDeletedSuccess": "Elemento borrado",
|
"ToastItemDeletedSuccess": "Elemento borrado",
|
||||||
@@ -1029,6 +1081,7 @@
|
|||||||
"ToastMustHaveAtLeastOnePath": "Debe tener al menos una ruta",
|
"ToastMustHaveAtLeastOnePath": "Debe tener al menos una ruta",
|
||||||
"ToastNameEmailRequired": "Son obligatorios el nombre y el correo electrónico",
|
"ToastNameEmailRequired": "Son obligatorios el nombre y el correo electrónico",
|
||||||
"ToastNameRequired": "Nombre obligatorio",
|
"ToastNameRequired": "Nombre obligatorio",
|
||||||
|
"ToastNewApiKeyUserError": "Debe seleccionar un usuario",
|
||||||
"ToastNewEpisodesFound": "{0} nuevo(s) episodio(s) encontrado(s)",
|
"ToastNewEpisodesFound": "{0} nuevo(s) episodio(s) encontrado(s)",
|
||||||
"ToastNewUserCreatedFailed": "No se pudo crear la cuenta: «{0}»",
|
"ToastNewUserCreatedFailed": "No se pudo crear la cuenta: «{0}»",
|
||||||
"ToastNewUserCreatedSuccess": "Nueva cuenta creada",
|
"ToastNewUserCreatedSuccess": "Nueva cuenta creada",
|
||||||
@@ -1053,6 +1106,7 @@
|
|||||||
"ToastPlaylistUpdateSuccess": "Lista de reproducción actualizada",
|
"ToastPlaylistUpdateSuccess": "Lista de reproducción actualizada",
|
||||||
"ToastPodcastCreateFailed": "No se pudo crear el pódcast",
|
"ToastPodcastCreateFailed": "No se pudo crear el pódcast",
|
||||||
"ToastPodcastCreateSuccess": "Se creó el pódcast correctamente",
|
"ToastPodcastCreateSuccess": "Se creó el pódcast correctamente",
|
||||||
|
"ToastPodcastEpisodeUpdated": "Episodio actualizado",
|
||||||
"ToastPodcastGetFeedFailed": "No se puede obtener el podcast",
|
"ToastPodcastGetFeedFailed": "No se puede obtener el podcast",
|
||||||
"ToastPodcastNoEpisodesInFeed": "No se han encontrado episodios en el feed del RSS",
|
"ToastPodcastNoEpisodesInFeed": "No se han encontrado episodios en el feed del RSS",
|
||||||
"ToastPodcastNoRssFeed": "El pódcast no tiene suministro RSS",
|
"ToastPodcastNoRssFeed": "El pódcast no tiene suministro RSS",
|
||||||
@@ -1066,8 +1120,8 @@
|
|||||||
"ToastRemoveFailed": "Error al eliminar",
|
"ToastRemoveFailed": "Error al eliminar",
|
||||||
"ToastRemoveItemFromCollectionFailed": "Error al eliminar el elemento de la colección",
|
"ToastRemoveItemFromCollectionFailed": "Error al eliminar el elemento de la colección",
|
||||||
"ToastRemoveItemFromCollectionSuccess": "Elemento eliminado de la colección",
|
"ToastRemoveItemFromCollectionSuccess": "Elemento eliminado de la colección",
|
||||||
"ToastRemoveItemsWithIssuesFailed": "Error en la eliminación de artículos de biblioteca incorrectos",
|
"ToastRemoveItemsWithIssuesFailed": "Error en la eliminación de artículos de biblioteca con incidencias",
|
||||||
"ToastRemoveItemsWithIssuesSuccess": "Se eliminaron artículos de biblioteca incorrectos",
|
"ToastRemoveItemsWithIssuesSuccess": "Se eliminaron artículos de biblioteca con incidencias",
|
||||||
"ToastRenameFailed": "Error al cambiar el nombre",
|
"ToastRenameFailed": "Error al cambiar el nombre",
|
||||||
"ToastRescanFailed": "Error al volver a escanear para {0}",
|
"ToastRescanFailed": "Error al volver a escanear para {0}",
|
||||||
"ToastRescanRemoved": "Se eliminó el elemento reescaneado",
|
"ToastRescanRemoved": "Se eliminó el elemento reescaneado",
|
||||||
@@ -1103,5 +1157,13 @@
|
|||||||
"ToastUserPasswordChangeSuccess": "Contraseña modificada correctamente",
|
"ToastUserPasswordChangeSuccess": "Contraseña modificada correctamente",
|
||||||
"ToastUserPasswordMismatch": "No coinciden las contraseñas",
|
"ToastUserPasswordMismatch": "No coinciden las contraseñas",
|
||||||
"ToastUserPasswordMustChange": "La nueva contraseña no puede ser igual que la anterior",
|
"ToastUserPasswordMustChange": "La nueva contraseña no puede ser igual que la anterior",
|
||||||
"ToastUserRootRequireName": "Debe introducir un nombre de usuario administrativo"
|
"ToastUserRootRequireName": "Debe introducir un nombre de usuario administrativo",
|
||||||
|
"TooltipAddChapters": "Añadir capítulo(s)",
|
||||||
|
"TooltipAddOneSecond": "Añadir 1 segundo",
|
||||||
|
"TooltipAdjustChapterStart": "Pulse para ajustar la hora de inicio",
|
||||||
|
"TooltipLockAllChapters": "Bloquear todos los capítulos",
|
||||||
|
"TooltipLockChapter": "Bloquear capítulo (Mayús+clic para rango)",
|
||||||
|
"TooltipSubtractOneSecond": "Restar 1 segundo",
|
||||||
|
"TooltipUnlockAllChapters": "Desbloquear todos los capítulos",
|
||||||
|
"TooltipUnlockChapter": "Desbloquear capítulo (Mayús+clic para rango)"
|
||||||
}
|
}
|
||||||
+52
-41
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"ButtonAdd": "Lisa",
|
"ButtonAdd": "Lisa",
|
||||||
|
"ButtonAddApiKey": "Lisa API võti",
|
||||||
"ButtonAddChapters": "Lisa peatükid",
|
"ButtonAddChapters": "Lisa peatükid",
|
||||||
"ButtonAddDevice": "Lisa seade",
|
"ButtonAddDevice": "Lisa seade",
|
||||||
"ButtonAddLibrary": "Lisa raamatukogu",
|
"ButtonAddLibrary": "Lisa raamatukogu",
|
||||||
@@ -11,7 +12,7 @@
|
|||||||
"ButtonAuthors": "Autorid",
|
"ButtonAuthors": "Autorid",
|
||||||
"ButtonBack": "Tagasi",
|
"ButtonBack": "Tagasi",
|
||||||
"ButtonBrowseForFolder": "Sirvi kausta",
|
"ButtonBrowseForFolder": "Sirvi kausta",
|
||||||
"ButtonCancel": "Tühista",
|
"ButtonCancel": "Katkesta",
|
||||||
"ButtonCancelEncode": "Tühista kodeerimine",
|
"ButtonCancelEncode": "Tühista kodeerimine",
|
||||||
"ButtonChangeRootPassword": "Muuda põhiparooli",
|
"ButtonChangeRootPassword": "Muuda põhiparooli",
|
||||||
"ButtonCheckAndDownloadNewEpisodes": "Kontrolli ja laadi alla uued episoodid",
|
"ButtonCheckAndDownloadNewEpisodes": "Kontrolli ja laadi alla uued episoodid",
|
||||||
@@ -20,9 +21,9 @@
|
|||||||
"ButtonClearFilter": "Tühista filter",
|
"ButtonClearFilter": "Tühista filter",
|
||||||
"ButtonCloseFeed": "Sulge voog",
|
"ButtonCloseFeed": "Sulge voog",
|
||||||
"ButtonCloseSession": "Sulge avatud sessioon",
|
"ButtonCloseSession": "Sulge avatud sessioon",
|
||||||
"ButtonCollections": "Kogud",
|
"ButtonCollections": "Kollektsioonid",
|
||||||
"ButtonConfigureScanner": "Konfigureeri skanner",
|
"ButtonConfigureScanner": "Konfigureeri skanner",
|
||||||
"ButtonCreate": "Loo",
|
"ButtonCreate": "Loo uus",
|
||||||
"ButtonCreateBackup": "Loo varundus",
|
"ButtonCreateBackup": "Loo varundus",
|
||||||
"ButtonDelete": "Kustuta",
|
"ButtonDelete": "Kustuta",
|
||||||
"ButtonDownloadQueue": "Järjekord",
|
"ButtonDownloadQueue": "Järjekord",
|
||||||
@@ -37,7 +38,7 @@
|
|||||||
"ButtonIssues": "Probleemid",
|
"ButtonIssues": "Probleemid",
|
||||||
"ButtonJumpBackward": "Hüppa tagasi",
|
"ButtonJumpBackward": "Hüppa tagasi",
|
||||||
"ButtonJumpForward": "Hüppa edasi",
|
"ButtonJumpForward": "Hüppa edasi",
|
||||||
"ButtonLatest": "Uusim",
|
"ButtonLatest": "Viimased",
|
||||||
"ButtonLibrary": "Raamatukogu",
|
"ButtonLibrary": "Raamatukogu",
|
||||||
"ButtonLogout": "Logi välja",
|
"ButtonLogout": "Logi välja",
|
||||||
"ButtonLookup": "Otsi",
|
"ButtonLookup": "Otsi",
|
||||||
@@ -52,11 +53,11 @@
|
|||||||
"ButtonOk": "Ok",
|
"ButtonOk": "Ok",
|
||||||
"ButtonOpenFeed": "Ava voog",
|
"ButtonOpenFeed": "Ava voog",
|
||||||
"ButtonOpenManager": "Ava haldur",
|
"ButtonOpenManager": "Ava haldur",
|
||||||
"ButtonPause": "Peata",
|
"ButtonPause": "Paus",
|
||||||
"ButtonPlay": "Mängi",
|
"ButtonPlay": "Mängi",
|
||||||
"ButtonPlayAll": "Mängi kõik",
|
"ButtonPlayAll": "Mängi kõik",
|
||||||
"ButtonPlaying": "Mängib",
|
"ButtonPlaying": "Mängib",
|
||||||
"ButtonPlaylists": "Esitusloendid",
|
"ButtonPlaylists": "Playlist",
|
||||||
"ButtonPrevious": "Eelmine",
|
"ButtonPrevious": "Eelmine",
|
||||||
"ButtonPreviousChapter": "Eelmine peatükk",
|
"ButtonPreviousChapter": "Eelmine peatükk",
|
||||||
"ButtonPurgeAllCache": "Tühjenda kogu vahemälu",
|
"ButtonPurgeAllCache": "Tühjenda kogu vahemälu",
|
||||||
@@ -69,7 +70,7 @@
|
|||||||
"ButtonReadLess": "Loe vähem",
|
"ButtonReadLess": "Loe vähem",
|
||||||
"ButtonReadMore": "Loe rohkem",
|
"ButtonReadMore": "Loe rohkem",
|
||||||
"ButtonRefresh": "Värskenda",
|
"ButtonRefresh": "Värskenda",
|
||||||
"ButtonRemove": "Eemalda",
|
"ButtonRemove": "Kustuta",
|
||||||
"ButtonRemoveAll": "Eemalda kõik",
|
"ButtonRemoveAll": "Eemalda kõik",
|
||||||
"ButtonRemoveAllLibraryItems": "Eemalda kõik raamatukogu esemed",
|
"ButtonRemoveAllLibraryItems": "Eemalda kõik raamatukogu esemed",
|
||||||
"ButtonRemoveFromContinueListening": "Eemalda jätkake kuulamisest",
|
"ButtonRemoveFromContinueListening": "Eemalda jätkake kuulamisest",
|
||||||
@@ -120,12 +121,12 @@
|
|||||||
"HeaderCustomMetadataProviders": "Kohandatud metaandmete pakkujad",
|
"HeaderCustomMetadataProviders": "Kohandatud metaandmete pakkujad",
|
||||||
"HeaderDetails": "Detailid",
|
"HeaderDetails": "Detailid",
|
||||||
"HeaderDownloadQueue": "Allalaadimise järjekord",
|
"HeaderDownloadQueue": "Allalaadimise järjekord",
|
||||||
"HeaderEbookFiles": "E-raamatute failid",
|
"HeaderEbookFiles": "E-raamatu failid",
|
||||||
"HeaderEmail": "E-post",
|
"HeaderEmail": "E-post",
|
||||||
"HeaderEmailSettings": "E-posti seaded",
|
"HeaderEmailSettings": "E-posti seaded",
|
||||||
"HeaderEpisodes": "Episoodid",
|
"HeaderEpisodes": "Episoodid",
|
||||||
"HeaderEreaderDevices": "E-lugerite seadmed",
|
"HeaderEreaderDevices": "E-lugerite seadmed",
|
||||||
"HeaderEreaderSettings": "E-lugerite seadistused",
|
"HeaderEreaderSettings": "E-lugeja sätted",
|
||||||
"HeaderFiles": "Failid",
|
"HeaderFiles": "Failid",
|
||||||
"HeaderFindChapters": "Leia peatükid",
|
"HeaderFindChapters": "Leia peatükid",
|
||||||
"HeaderIgnoredFiles": "Ignoreeritud failid",
|
"HeaderIgnoredFiles": "Ignoreeritud failid",
|
||||||
@@ -155,11 +156,11 @@
|
|||||||
"HeaderPasswordAuthentication": "Parooli autentimine",
|
"HeaderPasswordAuthentication": "Parooli autentimine",
|
||||||
"HeaderPermissions": "Õigused",
|
"HeaderPermissions": "Õigused",
|
||||||
"HeaderPlayerQueue": "Mängija järjekord",
|
"HeaderPlayerQueue": "Mängija järjekord",
|
||||||
"HeaderPlaylist": "Mänguloend",
|
"HeaderPlaylist": "Playlist",
|
||||||
"HeaderPlaylistItems": "Mänguloendi esemed",
|
"HeaderPlaylistItems": "Playlisti esemed",
|
||||||
"HeaderPodcastsToAdd": "Lisatavad podcastid",
|
"HeaderPodcastsToAdd": "Lisatavad podcastid",
|
||||||
"HeaderPreviewCover": "Eelvaate kaas",
|
"HeaderPreviewCover": "Eelvaate kaas",
|
||||||
"HeaderRSSFeedGeneral": "RSS-i üksikasjad",
|
"HeaderRSSFeedGeneral": "RSS detailid",
|
||||||
"HeaderRSSFeedIsOpen": "RSS-voog on avatud",
|
"HeaderRSSFeedIsOpen": "RSS-voog on avatud",
|
||||||
"HeaderRSSFeeds": "RSS-vooged",
|
"HeaderRSSFeeds": "RSS-vooged",
|
||||||
"HeaderRemoveEpisode": "Eemalda episood",
|
"HeaderRemoveEpisode": "Eemalda episood",
|
||||||
@@ -174,10 +175,10 @@
|
|||||||
"HeaderSettingsExperimental": "Katsetusfunktsioonid",
|
"HeaderSettingsExperimental": "Katsetusfunktsioonid",
|
||||||
"HeaderSettingsGeneral": "Üldised",
|
"HeaderSettingsGeneral": "Üldised",
|
||||||
"HeaderSettingsScanner": "Skanner",
|
"HeaderSettingsScanner": "Skanner",
|
||||||
"HeaderSleepTimer": "Uinaku taimer",
|
"HeaderSleepTimer": "Unetaimer",
|
||||||
"HeaderStatsLargestItems": "Suurimad esemed",
|
"HeaderStatsLargestItems": "Suurimad esemed",
|
||||||
"HeaderStatsLongestItems": "Kõige pikemad esemed (tunnid)",
|
"HeaderStatsLongestItems": "Kõige pikemad esemed (tunnid)",
|
||||||
"HeaderStatsMinutesListeningChart": "Kuulamise minutid (viimased 7 päeva)",
|
"HeaderStatsMinutesListeningChart": "Kuulatud minutid (viimased 7 päeva)",
|
||||||
"HeaderStatsRecentSessions": "Hiljutised sessioonid",
|
"HeaderStatsRecentSessions": "Hiljutised sessioonid",
|
||||||
"HeaderStatsTop10Authors": "Top 10 autorit",
|
"HeaderStatsTop10Authors": "Top 10 autorit",
|
||||||
"HeaderStatsTop5Genres": "Top 5 žanrit",
|
"HeaderStatsTop5Genres": "Top 5 žanrit",
|
||||||
@@ -197,9 +198,10 @@
|
|||||||
"LabelActivity": "Tegevus",
|
"LabelActivity": "Tegevus",
|
||||||
"LabelAddToCollection": "Lisa kogusse",
|
"LabelAddToCollection": "Lisa kogusse",
|
||||||
"LabelAddToCollectionBatch": "Lisa {0} raamatut kogusse",
|
"LabelAddToCollectionBatch": "Lisa {0} raamatut kogusse",
|
||||||
"LabelAddToPlaylist": "Lisa mänguloendisse",
|
"LabelAddToPlaylist": "Lisa playlisti",
|
||||||
"LabelAddToPlaylistBatch": "Lisa {0} eset mänguloendisse",
|
"LabelAddToPlaylistBatch": "Lisa {0} eset mänguloendisse",
|
||||||
"LabelAddedAt": "Lisatud",
|
"LabelAddedAt": "Lisatud",
|
||||||
|
"LabelAddedDate": "Lisatud {0}",
|
||||||
"LabelAdminUsersOnly": "Ainult administraatorid",
|
"LabelAdminUsersOnly": "Ainult administraatorid",
|
||||||
"LabelAll": "Kõik",
|
"LabelAll": "Kõik",
|
||||||
"LabelAllUsers": "Kõik kasutajad",
|
"LabelAllUsers": "Kõik kasutajad",
|
||||||
@@ -208,10 +210,10 @@
|
|||||||
"LabelAlreadyInYourLibrary": "Juba teie raamatukogus",
|
"LabelAlreadyInYourLibrary": "Juba teie raamatukogus",
|
||||||
"LabelAppend": "Lisa",
|
"LabelAppend": "Lisa",
|
||||||
"LabelAuthor": "Autor",
|
"LabelAuthor": "Autor",
|
||||||
"LabelAuthorFirstLast": "Autor (Eesnimi Perekonnanimi)",
|
"LabelAuthorFirstLast": "Autor (eesnimi perekonnanimi)",
|
||||||
"LabelAuthorLastFirst": "Autor (Perekonnanimi, Eesnimi)",
|
"LabelAuthorLastFirst": "Autor (perekonnanimi, eesnimi)",
|
||||||
"LabelAuthors": "Autorid",
|
"LabelAuthors": "Autorid",
|
||||||
"LabelAutoDownloadEpisodes": "Automaatne episoodide allalaadimine",
|
"LabelAutoDownloadEpisodes": "Episoodide automaatne allalaadimine",
|
||||||
"LabelAutoFetchMetadata": "Automaatne metaandmete hankimine",
|
"LabelAutoFetchMetadata": "Automaatne metaandmete hankimine",
|
||||||
"LabelAutoFetchMetadataHelp": "Toob tiitli, autori ja seeria metaandmed üleslaadimise hõlbustamiseks. Lisametaandmed võivad pärast üleslaadimist vajada vastavust.",
|
"LabelAutoFetchMetadataHelp": "Toob tiitli, autori ja seeria metaandmed üleslaadimise hõlbustamiseks. Lisametaandmed võivad pärast üleslaadimist vajada vastavust.",
|
||||||
"LabelAutoLaunch": "Automaatne käivitamine",
|
"LabelAutoLaunch": "Automaatne käivitamine",
|
||||||
@@ -244,7 +246,7 @@
|
|||||||
"LabelConfirmPassword": "Kinnita parool",
|
"LabelConfirmPassword": "Kinnita parool",
|
||||||
"LabelContinueListening": "Jätka kuulamist",
|
"LabelContinueListening": "Jätka kuulamist",
|
||||||
"LabelContinueReading": "Jätka lugemist",
|
"LabelContinueReading": "Jätka lugemist",
|
||||||
"LabelContinueSeries": "Jätka seeriat",
|
"LabelContinueSeries": "Jäta sarja",
|
||||||
"LabelCover": "Ümbris",
|
"LabelCover": "Ümbris",
|
||||||
"LabelCoverImageURL": "Ümbrise pildi URL",
|
"LabelCoverImageURL": "Ümbrise pildi URL",
|
||||||
"LabelCreatedAt": "Loodud",
|
"LabelCreatedAt": "Loodud",
|
||||||
@@ -265,7 +267,7 @@
|
|||||||
"LabelDiscover": "Avasta",
|
"LabelDiscover": "Avasta",
|
||||||
"LabelDownload": "Lae alla",
|
"LabelDownload": "Lae alla",
|
||||||
"LabelDownloadNEpisodes": "Lae alla {0} episoodi",
|
"LabelDownloadNEpisodes": "Lae alla {0} episoodi",
|
||||||
"LabelDuration": "Kestus",
|
"LabelDuration": "Kestvus",
|
||||||
"LabelDurationFound": "Leitud kestus:",
|
"LabelDurationFound": "Leitud kestus:",
|
||||||
"LabelEbook": "E-raamat",
|
"LabelEbook": "E-raamat",
|
||||||
"LabelEbooks": "E-raamatud",
|
"LabelEbooks": "E-raamatud",
|
||||||
@@ -278,6 +280,7 @@
|
|||||||
"LabelEmbeddedCover": "Manustatud kaas",
|
"LabelEmbeddedCover": "Manustatud kaas",
|
||||||
"LabelEnable": "Luba",
|
"LabelEnable": "Luba",
|
||||||
"LabelEnd": "Lõpp",
|
"LabelEnd": "Lõpp",
|
||||||
|
"LabelEndOfChapter": "Peatükki lõpp",
|
||||||
"LabelEpisode": "Episood",
|
"LabelEpisode": "Episood",
|
||||||
"LabelEpisodeTitle": "Episoodi pealkiri",
|
"LabelEpisodeTitle": "Episoodi pealkiri",
|
||||||
"LabelEpisodeType": "Episoodi tüüp",
|
"LabelEpisodeType": "Episoodi tüüp",
|
||||||
@@ -288,13 +291,14 @@
|
|||||||
"LabelFile": "Fail",
|
"LabelFile": "Fail",
|
||||||
"LabelFileBirthtime": "Faili sünniaeg",
|
"LabelFileBirthtime": "Faili sünniaeg",
|
||||||
"LabelFileModified": "Faili muudetud",
|
"LabelFileModified": "Faili muudetud",
|
||||||
"LabelFilename": "Failinimi",
|
"LabelFilename": "Faili nimi",
|
||||||
"LabelFilterByUser": "Filtri alusel kasutaja järgi",
|
"LabelFilterByUser": "Filtri alusel kasutaja järgi",
|
||||||
"LabelFindEpisodes": "Otsi episoodid",
|
"LabelFindEpisodes": "Otsi episoodid",
|
||||||
"LabelFinished": "Lõpetatud",
|
"LabelFinished": "Lõpetatud",
|
||||||
"LabelFolder": "Kaust",
|
"LabelFolder": "Kaust",
|
||||||
"LabelFolders": "Kataloogid",
|
"LabelFolders": "Kataloogid",
|
||||||
"LabelFontBold": "Paks",
|
"LabelFontBold": "Paks",
|
||||||
|
"LabelFontBoldness": "Fondi paksus",
|
||||||
"LabelFontFamily": "Fondi pere",
|
"LabelFontFamily": "Fondi pere",
|
||||||
"LabelFontItalic": "Kaldkiri",
|
"LabelFontItalic": "Kaldkiri",
|
||||||
"LabelFontScale": "Fondi suurus",
|
"LabelFontScale": "Fondi suurus",
|
||||||
@@ -303,7 +307,7 @@
|
|||||||
"LabelGenre": "Žanr",
|
"LabelGenre": "Žanr",
|
||||||
"LabelGenres": "Žanrid",
|
"LabelGenres": "Žanrid",
|
||||||
"LabelHardDeleteFile": "Faili lõplik kustutamine",
|
"LabelHardDeleteFile": "Faili lõplik kustutamine",
|
||||||
"LabelHasEbook": "On e-raamat",
|
"LabelHasEbook": "E-raamat olemas",
|
||||||
"LabelHasSupplementaryEbook": "On täiendav e-raamat",
|
"LabelHasSupplementaryEbook": "On täiendav e-raamat",
|
||||||
"LabelHighestPriority": "Kõrgeim prioriteet",
|
"LabelHighestPriority": "Kõrgeim prioriteet",
|
||||||
"LabelHour": "Tund",
|
"LabelHour": "Tund",
|
||||||
@@ -311,7 +315,7 @@
|
|||||||
"LabelImageURLFromTheWeb": "Pildi URL veebist",
|
"LabelImageURLFromTheWeb": "Pildi URL veebist",
|
||||||
"LabelInProgress": "Pooleli",
|
"LabelInProgress": "Pooleli",
|
||||||
"LabelIncludeInTracklist": "Kaasa jälgimisloendis",
|
"LabelIncludeInTracklist": "Kaasa jälgimisloendis",
|
||||||
"LabelIncomplete": "Puudulik",
|
"LabelIncomplete": "Lõpetamata",
|
||||||
"LabelInterval": "Intervall",
|
"LabelInterval": "Intervall",
|
||||||
"LabelIntervalCustomDailyWeekly": "Kohandatud päevane/nädalane",
|
"LabelIntervalCustomDailyWeekly": "Kohandatud päevane/nädalane",
|
||||||
"LabelIntervalEvery12Hours": "Iga 12 tunni tagant",
|
"LabelIntervalEvery12Hours": "Iga 12 tunni tagant",
|
||||||
@@ -322,9 +326,10 @@
|
|||||||
"LabelIntervalEveryDay": "Iga päev",
|
"LabelIntervalEveryDay": "Iga päev",
|
||||||
"LabelIntervalEveryHour": "Iga tunni tagant",
|
"LabelIntervalEveryHour": "Iga tunni tagant",
|
||||||
"LabelInvert": "Pööra ümber",
|
"LabelInvert": "Pööra ümber",
|
||||||
|
"LabelIpAddress": "IP-aadress",
|
||||||
"LabelItem": "Kirje",
|
"LabelItem": "Kirje",
|
||||||
"LabelLanguage": "Keel",
|
"LabelLanguage": "Keel",
|
||||||
"LabelLanguageDefaultServer": "Vaikeserveri keel",
|
"LabelLanguageDefaultServer": "Serveri vaikekeel",
|
||||||
"LabelLastBookAdded": "Viimati lisatud raamat",
|
"LabelLastBookAdded": "Viimati lisatud raamat",
|
||||||
"LabelLastBookUpdated": "Viimati uuendatud raamat",
|
"LabelLastBookUpdated": "Viimati uuendatud raamat",
|
||||||
"LabelLastSeen": "Viimati nähtud",
|
"LabelLastSeen": "Viimati nähtud",
|
||||||
@@ -370,7 +375,7 @@
|
|||||||
"LabelNextBackupDate": "Järgmine varukoopia kuupäev",
|
"LabelNextBackupDate": "Järgmine varukoopia kuupäev",
|
||||||
"LabelNextScheduledRun": "Järgmine ajakava järgmine",
|
"LabelNextScheduledRun": "Järgmine ajakava järgmine",
|
||||||
"LabelNoEpisodesSelected": "Episoodid pole valitud",
|
"LabelNoEpisodesSelected": "Episoodid pole valitud",
|
||||||
"LabelNotFinished": "Ei ole lõpetatud",
|
"LabelNotFinished": "Lõpetamata",
|
||||||
"LabelNotStarted": "Pole alustatud",
|
"LabelNotStarted": "Pole alustatud",
|
||||||
"LabelNotes": "Märkused",
|
"LabelNotes": "Märkused",
|
||||||
"LabelNotificationAppriseURL": "Apprise URL-id",
|
"LabelNotificationAppriseURL": "Apprise URL-id",
|
||||||
@@ -383,7 +388,7 @@
|
|||||||
"LabelNotificationsMaxQueueSize": "Teavituste sündmuste maksimaalne järjekorra suurus",
|
"LabelNotificationsMaxQueueSize": "Teavituste sündmuste maksimaalne järjekorra suurus",
|
||||||
"LabelNotificationsMaxQueueSizeHelp": "Sündmused on piiratud 1 sekundiga. Sündmusi ignoreeritakse, kui järjekord on maksimumsuuruses. See takistab teavituste rämpsposti.",
|
"LabelNotificationsMaxQueueSizeHelp": "Sündmused on piiratud 1 sekundiga. Sündmusi ignoreeritakse, kui järjekord on maksimumsuuruses. See takistab teavituste rämpsposti.",
|
||||||
"LabelNumberOfBooks": "Raamatute arv",
|
"LabelNumberOfBooks": "Raamatute arv",
|
||||||
"LabelNumberOfEpisodes": "Episoodide arv",
|
"LabelNumberOfEpisodes": "# episoode",
|
||||||
"LabelOpenRSSFeed": "Ava RSS voog",
|
"LabelOpenRSSFeed": "Ava RSS voog",
|
||||||
"LabelOverwrite": "Kirjuta üle",
|
"LabelOverwrite": "Kirjuta üle",
|
||||||
"LabelPassword": "Parool",
|
"LabelPassword": "Parool",
|
||||||
@@ -398,16 +403,18 @@
|
|||||||
"LabelPhotoPathURL": "Foto tee/URL",
|
"LabelPhotoPathURL": "Foto tee/URL",
|
||||||
"LabelPlayMethod": "Esitusmeetod",
|
"LabelPlayMethod": "Esitusmeetod",
|
||||||
"LabelPlaylists": "Mänguloendid",
|
"LabelPlaylists": "Mänguloendid",
|
||||||
|
"LabelPodcast": "Podcast",
|
||||||
"LabelPodcastSearchRegion": "Podcasti otsingu piirkond",
|
"LabelPodcastSearchRegion": "Podcasti otsingu piirkond",
|
||||||
"LabelPodcastType": "Podcasti tüüp",
|
"LabelPodcastType": "Podcasti tüüp",
|
||||||
"LabelPodcasts": "Podcastid",
|
"LabelPodcasts": "Podcastid",
|
||||||
"LabelPrefixesToIgnore": "Eiramiseks eesliited (tõstutundetu)",
|
"LabelPrefixesToIgnore": "Eiramiseks eesliited (tõstutundetu)",
|
||||||
"LabelPreventIndexing": "Vältige oma voogu indekseerimist iTunes'i ja Google podcasti kataloogides",
|
"LabelPreventIndexing": "Vältige oma voogu indekseerimist iTunes'i ja Google podcasti kataloogides",
|
||||||
"LabelPrimaryEbook": "Esmane e-raamat",
|
"LabelPrimaryEbook": "Esmane e-raamat",
|
||||||
"LabelProgress": "Edenemine",
|
"LabelProgress": "Progress",
|
||||||
"LabelProvider": "Pakkuja",
|
"LabelProvider": "Pakkuja",
|
||||||
"LabelPubDate": "Avaldamise kuupäev",
|
"LabelPubDate": "Publitseerimise kuupäev",
|
||||||
"LabelPublishYear": "Aasta avaldamine",
|
"LabelPublishYear": "Publitseerimise aasta",
|
||||||
|
"LabelPublishedDate": "Publitseeritud {0}",
|
||||||
"LabelPublisher": "Kirjastaja",
|
"LabelPublisher": "Kirjastaja",
|
||||||
"LabelRSSFeedCustomOwnerEmail": "Kohandatud omaniku e-post",
|
"LabelRSSFeedCustomOwnerEmail": "Kohandatud omaniku e-post",
|
||||||
"LabelRSSFeedCustomOwnerName": "Kohandatud omaniku nimi",
|
"LabelRSSFeedCustomOwnerName": "Kohandatud omaniku nimi",
|
||||||
@@ -415,7 +422,8 @@
|
|||||||
"LabelRSSFeedPreventIndexing": "Vältige indekseerimist",
|
"LabelRSSFeedPreventIndexing": "Vältige indekseerimist",
|
||||||
"LabelRSSFeedSlug": "RSS voog Slug",
|
"LabelRSSFeedSlug": "RSS voog Slug",
|
||||||
"LabelRSSFeedURL": "RSS voog URL",
|
"LabelRSSFeedURL": "RSS voog URL",
|
||||||
"LabelRead": "Lugenud",
|
"LabelRandomly": "Juhuslikus järjekorras",
|
||||||
|
"LabelRead": "Loetud läbi",
|
||||||
"LabelReadAgain": "Loe uuesti",
|
"LabelReadAgain": "Loe uuesti",
|
||||||
"LabelReadEbookWithoutProgress": "Lugege e-raamatut ilma edenemist säilitamata",
|
"LabelReadEbookWithoutProgress": "Lugege e-raamatut ilma edenemist säilitamata",
|
||||||
"LabelRecentSeries": "Hiljutised seeriad",
|
"LabelRecentSeries": "Hiljutised seeriad",
|
||||||
@@ -452,8 +460,8 @@
|
|||||||
"LabelSettingsFindCoversHelp": "Kui teie heliraamatul pole sisseehitatud ümbrist ega ümbrise pilti kaustas, proovib skanner leida ümbrist.<br>Märkus: see pikendab skaneerimisaega",
|
"LabelSettingsFindCoversHelp": "Kui teie heliraamatul pole sisseehitatud ümbrist ega ümbrise pilti kaustas, proovib skanner leida ümbrist.<br>Märkus: see pikendab skaneerimisaega",
|
||||||
"LabelSettingsHideSingleBookSeries": "Peida üksikute raamatute seeriad",
|
"LabelSettingsHideSingleBookSeries": "Peida üksikute raamatute seeriad",
|
||||||
"LabelSettingsHideSingleBookSeriesHelp": "Ühe raamatuga seeriaid peidetakse seeria lehelt ja avalehe riiulitelt.",
|
"LabelSettingsHideSingleBookSeriesHelp": "Ühe raamatuga seeriaid peidetakse seeria lehelt ja avalehe riiulitelt.",
|
||||||
"LabelSettingsHomePageBookshelfView": "Avaleht kasutage raamatukoguvaadet",
|
"LabelSettingsHomePageBookshelfView": "Avalehel kasuta raamaturiiulivaadet",
|
||||||
"LabelSettingsLibraryBookshelfView": "Raamatukogu kasutamiseks kasutage raamatukoguvaadet",
|
"LabelSettingsLibraryBookshelfView": "Raamatukogus kasuta raamaturiiulivaadet",
|
||||||
"LabelSettingsParseSubtitles": "Lugege subtiitreid",
|
"LabelSettingsParseSubtitles": "Lugege subtiitreid",
|
||||||
"LabelSettingsParseSubtitlesHelp": "Eraldage subtiitrid heliraamatu kaustade nimedest.<br>Subtiitrid peavad olema eraldatud kasutades \" - \".<br>Näiteks: \"Raamatu pealkiri - Siin on alapealkiri\" alapealkiri on \"Siin on alapealkiri\"",
|
"LabelSettingsParseSubtitlesHelp": "Eraldage subtiitrid heliraamatu kaustade nimedest.<br>Subtiitrid peavad olema eraldatud kasutades \" - \".<br>Näiteks: \"Raamatu pealkiri - Siin on alapealkiri\" alapealkiri on \"Siin on alapealkiri\"",
|
||||||
"LabelSettingsPreferMatchedMetadata": "Eelista sobitatud metaandmeid",
|
"LabelSettingsPreferMatchedMetadata": "Eelista sobitatud metaandmeid",
|
||||||
@@ -469,9 +477,9 @@
|
|||||||
"LabelSettingsStoreMetadataWithItem": "Salvesta metaandmed üksusega",
|
"LabelSettingsStoreMetadataWithItem": "Salvesta metaandmed üksusega",
|
||||||
"LabelSettingsStoreMetadataWithItemHelp": "Vaikimisi salvestatakse metaandmed /metadata/items kausta. Selle seadistuse lubamine salvestab metaandmed teie raamatukogu üksuse kaustadesse",
|
"LabelSettingsStoreMetadataWithItemHelp": "Vaikimisi salvestatakse metaandmed /metadata/items kausta. Selle seadistuse lubamine salvestab metaandmed teie raamatukogu üksuse kaustadesse",
|
||||||
"LabelSettingsTimeFormat": "Kellaaja vorming",
|
"LabelSettingsTimeFormat": "Kellaaja vorming",
|
||||||
"LabelShowAll": "Näita kõiki",
|
"LabelShowAll": "Näita kõik",
|
||||||
"LabelSize": "Suurus",
|
"LabelSize": "Suurus",
|
||||||
"LabelSleepTimer": "Uinaku taimer",
|
"LabelSleepTimer": "Unetaimer",
|
||||||
"LabelStart": "Alusta",
|
"LabelStart": "Alusta",
|
||||||
"LabelStartTime": "Alustamise aeg",
|
"LabelStartTime": "Alustamise aeg",
|
||||||
"LabelStarted": "Alustatud",
|
"LabelStarted": "Alustatud",
|
||||||
@@ -480,17 +488,17 @@
|
|||||||
"LabelStatsAuthors": "Autorid",
|
"LabelStatsAuthors": "Autorid",
|
||||||
"LabelStatsBestDay": "Parim päev",
|
"LabelStatsBestDay": "Parim päev",
|
||||||
"LabelStatsDailyAverage": "Päevane keskmine",
|
"LabelStatsDailyAverage": "Päevane keskmine",
|
||||||
"LabelStatsDays": "Päevad",
|
"LabelStatsDays": "Päevi",
|
||||||
"LabelStatsDaysListened": "Kuulatud päevad",
|
"LabelStatsDaysListened": "Kuulatud päevad",
|
||||||
"LabelStatsHours": "Tunnid",
|
"LabelStatsHours": "Tunnid",
|
||||||
"LabelStatsInARow": "järjest",
|
"LabelStatsInARow": "järjest",
|
||||||
"LabelStatsItemsFinished": "Lõpetatud üksused",
|
"LabelStatsItemsFinished": "Lõpetatud raamatud",
|
||||||
"LabelStatsItemsInLibrary": "Üksused raamatukogus",
|
"LabelStatsItemsInLibrary": "Üksused raamatukogus",
|
||||||
"LabelStatsMinutes": "minutit",
|
"LabelStatsMinutes": "minuteid",
|
||||||
"LabelStatsMinutesListening": "Kuulamise minutid",
|
"LabelStatsMinutesListening": "Kuulamise minutid",
|
||||||
"LabelStatsOverallDays": "Kokku päevad",
|
"LabelStatsOverallDays": "Kokku päevad",
|
||||||
"LabelStatsOverallHours": "Kokku tunnid",
|
"LabelStatsOverallHours": "Kokku tunnid",
|
||||||
"LabelStatsWeekListening": "Nädala kuulamine",
|
"LabelStatsWeekListening": "Nädala keskmine",
|
||||||
"LabelSubtitle": "Alapealkiri",
|
"LabelSubtitle": "Alapealkiri",
|
||||||
"LabelSupportedFileTypes": "Toetatud failitüübid",
|
"LabelSupportedFileTypes": "Toetatud failitüübid",
|
||||||
"LabelTag": "Silt",
|
"LabelTag": "Silt",
|
||||||
@@ -502,7 +510,7 @@
|
|||||||
"LabelTextEditorNumberedList": "Numberloend",
|
"LabelTextEditorNumberedList": "Numberloend",
|
||||||
"LabelTextEditorUnlink": "Eemalda link",
|
"LabelTextEditorUnlink": "Eemalda link",
|
||||||
"LabelTheme": "Teema",
|
"LabelTheme": "Teema",
|
||||||
"LabelThemeDark": "Tume",
|
"LabelThemeDark": "Pime",
|
||||||
"LabelThemeLight": "Hele",
|
"LabelThemeLight": "Hele",
|
||||||
"LabelTimeBase": "Aja alus",
|
"LabelTimeBase": "Aja alus",
|
||||||
"LabelTimeListened": "Kuulatud aeg",
|
"LabelTimeListened": "Kuulatud aeg",
|
||||||
@@ -527,7 +535,7 @@
|
|||||||
"LabelType": "Tüüp",
|
"LabelType": "Tüüp",
|
||||||
"LabelUnabridged": "Täismahus",
|
"LabelUnabridged": "Täismahus",
|
||||||
"LabelUndo": "Võta tagasi",
|
"LabelUndo": "Võta tagasi",
|
||||||
"LabelUnknown": "Tundmatu",
|
"LabelUnknown": "Teadmata",
|
||||||
"LabelUpdateCover": "Uuenda kaant",
|
"LabelUpdateCover": "Uuenda kaant",
|
||||||
"LabelUpdateCoverHelp": "Luba üle kirjutamine olemasolevate kaante jaoks valitud raamatutele, kui leitakse sobivus",
|
"LabelUpdateCoverHelp": "Luba üle kirjutamine olemasolevate kaante jaoks valitud raamatutele, kui leitakse sobivus",
|
||||||
"LabelUpdateDetails": "Uuenda üksikasju",
|
"LabelUpdateDetails": "Uuenda üksikasju",
|
||||||
@@ -555,9 +563,11 @@
|
|||||||
"MessageAppriseDescription": "Selle funktsiooni kasutamiseks peate käivitama <a href=\"https://github.com/caronc/apprise-api\" target=\"_blank\">Apprise API</a> eksemplari või API, mis töötleb samu päringuid. <br />Apprise API URL peaks olema täielik URL-rada teatise saatmiseks, näiteks kui teie API eksemplar töötab aadressil <code>http://192.168.1.1:8337</code>, siis peaksite sisestama <code>http://192.168.1.1:8337/notify</code>.",
|
"MessageAppriseDescription": "Selle funktsiooni kasutamiseks peate käivitama <a href=\"https://github.com/caronc/apprise-api\" target=\"_blank\">Apprise API</a> eksemplari või API, mis töötleb samu päringuid. <br />Apprise API URL peaks olema täielik URL-rada teatise saatmiseks, näiteks kui teie API eksemplar töötab aadressil <code>http://192.168.1.1:8337</code>, siis peaksite sisestama <code>http://192.168.1.1:8337/notify</code>.",
|
||||||
"MessageBackupsDescription": "Varukoopiad hõlmavad kasutajaid, kasutajate edenemist, raamatukogu üksikasju, serveri seadeid ja kaustades <code>/metadata/items</code> ja <code>/metadata/authors</code> salvestatud pilte. Varukoopiad ei hõlma ühtegi teie raamatukogu kaustades olevat faili.",
|
"MessageBackupsDescription": "Varukoopiad hõlmavad kasutajaid, kasutajate edenemist, raamatukogu üksikasju, serveri seadeid ja kaustades <code>/metadata/items</code> ja <code>/metadata/authors</code> salvestatud pilte. Varukoopiad ei hõlma ühtegi teie raamatukogu kaustades olevat faili.",
|
||||||
"MessageBatchQuickMatchDescription": "Kiire sobitamine üritab lisada valitud üksustele puuduvad kaaned ja metaandmed. Luba allpool olevad valikud, et lubada Kiire sobitamine'il üle kirjutada olemasolevaid kaasi ja/või metaandmeid.",
|
"MessageBatchQuickMatchDescription": "Kiire sobitamine üritab lisada valitud üksustele puuduvad kaaned ja metaandmed. Luba allpool olevad valikud, et lubada Kiire sobitamine'il üle kirjutada olemasolevaid kaasi ja/või metaandmeid.",
|
||||||
"MessageBookshelfNoCollections": "Te pole veel ühtegi kogumit teinud",
|
"MessageBookshelfNoCollections": "Te pole veel ühtegi kollektsiooni teinud",
|
||||||
|
"MessageBookshelfNoCollectionsHelp": "Kollektsioonid on avalikud. Kõik kasutajad kellel on olemas ligipääs raamatukogule saavad neid näha.",
|
||||||
"MessageBookshelfNoRSSFeeds": "Ühtegi RSS-i voogu pole avatud",
|
"MessageBookshelfNoRSSFeeds": "Ühtegi RSS-i voogu pole avatud",
|
||||||
"MessageBookshelfNoResultsForFilter": "Filtrile \"{0}: {1}\" pole tulemusi",
|
"MessageBookshelfNoResultsForFilter": "Filtrile \"{0}: {1}\" pole tulemusi",
|
||||||
|
"MessageBookshelfNoResultsForQuery": "Päringul ei ole tulemusi",
|
||||||
"MessageBookshelfNoSeries": "Teil pole ühtegi seeriat",
|
"MessageBookshelfNoSeries": "Teil pole ühtegi seeriat",
|
||||||
"MessageChapterEndIsAfter": "Peatüki lõpp on pärast teie heliraamatu lõppu",
|
"MessageChapterEndIsAfter": "Peatüki lõpp on pärast teie heliraamatu lõppu",
|
||||||
"MessageChapterErrorFirstNotZero": "Esimene peatükk peab algama 0-st",
|
"MessageChapterErrorFirstNotZero": "Esimene peatükk peab algama 0-st",
|
||||||
@@ -594,6 +604,7 @@
|
|||||||
"MessageConfirmRenameTagMergeNote": "Märkus: See silt on juba olemas, nii et need ühendatakse.",
|
"MessageConfirmRenameTagMergeNote": "Märkus: See silt on juba olemas, nii et need ühendatakse.",
|
||||||
"MessageConfirmRenameTagWarning": "Hoiatus! Sarnane silt erineva puhvriga on juba olemas \"{0}\".",
|
"MessageConfirmRenameTagWarning": "Hoiatus! Sarnane silt erineva puhvriga on juba olemas \"{0}\".",
|
||||||
"MessageConfirmSendEbookToDevice": "Olete kindel, et soovite saata {0} e-raamatu \"{1}\" seadmesse \"{2}\"?",
|
"MessageConfirmSendEbookToDevice": "Olete kindel, et soovite saata {0} e-raamatu \"{1}\" seadmesse \"{2}\"?",
|
||||||
|
"MessageDaysListenedInTheLastYear": "{0} päeva kuuldud viimase aasta jooksul",
|
||||||
"MessageDownloadingEpisode": "Episoodi allalaadimine",
|
"MessageDownloadingEpisode": "Episoodi allalaadimine",
|
||||||
"MessageDragFilesIntoTrackOrder": "Lohistage failid õigesse järjekorda",
|
"MessageDragFilesIntoTrackOrder": "Lohistage failid õigesse järjekorda",
|
||||||
"MessageEmbedFinished": "Manustamine lõpetatud!",
|
"MessageEmbedFinished": "Manustamine lõpetatud!",
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"ButtonAdd": "افزودن",
|
||||||
|
"ButtonAuthors": "ناشر",
|
||||||
|
"ButtonBack": "بازگشت",
|
||||||
|
"ButtonCancel": "انصراف",
|
||||||
|
"ButtonClearFilter": "حذف صافی",
|
||||||
|
"ButtonCloseFeed": "بستن فید",
|
||||||
|
"ButtonCollections": "مجموعه ها",
|
||||||
|
"ButtonCreate": "ساختن",
|
||||||
|
"ButtonDelete": "حذف",
|
||||||
|
"ButtonHome": "خانه",
|
||||||
|
"ButtonIssues": "مشکلات",
|
||||||
|
"ButtonLatest": "جدیدترین",
|
||||||
|
"ButtonLibrary": "کتابخانه",
|
||||||
|
"ButtonOk": "تایید",
|
||||||
|
"ButtonOpenFeed": "باز کردن فید",
|
||||||
|
"ButtonPause": "توقف",
|
||||||
|
"ButtonPlay": "پخش",
|
||||||
|
"ButtonPlaylists": "لیست پخش",
|
||||||
|
"ButtonRead": "خواندن",
|
||||||
|
"ButtonReadLess": "خواندن کمتر",
|
||||||
|
"ButtonReadMore": "خواندن بیشتر",
|
||||||
|
"ButtonRemove": "حذف",
|
||||||
|
"ButtonSave": "ذخیره",
|
||||||
|
"ButtonSearch": "جستجو",
|
||||||
|
"ButtonSeries": "مجموعه",
|
||||||
|
"ButtonSubmit": "ثبت"
|
||||||
|
}
|
||||||
+79
-11
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"ButtonAdd": "Lisää",
|
"ButtonAdd": "Lisää",
|
||||||
|
"ButtonAddApiKey": "Lisää API avain",
|
||||||
"ButtonAddChapters": "Lisää lukuja",
|
"ButtonAddChapters": "Lisää lukuja",
|
||||||
"ButtonAddDevice": "Lisää laite",
|
"ButtonAddDevice": "Lisää laite",
|
||||||
"ButtonAddLibrary": "Lisää kirjasto",
|
"ButtonAddLibrary": "Lisää kirjasto",
|
||||||
@@ -20,6 +21,7 @@
|
|||||||
"ButtonChooseAFolder": "Valitse kansio",
|
"ButtonChooseAFolder": "Valitse kansio",
|
||||||
"ButtonChooseFiles": "Valitse tiedostot",
|
"ButtonChooseFiles": "Valitse tiedostot",
|
||||||
"ButtonClearFilter": "Poista suodatus",
|
"ButtonClearFilter": "Poista suodatus",
|
||||||
|
"ButtonClose": "Sulje",
|
||||||
"ButtonCloseFeed": "Sulje syöte",
|
"ButtonCloseFeed": "Sulje syöte",
|
||||||
"ButtonCloseSession": "Sulje Avoin Sessio",
|
"ButtonCloseSession": "Sulje Avoin Sessio",
|
||||||
"ButtonCollections": "Kokoelmat",
|
"ButtonCollections": "Kokoelmat",
|
||||||
@@ -44,6 +46,7 @@
|
|||||||
"ButtonLatest": "Viimeisimmät",
|
"ButtonLatest": "Viimeisimmät",
|
||||||
"ButtonLibrary": "Kirjasto",
|
"ButtonLibrary": "Kirjasto",
|
||||||
"ButtonLogout": "Kirjaudu ulos",
|
"ButtonLogout": "Kirjaudu ulos",
|
||||||
|
"ButtonLogoutAllDevices": "Kirjaudu ulos kaikista laitteista",
|
||||||
"ButtonLookup": "Hae",
|
"ButtonLookup": "Hae",
|
||||||
"ButtonManageTracks": "Hallitse raitoja",
|
"ButtonManageTracks": "Hallitse raitoja",
|
||||||
"ButtonMapChapterTitles": "Kartoita lukujen nimet",
|
"ButtonMapChapterTitles": "Kartoita lukujen nimet",
|
||||||
@@ -119,11 +122,13 @@
|
|||||||
"HeaderAccount": "Tili",
|
"HeaderAccount": "Tili",
|
||||||
"HeaderAddCustomMetadataProvider": "Lisää mukautettu metadata tarjoaja",
|
"HeaderAddCustomMetadataProvider": "Lisää mukautettu metadata tarjoaja",
|
||||||
"HeaderAdvanced": "Edistynyt",
|
"HeaderAdvanced": "Edistynyt",
|
||||||
|
"HeaderApiKeys": "API avaimet",
|
||||||
"HeaderAppriseNotificationSettings": "Apprise-ilmoitusasetukset",
|
"HeaderAppriseNotificationSettings": "Apprise-ilmoitusasetukset",
|
||||||
"HeaderAudioTracks": "Ääniraidat",
|
"HeaderAudioTracks": "Ääniraidat",
|
||||||
"HeaderAudiobookTools": "Äänikirjojen tiedostonhallintatyökalut",
|
"HeaderAudiobookTools": "Äänikirjojen tiedostonhallintatyökalut",
|
||||||
"HeaderAuthentication": "Todennus",
|
"HeaderAuthentication": "Todennus",
|
||||||
"HeaderBackups": "Varmuuskopiot",
|
"HeaderBackups": "Varmuuskopiot",
|
||||||
|
"HeaderBulkChapterModal": "Lisää useita kappaleita",
|
||||||
"HeaderChangePassword": "Vaihda salasana",
|
"HeaderChangePassword": "Vaihda salasana",
|
||||||
"HeaderChapters": "Luvut",
|
"HeaderChapters": "Luvut",
|
||||||
"HeaderChooseAFolder": "Valitse kansio",
|
"HeaderChooseAFolder": "Valitse kansio",
|
||||||
@@ -162,6 +167,7 @@
|
|||||||
"HeaderMetadataOrderOfPrecedence": "Metadatan tärkeysjärjestys",
|
"HeaderMetadataOrderOfPrecedence": "Metadatan tärkeysjärjestys",
|
||||||
"HeaderMetadataToEmbed": "Sisällytettävä metadata",
|
"HeaderMetadataToEmbed": "Sisällytettävä metadata",
|
||||||
"HeaderNewAccount": "Uusi tili",
|
"HeaderNewAccount": "Uusi tili",
|
||||||
|
"HeaderNewApiKey": "Uusi API avain",
|
||||||
"HeaderNewLibrary": "Uusi kirjasto",
|
"HeaderNewLibrary": "Uusi kirjasto",
|
||||||
"HeaderNotificationCreate": "Luo ilmoitus",
|
"HeaderNotificationCreate": "Luo ilmoitus",
|
||||||
"HeaderNotificationUpdate": "Päivitä ilmoitus",
|
"HeaderNotificationUpdate": "Päivitä ilmoitus",
|
||||||
@@ -177,6 +183,7 @@
|
|||||||
"HeaderPlaylist": "Soittolista",
|
"HeaderPlaylist": "Soittolista",
|
||||||
"HeaderPlaylistItems": "Soittolistan kohteet",
|
"HeaderPlaylistItems": "Soittolistan kohteet",
|
||||||
"HeaderPodcastsToAdd": "Lisättävät podcastit",
|
"HeaderPodcastsToAdd": "Lisättävät podcastit",
|
||||||
|
"HeaderPresets": "Esivalinnat",
|
||||||
"HeaderPreviewCover": "Esikatsele kansikuvaa",
|
"HeaderPreviewCover": "Esikatsele kansikuvaa",
|
||||||
"HeaderRSSFeedGeneral": "RSS yksityiskohdat",
|
"HeaderRSSFeedGeneral": "RSS yksityiskohdat",
|
||||||
"HeaderRSSFeedIsOpen": "RSS syöte on avoinna",
|
"HeaderRSSFeedIsOpen": "RSS syöte on avoinna",
|
||||||
@@ -188,12 +195,14 @@
|
|||||||
"HeaderScheduleEpisodeDownloads": "Ajoita automaattiset jaksolataukset",
|
"HeaderScheduleEpisodeDownloads": "Ajoita automaattiset jaksolataukset",
|
||||||
"HeaderScheduleLibraryScans": "Ajoita automaattiset kirjastoskannaukset",
|
"HeaderScheduleLibraryScans": "Ajoita automaattiset kirjastoskannaukset",
|
||||||
"HeaderSession": "Istunto",
|
"HeaderSession": "Istunto",
|
||||||
|
"HeaderSessions": "Istunnot",
|
||||||
"HeaderSetBackupSchedule": "Aseta varmuuskopiointiaikataulu",
|
"HeaderSetBackupSchedule": "Aseta varmuuskopiointiaikataulu",
|
||||||
"HeaderSettings": "Asetukset",
|
"HeaderSettings": "Asetukset",
|
||||||
"HeaderSettingsDisplay": "Näyttö",
|
"HeaderSettingsDisplay": "Näyttö",
|
||||||
"HeaderSettingsExperimental": "Kokeelliset ominaisuudet",
|
"HeaderSettingsExperimental": "Kokeelliset ominaisuudet",
|
||||||
"HeaderSettingsGeneral": "Yleiset",
|
"HeaderSettingsGeneral": "Yleiset",
|
||||||
"HeaderSettingsScanner": "Skannaaja",
|
"HeaderSettingsScanner": "Skannaaja",
|
||||||
|
"HeaderSettingsSecurity": "Turvallisuus",
|
||||||
"HeaderSettingsWebClient": "Webasiakasohjelma",
|
"HeaderSettingsWebClient": "Webasiakasohjelma",
|
||||||
"HeaderSleepTimer": "Uniajastin",
|
"HeaderSleepTimer": "Uniajastin",
|
||||||
"HeaderStatsLargestItems": "Suurimmat kohteet",
|
"HeaderStatsLargestItems": "Suurimmat kohteet",
|
||||||
@@ -205,6 +214,7 @@
|
|||||||
"HeaderTableOfContents": "Sisällysluettelo",
|
"HeaderTableOfContents": "Sisällysluettelo",
|
||||||
"HeaderTools": "Työkalut",
|
"HeaderTools": "Työkalut",
|
||||||
"HeaderUpdateAccount": "Päivitä tili",
|
"HeaderUpdateAccount": "Päivitä tili",
|
||||||
|
"HeaderUpdateApiKey": "Päivitä API avain",
|
||||||
"HeaderUpdateAuthor": "Päivitä tekijä",
|
"HeaderUpdateAuthor": "Päivitä tekijä",
|
||||||
"HeaderUpdateDetails": "Päivitä yksityiskohdat",
|
"HeaderUpdateDetails": "Päivitä yksityiskohdat",
|
||||||
"HeaderUpdateLibrary": "Päivitä kirjasto",
|
"HeaderUpdateLibrary": "Päivitä kirjasto",
|
||||||
@@ -214,7 +224,7 @@
|
|||||||
"LabelAbridged": "Lyhennetty",
|
"LabelAbridged": "Lyhennetty",
|
||||||
"LabelAbridgedChecked": "Lyhennetty (tarkistettu)",
|
"LabelAbridgedChecked": "Lyhennetty (tarkistettu)",
|
||||||
"LabelAbridgedUnchecked": "Lyhentämätön (tarkistamaton)",
|
"LabelAbridgedUnchecked": "Lyhentämätön (tarkistamaton)",
|
||||||
"LabelAccessibleBy": "Saavutettavissa:",
|
"LabelAccessibleBy": "Saavutettavissa",
|
||||||
"LabelAccountType": "Tilin tyyppi",
|
"LabelAccountType": "Tilin tyyppi",
|
||||||
"LabelAccountTypeAdmin": "Järjestelmänvalvoja",
|
"LabelAccountTypeAdmin": "Järjestelmänvalvoja",
|
||||||
"LabelAccountTypeGuest": "Vieras",
|
"LabelAccountTypeGuest": "Vieras",
|
||||||
@@ -234,6 +244,10 @@
|
|||||||
"LabelAllUsersExcludingGuests": "Kaikki käyttäjät vieraita lukuun ottamatta",
|
"LabelAllUsersExcludingGuests": "Kaikki käyttäjät vieraita lukuun ottamatta",
|
||||||
"LabelAllUsersIncludingGuests": "Kaikki käyttäjät mukaan lukien vieraat",
|
"LabelAllUsersIncludingGuests": "Kaikki käyttäjät mukaan lukien vieraat",
|
||||||
"LabelAlreadyInYourLibrary": "Jo kirjastossasi",
|
"LabelAlreadyInYourLibrary": "Jo kirjastossasi",
|
||||||
|
"LabelApiKeyCreated": "API avain \"{0}\" luotu onnistuneesti.",
|
||||||
|
"LabelApiKeyCreatedDescription": "Varmista, että kopioit API avaimen. Sitä ei näytetä enää tämän jälkeen.",
|
||||||
|
"LabelApiKeyUser": "Toimi käyttäjän puolesta",
|
||||||
|
"LabelApiKeyUserDescription": "Tällä API-avaimella on samat käyttöoikeudet kuin käyttäjällä, jonka puolesta se toimii. Tämä näkyy lokeissa samalla tavalla kuin jos käyttäjä itse tekisi pyynnön.",
|
||||||
"LabelApiToken": "Sovellusliittymätunnus",
|
"LabelApiToken": "Sovellusliittymätunnus",
|
||||||
"LabelAppend": "Lisää loppuun",
|
"LabelAppend": "Lisää loppuun",
|
||||||
"LabelAudioBitrate": "Äänen bittinopeus (esim. 128k)",
|
"LabelAudioBitrate": "Äänen bittinopeus (esim. 128k)",
|
||||||
@@ -263,7 +277,7 @@
|
|||||||
"LabelBonus": "Bonus",
|
"LabelBonus": "Bonus",
|
||||||
"LabelBooks": "Kirjat",
|
"LabelBooks": "Kirjat",
|
||||||
"LabelButtonText": "Painikkeen teksti",
|
"LabelButtonText": "Painikkeen teksti",
|
||||||
"LabelByAuthor": "tekijältä {0}",
|
"LabelByAuthor": "Tekijältä: {0}",
|
||||||
"LabelChangePassword": "Vaihda salasana",
|
"LabelChangePassword": "Vaihda salasana",
|
||||||
"LabelChannels": "Kanavat",
|
"LabelChannels": "Kanavat",
|
||||||
"LabelChapterCount": "{0} lukua",
|
"LabelChapterCount": "{0} lukua",
|
||||||
@@ -283,6 +297,7 @@
|
|||||||
"LabelContinueListening": "Jatka kuuntelua",
|
"LabelContinueListening": "Jatka kuuntelua",
|
||||||
"LabelContinueReading": "Jatka lukemista",
|
"LabelContinueReading": "Jatka lukemista",
|
||||||
"LabelContinueSeries": "Jatka sarjoja",
|
"LabelContinueSeries": "Jatka sarjoja",
|
||||||
|
"LabelCorsAllowed": "Salli CORS Origins",
|
||||||
"LabelCover": "Kansikuva",
|
"LabelCover": "Kansikuva",
|
||||||
"LabelCoverImageURL": "Kansikuvan URL-osoite",
|
"LabelCoverImageURL": "Kansikuvan URL-osoite",
|
||||||
"LabelCoverProvider": "Kansikuvan tarjoaja",
|
"LabelCoverProvider": "Kansikuvan tarjoaja",
|
||||||
@@ -296,6 +311,7 @@
|
|||||||
"LabelDeleteFromFileSystemCheckbox": "Poista tiedostojärjestelmästä (poista merkintä, jos haluat poistaa vain tietokannasta)",
|
"LabelDeleteFromFileSystemCheckbox": "Poista tiedostojärjestelmästä (poista merkintä, jos haluat poistaa vain tietokannasta)",
|
||||||
"LabelDescription": "Kuvaus",
|
"LabelDescription": "Kuvaus",
|
||||||
"LabelDeselectAll": "Poista valinta kaikista",
|
"LabelDeselectAll": "Poista valinta kaikista",
|
||||||
|
"LabelDetectedPattern": "Tunnista malli:",
|
||||||
"LabelDevice": "Laite",
|
"LabelDevice": "Laite",
|
||||||
"LabelDeviceInfo": "Laitteen tiedot",
|
"LabelDeviceInfo": "Laitteen tiedot",
|
||||||
"LabelDeviceIsAvailableTo": "Laite on saatavilla...",
|
"LabelDeviceIsAvailableTo": "Laite on saatavilla...",
|
||||||
@@ -345,7 +361,11 @@
|
|||||||
"LabelExample": "Esimerkki",
|
"LabelExample": "Esimerkki",
|
||||||
"LabelExpandSeries": "Laajenna sarja",
|
"LabelExpandSeries": "Laajenna sarja",
|
||||||
"LabelExpandSubSeries": "Laajenna alisarja",
|
"LabelExpandSubSeries": "Laajenna alisarja",
|
||||||
"LabelExplicit": "Yksiselitteinen",
|
"LabelExpired": "Vanhentunut",
|
||||||
|
"LabelExpiresAt": "Vanhentuu",
|
||||||
|
"LabelExpiresInSeconds": "Vanhentuu (sekunnissa)",
|
||||||
|
"LabelExpiresNever": "Ei koskaan",
|
||||||
|
"LabelExplicit": "Sopimaton",
|
||||||
"LabelExplicitChecked": "Yksiselitteinen (valittu)",
|
"LabelExplicitChecked": "Yksiselitteinen (valittu)",
|
||||||
"LabelExplicitUnchecked": "Ei yksiselitteinen (ei valittu)",
|
"LabelExplicitUnchecked": "Ei yksiselitteinen (ei valittu)",
|
||||||
"LabelExportOPML": "Vie OPML",
|
"LabelExportOPML": "Vie OPML",
|
||||||
@@ -360,11 +380,12 @@
|
|||||||
"LabelFilterByUser": "Suodata käyttäjien perusteella",
|
"LabelFilterByUser": "Suodata käyttäjien perusteella",
|
||||||
"LabelFindEpisodes": "Etsi jaksoja",
|
"LabelFindEpisodes": "Etsi jaksoja",
|
||||||
"LabelFinished": "Valmis",
|
"LabelFinished": "Valmis",
|
||||||
|
"LabelFinishedDate": "Valmis {0}",
|
||||||
"LabelFolder": "Kansio",
|
"LabelFolder": "Kansio",
|
||||||
"LabelFolders": "Kansiot",
|
"LabelFolders": "Kansiot",
|
||||||
"LabelFontBold": "Lihavoitu",
|
"LabelFontBold": "Lihavoitu",
|
||||||
"LabelFontBoldness": "Kirjasintyyppien lihavointi",
|
"LabelFontBoldness": "Kirjasintyyppien lihavointi",
|
||||||
"LabelFontFamily": "Kirjasinperhe",
|
"LabelFontFamily": "Fonttiperhe",
|
||||||
"LabelFontItalic": "Kursiivi",
|
"LabelFontItalic": "Kursiivi",
|
||||||
"LabelFontScale": "Kirjasintyyppien skaalautuminen",
|
"LabelFontScale": "Kirjasintyyppien skaalautuminen",
|
||||||
"LabelFontStrikethrough": "Yliviivattu",
|
"LabelFontStrikethrough": "Yliviivattu",
|
||||||
@@ -396,6 +417,7 @@
|
|||||||
"LabelIntervalEveryHour": "Joka tunti",
|
"LabelIntervalEveryHour": "Joka tunti",
|
||||||
"LabelIntervalEveryMinute": "Joka minuutti",
|
"LabelIntervalEveryMinute": "Joka minuutti",
|
||||||
"LabelInvert": "Saa käänteiseksi",
|
"LabelInvert": "Saa käänteiseksi",
|
||||||
|
"LabelIpAddress": "IP-osoite",
|
||||||
"LabelItem": "Kohde",
|
"LabelItem": "Kohde",
|
||||||
"LabelJumpBackwardAmount": "Taaksepäin-hyppyjen määrä",
|
"LabelJumpBackwardAmount": "Taaksepäin-hyppyjen määrä",
|
||||||
"LabelJumpForwardAmount": "Eteenpäin-hyppyjen määrä",
|
"LabelJumpForwardAmount": "Eteenpäin-hyppyjen määrä",
|
||||||
@@ -404,6 +426,7 @@
|
|||||||
"LabelLanguages": "Kielet",
|
"LabelLanguages": "Kielet",
|
||||||
"LabelLastBookAdded": "Viimeisin lisätty kirja",
|
"LabelLastBookAdded": "Viimeisin lisätty kirja",
|
||||||
"LabelLastBookUpdated": "Viimeisin päivitetty kirja",
|
"LabelLastBookUpdated": "Viimeisin päivitetty kirja",
|
||||||
|
"LabelLastProgressDate": "Viimeisin edistyminen {0}",
|
||||||
"LabelLastSeen": "Nähty viimeksi",
|
"LabelLastSeen": "Nähty viimeksi",
|
||||||
"LabelLastTime": "Viimeinen kerta",
|
"LabelLastTime": "Viimeinen kerta",
|
||||||
"LabelLastUpdate": "Viimeisin päivitys",
|
"LabelLastUpdate": "Viimeisin päivitys",
|
||||||
@@ -416,6 +439,9 @@
|
|||||||
"LabelLibraryFilterSublistEmpty": "Ei {0}",
|
"LabelLibraryFilterSublistEmpty": "Ei {0}",
|
||||||
"LabelLibraryItem": "Kirjaston kohde",
|
"LabelLibraryItem": "Kirjaston kohde",
|
||||||
"LabelLibraryName": "Kirjaston nimi",
|
"LabelLibraryName": "Kirjaston nimi",
|
||||||
|
"LabelLibrarySortByProgress": "Edistyminen: Viimeksi päivitetty",
|
||||||
|
"LabelLibrarySortByProgressFinished": "Edistyminen: Valmis",
|
||||||
|
"LabelLibrarySortByProgressStarted": "Edistyminen: Aloitettu",
|
||||||
"LabelLimit": "Raja",
|
"LabelLimit": "Raja",
|
||||||
"LabelLineSpacing": "Riviväli",
|
"LabelLineSpacing": "Riviväli",
|
||||||
"LabelListenAgain": "Kuuntele uudelleen",
|
"LabelListenAgain": "Kuuntele uudelleen",
|
||||||
@@ -424,6 +450,7 @@
|
|||||||
"LabelLogLevelWarn": "Varoitus",
|
"LabelLogLevelWarn": "Varoitus",
|
||||||
"LabelLookForNewEpisodesAfterDate": "Etsi uusia jaksoja tämän päivämäärän jälkeen",
|
"LabelLookForNewEpisodesAfterDate": "Etsi uusia jaksoja tämän päivämäärän jälkeen",
|
||||||
"LabelLowestPriority": "Vähiten tärkeä",
|
"LabelLowestPriority": "Vähiten tärkeä",
|
||||||
|
"LabelMatchConfidence": "Varmuus",
|
||||||
"LabelMatchExistingUsersBy": "Vastaa olemassa olevia käyttäjiä mukaan",
|
"LabelMatchExistingUsersBy": "Vastaa olemassa olevia käyttäjiä mukaan",
|
||||||
"LabelMatchExistingUsersByDescription": "Käytetään olemassa olevien käyttäjien yhdistämiseen. Kun yhteys on muodostettu, käyttäjät saavat yksilöllisen tunnuksen SSO-palveluntarjoajaltasi",
|
"LabelMatchExistingUsersByDescription": "Käytetään olemassa olevien käyttäjien yhdistämiseen. Kun yhteys on muodostettu, käyttäjät saavat yksilöllisen tunnuksen SSO-palveluntarjoajaltasi",
|
||||||
"LabelMaxEpisodesToDownload": "Jaksojen maksimilatausmäärä. 0 poistaa rajoituksen.",
|
"LabelMaxEpisodesToDownload": "Jaksojen maksimilatausmäärä. 0 poistaa rajoituksen.",
|
||||||
@@ -453,7 +480,9 @@
|
|||||||
"LabelNewestAuthors": "Uusimmat tekijät",
|
"LabelNewestAuthors": "Uusimmat tekijät",
|
||||||
"LabelNewestEpisodes": "Uusimmat jaksot",
|
"LabelNewestEpisodes": "Uusimmat jaksot",
|
||||||
"LabelNextBackupDate": "Seuraava varmuuskopiointipäivämäärä",
|
"LabelNextBackupDate": "Seuraava varmuuskopiointipäivämäärä",
|
||||||
|
"LabelNextChapters": "Seuraavat luvut:",
|
||||||
"LabelNextScheduledRun": "Seuraava ajastettu suorittaminen",
|
"LabelNextScheduledRun": "Seuraava ajastettu suorittaminen",
|
||||||
|
"LabelNoApiKeys": "Ei API-avaimia",
|
||||||
"LabelNoCustomMetadataProviders": "Ei mukautettuja kuvailutietojen toimittajia",
|
"LabelNoCustomMetadataProviders": "Ei mukautettuja kuvailutietojen toimittajia",
|
||||||
"LabelNoEpisodesSelected": "Jaksoja ei ole valittu",
|
"LabelNoEpisodesSelected": "Jaksoja ei ole valittu",
|
||||||
"LabelNotFinished": "Ei valmis",
|
"LabelNotFinished": "Ei valmis",
|
||||||
@@ -469,6 +498,7 @@
|
|||||||
"LabelNotificationsMaxQueueSize": "Ilmoitustapahtumajonon enimmäispituus",
|
"LabelNotificationsMaxQueueSize": "Ilmoitustapahtumajonon enimmäispituus",
|
||||||
"LabelNotificationsMaxQueueSizeHelp": "Tapahtumat on rajoitettu ampumaan yksi sekunnissa. Tapahtumat ohitetaan, jos jono on enimmäiskoko. Tämä estää ilmoitusten roskapostin.",
|
"LabelNotificationsMaxQueueSizeHelp": "Tapahtumat on rajoitettu ampumaan yksi sekunnissa. Tapahtumat ohitetaan, jos jono on enimmäiskoko. Tämä estää ilmoitusten roskapostin.",
|
||||||
"LabelNumberOfBooks": "Kirjojen määrä",
|
"LabelNumberOfBooks": "Kirjojen määrä",
|
||||||
|
"LabelNumberOfChapters": "Lukujen lukumäärä:",
|
||||||
"LabelNumberOfEpisodes": "# jaksoja",
|
"LabelNumberOfEpisodes": "# jaksoja",
|
||||||
"LabelOpenIDAdvancedPermsClaimDescription": "OpenID-vaatimuksen nimi, joka sisältää lisäoikeudet sovelluksen käyttäjän toimiin, joita sovelletaan muihin kuin järjestelmänvalvojan rooleihin (<b>jos määritetty</b>). Jos vaatimus puuttuu vastauksesta, pääsy ABS:iin evätään. Jos yksittäinen vaihtoehto puuttuu, sitä käsitellään <code>false</code>-arvona. Varmista, että identiteetin tarjoajan vaatimus vastaa odotettua rakennetta:",
|
"LabelOpenIDAdvancedPermsClaimDescription": "OpenID-vaatimuksen nimi, joka sisältää lisäoikeudet sovelluksen käyttäjän toimiin, joita sovelletaan muihin kuin järjestelmänvalvojan rooleihin (<b>jos määritetty</b>). Jos vaatimus puuttuu vastauksesta, pääsy ABS:iin evätään. Jos yksittäinen vaihtoehto puuttuu, sitä käsitellään <code>false</code>-arvona. Varmista, että identiteetin tarjoajan vaatimus vastaa odotettua rakennetta:",
|
||||||
"LabelOpenIDClaims": "Jätä seuraavat vaihtoehdot tyhjiksi, jos haluat poistaa edistyneen ryhmän ja lupien määrityksen käytöstä ja määrittää sitten automaattisesti käyttäjäryhmän.",
|
"LabelOpenIDClaims": "Jätä seuraavat vaihtoehdot tyhjiksi, jos haluat poistaa edistyneen ryhmän ja lupien määrityksen käytöstä ja määrittää sitten automaattisesti käyttäjäryhmän.",
|
||||||
@@ -513,7 +543,7 @@
|
|||||||
"LabelPublishers": "Julkaisijat",
|
"LabelPublishers": "Julkaisijat",
|
||||||
"LabelRSSFeedCustomOwnerEmail": "Mukautettu omistajan sähköposti",
|
"LabelRSSFeedCustomOwnerEmail": "Mukautettu omistajan sähköposti",
|
||||||
"LabelRSSFeedCustomOwnerName": "Mukautettu omistajan nimi",
|
"LabelRSSFeedCustomOwnerName": "Mukautettu omistajan nimi",
|
||||||
"LabelRSSFeedOpen": "RSS-syöte avoin",
|
"LabelRSSFeedOpen": "RSS Syöte Avoin",
|
||||||
"LabelRSSFeedPreventIndexing": "Estä indeksointi",
|
"LabelRSSFeedPreventIndexing": "Estä indeksointi",
|
||||||
"LabelRSSFeedSlug": "RSS-syöte Slug",
|
"LabelRSSFeedSlug": "RSS-syöte Slug",
|
||||||
"LabelRSSFeedURL": "RSS-syötteen URL-osoite",
|
"LabelRSSFeedURL": "RSS-syötteen URL-osoite",
|
||||||
@@ -523,7 +553,7 @@
|
|||||||
"LabelReadAgain": "Lue uudelleen",
|
"LabelReadAgain": "Lue uudelleen",
|
||||||
"LabelReadEbookWithoutProgress": "Lue s-kirja tallentamatta edistymistietoja",
|
"LabelReadEbookWithoutProgress": "Lue s-kirja tallentamatta edistymistietoja",
|
||||||
"LabelRecentSeries": "Viimeisimmät sarjat",
|
"LabelRecentSeries": "Viimeisimmät sarjat",
|
||||||
"LabelRecentlyAdded": "Viimeeksi lisätyt",
|
"LabelRecentlyAdded": "Viimeksi lisätyt",
|
||||||
"LabelRecommended": "Suositeltu",
|
"LabelRecommended": "Suositeltu",
|
||||||
"LabelRedo": "Tee uudelleen",
|
"LabelRedo": "Tee uudelleen",
|
||||||
"LabelRegion": "Alue",
|
"LabelRegion": "Alue",
|
||||||
@@ -543,6 +573,7 @@
|
|||||||
"LabelSelectAll": "Valitse kaikki",
|
"LabelSelectAll": "Valitse kaikki",
|
||||||
"LabelSelectAllEpisodes": "Valitse kaikki jaksot",
|
"LabelSelectAllEpisodes": "Valitse kaikki jaksot",
|
||||||
"LabelSelectEpisodesShowing": "Valitse {0} näytettävää jaksoa",
|
"LabelSelectEpisodesShowing": "Valitse {0} näytettävää jaksoa",
|
||||||
|
"LabelSelectUser": "Valitse käyttäjä",
|
||||||
"LabelSelectUsers": "Valitse käyttäjät",
|
"LabelSelectUsers": "Valitse käyttäjät",
|
||||||
"LabelSendEbookToDevice": "Lähetä s-kirja kohteeseen...",
|
"LabelSendEbookToDevice": "Lähetä s-kirja kohteeseen...",
|
||||||
"LabelSequence": "Sekvenssi",
|
"LabelSequence": "Sekvenssi",
|
||||||
@@ -560,8 +591,8 @@
|
|||||||
"LabelSettingsBookshelfViewHelp": "Skeuomorfinen muotoilu puisilla hyllyillä",
|
"LabelSettingsBookshelfViewHelp": "Skeuomorfinen muotoilu puisilla hyllyillä",
|
||||||
"LabelSettingsChromecastSupport": "Chromecast-tuki",
|
"LabelSettingsChromecastSupport": "Chromecast-tuki",
|
||||||
"LabelSettingsDateFormat": "Päivämäärän muoto",
|
"LabelSettingsDateFormat": "Päivämäärän muoto",
|
||||||
"LabelSettingsEnableWatcher": "Skannaa kirjastot automaattisesti muutoksien varalta",
|
"LabelSettingsEnableWatcher": "Vahdi kirjastoja automaattisesti muutoksien varalta",
|
||||||
"LabelSettingsEnableWatcherForLibrary": "Skannaa kirjastot automaattisesti muutoksien varalta",
|
"LabelSettingsEnableWatcherForLibrary": "Vahdi kirjastoja automaattisesti muutoksien varalta",
|
||||||
"LabelSettingsEnableWatcherHelp": "Ottaa käyttöön kohteiden automaattisen lisäämisen ja päivityksen kun tiedostomuutoksia havaitaan. *Tarvitsee palvelimen uudelleenkäynnistyksen",
|
"LabelSettingsEnableWatcherHelp": "Ottaa käyttöön kohteiden automaattisen lisäämisen ja päivityksen kun tiedostomuutoksia havaitaan. *Tarvitsee palvelimen uudelleenkäynnistyksen",
|
||||||
"LabelSettingsEpubsAllowScriptedContent": "Salli komentosarjamuotoinen sisältö epubissa",
|
"LabelSettingsEpubsAllowScriptedContent": "Salli komentosarjamuotoinen sisältö epubissa",
|
||||||
"LabelSettingsEpubsAllowScriptedContentHelp": "Salli epub-tiedostojen suorittaa komentosarjoja. On suositeltavaa pitää tämä asetus pois käytöstä, ellet luota epub-tiedostojen lähteeseen.",
|
"LabelSettingsEpubsAllowScriptedContentHelp": "Salli epub-tiedostojen suorittaa komentosarjoja. On suositeltavaa pitää tämä asetus pois käytöstä, ellet luota epub-tiedostojen lähteeseen.",
|
||||||
@@ -610,6 +641,7 @@
|
|||||||
"LabelStartTime": "Aloitusaika",
|
"LabelStartTime": "Aloitusaika",
|
||||||
"LabelStarted": "Aloitettu",
|
"LabelStarted": "Aloitettu",
|
||||||
"LabelStartedAt": "Aloitettu",
|
"LabelStartedAt": "Aloitettu",
|
||||||
|
"LabelStartedDate": "Aloitettu {0}",
|
||||||
"LabelStatsAudioTracks": "Ääniraidat",
|
"LabelStatsAudioTracks": "Ääniraidat",
|
||||||
"LabelStatsAuthors": "Tekijät",
|
"LabelStatsAuthors": "Tekijät",
|
||||||
"LabelStatsBestDay": "Paras päivä",
|
"LabelStatsBestDay": "Paras päivä",
|
||||||
@@ -639,6 +671,7 @@
|
|||||||
"LabelTheme": "Teema",
|
"LabelTheme": "Teema",
|
||||||
"LabelThemeDark": "Tumma",
|
"LabelThemeDark": "Tumma",
|
||||||
"LabelThemeLight": "Kirkas",
|
"LabelThemeLight": "Kirkas",
|
||||||
|
"LabelThemeSepia": "Seepia",
|
||||||
"LabelTimeBase": "Aika-alusta",
|
"LabelTimeBase": "Aika-alusta",
|
||||||
"LabelTimeDurationXHours": "{0} tuntia",
|
"LabelTimeDurationXHours": "{0} tuntia",
|
||||||
"LabelTimeDurationXMinutes": "{0} minuuttia",
|
"LabelTimeDurationXMinutes": "{0} minuuttia",
|
||||||
@@ -706,6 +739,10 @@
|
|||||||
"LabelYourProgress": "Edistymisesi",
|
"LabelYourProgress": "Edistymisesi",
|
||||||
"MessageAddToPlayerQueue": "Lisää soittimen jonoon",
|
"MessageAddToPlayerQueue": "Lisää soittimen jonoon",
|
||||||
"MessageAppriseDescription": "Käyttääksesi tätä toimintoa tarvitset <a href=\"https://github.com/caronc/apprise-api\" target=\"_blank\">Apprise API</a> -instanssin tai rajapinnan joka käsittelee samoja pyyntöjä. <br />Apprise rajapinnan osoite tulee olla täysi URL polku ilmoituksen lähetykseen, esim. jos rajapinta on osoitteessa <code>http://192.168.1.1:8337</code>,niin arvoksi tulee antaa <code>http://192.168.1.1:8337/notify</code>.",
|
"MessageAppriseDescription": "Käyttääksesi tätä toimintoa tarvitset <a href=\"https://github.com/caronc/apprise-api\" target=\"_blank\">Apprise API</a> -instanssin tai rajapinnan joka käsittelee samoja pyyntöjä. <br />Apprise rajapinnan osoite tulee olla täysi URL polku ilmoituksen lähetykseen, esim. jos rajapinta on osoitteessa <code>http://192.168.1.1:8337</code>,niin arvoksi tulee antaa <code>http://192.168.1.1:8337/notify</code>.",
|
||||||
|
"MessageAsinCheck": "Varmista, että käytät ASIN-tunnusta oikealta Audible-alueelta, ei Amazonista.",
|
||||||
|
"MessageAuthenticationLegacyTokenWarning": "Vanhat API-tunnukset poistetaan tulevaisuudessa. Käytä sen sijaan <a href=\"/config/api-keys\">API-avaimia</a>.",
|
||||||
|
"MessageAuthenticationOIDCChangesRestart": "Käynnistä palvelin uudelleen tallennuksen jälkeen ottaaksesi OIDC-muutokset käyttöön.",
|
||||||
|
"MessageAuthenticationSecurityMessage": "Tunnistautumisen tietoturvaa on parannettu. Kaikkien käyttäjien tulee kirjautua sisään uudelleen.",
|
||||||
"MessageBackupsDescription": "Varmuuskopiot sisältävät käyttäjät, käyttäjien edistymisen, kirjastokohteiden tiedot, palvelinasetukset ja <code>/metadata/items</code>- ja <code>/metadata/authors</code> -kansioihin tallennetut kuvat. Varmuuskopiot <strong>eivät sisällä</strong> kirjastosi kansioihin tallennettuja tiedostoja.",
|
"MessageBackupsDescription": "Varmuuskopiot sisältävät käyttäjät, käyttäjien edistymisen, kirjastokohteiden tiedot, palvelinasetukset ja <code>/metadata/items</code>- ja <code>/metadata/authors</code> -kansioihin tallennetut kuvat. Varmuuskopiot <strong>eivät sisällä</strong> kirjastosi kansioihin tallennettuja tiedostoja.",
|
||||||
"MessageBackupsLocationEditNote": "Huomautus: Varmuuskopion sijainnin päivittäminen ei siirrä tai muokkaa olemassa olevia varmuuskopioita",
|
"MessageBackupsLocationEditNote": "Huomautus: Varmuuskopion sijainnin päivittäminen ei siirrä tai muokkaa olemassa olevia varmuuskopioita",
|
||||||
"MessageBackupsLocationNoEditNote": "Huomautus: Varmuuskopion sijainti asetetaan ympäristömuuttujan kautta, eikä sitä voi muuttaa tässä.",
|
"MessageBackupsLocationNoEditNote": "Huomautus: Varmuuskopion sijainti asetetaan ympäristömuuttujan kautta, eikä sitä voi muuttaa tässä.",
|
||||||
@@ -719,6 +756,7 @@
|
|||||||
"MessageBookshelfNoResultsForFilter": "Ei tuloksia suodattimelle \"{0}: {1}\"",
|
"MessageBookshelfNoResultsForFilter": "Ei tuloksia suodattimelle \"{0}: {1}\"",
|
||||||
"MessageBookshelfNoResultsForQuery": "Ei tuloksia kyselylle",
|
"MessageBookshelfNoResultsForQuery": "Ei tuloksia kyselylle",
|
||||||
"MessageBookshelfNoSeries": "Sinulla ei ole sarjoja",
|
"MessageBookshelfNoSeries": "Sinulla ei ole sarjoja",
|
||||||
|
"MessageBulkChapterPattern": "Kuinka monta lukua haluaisit lisätä tällä numerointimallilla?",
|
||||||
"MessageChapterEndIsAfter": "Luvun loppu sijaitsee äänikirjan lopun jälkeen",
|
"MessageChapterEndIsAfter": "Luvun loppu sijaitsee äänikirjan lopun jälkeen",
|
||||||
"MessageChapterErrorFirstNotZero": "Ensimmäisen luvun tulee alkaa nollasta",
|
"MessageChapterErrorFirstNotZero": "Ensimmäisen luvun tulee alkaa nollasta",
|
||||||
"MessageChapterErrorStartGteDuration": "Epäkelvollinen aloitusaika; on oltava lyhyempi kuin äänikirjan kesto",
|
"MessageChapterErrorStartGteDuration": "Epäkelvollinen aloitusaika; on oltava lyhyempi kuin äänikirjan kesto",
|
||||||
@@ -727,6 +765,7 @@
|
|||||||
"MessageChaptersNotFound": "Kappaleita ei löydy",
|
"MessageChaptersNotFound": "Kappaleita ei löydy",
|
||||||
"MessageCheckingCron": "Tarkistetaan cronia...",
|
"MessageCheckingCron": "Tarkistetaan cronia...",
|
||||||
"MessageConfirmCloseFeed": "Oletko varma, että haluat sulkea tämän syötteen?",
|
"MessageConfirmCloseFeed": "Oletko varma, että haluat sulkea tämän syötteen?",
|
||||||
|
"MessageConfirmDeleteApiKey": "Haluatko varmasti poistaa API-avaimen \"{0}\"?",
|
||||||
"MessageConfirmDeleteBackup": "Oletko varma, että haluat poistaa varmuuskopion {0}:lle?",
|
"MessageConfirmDeleteBackup": "Oletko varma, että haluat poistaa varmuuskopion {0}:lle?",
|
||||||
"MessageConfirmDeleteDevice": "Oletko varma, että haluat poistaa s-lukulaitteen \"{0}\"?",
|
"MessageConfirmDeleteDevice": "Oletko varma, että haluat poistaa s-lukulaitteen \"{0}\"?",
|
||||||
"MessageConfirmDeleteFile": "Tämä poistaa tiedoston tiedostojärjestelmästäsi. Oletko varma?",
|
"MessageConfirmDeleteFile": "Tämä poistaa tiedoston tiedostojärjestelmästäsi. Oletko varma?",
|
||||||
@@ -738,6 +777,7 @@
|
|||||||
"MessageConfirmDeleteSession": "Oletko varma, että haluat poistaa tämän istunnon?",
|
"MessageConfirmDeleteSession": "Oletko varma, että haluat poistaa tämän istunnon?",
|
||||||
"MessageConfirmEmbedMetadataInAudioFiles": "Oletko varma, että haluat upottaa metatiedot {0} äänitiedostoihin?",
|
"MessageConfirmEmbedMetadataInAudioFiles": "Oletko varma, että haluat upottaa metatiedot {0} äänitiedostoihin?",
|
||||||
"MessageConfirmForceReScan": "Oletko varma, että haluat pakottaa uudelleenskannauksen?",
|
"MessageConfirmForceReScan": "Oletko varma, että haluat pakottaa uudelleenskannauksen?",
|
||||||
|
"MessageConfirmLogoutDevice": "Haluatko varmasti kirjautua ulos palvelusta \"{0}\"?",
|
||||||
"MessageConfirmMarkAllEpisodesFinished": "Oletko varma, että haluat merkitä kaikki jaksot päättyneiksi?",
|
"MessageConfirmMarkAllEpisodesFinished": "Oletko varma, että haluat merkitä kaikki jaksot päättyneiksi?",
|
||||||
"MessageConfirmMarkAllEpisodesNotFinished": "Oletko varma, että haluat merkitä kaikki jaksot ei-valmiiksi?",
|
"MessageConfirmMarkAllEpisodesNotFinished": "Oletko varma, että haluat merkitä kaikki jaksot ei-valmiiksi?",
|
||||||
"MessageConfirmMarkItemFinished": "Oletko varma, että haluat merkitä \"{0}\":n valmiiksi?",
|
"MessageConfirmMarkItemFinished": "Oletko varma, että haluat merkitä \"{0}\":n valmiiksi?",
|
||||||
@@ -754,6 +794,7 @@
|
|||||||
"MessageConfirmRemoveAuthor": "Oletko varma, että haluat poistaa tekijän \"{0}\"?",
|
"MessageConfirmRemoveAuthor": "Oletko varma, että haluat poistaa tekijän \"{0}\"?",
|
||||||
"MessageConfirmRemoveCollection": "Oletko varma, että haluat poistaa kokoelman \"{0}\"?",
|
"MessageConfirmRemoveCollection": "Oletko varma, että haluat poistaa kokoelman \"{0}\"?",
|
||||||
"MessageConfirmRemoveEpisode": "Oletko varma, että haluat poistaa jakson \"{0}\"?",
|
"MessageConfirmRemoveEpisode": "Oletko varma, että haluat poistaa jakson \"{0}\"?",
|
||||||
|
"MessageConfirmRemoveEpisodeNote": "Huomioi: Tämä ei poista äänitiedostoa, ellei \"Poista tiedosto pysyvästi\" -asetusta ole valittuna",
|
||||||
"MessageConfirmRemoveEpisodes": "Oletko varma, että haluat poistaa {0} jaksoa?",
|
"MessageConfirmRemoveEpisodes": "Oletko varma, että haluat poistaa {0} jaksoa?",
|
||||||
"MessageConfirmRemoveListeningSessions": "Oletko varma, että haluat poistaa {0} kuuntelukertaa?",
|
"MessageConfirmRemoveListeningSessions": "Oletko varma, että haluat poistaa {0} kuuntelukertaa?",
|
||||||
"MessageConfirmRemoveMetadataFiles": "Oletko varma, että haluat poistaa kaikki metadata.{0}-tiedostot kirjaston kohdekansioista?",
|
"MessageConfirmRemoveMetadataFiles": "Oletko varma, että haluat poistaa kaikki metadata.{0}-tiedostot kirjaston kohdekansioista?",
|
||||||
@@ -779,6 +820,8 @@
|
|||||||
"MessageFeedURLWillBe": "Syötteen URL tulee olemaan {0}",
|
"MessageFeedURLWillBe": "Syötteen URL tulee olemaan {0}",
|
||||||
"MessageFetching": "Haetaan...",
|
"MessageFetching": "Haetaan...",
|
||||||
"MessageForceReScanDescription": "skannaa kaikki tiedostot uudelleen kuten uusi tarkistus. Äänitiedoston ID3-tunnisteet, OPF-tiedostot ja tekstitiedostot skannataan uusina.",
|
"MessageForceReScanDescription": "skannaa kaikki tiedostot uudelleen kuten uusi tarkistus. Äänitiedoston ID3-tunnisteet, OPF-tiedostot ja tekstitiedostot skannataan uusina.",
|
||||||
|
"MessageHeatmapListeningTimeTooltip": "<strong>{0} kuunnellaan</strong> on {1}",
|
||||||
|
"MessageHeatmapNoListeningSessions": "Ei kuuntelujaksoja {0}",
|
||||||
"MessageImportantNotice": "Tärkeä huomautus!",
|
"MessageImportantNotice": "Tärkeä huomautus!",
|
||||||
"MessageInsertChapterBelow": "Syötä luku alle",
|
"MessageInsertChapterBelow": "Syötä luku alle",
|
||||||
"MessageInvalidAsin": "Virheellinen ASIN",
|
"MessageInvalidAsin": "Virheellinen ASIN",
|
||||||
@@ -849,10 +892,11 @@
|
|||||||
"MessageResetChaptersConfirm": "Oletko varma, että haluat nollata luvut ja kumota tekemäsi muutokset?",
|
"MessageResetChaptersConfirm": "Oletko varma, että haluat nollata luvut ja kumota tekemäsi muutokset?",
|
||||||
"MessageRestoreBackupConfirm": "Oletko varma, että haluat palauttaa varmuuskopion, joka on luotu",
|
"MessageRestoreBackupConfirm": "Oletko varma, että haluat palauttaa varmuuskopion, joka on luotu",
|
||||||
"MessageRestoreBackupWarning": "Varmuuskopion palauttaminen korvaa koko /config:ssa sijaitsevan tietokannan, ja kansikuvat /metadata/items & /metadata/authors:ssa.<br /><br />Varmuuskopiot eivät muuta kirjastokansioissasi olevia tiedostoja. Jos olet ottanut käyttöön palvelinasetuksissa kansikuvien ja metatietojen tallentamisen kirjaston kansioihin, niitä ei varmuuskopioida tai korvata.<br /><br />Kaikki palvelintasi käyttävät asiakkaat virkistetään automaattisesti.",
|
"MessageRestoreBackupWarning": "Varmuuskopion palauttaminen korvaa koko /config:ssa sijaitsevan tietokannan, ja kansikuvat /metadata/items & /metadata/authors:ssa.<br /><br />Varmuuskopiot eivät muuta kirjastokansioissasi olevia tiedostoja. Jos olet ottanut käyttöön palvelinasetuksissa kansikuvien ja metatietojen tallentamisen kirjaston kansioihin, niitä ei varmuuskopioida tai korvata.<br /><br />Kaikki palvelintasi käyttävät asiakkaat virkistetään automaattisesti.",
|
||||||
"MessageScheduleLibraryScanNote": "Suurimmalle osaa käyttäjistä on suositeltavaa jättää tämä ominaisuus pois päältä ja säilyttää kansiotarkkailu päällä. Kansiotarkkailu havaitsee automaattisesti tiedostomuutokset kirjaston kansioissa. Kansiotarkkailu ei toimi kaikille tiedostojärjestelmille (kuten NFS), jolloin voidaan käyttää ajastettuja kirjastoskannauksia.",
|
"MessageScheduleLibraryScanNote": "Suurimmalle osaa käyttäjistä on suositeltavaa jättää tämä ominaisuus pois päältä ja \"Tarkkaile kirjaston muutoksia automaattisesti\" -asetus pidetään käytössä - se havaitsee muutokset kirjastokansioissasi automaattisesti. Ota tämä ominaisuus käyttöön, jos \"Tarkkaile kirjaston muutoksia automaattisesti\" ei toimi tiedostojärjestelmässäsi (kuten NFS).",
|
||||||
"MessageScheduleRunEveryWeekdayAtTime": "Suorita joka {0} klo {1}",
|
"MessageScheduleRunEveryWeekdayAtTime": "Suorita joka {0} klo {1}",
|
||||||
"MessageSearchResultsFor": "Hakutulokset haulle",
|
"MessageSearchResultsFor": "Hakutulokset haulle",
|
||||||
"MessageSelected": "{0} valittuna",
|
"MessageSelected": "{0} valittuna",
|
||||||
|
"MessageSeriesSequenceCannotContainSpaces": "Sarjan sekvenssi ei voi sisältää välilyöntejä",
|
||||||
"MessageServerCouldNotBeReached": "Palvelimelle ei saatu yhteyttä",
|
"MessageServerCouldNotBeReached": "Palvelimelle ei saatu yhteyttä",
|
||||||
"MessageSetChaptersFromTracksDescription": "Aseta luvut käyttämällä kutakin äänitiedostoa lukuna ja luvun otsikkoa äänitiedoston nimenä",
|
"MessageSetChaptersFromTracksDescription": "Aseta luvut käyttämällä kutakin äänitiedostoa lukuna ja luvun otsikkoa äänitiedoston nimenä",
|
||||||
"MessageShareExpirationWillBe": "Umpeutuminen on <strong>{0}</strong>",
|
"MessageShareExpirationWillBe": "Umpeutuminen on <strong>{0}</strong>",
|
||||||
@@ -894,7 +938,7 @@
|
|||||||
"MessageTaskScanningFileChanges": "Tarkastetaan tiedoston muutoksia \"{0}\":sta",
|
"MessageTaskScanningFileChanges": "Tarkastetaan tiedoston muutoksia \"{0}\":sta",
|
||||||
"MessageTaskScanningLibrary": "Tarkastetaan kirjastoa \"{0}\"",
|
"MessageTaskScanningLibrary": "Tarkastetaan kirjastoa \"{0}\"",
|
||||||
"MessageTaskTargetDirectoryNotWritable": "Kohdehakemisto ei ole kirjoitettava",
|
"MessageTaskTargetDirectoryNotWritable": "Kohdehakemisto ei ole kirjoitettava",
|
||||||
"MessageThinking": "Ajattellaan...",
|
"MessageThinking": "Ajatellaan...",
|
||||||
"MessageUploaderItemFailed": "Lataaminen ulospäin epäonnistui",
|
"MessageUploaderItemFailed": "Lataaminen ulospäin epäonnistui",
|
||||||
"MessageUploaderItemSuccess": "Onnistuneesti ladattu! ulospäin!",
|
"MessageUploaderItemSuccess": "Onnistuneesti ladattu! ulospäin!",
|
||||||
"MessageUploading": "Ladataan! ulospäin...",
|
"MessageUploading": "Ladataan! ulospäin...",
|
||||||
@@ -914,7 +958,10 @@
|
|||||||
"NotificationOnBackupCompletedDescription": "Laukaistu, kun varmuuskopiointi on valmis",
|
"NotificationOnBackupCompletedDescription": "Laukaistu, kun varmuuskopiointi on valmis",
|
||||||
"NotificationOnBackupFailedDescription": "Laukaistu, kun varmuuskopiointi epäonnistuu",
|
"NotificationOnBackupFailedDescription": "Laukaistu, kun varmuuskopiointi epäonnistuu",
|
||||||
"NotificationOnEpisodeDownloadedDescription": "Laukaistu, kun podcast-jakso ladataan automaattisesti",
|
"NotificationOnEpisodeDownloadedDescription": "Laukaistu, kun podcast-jakso ladataan automaattisesti",
|
||||||
|
"NotificationOnRSSFeedDisabledDescription": "Laukaistaan, kun automaattiset jaksolataukset poistetaan käytöstä liian monen epäonnistuneen yrityksen vuoksi",
|
||||||
|
"NotificationOnRSSFeedFailedDescription": "Laukaistaan, kun RRS-syötteen pyyntö epäonnistuu automaattisessa jaksolatauksessa",
|
||||||
"NotificationOnTestDescription": "Tapahtuma ilmoitusjärjestelmän testaamista varten",
|
"NotificationOnTestDescription": "Tapahtuma ilmoitusjärjestelmän testaamista varten",
|
||||||
|
"PlaceholderBulkChapterInput": "Syötä luvun otsikko tai käytä numerointia (esim. 'Episodi 1', 'Luku 10', '1.')",
|
||||||
"PlaceholderNewCollection": "Uusi kokoelman nimi",
|
"PlaceholderNewCollection": "Uusi kokoelman nimi",
|
||||||
"PlaceholderNewFolderPath": "Uusi kansion polku",
|
"PlaceholderNewFolderPath": "Uusi kansion polku",
|
||||||
"PlaceholderNewPlaylist": "Uusi soittolistan nimi",
|
"PlaceholderNewPlaylist": "Uusi soittolistan nimi",
|
||||||
@@ -968,15 +1015,23 @@
|
|||||||
"ToastBookmarkCreateFailed": "Kirjanmerkin luominen epäonnistui",
|
"ToastBookmarkCreateFailed": "Kirjanmerkin luominen epäonnistui",
|
||||||
"ToastBookmarkCreateSuccess": "Kirjanmerkki lisätty",
|
"ToastBookmarkCreateSuccess": "Kirjanmerkki lisätty",
|
||||||
"ToastBookmarkRemoveSuccess": "Kirjanmerkki poistettu",
|
"ToastBookmarkRemoveSuccess": "Kirjanmerkki poistettu",
|
||||||
|
"ToastBulkChapterInvalidCount": "Syötä numero 1 ja 150 välillä",
|
||||||
"ToastCachePurgeFailed": "Välimuistin tyhjentäminen epäonnistui",
|
"ToastCachePurgeFailed": "Välimuistin tyhjentäminen epäonnistui",
|
||||||
"ToastCachePurgeSuccess": "Välimuisti tyhjennetty onnistuneesti",
|
"ToastCachePurgeSuccess": "Välimuisti tyhjennetty onnistuneesti",
|
||||||
|
"ToastChapterLocked": "Luku on lukittu.",
|
||||||
|
"ToastChapterStartTimeAdjusted": "Luvun aloitusaikaa on säädetty {0} sekunnilla",
|
||||||
|
"ToastChaptersAllLocked": "Kaikki luvut ovat lukittuina. Avaa lukuja vaihtaaksesi niiden aikoja.",
|
||||||
"ToastChaptersHaveErrors": "Luvuissa on virheitä",
|
"ToastChaptersHaveErrors": "Luvuissa on virheitä",
|
||||||
|
"ToastChaptersInvalidShiftAmountLast": "Virheellinen siirtomäärä. Viimeisen luvun aloitusaika ylittäisi tämän äänikirjan keston.",
|
||||||
|
"ToastChaptersInvalidShiftAmountStart": "Virheellinen siirtomäärä. Ensimmäisen luvun pituudeksi tulisi nolla tai negatiivinen arvo, ja toinen luku kirjoittaisi sen päälle. Kasvata toisen luvun aloitusaikaa.",
|
||||||
"ToastChaptersMustHaveTitles": "Lukuilla on oltava otsikot",
|
"ToastChaptersMustHaveTitles": "Lukuilla on oltava otsikot",
|
||||||
"ToastChaptersRemoved": "Luvut poistettu",
|
"ToastChaptersRemoved": "Luvut poistettu",
|
||||||
"ToastChaptersUpdated": "Luvut päivitetty",
|
"ToastChaptersUpdated": "Luvut päivitetty",
|
||||||
"ToastCollectionItemsAddFailed": "Kohteen/kohteiden lisääminen kokoelmaan epäonnistui",
|
"ToastCollectionItemsAddFailed": "Kohteen/kohteiden lisääminen kokoelmaan epäonnistui",
|
||||||
"ToastCollectionRemoveSuccess": "Kokoelma poistettu",
|
"ToastCollectionRemoveSuccess": "Kokoelma poistettu",
|
||||||
"ToastCollectionUpdateSuccess": "Kokoelma päivitetty",
|
"ToastCollectionUpdateSuccess": "Kokoelma päivitetty",
|
||||||
|
"ToastConnectionNotAvailable": "Verkkoyhteyttä ei saatavilla. Yritä hetken päästä uudelleen",
|
||||||
|
"ToastCoverSearchFailed": "Kansikuvan haku epäonnistui",
|
||||||
"ToastCoverUpdateFailed": "Kansikuvan päivitys epäonnistui",
|
"ToastCoverUpdateFailed": "Kansikuvan päivitys epäonnistui",
|
||||||
"ToastDateTimeInvalidOrIncomplete": "Päivämäärä ja aika ovat epäkelvolliset tai puutteelliset",
|
"ToastDateTimeInvalidOrIncomplete": "Päivämäärä ja aika ovat epäkelvolliset tai puutteelliset",
|
||||||
"ToastDeleteFileFailed": "Tiedoston poistaminen epäonnistui",
|
"ToastDeleteFileFailed": "Tiedoston poistaminen epäonnistui",
|
||||||
@@ -992,6 +1047,8 @@
|
|||||||
"ToastEpisodeDownloadQueueClearSuccess": "Jakson latausjono tyhjennetty",
|
"ToastEpisodeDownloadQueueClearSuccess": "Jakson latausjono tyhjennetty",
|
||||||
"ToastEpisodeUpdateSuccess": "{0} jaksoa päivitetty",
|
"ToastEpisodeUpdateSuccess": "{0} jaksoa päivitetty",
|
||||||
"ToastErrorCannotShare": "Ei voi jakaa alkuperäisesti tällä laitteella",
|
"ToastErrorCannotShare": "Ei voi jakaa alkuperäisesti tällä laitteella",
|
||||||
|
"ToastFailedToCreate": "Luonti epäonnistui",
|
||||||
|
"ToastFailedToDelete": "Poisto epäonnistui",
|
||||||
"ToastFailedToLoadData": "Tietojen lataaminen epäonnistui",
|
"ToastFailedToLoadData": "Tietojen lataaminen epäonnistui",
|
||||||
"ToastFailedToMatch": "Vastaaminen epäonnistui",
|
"ToastFailedToMatch": "Vastaaminen epäonnistui",
|
||||||
"ToastFailedToShare": "Jakaminen epäonnistui",
|
"ToastFailedToShare": "Jakaminen epäonnistui",
|
||||||
@@ -999,6 +1056,7 @@
|
|||||||
"ToastInvalidImageUrl": "Epäkelvollinen kuvan URL-osoite",
|
"ToastInvalidImageUrl": "Epäkelvollinen kuvan URL-osoite",
|
||||||
"ToastInvalidMaxEpisodesToDownload": "Ladattavien jaksojen enimmäismäärä on epäkelvollinen",
|
"ToastInvalidMaxEpisodesToDownload": "Ladattavien jaksojen enimmäismäärä on epäkelvollinen",
|
||||||
"ToastInvalidUrl": "Epäkelvollinen URL-osoite",
|
"ToastInvalidUrl": "Epäkelvollinen URL-osoite",
|
||||||
|
"ToastInvalidUrls": "Yksi tai useampi URL on virheellinen",
|
||||||
"ToastItemCoverUpdateSuccess": "Kohteen kansikuva päivitetty",
|
"ToastItemCoverUpdateSuccess": "Kohteen kansikuva päivitetty",
|
||||||
"ToastItemDeletedFailed": "Kohteen poistaminen epäonnistui",
|
"ToastItemDeletedFailed": "Kohteen poistaminen epäonnistui",
|
||||||
"ToastItemDeletedSuccess": "Poistettu kohde",
|
"ToastItemDeletedSuccess": "Poistettu kohde",
|
||||||
@@ -1023,6 +1081,7 @@
|
|||||||
"ToastMustHaveAtLeastOnePath": "On oltava vähintään yksi polku",
|
"ToastMustHaveAtLeastOnePath": "On oltava vähintään yksi polku",
|
||||||
"ToastNameEmailRequired": "Nimi ja sähköpostiosoite vaaditaan",
|
"ToastNameEmailRequired": "Nimi ja sähköpostiosoite vaaditaan",
|
||||||
"ToastNameRequired": "Nimi vaaditaan",
|
"ToastNameRequired": "Nimi vaaditaan",
|
||||||
|
"ToastNewApiKeyUserError": "Täytyy valita käyttäjä",
|
||||||
"ToastNewEpisodesFound": "{0} uutta jaksoa löydetty",
|
"ToastNewEpisodesFound": "{0} uutta jaksoa löydetty",
|
||||||
"ToastNewUserCreatedFailed": "Tilin \"{0}\" luominen epäonnistui",
|
"ToastNewUserCreatedFailed": "Tilin \"{0}\" luominen epäonnistui",
|
||||||
"ToastNewUserCreatedSuccess": "Uusi tili luotu",
|
"ToastNewUserCreatedSuccess": "Uusi tili luotu",
|
||||||
@@ -1047,6 +1106,7 @@
|
|||||||
"ToastPlaylistUpdateSuccess": "Soittolista päivitetty",
|
"ToastPlaylistUpdateSuccess": "Soittolista päivitetty",
|
||||||
"ToastPodcastCreateFailed": "Podcastin luominen epäonnistui",
|
"ToastPodcastCreateFailed": "Podcastin luominen epäonnistui",
|
||||||
"ToastPodcastCreateSuccess": "Podcastin luominen onnistui",
|
"ToastPodcastCreateSuccess": "Podcastin luominen onnistui",
|
||||||
|
"ToastPodcastEpisodeUpdated": "Episodi päivitetty",
|
||||||
"ToastPodcastGetFeedFailed": "Podcast-syötteen saaminen epäonnistui",
|
"ToastPodcastGetFeedFailed": "Podcast-syötteen saaminen epäonnistui",
|
||||||
"ToastPodcastNoEpisodesInFeed": "RSS-syötteestä ei löytynyt jaksoja",
|
"ToastPodcastNoEpisodesInFeed": "RSS-syötteestä ei löytynyt jaksoja",
|
||||||
"ToastPodcastNoRssFeed": "Podcastilla ei ole RSS-syötettä",
|
"ToastPodcastNoRssFeed": "Podcastilla ei ole RSS-syötettä",
|
||||||
@@ -1097,5 +1157,13 @@
|
|||||||
"ToastUserPasswordChangeSuccess": "Salasana vaihdettu onnistuneesti",
|
"ToastUserPasswordChangeSuccess": "Salasana vaihdettu onnistuneesti",
|
||||||
"ToastUserPasswordMismatch": "Salasanat eivät täsmää",
|
"ToastUserPasswordMismatch": "Salasanat eivät täsmää",
|
||||||
"ToastUserPasswordMustChange": "Uusi salasana ei voi olla sama kuin vanha salasana",
|
"ToastUserPasswordMustChange": "Uusi salasana ei voi olla sama kuin vanha salasana",
|
||||||
"ToastUserRootRequireName": "Pääkäyttäjän nimi on pakollinen"
|
"ToastUserRootRequireName": "Pääkäyttäjän nimi on pakollinen",
|
||||||
|
"TooltipAddChapters": "Lisää luku tai lukuja",
|
||||||
|
"TooltipAddOneSecond": "Lisää 1 sekunti",
|
||||||
|
"TooltipAdjustChapterStart": "Napauta säätääksesi aloitusaikaa",
|
||||||
|
"TooltipLockAllChapters": "Lukitse kaikki luvut",
|
||||||
|
"TooltipLockChapter": "Lukitse luku (Shift+napauta valitaksesi alueen)",
|
||||||
|
"TooltipSubtractOneSecond": "Vähennä 1 sekunti",
|
||||||
|
"TooltipUnlockAllChapters": "Avaa kaikki luvut",
|
||||||
|
"TooltipUnlockChapter": "Avaa luku (Shift+napauta valitaksesi alueen)"
|
||||||
}
|
}
|
||||||
Loaded 100 of 255 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user