Compare commits

...
Author SHA1 Message Date
advplyr a77f345596 Update create bookmark to not autofocus input and leave empty with placeholder 2025-06-22 17:36:09 -05:00
advplyrandGitHub 6a2f487ed5 Merge pull request #1608 from NickSkier/ui_black_theme
Add: UI Black/OLED theme
2025-06-20 16:55:41 -05:00
advplyr 616cf9029d Fix audio player colors for black theme 2025-06-20 16:51:19 -05:00
NickSkier 3f21b4172b Add: UI Black/OLED theme 2025-06-20 01:05:46 +03:00
advplyrandGitHub 62f6a11522 Merge pull request #1589 from weblate/weblate-audiobookshelf-abs-mobile-app
Translations update from Hosted Weblate
2025-06-19 16:24:42 -05:00
burghy86andHosted Weblate ae1dce455d Translated using Weblate (Italian)
Currently translated at 100.0% (352 of 352 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/it/
2025-06-19 23:01:48 +02:00
B0raxandHosted Weblate 7b5dc52620 Translated using Weblate (German)
Currently translated at 99.7% (351 of 352 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/de/
2025-06-19 23:01:47 +02:00
Mathias FrancoandHosted Weblate 0bf50de54d Translated using Weblate (Dutch)
Currently translated at 100.0% (352 of 352 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/nl/
2025-06-17 22:01:57 +02:00
biuklijaandHosted Weblate 1eec470902 Translated using Weblate (Croatian)
Currently translated at 100.0% (352 of 352 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/hr/
2025-06-17 22:01:56 +02:00
petr-prikrylandHosted Weblate 867dc69479 Translated using Weblate (Czech)
Currently translated at 99.1% (349 of 352 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/cs/
2025-06-17 22:01:54 +02:00
ugyesandHosted Weblate 9792f4ebc1 Translated using Weblate (Hungarian)
Currently translated at 100.0% (352 of 352 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/hu/
2025-06-12 11:02:03 +02:00
Dawid KuźnickiandHosted Weblate a44fc41caa Translated using Weblate (Polish)
Currently translated at 98.2% (346 of 352 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/pl/
2025-06-10 09:06:17 +00:00
Grzegorz OrlowskiandHosted Weblate 1927dbf0ad Translated using Weblate (Polish)
Currently translated at 98.2% (346 of 352 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/pl/
2025-06-10 09:06:16 +00:00
RekentekandHosted Weblate 7052674f32 Translated using Weblate (Dutch)
Currently translated at 98.0% (345 of 352 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/nl/
2025-06-10 09:06:16 +00:00
Daniel SchosserandHosted Weblate 9a487f3bb6 Translated using Weblate (German)
Currently translated at 100.0% (352 of 352 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/de/
2025-06-10 09:06:15 +00:00
David Havndrup MunchandHosted Weblate d6242c350d Translated using Weblate (Danish)
Currently translated at 98.0% (345 of 352 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/da/
2025-06-10 09:06:14 +00:00
PlazecandHosted Weblate 4cc4aceb41 Translated using Weblate (Czech)
Currently translated at 100.0% (352 of 352 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/cs/
2025-06-10 09:06:13 +00:00
peter cernyandHosted Weblate dd8f4d6201 Translated using Weblate (Slovak)
Currently translated at 99.7% (351 of 352 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/sk/
2025-06-07 21:01:56 +02:00
Usama KhalilandHosted Weblate f44dcdf124 Translated using Weblate (Arabic)
Currently translated at 100.0% (352 of 352 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/ar/
2025-06-07 21:01:54 +02:00
thehijackerandHosted Weblate 65e8f2317e Translated using Weblate (Slovenian)
Currently translated at 100.0% (352 of 352 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/sl/
2025-06-07 21:01:51 +02:00
SunSpringandHosted Weblate 1c4f43db7c Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (352 of 352 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/zh_Hans/
2025-06-07 21:01:49 +02:00
max grakovandHosted Weblate 24b9df6fbd Translated using Weblate (Russian)
Currently translated at 100.0% (352 of 352 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/ru/
2025-06-07 21:01:47 +02:00
Максим ГорпинічandHosted Weblate c46891ecb0 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (352 of 352 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/uk/
2025-06-06 00:01:47 +02:00
Anders NormanandHosted Weblate e723601f6b Translated using Weblate (Norwegian Bokmål)
Currently translated at 71.5% (251 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/nb_NO/
2025-06-04 00:17:08 +02:00
DRandHosted Weblate 77545df174 Translated using Weblate (Hebrew)
Currently translated at 100.0% (351 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/he/
2025-06-04 00:17:07 +02:00
Grzegorz OrlowskiandHosted Weblate 7e136b17a5 Translated using Weblate (Polish)
Currently translated at 98.2% (345 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/pl/
2025-06-04 00:17:07 +02:00
Adolfo Jayme BarrientosandHosted Weblate a970a06f57 Translated using Weblate (Catalan)
Currently translated at 80.0% (281 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/ca/
2025-06-04 00:17:06 +02:00
ABS translatorandHosted Weblate 95dd78d4aa Translated using Weblate (Arabic)
Currently translated at 100.0% (351 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/ar/
2025-06-04 00:17:05 +02:00
Grzegorz OrlowskiandHosted Weblate eeaf33be20 Translated using Weblate (Polish)
Currently translated at 96.8% (340 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/pl/
2025-06-04 00:17:04 +02:00
Adolfo Jayme BarrientosandHosted Weblate 7ed0cd26fe Translated using Weblate (Spanish)
Currently translated at 100.0% (351 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/es/
2025-06-04 00:17:03 +02:00
advplyr d26403c800 Add book/podcast library filter for RSS Feed Open 2025-06-03 17:16:54 -05:00
advplyrandGitHub 5ed6e3a6a3 Merge pull request #1573 from weblate/weblate-audiobookshelf-abs-mobile-app
Translations update from Hosted Weblate
2025-05-24 17:11:31 -05:00
peter cernyandHosted Weblate 7e83405370 Translated using Weblate (Slovak)
Currently translated at 99.7% (350 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/sk/
2025-05-24 00:19:32 +02:00
biuklijaandHosted Weblate a5de31da2b Translated using Weblate (Croatian)
Currently translated at 100.0% (351 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/hr/
2025-05-24 00:19:31 +02:00
peter cernyandHosted Weblate 39c06005ed Translated using Weblate (Slovak)
Currently translated at 93.7% (329 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/sk/
2025-05-24 00:19:30 +02:00
Usama KhalilandHosted Weblate 9479160044 Translated using Weblate (Arabic)
Currently translated at 100.0% (351 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/ar/
2025-05-24 00:19:30 +02:00
Usama KhalilandHosted Weblate 46ec7369e5 Translated using Weblate (Arabic)
Currently translated at 100.0% (351 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/ar/
2025-05-24 00:19:29 +02:00
ABS translatorandHosted Weblate 424e7d742b Translated using Weblate (Arabic)
Currently translated at 100.0% (351 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/ar/
2025-05-24 00:19:28 +02:00
Usama KhalilandHosted Weblate 44036399b9 Translated using Weblate (Arabic)
Currently translated at 100.0% (351 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/ar/
2025-05-24 00:19:28 +02:00
Adolfo Jayme BarrientosandHosted Weblate e4394da467 Translated using Weblate (Catalan)
Currently translated at 79.4% (279 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/ca/
2025-05-24 00:19:27 +02:00
Usama KhalilandHosted Weblate b837ada3f8 Translated using Weblate (Arabic)
Currently translated at 76.6% (269 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/ar/
2025-05-24 00:19:27 +02:00
Adolfo Jayme BarrientosandHosted Weblate a623de89aa Translated using Weblate (Spanish)
Currently translated at 100.0% (351 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/es/
2025-05-24 00:19:26 +02:00
peter cernyandHosted Weblate 2768407907 Translated using Weblate (Slovak)
Currently translated at 85.4% (300 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/sk/
2025-05-24 00:19:26 +02:00
polarwoodandHosted Weblate 64ed35d2b1 Translated using Weblate (Turkish)
Currently translated at 77.7% (273 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/tr/
2025-05-24 00:19:25 +02:00
J. LavoieandHosted Weblate b92f4dfa02 Translated using Weblate (Italian)
Currently translated at 100.0% (351 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/it/
2025-05-24 00:19:25 +02:00
J. LavoieandHosted Weblate e4f02b7a51 Translated using Weblate (French)
Currently translated at 100.0% (351 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/fr/
2025-05-24 00:19:24 +02:00
J. LavoieandHosted Weblate 24c3f45018 Translated using Weblate (German)
Currently translated at 100.0% (351 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/de/
2025-05-24 00:19:23 +02:00
MichalandHosted Weblate fcf55eb581 Translated using Weblate (Slovak)
Currently translated at 54.4% (191 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/sk/
2025-05-24 00:19:23 +02:00
peter cernyandHosted Weblate 9ade7add32 Translated using Weblate (Slovak)
Currently translated at 54.4% (191 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/sk/
2025-05-24 00:19:22 +02:00
Jaakko RantamäkiandHosted Weblate d16dfcb4b4 Translated using Weblate (Finnish)
Currently translated at 98.2% (345 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/fi/
2025-05-24 00:19:22 +02:00
Максим ГорпинічandHosted Weblate 37c58a5d32 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (351 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/uk/
2025-05-24 00:19:21 +02:00
peter cernyandHosted Weblate e6cdde4f70 Translated using Weblate (Slovak)
Currently translated at 13.6% (48 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/sk/
2025-05-24 00:19:20 +02:00
Oleg IvasenkoandHosted Weblate 93c0adecbd Translated using Weblate (Russian)
Currently translated at 100.0% (351 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/ru/
2025-05-24 00:19:20 +02:00
advplyrandGitHub 33d44a5181 Merge pull request #1584 from advplyr/abridged_indicator
Add abridged indicator #1477
2025-05-23 17:19:11 -05:00
advplyr 80e6fa7e7a Add abridged indicator #1477 2025-05-23 17:04:26 -05:00
advplyrandGitHub b8eed48112 Merge pull request #1582 from advplyr/handle_android_edgetoedge
Fix android system bars overlapping UI #1564 #1574
2025-05-21 17:52:19 -05:00
advplyr 8d563dcfed Remove unnecessary styles.xml 2025-05-21 17:38:05 -05:00
advplyr 1cf36e5549 Fix android system bars overlapping UI #1564 #1574 2025-05-21 17:26:31 -05:00
advplyrandGitHub 1357a0628f Merge pull request #1577 from golinski/jackson-reuse
Reuse the existing ObjectMapper
2025-05-18 17:13:58 -05:00
advplyr c4fe0680f3 Remove unused imports 2025-05-18 17:06:06 -05:00
advplyr 16694aa932 Update progress bar box shadow for visibility #1576 2025-05-17 17:06:28 -05:00
Michał Goliński ea59ad2953 Reuse the existing ObjectMapper 2025-05-17 20:37:59 +02:00
advplyrandGitHub cf2f684e80 Merge pull request #1557 from weblate/weblate-audiobookshelf-abs-mobile-app
Translations update from Hosted Weblate
2025-05-10 16:56:47 -05:00
Nicholas WandHosted Weblate 01522eda43 Added translation using Weblate (Slovak) 2025-05-10 15:44:43 +02:00
Adolfo Jayme BarrientosandHosted Weblate a200ee1310 Translated using Weblate (Catalan)
Currently translated at 78.9% (277 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/ca/
2025-05-10 15:44:42 +02:00
Adolfo Jayme BarrientosandHosted Weblate 579a07baa2 Translated using Weblate (Catalan)
Currently translated at 78.6% (276 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/ca/
2025-05-09 14:11:21 +02:00
Adolfo Jayme BarrientosandHosted Weblate a82dd88b1f Translated using Weblate (Spanish)
Currently translated at 100.0% (351 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/es/
2025-05-09 14:11:21 +02:00
thehijackerandHosted Weblate 36ba98920a Translated using Weblate (Slovenian)
Currently translated at 100.0% (351 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/sl/
2025-05-07 00:01:46 +02:00
Adolfo Jayme BarrientosandHosted Weblate 47cc0c34eb Translated using Weblate (Spanish)
Currently translated at 100.0% (351 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/es/
2025-05-07 00:01:45 +02:00
Adolfo Jayme BarrientosandHosted Weblate 53eaca8724 Translated using Weblate (Spanish)
Currently translated at 96.8% (340 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/es/
2025-05-04 23:19:23 +02:00
ABS translatorandHosted Weblate 8a2814b391 Translated using Weblate (Arabic)
Currently translated at 69.8% (245 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/ar/
2025-05-04 23:19:23 +02:00
burghy86andHosted Weblate 345c8ab217 Translated using Weblate (Italian)
Currently translated at 100.0% (351 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/it/
2025-05-04 23:19:23 +02:00
ABS translatorandHosted Weblate 7c010895e0 Translated using Weblate (Arabic)
Currently translated at 59.8% (210 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/ar/
2025-05-04 23:19:23 +02:00
SunSpringandHosted Weblate e716cfd19b Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (351 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/zh_Hans/
2025-05-04 23:19:23 +02:00
Sergey PonomarevandHosted Weblate 461a6c8be5 Translated using Weblate (Russian)
Currently translated at 100.0% (351 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/ru/
2025-05-04 23:19:23 +02:00
Максим ГорпинічandHosted Weblate 3360f1a3f6 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (351 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/uk/
2025-05-04 23:19:23 +02:00
Robin StolpeandHosted Weblate 8b939e8a02 Translated using Weblate (Swedish)
Currently translated at 100.0% (351 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/sv/
2025-05-04 23:19:23 +02:00
Fredrik LindqvistandHosted Weblate 3a8998081c Translated using Weblate (Swedish)
Currently translated at 100.0% (351 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/sv/
2025-05-04 23:19:23 +02:00
dvc05andHosted Weblate 9b986a7b15 Translated using Weblate (Norwegian Bokmål)
Currently translated at 71.5% (251 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/nb_NO/
2025-05-04 23:19:23 +02:00
Kabika82andHosted Weblate 69ab395798 Translated using Weblate (Hungarian)
Currently translated at 100.0% (351 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/hu/
2025-05-04 23:19:23 +02:00
biuklijaandHosted Weblate 7aa3c33348 Translated using Weblate (Croatian)
Currently translated at 99.7% (350 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/hr/
2025-05-04 23:19:23 +02:00
johes00andHosted Weblate 734328dd1f Translated using Weblate (German)
Currently translated at 100.0% (351 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/de/
2025-05-04 23:19:23 +02:00
kuci-JKandHosted Weblate 7d6c30e733 Translated using Weblate (Czech)
Currently translated at 100.0% (351 of 351 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/cs/
2025-05-04 23:19:23 +02:00
advplyr 3e682dfe50 Fix local cover images not showing in android auto #1565 2025-05-04 16:19:16 -05:00
advplyrandGitHub 50efda3858 Merge pull request #1561 from nichwall/android_vscode_subproject
Add: settings for gradle project in subfolder
2025-04-30 17:15:56 -05:00
advplyrandGitHub ca1b9e2bdb Merge pull request #1562 from nichwall/workflow_updates
Template updates
2025-04-28 09:17:12 -05:00
Nicholas Wallace aa3a91b9d9 Add pull request template 2025-04-27 16:58:50 -07:00
Nicholas Wallace 7117608445 Update app versions in issue template 2025-04-27 16:56:02 -07:00
Nicholas Wallace 6de640f53f Add: settings for gradle project in subfolder 2025-04-27 16:47:44 -07:00
advplyr 75627ea40f iOS version bump 0.9.81 & pod update 2025-04-26 10:03:57 -05:00
advplyr 0fa04d7d9a Version bump v0.9.81-beta 2025-04-25 16:56:34 -05:00
advplyrandGitHub 1e76ebe075 Merge pull request #1556 from Zibbp/master
fix(InternalDownloadManager): add accept-encoding identity to requests
2025-04-25 16:25:07 -05:00
advplyrandGitHub 965da2fee3 Merge pull request #1547 from weblate/weblate-audiobookshelf-abs-mobile-app
Translations update from Hosted Weblate
2025-04-25 16:24:51 -05:00
Zibbp b03f59ace3 fix(InternalDownloadManager): set accept-encoding header on just the download task 2025-04-25 15:51:46 -05:00
SunSpringandHosted Weblate 79c7244b24 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (349 of 349 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/zh_Hans/
2025-04-25 00:29:31 +02:00
PimandHosted Weblate 0843be3f4e Translated using Weblate (Dutch)
Currently translated at 97.9% (342 of 349 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/nl/
2025-04-25 00:29:31 +02:00
Kabika82andHosted Weblate 6911f368e5 Translated using Weblate (Hungarian)
Currently translated at 100.0% (349 of 349 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/hu/
2025-04-25 00:29:31 +02:00
cebo29andHosted Weblate 42167ea738 Translated using Weblate (German)
Currently translated at 100.0% (349 of 349 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/de/
2025-04-25 00:29:31 +02:00
thehijackerandHosted Weblate 1c57d3506a Translated using Weblate (Slovenian)
Currently translated at 100.0% (349 of 349 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/sl/
2025-04-25 00:29:31 +02:00
Максим ГорпинічandHosted Weblate 8adc6fae4c Translated using Weblate (Ukrainian)
Currently translated at 100.0% (349 of 349 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/uk/
2025-04-25 00:29:31 +02:00
NickSkierandHosted Weblate e9746577ba Translated using Weblate (Russian)
Currently translated at 100.0% (349 of 349 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/ru/
2025-04-25 00:29:31 +02:00
max grakovandHosted Weblate 9f68730622 Translated using Weblate (Russian)
Currently translated at 100.0% (349 of 349 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/ru/
2025-04-25 00:29:31 +02:00
biuklijaandHosted Weblate f019b67b0c Translated using Weblate (Croatian)
Currently translated at 99.7% (348 of 349 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/hr/
2025-04-25 00:29:31 +02:00
advplyrandGitHub 0f650c0572 Merge pull request #1555 from advplyr/sleep_timer_chime_android
Add:Android sleep timer setting to play a chime when almost finished
2025-04-24 17:29:25 -05:00
Zibbp dfc77ea0d0 fix(InternalDownloadManager): add accept-encoding identity to requests 2025-04-24 17:04:08 -05:00
advplyr 67f514524f Remove unused imports and release log 2025-04-24 17:03:14 -05:00
advplyr d97c6a0872 Add:Android sleep timer setting to play a chime when almost finished #600 2025-04-24 16:42:55 -05:00
advplyr e7ad62760f Fix android cover image not showing in notification for downloaded media #1493, upgrade glide 2025-04-23 17:01:52 -05:00
advplyr fd34ea8124 Show change library dropdown in app bar when socket is not connected #1494 2025-04-23 15:46:19 -05:00
advplyr 5db94bf5b8 Fix series sequence text color on book cards in light mode #1549 2025-04-22 16:50:21 -05:00
advplyr 796d6d79d4 Add logs for android auto 2025-04-21 17:34:30 -05:00
advplyr 03aafafe1c Fix bug with AbsLogger not initialized 2025-04-21 17:11:23 -05:00
advplyr 3f303abc19 iOS version bump 0.9.80 2025-04-20 17:17:18 -05:00
advplyr 85d6958025 Version bump v0.9.80-beta 2025-04-20 16:54:49 -05:00
advplyrandGitHub 669bd7827b Merge pull request #1545 from weblate/weblate-audiobookshelf-abs-mobile-app
Translations update from Hosted Weblate
2025-04-20 16:17:36 -05:00
petr-prikrylandHosted Weblate 2b48f0c6a9 Translated using Weblate (Czech)
Currently translated at 100.0% (345 of 345 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/cs/
2025-04-20 21:11:10 +00:00
ABS translatorandHosted Weblate 2c44d38906 Translated using Weblate (Arabic)
Currently translated at 52.1% (180 of 345 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/ar/
2025-04-20 21:11:10 +00:00
Максим ГорпинічandHosted Weblate 750726ff6a Translated using Weblate (Ukrainian)
Currently translated at 100.0% (345 of 345 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/uk/
2025-04-20 21:11:09 +00:00
Jakob ZollandHosted Weblate dafab492fe Translated using Weblate (German)
Currently translated at 100.0% (345 of 345 strings)

Translation: Audiobookshelf/Abs Mobile App
Translate-URL: https://hosted.weblate.org/projects/audiobookshelf/abs-mobile-app/de/
2025-04-20 21:11:08 +00:00
advplyr 6419c8dc3a Update deploy-apk workflow for java 21 2025-04-20 16:10:54 -05:00
advplyrandGitHub 3bb5ce5924 Merge pull request #1546 from advplyr/abslogger
Logs page with AbsLogger plugin
2025-04-20 16:09:14 -05:00
advplyr 882c2749ab Add AbsLogger stub to iOS, update iOS plugins for capacitor 7 2025-04-20 16:06:52 -05:00
advplyr 26b0fae0fb Setup onLog event, add app version & platform to logs and share filename 2025-04-20 14:33:48 -05:00
advplyr fe921fd5b1 Update AbsLogger to have a tag with logs 2025-04-20 12:36:27 -05:00
advplyr 88e1877742 More AbsLogs and clean logs older than 48 hours on init 2025-04-20 12:18:10 -05:00
advplyr 74758c7762 Add clear logs, use more menu dialog 2025-04-20 10:32:52 -05:00
advplyr 2000534e37 Update logs to mask server address, add share txt file button 2025-04-20 10:06:52 -05:00
advplyr 390388fe83 Add AbsLogger plugin, persist logs to db, logs page for android 2025-04-19 17:26:32 -05:00
advplyrandGitHub b9e3ccd0c1 Merge pull request #1543 from advplyr/capacitor_v7
Update to capacitor v7
2025-04-17 17:57:22 -05:00
90 changed files with 2208 additions and 369 deletions
+4 -2
View File
@@ -72,10 +72,12 @@ body:
description: Please ensure your app is up to date. *If you are using a 3rd-party app, please reach out to them directly.*
multiple: true
options:
- 'Android App - 0.9.81'
- 'iOS App - 0.9.81'
- 'Android App - 0.9.80'
- 'iOS App - 0.9.80'
- 'Android App - 0.9.79'
- 'iOS App - 0.9.79'
- 'Android App - 0.9.78'
- 'iOS App - 0.9.78'
validations:
required: true
- type: dropdown
+6 -4
View File
@@ -43,10 +43,12 @@ body:
description: Please ensure your app is up to date. *If you are using a 3rd-party app, please reach out to them directly.*
multiple: true
options:
- Android App - 0.9.79
- iOS App - 0.9.79
- Android App - 0.9.78
- iOS App - 0.9.78
- 'Android App - 0.9.81'
- 'iOS App - 0.9.81'
- 'Android App - 0.9.80'
- 'iOS App - 0.9.80'
- 'Android App - 0.9.79'
- 'iOS App - 0.9.79'
validations:
required: true
- type: textarea
+41
View File
@@ -0,0 +1,41 @@
<!--
For Work In Progress Pull Requests, please use the Draft PR feature,
see https://github.blog/2019-02-14-introducing-draft-pull-requests/ for further details.
If you do not follow this template, the PR may be closed without review.
Please ensure all checks pass.
If you are a new contributor, the workflows will need to be manually approved before they run.
-->
## Brief summary
<!-- Please provide a brief summary of what your PR attempts to achieve. -->
## Which issue is fixed?
<!-- Which issue number does this PR fix? Ex: "Fixes #1234" -->
## Pull Request Type
<!--
Does this affect only Android, only iOS, or both?
Does this change the frontend or the backend of the apps?
-->
## In-depth Description
<!--
Describe your solution in more depth.
How does it work? Why is this the best solution?
Does it solve a problem that affects multiple users or is this an edge case for your setup?
-->
## How have you tested this?
<!-- Please describe in detail with reproducible steps how you tested your changes. -->
## Screenshots
<!-- If your PR includes any changes to the front-end, please include screenshots or a
short video from before and after your changes. -->
+1 -1
View File
@@ -24,7 +24,7 @@ jobs:
uses: actions/setup-java@v2
with:
distribution: 'temurin'
java-version: 17
java-version: 21
- name: install dependencies
run: npm ci
+6
View File
@@ -0,0 +1,6 @@
{
"java.project.root": "android",
"java.import.gradle.enabled": true,
"java.import.gradle.wrapper.enabled": true,
"java.import.gradle.user.home": "${workspaceFolder}/.gradle"
}
+2 -2
View File
@@ -36,8 +36,8 @@ android {
applicationId "com.audiobookshelf.app"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 110
versionName "0.9.79-beta"
versionCode 112
versionName "0.9.81-beta"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
manifestPlaceholders = [
"appAuthRedirectScheme": "com.audiobookshelf.app"
@@ -5,6 +5,10 @@
"plugins": {
"CapacitorHttp": {
"enabled": false
},
"StatusBar": {
"backgroundColor": "#232323",
"style": "DARK"
}
},
"server": {
@@ -6,10 +6,15 @@ import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.os.IBinder
import android.util.Log
import android.view.ViewGroup
import android.view.WindowInsets
import android.webkit.WebView
import androidx.core.app.ActivityCompat
import androidx.core.view.updateLayoutParams
import com.anggrayudi.storage.SimpleStorage
import com.anggrayudi.storage.SimpleStorageHelper
import com.audiobookshelf.app.managers.DbManager
@@ -18,6 +23,7 @@ import com.audiobookshelf.app.plugins.AbsAudioPlayer
import com.audiobookshelf.app.plugins.AbsDatabase
import com.audiobookshelf.app.plugins.AbsDownloader
import com.audiobookshelf.app.plugins.AbsFileSystem
import com.audiobookshelf.app.plugins.AbsLogger
import com.getcapacitor.BridgeActivity
@@ -39,29 +45,58 @@ class MainActivity : BridgeActivity() {
)
public override fun onCreate(savedInstanceState: Bundle?) {
// TODO: Optimize using strict mode logs
// StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder()
// .detectDiskReads()
// .detectDiskWrites().detectAll()
// .detectNetwork() // or .detectAll() for all detectable problems
// .penaltyLog()
// .build())
// StrictMode.setVmPolicy(VmPolicy.Builder()
// .detectLeakedSqlLiteObjects()
// .detectLeakedClosableObjects()
// .penaltyLog()
// .build())
DbManager.initialize(applicationContext)
registerPlugin(AbsAudioPlayer::class.java)
registerPlugin(AbsDownloader::class.java)
registerPlugin(AbsFileSystem::class.java)
registerPlugin(AbsDatabase::class.java)
registerPlugin(AbsLogger::class.java)
super.onCreate(savedInstanceState)
Log.d(tag, "onCreate")
// Update the margins to handle edge-to-edge enforced in SDK 35
// See: https://developer.android.com/develop/ui/views/layout/edge-to-edge
val webView: WebView = findViewById(R.id.webview)
webView.setOnApplyWindowInsetsListener { v, insets ->
val (left, top, right, bottom) = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val sysInsets = insets.getInsets(WindowInsets.Type.systemBars())
Log.d(tag, "safe sysInsets: $sysInsets")
arrayOf(sysInsets.left, sysInsets.top, sysInsets.right, sysInsets.bottom)
} else {
arrayOf(
insets.systemWindowInsetLeft,
insets.systemWindowInsetTop,
insets.systemWindowInsetRight,
insets.systemWindowInsetBottom
)
}
// Inject as CSS variables
// NOTE: Possibly able to use in the future to support edge-to-edge better.
val js = """
document.documentElement.style.setProperty('--safe-area-inset-top', '${top}px');
document.documentElement.style.setProperty('--safe-area-inset-bottom', '${bottom}px');
document.documentElement.style.setProperty('--safe-area-inset-left', '${left}px');
document.documentElement.style.setProperty('--safe-area-inset-right', '${right}px');
""".trimIndent()
webView.evaluateJavascript(js, null)
// Set margins
v.updateLayoutParams<ViewGroup.MarginLayoutParams> {
leftMargin = left
bottomMargin = bottom
rightMargin = right
topMargin = top
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
WindowInsets.CONSUMED
} else {
insets
}
}
val permission = ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
if (permission != PackageManager.PERMISSION_GRANTED) {
@@ -135,6 +135,7 @@ data class DeviceSettings(
var sleepTimerLength: Long, // Time in milliseconds
var disableSleepTimerFadeOut: Boolean,
var disableSleepTimerResetFeedback: Boolean,
var enableSleepTimerAlmostDoneChime: Boolean,
var languageCode: String,
var downloadUsingCellular: DownloadUsingCellularSetting,
var streamingUsingCellular: StreamingUsingCellularSetting,
@@ -163,6 +164,7 @@ data class DeviceSettings(
autoSleepTimerAutoRewindTime = 300000L, // 5 minutes
disableSleepTimerFadeOut = false,
disableSleepTimerResetFeedback = false,
enableSleepTimerAlmostDoneChime = false,
languageCode = "en-us",
downloadUsingCellular = DownloadUsingCellularSetting.ALWAYS,
streamingUsingCellular = StreamingUsingCellularSetting.ALWAYS,
@@ -188,9 +190,9 @@ data class DeviceSettings(
@JsonIgnore
fun getShakeThresholdGravity() : Float { // Used in ShakeDetector
return if (shakeSensitivity == ShakeSensitivitySetting.VERY_HIGH) 1.2f
else if (shakeSensitivity == ShakeSensitivitySetting.HIGH) 1.4f
else if (shakeSensitivity == ShakeSensitivitySetting.MEDIUM) 1.6f
return if (shakeSensitivity == ShakeSensitivitySetting.VERY_HIGH) 1.1f
else if (shakeSensitivity == ShakeSensitivitySetting.HIGH) 1.3f
else if (shakeSensitivity == ShakeSensitivitySetting.MEDIUM) 1.5f
else if (shakeSensitivity == ShakeSensitivitySetting.LOW) 2f
else if (shakeSensitivity == ShakeSensitivitySetting.VERY_LOW) 2.7f
else {
@@ -5,8 +5,7 @@
package com.audiobookshelf.app.data
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
import com.fasterxml.jackson.core.json.JsonReadFeature
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import org.json.JSONObject
@@ -18,8 +17,7 @@ data class ItemInProgress(
val isLocal: Boolean
) {
companion object {
fun makeFromServerObject(serverItem: JSONObject):ItemInProgress {
val jacksonMapper = jacksonObjectMapper().enable(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature())
fun makeFromServerObject(serverItem: JSONObject, jacksonMapper: ObjectMapper):ItemInProgress {
val libraryItem = jacksonMapper.readValue<LibraryItem>(serverItem.toString())
var episode:PodcastEpisode? = null
@@ -32,8 +32,9 @@ object DeviceManager {
var deviceData: DeviceData = dbManager.getDeviceData()
var serverConnectionConfig: ServerConnectionConfig? = null
val serverConnectionConfigId
get() = serverConnectionConfig?.id ?: ""
val serverConnectionConfigId get() = serverConnectionConfig?.id ?: ""
val serverConnectionConfigName get() = serverConnectionConfig?.name ?: ""
val serverConnectionConfigString get() = serverConnectionConfig?.name ?: "No server connection"
val serverAddress
get() = serverConnectionConfig?.address ?: ""
val serverUserId
@@ -63,6 +64,10 @@ object DeviceManager {
if (deviceData.deviceSettings?.autoSleepTimerAutoRewindTime == null) {
deviceData.deviceSettings?.autoSleepTimerAutoRewindTime = 300000L // 5 minutes
}
// Initialize sleep timer almost done chime added in v0.9.81
if (deviceData.deviceSettings?.enableSleepTimerAlmostDoneChime == null) {
deviceData.deviceSettings?.enableSleepTimerAlmostDoneChime = false
}
// Language added in v0.9.69
if (deviceData.deviceSettings?.languageCode == null) {
@@ -4,6 +4,8 @@ import android.content.Context
import android.util.Log
import com.audiobookshelf.app.data.*
import com.audiobookshelf.app.models.DownloadItem
import com.audiobookshelf.app.plugins.AbsLog
import com.audiobookshelf.app.plugins.AbsLogger
import io.paperdb.Paper
import java.io.File
@@ -287,4 +289,35 @@ class DbManager {
}
return sessions
}
fun saveLog(log:AbsLog) {
Paper.book("log").write(log.id, log)
}
fun getAllLogs() : List<AbsLog> {
val logs:MutableList<AbsLog> = mutableListOf()
Paper.book("log").allKeys.forEach { logId ->
Paper.book("log").read<AbsLog>(logId)?.let {
logs.add(it)
}
}
return logs.sortedBy { it.timestamp }
}
fun removeAllLogs() {
Paper.book("log").destroy()
}
fun cleanLogs() {
val numberOfHoursToKeep = 48
val keepLogCutoff = System.currentTimeMillis() - (3600000 * numberOfHoursToKeep)
val allLogs = getAllLogs()
var logsRemoved = 0
allLogs.forEach {
if (it.timestamp < keepLogCutoff) {
Paper.book("log").delete(it.id)
logsRemoved++
}
}
if (logsRemoved > 0) {
AbsLogger.info("DbManager", "cleanLogs: Removed $logsRemoved logs older than $numberOfHoursToKeep hours")
}
}
}
@@ -29,7 +29,7 @@ class InternalDownloadManager(
*/
@Throws(IOException::class)
fun download(url: String) {
val request: Request = Request.Builder().url(url).build()
val request: Request = Request.Builder().url(url).addHeader("Accept-Encoding", "identity").build()
client.newCall(request)
.enqueue(
object : Callback {
@@ -1,15 +1,20 @@
package com.audiobookshelf.app.managers
import android.content.Context
import android.media.MediaPlayer
import android.os.*
import android.util.Log
import com.audiobookshelf.app.R
import com.audiobookshelf.app.device.DeviceManager
import com.audiobookshelf.app.player.PlayerNotificationService
import com.audiobookshelf.app.player.SLEEP_TIMER_WAKE_UP_EXPIRATION
import com.audiobookshelf.app.plugins.AbsLogger
import java.util.*
import kotlin.concurrent.schedule
import kotlin.math.roundToInt
const val SLEEP_TIMER_CHIME_SOUND_VOLUME = 0.7f
class SleepTimerManager
constructor(private val playerNotificationService: PlayerNotificationService) {
private val tag = "SleepTimerManager"
@@ -156,6 +161,10 @@ constructor(private val playerNotificationService: PlayerNotificationService) {
)
}
if (sleepTimeSecondsRemaining == 30 && sleepTimerElapsed > 1 && DeviceManager.deviceData.deviceSettings?.enableSleepTimerAlmostDoneChime == true) {
playChimeSound()
}
if (sleepTimeSecondsRemaining <= 0) {
Log.d(tag, "Sleep Timer Pausing Player on Chapter")
pause()
@@ -263,6 +272,18 @@ constructor(private val playerNotificationService: PlayerNotificationService) {
}
}
/** Plays chime sound */
private fun playChimeSound() {
AbsLogger.info(tag, "playChimeSound: Playing sleep timer chime sound")
val ctx = playerNotificationService.getContext()
val mediaPlayer = MediaPlayer.create(ctx, R.raw.bell)
mediaPlayer.setVolume(SLEEP_TIMER_CHIME_SOUND_VOLUME, SLEEP_TIMER_CHIME_SOUND_VOLUME)
mediaPlayer.start()
mediaPlayer.setOnCompletionListener {
mediaPlayer.release()
}
}
/**
* Gets the chapter end time for use in End of Chapter timers. If less than 10 seconds remain in
* the chapter, then use the next chapter.
@@ -136,7 +136,6 @@ class MediaManager(private var apiHandler: ApiHandler, var ctx: Context) {
val serverConnConfig = if (DeviceManager.isConnectedToServer) DeviceManager.serverConnectionConfig else DeviceManager.deviceData.getLastServerConnectionConfig()
if (!DeviceManager.isConnectedToServer || !DeviceManager.checkConnectivity(ctx) || serverConnConfig == null || serverConnConfig.id !== serverConfigIdUsed) {
Log.d(tag, "Reset caches")
podcastEpisodeLibraryItemMap = mutableMapOf()
serverLibraries = listOf()
serverLibraryItems = mutableListOf()
@@ -8,6 +8,7 @@ import com.audiobookshelf.app.data.MediaProgress
import com.audiobookshelf.app.data.PlaybackSession
import com.audiobookshelf.app.device.DeviceManager
import com.audiobookshelf.app.player.PlayerNotificationService
import com.audiobookshelf.app.plugins.AbsLogger
import com.audiobookshelf.app.server.ApiHandler
import java.util.*
import kotlin.concurrent.schedule
@@ -208,6 +209,7 @@ class MediaProgressSyncer(
MediaEventManager.seekEvent(currentPlaybackSession!!, null)
}
// Currently unused
fun syncFromServerProgress(mediaProgress: MediaProgress) {
currentPlaybackSession?.let {
it.updatedAt = mediaProgress.lastUpdate
@@ -260,44 +262,46 @@ class MediaProgressSyncer(
tag,
"Sync local device current serverConnectionConfigId=${DeviceManager.serverConnectionConfig?.id}"
)
AbsLogger.info("MediaProgressSyncer", "sync: Saved local progress (title: \"$currentDisplayTitle\") (currentTime: $currentTime) (session id: ${it.id})")
// Local library item is linked to a server library item
// Send sync to server also if connected to this server and local item belongs to this
// server
val isConnectedToSameServer = it.serverConnectionConfigId != null && DeviceManager.serverConnectionConfig?.id == it.serverConnectionConfigId
if (hasNetworkConnection &&
shouldSyncServer &&
!it.libraryItemId.isNullOrEmpty() &&
it.serverConnectionConfigId != null &&
DeviceManager.serverConnectionConfig?.id == it.serverConnectionConfigId
isConnectedToSameServer
) {
apiHandler.sendLocalProgressSync(it) { syncSuccess, errorMsg ->
if (syncSuccess) {
failedSyncs = 0
playerNotificationService.alertSyncSuccess()
DeviceManager.dbManager.removePlaybackSession(it.id) // Remove session from db
AbsLogger.info("MediaProgressSyncer", "sync: Successfully synced local progress (title: \"$currentDisplayTitle\") (currentTime: $currentTime) (session id: ${it.id})")
} else {
failedSyncs++
if (failedSyncs == 2) {
playerNotificationService.alertSyncFailing() // Show alert in client
failedSyncs = 0
}
Log.e(
tag,
"Local Progress sync failed ($failedSyncs) to send to server $currentDisplayTitle for time $currentTime with session id=${it.id}"
)
AbsLogger.error("MediaProgressSyncer", "sync: Local progress sync failed (count: $failedSyncs) (title: \"$currentDisplayTitle\") (currentTime: $currentTime) (session id: ${it.id}) (${DeviceManager.serverConnectionConfigName})")
}
cb(SyncResult(true, syncSuccess, errorMsg))
}
} else {
AbsLogger.info("MediaProgressSyncer", "sync: Not sending local progress to server (title: \"$currentDisplayTitle\") (currentTime: $currentTime) (session id: ${it.id}) (hasNetworkConnection: $hasNetworkConnection) (isConnectedToSameServer: $isConnectedToSameServer)")
cb(SyncResult(false, null, null))
}
}
} else if (hasNetworkConnection && shouldSyncServer) {
Log.d(tag, "sync: currentSessionId=$currentSessionId")
AbsLogger.info("MediaProgressSyncer", "sync: Sending progress sync to server (title: \"$currentDisplayTitle\") (currentTime: $currentTime) (session id: ${currentSessionId}) (${DeviceManager.serverConnectionConfigName})")
apiHandler.sendProgressSync(currentSessionId, syncData) { syncSuccess, errorMsg ->
if (syncSuccess) {
Log.d(tag, "Progress sync data sent to server $currentDisplayTitle for time $currentTime")
AbsLogger.info("MediaProgressSyncer", "sync: Successfully synced progress (title: \"$currentDisplayTitle\") (currentTime: $currentTime) (session id: ${currentSessionId}) (${DeviceManager.serverConnectionConfigName})")
failedSyncs = 0
playerNotificationService.alertSyncSuccess()
lastSyncTime = System.currentTimeMillis()
@@ -308,14 +312,12 @@ class MediaProgressSyncer(
playerNotificationService.alertSyncFailing() // Show alert in client
failedSyncs = 0
}
Log.e(
tag,
"Progress sync failed ($failedSyncs) to send to server $currentDisplayTitle for time $currentTime with session id=${currentSessionId}"
)
AbsLogger.error("MediaProgressSyncer", "sync: Progress sync failed (count: $failedSyncs) (title: \"$currentDisplayTitle\") (currentTime: $currentTime) (session id: $currentSessionId) (${DeviceManager.serverConnectionConfigName})")
}
cb(SyncResult(true, syncSuccess, errorMsg))
}
} else {
AbsLogger.info("MediaProgressSyncer", "sync: Not sending progress to server (title: \"$currentDisplayTitle\") (currentTime: $currentTime) (session id: $currentSessionId) (${DeviceManager.serverConnectionConfigName}) (hasNetworkConnection: $hasNetworkConnection)")
cb(SyncResult(false, null, null))
}
}
@@ -7,7 +7,6 @@ import android.net.Uri
import android.os.Build
import android.provider.MediaStore
import android.support.v4.media.session.MediaControllerCompat
import android.util.Log
import com.audiobookshelf.app.BuildConfig
import com.audiobookshelf.app.R
import com.bumptech.glide.Glide
@@ -15,7 +14,7 @@ import com.google.android.exoplayer2.Player
import com.google.android.exoplayer2.ui.PlayerNotificationManager
import kotlinx.coroutines.*
class AbMediaDescriptionAdapter constructor(private val controller: MediaControllerCompat, private val playerNotificationService: PlayerNotificationService) : PlayerNotificationManager.MediaDescriptionAdapter {
class AbMediaDescriptionAdapter (private val controller: MediaControllerCompat, private val playerNotificationService: PlayerNotificationService) : PlayerNotificationManager.MediaDescriptionAdapter {
private val tag = "MediaDescriptionAdapter"
private var currentIconUri: Uri? = null
@@ -36,12 +35,17 @@ class AbMediaDescriptionAdapter constructor(private val controller: MediaControl
callback: PlayerNotificationManager.BitmapCallback
): Bitmap? {
val albumArtUri = controller.metadata.description.iconUri
val albumBitmap = controller.metadata.description.iconBitmap
// For local cover images, bitmap is set in PlayerNotificationService TimelineQueueNavigator.getMediaDescription
if (albumBitmap != null) {
return albumBitmap
}
return if (currentIconUri != albumArtUri || currentBitmap == null) {
// Cache the bitmap for the current audiobook so that successive calls to
// `getCurrentLargeIcon` don't cause the bitmap to be recreated.
currentIconUri = albumArtUri
Log.d(tag, "ART $currentIconUri")
if (currentIconUri.toString().startsWith("content://")) {
currentBitmap = if (Build.VERSION.SDK_INT < 28) {
@@ -61,7 +65,6 @@ class AbMediaDescriptionAdapter constructor(private val controller: MediaControl
}
null
}
} else {
currentBitmap
}
@@ -8,7 +8,6 @@ import android.util.Log
import android.view.KeyEvent
import com.audiobookshelf.app.data.LibraryItemWrapper
import com.audiobookshelf.app.data.PodcastEpisode
import com.audiobookshelf.app.device.DeviceManager
import java.util.*
import kotlin.concurrent.schedule
@@ -36,6 +36,7 @@ import com.audiobookshelf.app.media.MediaManager
import com.audiobookshelf.app.media.MediaProgressSyncer
import com.audiobookshelf.app.media.getUriToAbsIconDrawable
import com.audiobookshelf.app.media.getUriToDrawable
import com.audiobookshelf.app.plugins.AbsLogger
import com.audiobookshelf.app.server.ApiHandler
import com.google.android.exoplayer2.*
import com.google.android.exoplayer2.audio.AudioAttributes
@@ -310,17 +311,20 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
val coverUri = currentPlaybackSession!!.getCoverUri(ctx)
var bitmap: Bitmap? = null
// Local covers get bitmap
// Local covers get bitmap
// Note: In Android Auto for local cover images, setting the icon uri to a local path does not work (cover is blank)
// so we create and set the bitmap here instead of AbMediaDescriptionAdapter
if (currentPlaybackSession!!.localLibraryItem?.coverContentUrl != null) {
bitmap =
if (Build.VERSION.SDK_INT < 28) {
MediaStore.Images.Media.getBitmap(ctx.contentResolver, coverUri)
} else {
val source: ImageDecoder.Source =
ImageDecoder.createSource(ctx.contentResolver, coverUri)
ImageDecoder.decodeBitmap(source)
}
if (Build.VERSION.SDK_INT < 28) {
MediaStore.Images.Media.getBitmap(ctx.contentResolver, coverUri)
} else {
val source: ImageDecoder.Source =
ImageDecoder.createSource(ctx.contentResolver, coverUri)
ImageDecoder.decodeBitmap(source)
}
}
// Fix for local images crashing on Android 11 for specific devices
@@ -347,7 +351,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
.setTitle(currentPlaybackSession!!.displayTitle)
bitmap?.let { mediaDescriptionBuilder.setIconBitmap(it) }
?: mediaDescriptionBuilder.setIconUri(coverUri)
?: mediaDescriptionBuilder.setIconUri(coverUri)
return mediaDescriptionBuilder.build()
}
@@ -452,7 +456,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
playbackSession
) // Save playback session to use when app is closed
Log.d(tag, "Set CurrentPlaybackSession MediaPlayer ${currentPlaybackSession?.mediaPlayer}")
AbsLogger.info("PlayerNotificationService", "preparePlayer: Started playback session for item ${currentPlaybackSession?.mediaItemId}. MediaPlayer ${currentPlaybackSession?.mediaPlayer}")
// Notify client
clientEventEmitter?.onPlaybackSession(playbackSession)
@@ -469,7 +473,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
val mediaSource: MediaSource
if (playbackSession.isLocal) {
Log.d(tag, "Playing Local Item")
AbsLogger.info("PlayerNotificationService", "preparePlayer: Playing local item ${currentPlaybackSession?.mediaItemId}.")
val dataSourceFactory = DefaultDataSource.Factory(ctx)
val extractorsFactory = DefaultExtractorsFactory()
@@ -483,7 +487,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
ProgressiveMediaSource.Factory(dataSourceFactory, extractorsFactory)
.createMediaSource(mediaItems[0])
} else if (!playbackSession.isHLS) {
Log.d(tag, "Direct Playing Item")
AbsLogger.info("PlayerNotificationService", "preparePlayer: Direct playing item ${currentPlaybackSession?.mediaItemId}.")
val dataSourceFactory = DefaultHttpDataSource.Factory()
val extractorsFactory = DefaultExtractorsFactory()
@@ -498,7 +502,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
ProgressiveMediaSource.Factory(dataSourceFactory, extractorsFactory)
.createMediaSource(mediaItems[0])
} else {
Log.d(tag, "Playing HLS Item")
AbsLogger.info("PlayerNotificationService", "preparePlayer: Playing HLS stream of item ${currentPlaybackSession?.mediaItemId}.")
val dataSourceFactory = DefaultHttpDataSource.Factory()
dataSourceFactory.setUserAgent(channelId)
dataSourceFactory.setDefaultRequestProperties(
@@ -1105,11 +1109,12 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
// No further calls will be made to other media browsing methods.
null
} else {
Log.d(tag, "Android Auto starting $clientPackageName $clientUid")
AbsLogger.info(tag, "onGetRoot: clientPackageName: $clientPackageName, clientUid: $clientUid")
isStarted = true
// Reset cache if no longer connected to server or server changed
if (mediaManager.checkResetServerItems()) {
AbsLogger.info(tag, "onGetRoot: Reset Android Auto server items cache (${DeviceManager.serverConnectionConfigString})")
forceReloadingAndroidAuto = true
}
@@ -1134,7 +1139,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
parentMediaId: String,
result: Result<MutableList<MediaBrowserCompat.MediaItem>>
) {
Log.d(tag, "ON LOAD CHILDREN $parentMediaId")
AbsLogger.info(tag, "onLoadChildren: parentMediaId: $parentMediaId (${DeviceManager.serverConnectionConfigString})")
result.detach()
@@ -1145,7 +1150,6 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
}
if (parentMediaId == DOWNLOADS_ROOT) { // Load downloads
val localBooks = DeviceManager.dbManager.getLocalLibraryItems("book")
val localPodcasts = DeviceManager.dbManager.getLocalLibraryItems("podcast")
val localBrowseItems: MutableList<MediaBrowserCompat.MediaItem> = mutableListOf()
@@ -1242,8 +1246,10 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
Log.d(tag, "Trying to initialize browseTree.")
if (!this::browseTree.isInitialized || forceReloadingAndroidAuto) {
forceReloadingAndroidAuto = false
AbsLogger.info(tag, "onLoadChildren: Loading Android Auto items")
mediaManager.loadAndroidAutoItems {
Log.d(tag, "android auto loaded. Starting browseTree initialize")
AbsLogger.info(tag, "onLoadChildren: Loaded Android Auto data, initializing browseTree")
browseTree =
BrowseTree(
this,
@@ -1259,15 +1265,21 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
MediaBrowserCompat.MediaItem.FLAG_BROWSABLE
)
}
Log.d(tag, "browseTree initialize and android auto loaded")
result.sendResult(children as MutableList<MediaBrowserCompat.MediaItem>?)
firstLoadDone = true
if (mediaManager.serverLibraries.isNotEmpty()) {
Log.d(tag, "Starting personalization fetch")
mediaManager.populatePersonalizedDataForAllLibraries { notifyChildrenChanged("/") }
AbsLogger.info(tag, "onLoadChildren: Android Auto fetching personalized data for all libraries")
mediaManager.populatePersonalizedDataForAllLibraries {
AbsLogger.info(tag, "onLoadChildren: Android Auto loaded personalized data for all libraries")
notifyChildrenChanged("/")
}
Log.d(tag, "Initialize inprogress items")
mediaManager.initializeInProgressItems { notifyChildrenChanged("/") }
AbsLogger.info(tag, "onLoadChildren: Android Auto fetching in progress items")
mediaManager.initializeInProgressItems {
AbsLogger.info(tag, "onLoadChildren: Android Auto loaded in progress items")
notifyChildrenChanged("/")
}
}
}
} else {
@@ -1287,7 +1299,8 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
MediaBrowserCompat.MediaItem.FLAG_BROWSABLE
)
}
Log.d(tag, "browseTree initialize and android auto loaded")
AbsLogger.info(tag, "onLoadChildren: Android auto data loaded")
result.sendResult(children as MutableList<MediaBrowserCompat.MediaItem>?)
}
} else if (parentMediaId == LIBRARIES_ROOT || parentMediaId == RECENTLY_ROOT) {
@@ -5,6 +5,7 @@ import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.hardware.SensorManager
import com.audiobookshelf.app.device.DeviceManager
import com.audiobookshelf.app.plugins.AbsLogger
import kotlin.math.sqrt
class ShakeDetector : SensorEventListener {
@@ -46,6 +47,7 @@ class ShakeDetector : SensorEventListener {
if (mShakeTimestamp + SHAKE_COUNT_RESET_TIME_MS < now) {
mShakeCount = 0
}
AbsLogger.info("ShakeDetector", "Device shake above threshold ($gForce > $shakeThreshold)")
mShakeTimestamp = now
mShakeCount++
mListener!!.onShake(mShakeCount)
@@ -180,7 +180,8 @@ class AbsAudioPlayer : Plugin() {
val playWhenReady = call.getBoolean("playWhenReady") == true
val playbackRate = call.getFloat("playbackRate",1f) ?: 1f
val startTimeOverride = call.getDouble("startTime")
Log.d(tag, "prepareLibraryItem lid=$libraryItemId, startTimeOverride=$startTimeOverride, playbackRate=$playbackRate")
AbsLogger.info("AbsAudioPlayer", "prepareLibraryItem: lid=$libraryItemId, startTimeOverride=$startTimeOverride, playbackRate=$playbackRate")
if (libraryItemId.isEmpty()) {
Log.e(tag, "Invalid call to play library item no library item id")
@@ -36,6 +36,7 @@ class AbsDatabase : Plugin() {
DeviceManager.dbManager.cleanLocalMediaProgress()
DeviceManager.dbManager.cleanLocalLibraryItems()
DeviceManager.dbManager.cleanLogs()
}
@PluginMethod
@@ -220,12 +221,11 @@ class AbsDatabase : Plugin() {
@PluginMethod
fun syncLocalSessionsWithServer(call:PluginCall) {
if (DeviceManager.serverConnectionConfig == null) {
Log.e(tag, "syncLocalSessionsWithServer not connected to server")
AbsLogger.error("AbsDatabase", "syncLocalSessionsWithServer: not connected to server")
return call.resolve()
}
apiHandler.syncLocalMediaProgressForUser {
Log.d(tag, "Finished syncing local media progress for user")
val savedSessions = DeviceManager.dbManager.getPlaybackSessions().filter { it.serverConnectionConfigId == DeviceManager.serverConnectionConfigId }
if (savedSessions.isNotEmpty()) {
@@ -233,6 +233,7 @@ class AbsDatabase : Plugin() {
if (!success) {
call.resolve(JSObject("{\"error\":\"$errorMsg\"}"))
} else {
AbsLogger.info("AbsDatabase", "syncLocalSessionsWithServer: Finished sending local playback sessions to server. Removing ${savedSessions.size} saved sessions.")
// Remove all local sessions
savedSessions.forEach {
DeviceManager.dbManager.removePlaybackSession(it.id)
@@ -241,6 +242,7 @@ class AbsDatabase : Plugin() {
}
}
} else {
AbsLogger.info("AbsDatabase", "syncLocalSessionsWithServer: No saved local playback sessions to send to server.")
call.resolve()
}
}
@@ -0,0 +1,80 @@
package com.audiobookshelf.app.plugins
import android.util.Log
import com.audiobookshelf.app.device.DeviceManager
import com.fasterxml.jackson.core.json.JsonReadFeature
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.getcapacitor.JSObject
import com.getcapacitor.Plugin
import com.getcapacitor.PluginCall
import com.getcapacitor.PluginMethod
import com.getcapacitor.annotation.CapacitorPlugin
import java.util.UUID
data class AbsLog(
var id:String,
var tag:String,
var level:String,
var message:String,
var timestamp:Long
)
data class AbsLogList(val value:List<AbsLog>)
@CapacitorPlugin(name = "AbsLogger")
class AbsLogger : Plugin() {
private var jacksonMapper = jacksonObjectMapper().enable(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature())
override fun load() {
onLogEmitter = { log:AbsLog ->
notifyListeners("onLog", JSObject(jacksonMapper.writeValueAsString(log)))
}
info("AbsLogger", "load: AbsLogger plugin initialized")
}
companion object {
var onLogEmitter:((log:AbsLog) -> Unit)? = null
fun log(level:String, tag:String, message:String) {
val absLog = AbsLog(id = UUID.randomUUID().toString(), tag, level, message, timestamp = System.currentTimeMillis())
DeviceManager.dbManager.saveLog(absLog)
onLogEmitter?.let { it(absLog) }
}
fun info(tag:String, message:String) {
Log.i("AbsLogger", message)
log("info", tag, message)
}
fun error(tag:String, message:String) {
Log.e("AbsLogger", message)
log("error", tag, message)
}
}
@PluginMethod
fun info(call: PluginCall) {
val msg = call.getString("message") ?: return call.reject("No message")
val tag = call.getString("tag") ?: ""
info(tag, msg)
call.resolve()
}
@PluginMethod
fun error(call: PluginCall) {
val msg = call.getString("message") ?: return call.reject("No message")
val tag = call.getString("tag") ?: ""
error(tag, msg)
call.resolve()
}
@PluginMethod
fun getAllLogs(call: PluginCall) {
val absLogs = DeviceManager.dbManager.getAllLogs()
call.resolve(JSObject(jacksonMapper.writeValueAsString(AbsLogList(absLogs))))
}
@PluginMethod
fun clearLogs(call: PluginCall) {
DeviceManager.dbManager.removeAllLogs()
call.resolve()
}
}
@@ -13,6 +13,7 @@ import com.audiobookshelf.app.media.MediaProgressSyncData
import com.audiobookshelf.app.media.SyncResult
import com.audiobookshelf.app.models.User
import com.audiobookshelf.app.BuildConfig
import com.audiobookshelf.app.plugins.AbsLogger
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
import com.fasterxml.jackson.core.json.JsonReadFeature
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
@@ -333,8 +334,7 @@ class ApiHandler(var ctx:Context) {
val array = it.getJSONArray("libraryItems")
for (i in 0 until array.length()) {
val jsobj = array.get(i) as JSONObject
val itemInProgress = ItemInProgress.makeFromServerObject(jsobj)
val itemInProgress = ItemInProgress.makeFromServerObject(jsobj, jacksonMapper)
items.add(itemInProgress)
}
}
@@ -468,22 +468,27 @@ class ApiHandler(var ctx:Context) {
val deviceInfo = DeviceInfo(deviceId, Build.MANUFACTURER, Build.MODEL, Build.VERSION.SDK_INT, BuildConfig.VERSION_NAME)
val payload = JSObject(jacksonMapper.writeValueAsString(LocalSessionsSyncRequestPayload(playbackSessions, deviceInfo)))
Log.d(tag, "Sending ${playbackSessions.size} saved local playback sessions to server")
AbsLogger.info("ApiHandler", "sendSyncLocalSessions: Sending ${playbackSessions.size} saved local playback sessions to server (${DeviceManager.serverConnectionConfigName})")
postRequest("/api/session/local-all", payload, null) {
if (!it.getString("error").isNullOrEmpty()) {
Log.e(tag, "Failed to sync local sessions")
AbsLogger.error("ApiHandler", "sendSyncLocalSessions: Failed to sync local sessions. (${it.getString("error")})")
cb(false, it.getString("error"))
} else {
val response = jacksonMapper.readValue<LocalSessionsSyncResponsePayload>(it.toString())
response.results.forEach { localSessionSyncResult ->
Log.d(tag, "Synced session result ${localSessionSyncResult.id}|${localSessionSyncResult.progressSynced}|${localSessionSyncResult.success}")
playbackSessions.find { ps -> ps.id == localSessionSyncResult.id }?.let { session ->
if (localSessionSyncResult.progressSynced == true) {
val syncResult = SyncResult(true, true, "Progress synced on server")
MediaEventManager.saveEvent(session, syncResult)
Log.i(tag, "Successfully synced session ${session.displayTitle} with server")
AbsLogger.info("ApiHandler", "sendSyncLocalSessions: Synced session \"${session.displayTitle}\" with server, server progress was updated for item ${session.mediaItemId}")
} else if (!localSessionSyncResult.success) {
Log.e(tag, "Failed to sync session ${session.displayTitle} with server. Error: ${localSessionSyncResult.error}")
AbsLogger.error("ApiHandler", "sendSyncLocalSessions: Failed to sync session \"${session.displayTitle}\" with server. Error: ${localSessionSyncResult.error}")
} else {
AbsLogger.info("ApiHandler", "sendSyncLocalSessions: Synced session \"${session.displayTitle}\" with server. Server progress was up-to-date for item ${session.mediaItemId}")
}
}
}
@@ -493,37 +498,72 @@ class ApiHandler(var ctx:Context) {
}
fun syncLocalMediaProgressForUser(cb: () -> Unit) {
AbsLogger.info("ApiHandler", "[ApiHandler] syncLocalMediaProgressForUser: Server connection ${DeviceManager.serverConnectionConfigName}")
// Get all local media progress for this server
val allLocalMediaProgress = DeviceManager.dbManager.getAllLocalMediaProgress().filter { it.serverConnectionConfigId == DeviceManager.serverConnectionConfigId }
if (allLocalMediaProgress.isEmpty()) {
Log.d(tag, "No local media progress to sync")
AbsLogger.info("ApiHandler", "[ApiHandler] syncLocalMediaProgressForUser: No local media progress to sync")
return cb()
}
getCurrentUser { _user ->
_user?.let { user->
AbsLogger.info("ApiHandler", "syncLocalMediaProgressForUser: Found ${allLocalMediaProgress.size} local media progress")
getCurrentUser { user ->
if (user == null) {
AbsLogger.error("ApiHandler", "syncLocalMediaProgressForUser: Failed to load user from server (${DeviceManager.serverConnectionConfigName})")
} else {
var numLocalMediaProgressUptToDate = 0
var numLocalMediaProgressUpdated = 0
// Compare server user progress with local progress
user.mediaProgress.forEach { mediaProgress ->
// Get matching local media progress
allLocalMediaProgress.find { it.isMatch(mediaProgress) }?.let { localMediaProgress ->
if (mediaProgress.lastUpdate > localMediaProgress.lastUpdate) {
Log.d(tag, "Server progress for media item id=\"${mediaProgress.mediaItemId}\" is more recent then local. Updating local current time ${localMediaProgress.currentTime} to ${mediaProgress.currentTime}")
val updateLogs = mutableListOf<String>()
if (mediaProgress.progress != localMediaProgress.progress) {
updateLogs.add("Updated progress from ${localMediaProgress.progress} to ${mediaProgress.progress}")
}
if (mediaProgress.currentTime != localMediaProgress.currentTime) {
updateLogs.add("Updated currentTime from ${localMediaProgress.currentTime} to ${mediaProgress.currentTime}")
}
if (mediaProgress.isFinished != localMediaProgress.isFinished) {
updateLogs.add("Updated isFinished from ${localMediaProgress.isFinished} to ${mediaProgress.isFinished}")
}
if (mediaProgress.ebookProgress != localMediaProgress.ebookProgress) {
updateLogs.add("Updated ebookProgress from ${localMediaProgress.isFinished} to ${mediaProgress.isFinished}")
}
if (updateLogs.isNotEmpty()) {
AbsLogger.info("ApiHandler", "syncLocalMediaProgressForUser: Server progress for item \"${mediaProgress.mediaItemId}\" is more recent than local (server lastUpdate=${mediaProgress.lastUpdate}, local lastUpdate=${localMediaProgress.lastUpdate}). ${updateLogs.joinToString()}")
}
localMediaProgress.updateFromServerMediaProgress(mediaProgress)
MediaEventManager.syncEvent(mediaProgress, "Sync on server connection")
// Only report sync if progress changed
if (updateLogs.isNotEmpty()) {
MediaEventManager.syncEvent(mediaProgress, "Sync on server connection")
}
DeviceManager.dbManager.saveLocalMediaProgress(localMediaProgress)
numLocalMediaProgressUpdated++
} else if (localMediaProgress.lastUpdate > mediaProgress.lastUpdate && localMediaProgress.ebookLocation != null && localMediaProgress.ebookLocation != mediaProgress.ebookLocation) {
// Patch ebook progress to server
AbsLogger.info("ApiHandler", "syncLocalMediaProgressForUser: Local progress for ebook item \"${mediaProgress.mediaItemId}\" is more recent than server progress. Local progress last updated ${localMediaProgress.lastUpdate}, server progress last updated ${mediaProgress.lastUpdate}. Sending server request to update ebook progress from ${mediaProgress.ebookProgress} to ${localMediaProgress.ebookProgress}")
val endpoint = "/api/me/progress/${localMediaProgress.libraryItemId}"
val updatePayload = JSObject()
updatePayload.put("ebookLocation", localMediaProgress.ebookLocation)
updatePayload.put("ebookProgress", localMediaProgress.ebookProgress)
updatePayload.put("lastUpdate", localMediaProgress.lastUpdate)
patchRequest(endpoint,updatePayload) {
Log.d(tag, "syncLocalMediaProgressForUser patched ebook progress")
AbsLogger.info("ApiHandler", "syncLocalMediaProgressForUser: Successfully updated server ebook progress for item item \"${mediaProgress.mediaItemId}\"")
}
} else {
numLocalMediaProgressUptToDate++
}
}
}
AbsLogger.info("ApiHandler", "syncLocalMediaProgressForUser: Finishing syncing local media progress with server. $numLocalMediaProgressUptToDate up-to-date, $numLocalMediaProgressUpdated updated")
}
cb()
}
@@ -7,6 +7,7 @@
tools:context=".MainActivity">
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Binary file not shown.
@@ -10,7 +10,7 @@
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:background">@null</item>
<item name="android:background">@color/background_dark</item>
<item name="android:statusBarColor">@color/background_dark</item>
<item name="android:navigationBarColor">@color/background_dark</item>
</style>
+2 -2
View File
@@ -3,5 +3,5 @@
<color name="light_blue_200">#FF81D4FA</color>
<color name="light_blue_600">#FF039BE5</color>
<color name="light_blue_900">#FF01579B</color>
<color name="background_dark">#262626</color>
</resources>
<color name="background_dark">#232323</color>
</resources>
+1 -1
View File
@@ -12,7 +12,7 @@
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.DayNight.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:background">@null</item>
<item name="android:background">@color/background_dark</item>
<item name="android:statusBarColor">@color/background_dark</item>
<item name="android:navigationBarColor">@color/background_dark</item>
</style>
+1 -1
View File
@@ -14,7 +14,7 @@ ext {
androidx_core_ktx_version = '1.16.0'
androidx_media_version = '1.7.0'
exoplayer_version = '2.18.7'
glide_version = '4.11.0'
glide_version = '4.16.0'
junit_version = '4.13.2'
kotlin_version = '2.1.0'
kotlin_coroutines_version = '1.10.1'
+7 -3
View File
@@ -1,5 +1,5 @@
@import "./tailwind.css";
@import "./fonts.css";
@import './tailwind.css';
@import './fonts.css';
@import './defaultStyles.css';
@import './absicons.css';
@import './transitions.css';
@@ -61,6 +61,10 @@ textarea {
box-shadow: 4px 1px 8px #11111166, -4px 1px 8px #11111166, 1px -4px 8px #11111166;
}
.box-shadow-progressbar {
box-shadow: 0px -1px 4px rgb(62, 50, 2, 0.5);
}
.shadow-height {
height: calc(100% - 4px);
}
@@ -164,4 +168,4 @@ Bookshelf Label
.tracksTable th {
padding: 4px 8px;
font-size: 0.75rem;
}
}
+19
View File
@@ -22,6 +22,25 @@
--gradient-minimized-audio-player: linear-gradient(145deg, rgba(38, 38, 38, 0.5) 0%, rgba(38, 38, 38, 0.9) 20%, rgb(38, 38, 38) 60%);
}
html[data-theme='black'] {
color: white;
--color-bg: 0 0 0;
--color-bg-hover: 0 0 0;
--color-fg: 230 237 243;
--color-fg-muted: 120 126 132;
--color-primary: 0 0 0;
--color-secondary: 0 0 0;
--color-border: 55 62 65;
--color-bg-toggle: 0 0 0;
--color-bg-toggle-selected: 35 35 35;
--color-track-cursor: 229 231 235;
--color-track: 107 114 128;
--color-track-buffered: 75 85 99;
--gradient-item-page: rgb(0, 0, 0);
--gradient-audio-player: rgb(0, 0, 0);
--gradient-minimized-audio-player: rgb(0, 0, 0);
}
html[data-theme='light'] {
color: black;
--color-bg: 255 255 255;
+4
View File
@@ -5,6 +5,10 @@
"plugins": {
"CapacitorHttp": {
"enabled": false
},
"StatusBar": {
"backgroundColor": "#232323",
"style": "DARK"
}
},
"server": {
+1 -4
View File
@@ -7,7 +7,7 @@
<a v-if="showBack" @click="back" class="rounded-full h-10 w-10 flex items-center justify-center mr-2 cursor-pointer">
<span class="material-symbols text-3xl text-fg">arrow_back</span>
</a>
<div v-if="user && currentLibrary && socketConnected">
<div v-if="user && currentLibrary">
<div class="pl-1.5 pr-2.5 py-2 bg-bg bg-opacity-30 rounded-md flex items-center" @click="clickShowLibraryModal">
<ui-library-icon :icon="currentLibraryIcon" :size="4" font-size="base" />
<p class="text-sm leading-4 ml-2 mt-0.5 max-w-24 truncate">{{ currentLibraryName }}</p>
@@ -56,9 +56,6 @@ export default {
this.$store.commit('setCastAvailable', val)
}
},
socketConnected() {
return this.$store.state.socketConnected
},
currentLibrary() {
return this.$store.getters['libraries/getCurrentLibrary']
},
+7 -4
View File
@@ -4,15 +4,15 @@
<div class="w-full h-full absolute top-0 left-0 pointer-events-none" style="background: var(--gradient-audio-player)" />
<div class="top-4 left-4 absolute cursor-pointer">
<span class="material-symbols text-5xl" :class="{ 'text-black text-opacity-75': coverBgIsLight }" @click="collapseFullscreen">keyboard_arrow_down</span>
<span class="material-symbols text-5xl" :class="{ 'text-black text-opacity-75': coverBgIsLight && theme !== 'black' }" @click="collapseFullscreen">keyboard_arrow_down</span>
</div>
<div v-show="showCastBtn" class="top-6 right-16 absolute cursor-pointer">
<span class="material-symbols text-3xl" :class="coverBgIsLight ? 'text-black' : ''" @click="castClick">{{ isCasting ? 'cast_connected' : 'cast' }}</span>
<span class="material-symbols text-3xl" :class="coverBgIsLight && theme !== 'black' ? 'text-black' : ''" @click="castClick">{{ isCasting ? 'cast_connected' : 'cast' }}</span>
</div>
<div class="top-6 right-4 absolute cursor-pointer">
<span class="material-symbols text-3xl" :class="{ 'text-black text-opacity-75': coverBgIsLight }" @click="showMoreMenuDialog = true">more_vert</span>
<span class="material-symbols text-3xl" :class="{ 'text-black text-opacity-75': coverBgIsLight && theme !== 'black' }" @click="showMoreMenuDialog = true">more_vert</span>
</div>
<p class="top-4 absolute left-0 right-0 mx-auto text-center uppercase tracking-widest text-opacity-75" :class="{ 'text-black text-opacity-75': coverBgIsLight }" style="font-size: 10px">{{ isDirectPlayMethod ? $strings.LabelPlaybackDirect : isLocalPlayMethod ? $strings.LabelPlaybackLocal : $strings.LabelPlaybackTranscode }}</p>
<p class="top-4 absolute left-0 right-0 mx-auto text-center uppercase tracking-widest text-opacity-75" :class="{ 'text-black text-opacity-75': coverBgIsLight && theme !== 'black' }" style="font-size: 10px">{{ isDirectPlayMethod ? $strings.LabelPlaybackDirect : isLocalPlayMethod ? $strings.LabelPlaybackLocal : $strings.LabelPlaybackTranscode }}</p>
</div>
<div v-if="playerSettings.useChapterTrack && playerSettings.useTotalTrack && showFullscreen" class="absolute total-track w-full z-30 px-6">
@@ -182,6 +182,9 @@ export default {
}
},
computed: {
theme() {
return document.documentElement.dataset.theme || 'dark'
},
menuItems() {
const items = []
// TODO: Implement on iOS
+2 -1
View File
@@ -9,7 +9,7 @@
</template>
<script>
import { AbsAudioPlayer } from '@/plugins/capacitor'
import { AbsAudioPlayer, AbsLogger } from '@/plugins/capacitor'
import { Dialog } from '@capacitor/dialog'
import CellularPermissionHelpers from '@/mixins/cellularPermissionHelpers'
@@ -190,6 +190,7 @@ export default {
})
},
async playLibraryItem(payload) {
await AbsLogger.info({ tag: 'AudioPlayerContainer', message: `playLibraryItem: Received play request for library item ${payload.libraryItemId} ${payload.episodeId ? `episode ${payload.episodeId}` : ''}` })
const libraryItemId = payload.libraryItemId
const episodeId = payload.episodeId
const startTime = payload.startTime
+9
View File
@@ -134,6 +134,15 @@ export default {
to: '/settings'
})
if (this.$platform !== 'ios') {
items.push({
icon: 'bug_report',
iconOutlined: true,
text: this.$strings.ButtonLogs,
to: '/logs'
})
}
if (this.serverConnectionConfig) {
items.push({
icon: 'language',
+3 -3
View File
@@ -59,7 +59,7 @@
</div>
<!-- No progress shown for collapsed series in library -->
<div v-if="!collapsedSeries && (!isPodcast || recentEpisode)" class="absolute bottom-0 left-0 h-1 shadow-sm max-w-full z-10 rounded-b" :class="itemIsFinished ? 'bg-success' : 'bg-yellow-400'" :style="{ width: width * userProgressPercent + 'px' }"></div>
<div v-if="!collapsedSeries && (!isPodcast || recentEpisode)" class="absolute bottom-0 left-0 h-1 max-w-full z-10 rounded-b box-shadow-progressbar" :class="itemIsFinished ? 'bg-success' : 'bg-yellow-400'" :style="{ width: width * userProgressPercent + 'px' }"></div>
<!-- Downloaded icon -->
<div v-if="showHasLocalDownload" class="absolute right-0 top-0 z-20" :style="{ top: (isPodcast || (seriesSequence && showSequence) ? 1.75 : 0.375) * sizeMultiplier + 'rem', right: 0.375 * sizeMultiplier + 'rem', padding: `${0.1 * sizeMultiplier}rem ${0.25 * sizeMultiplier}rem` }">
@@ -77,12 +77,12 @@
</div>
<!-- Series sequence -->
<div v-if="seriesSequence && showSequence && !isSelectionMode" class="absolute rounded-lg bg-black bg-opacity-90 box-shadow-md z-10" :style="{ top: 0.375 * sizeMultiplier + 'rem', right: 0.375 * sizeMultiplier + 'rem', padding: `${0.1 * sizeMultiplier}rem ${0.25 * sizeMultiplier}rem` }">
<div v-if="seriesSequence && showSequence && !isSelectionMode" class="absolute rounded-lg bg-black/90 text-white box-shadow-md z-10" :style="{ top: 0.375 * sizeMultiplier + 'rem', right: 0.375 * sizeMultiplier + 'rem', padding: `${0.1 * sizeMultiplier}rem ${0.25 * sizeMultiplier}rem` }">
<p :style="{ fontSize: sizeMultiplier * 0.8 + 'rem' }">#{{ seriesSequence }}</p>
</div>
<!-- Podcast Episode # -->
<div v-if="recentEpisodeNumber !== null && !isSelectionMode" class="absolute rounded-lg bg-black bg-opacity-90 box-shadow-md z-10" :style="{ top: 0.375 * sizeMultiplier + 'rem', right: 0.375 * sizeMultiplier + 'rem', padding: `${0.1 * sizeMultiplier}rem ${0.25 * sizeMultiplier}rem` }">
<div v-if="recentEpisodeNumber !== null && !isSelectionMode" class="absolute rounded-lg bg-black/90 box-shadow-md z-10" :style="{ top: 0.375 * sizeMultiplier + 'rem', right: 0.375 * sizeMultiplier + 'rem', padding: `${0.1 * sizeMultiplier}rem ${0.25 * sizeMultiplier}rem` }">
<p class="text-white" :style="{ fontSize: sizeMultiplier * 0.8 + 'rem' }">
Episode<span v-if="recentEpisodeNumber"> #{{ recentEpisodeNumber }}</span>
</p>
+1 -1
View File
@@ -5,7 +5,7 @@
<covers-group-cover v-if="series" ref="cover" :id="seriesId" :name="title" :book-items="books" :width="width" :height="height" :book-cover-aspect-ratio="bookCoverAspectRatio" />
</div>
<div v-if="seriesPercentInProgress > 0" class="absolute bottom-0 left-0 h-1 shadow-sm max-w-full z-10 rounded-b w-full" :class="isSeriesFinished ? 'bg-success' : 'bg-yellow-400'" :style="{ width: seriesPercentInProgress * 100 + '%' }" />
<div v-if="seriesPercentInProgress > 0" class="absolute bottom-0 left-0 h-1 max-w-full z-10 rounded-b w-full box-shadow-progressbar" :class="isSeriesFinished ? 'bg-success' : 'bg-yellow-400'" :style="{ width: seriesPercentInProgress * 100 + '%' }" />
<div v-if="isAltViewEnabled && isCategorized" class="absolute z-30 left-0 right-0 mx-auto -bottom-8 h-8 py-1 rounded-md text-center">
<p class="truncate" :style="{ fontSize: labelFontSize + 'rem' }">{{ title }}</p>
+6 -12
View File
@@ -17,7 +17,7 @@
<p class="text-xl font-mono">{{ this.$secondsToTimestamp(currentTime / _playbackRate) }}</p>
</div>
<ui-text-input-with-label v-model="newBookmarkTitle" ref="noteInput" label="Note" />
<ui-text-input-with-label v-model="newBookmarkTitle" :placeholder="bookmarkPlaceholder()" :autofocus="false" ref="noteInput" label="Note" />
<div class="flex justify-end mt-6">
<ui-btn color="success" class="w-full" @click.stop="submitBookmark">{{ selectedBookmark ? 'Update' : 'Create' }}</ui-btn>
</div>
@@ -93,6 +93,10 @@ export default {
}
},
methods: {
bookmarkPlaceholder() {
// using a method prevents caching the date
return this.$formatDate(Date.now(), 'MMM dd, yyyy HH:mm')
},
editBookmark(bm) {
this.selectedBookmark = bm
this.newBookmarkTitle = bm.title
@@ -157,18 +161,8 @@ export default {
},
createBookmark() {
this.selectedBookmark = null
this.newBookmarkTitle = this.$formatDate(Date.now(), 'MMM dd, yyyy HH:mm')
this.newBookmarkTitle = ''
this.showBookmarkTitleInput = true
// Auto focus the input and select the text
this.$nextTick(() => {
if (this.$refs.noteInput?.$refs.input?.$refs.input) {
this.$refs.noteInput.$refs.input.$refs.input.focus()
setTimeout(() => {
this.$refs.noteInput?.$refs.input?.$refs.input?.select()
}, 10)
}
})
},
async submitBookmark() {
await this.$hapticsImpact()
+10
View File
@@ -104,6 +104,11 @@ export default {
text: this.$strings.ButtonIssues,
value: 'issues',
sublist: false
},
{
text: this.$strings.LabelRSSFeedOpen,
value: 'feed-open',
sublist: false
}
],
podcastItems: [
@@ -120,6 +125,11 @@ export default {
text: this.$strings.LabelTag,
value: 'tags',
sublist: true
},
{
text: this.$strings.LabelRSSFeedOpen,
value: 'feed-open',
sublist: false
}
]
}
+5 -1
View File
@@ -1,6 +1,6 @@
<template>
<div class="relative">
<input v-model="input" ref="input" autofocus :type="type" :disabled="disabled" :readonly="readonly" autocorrect="off" autocapitalize="none" autocomplete="off" :placeholder="placeholder" class="py-2 w-full outline-none bg-primary disabled:text-fg-muted" :class="inputClass" @keyup="keyup" />
<input v-model="input" ref="input" :autofocus="autofocus" :type="type" :disabled="disabled" :readonly="readonly" autocorrect="off" autocapitalize="none" autocomplete="off" :placeholder="placeholder" class="py-2 w-full outline-none bg-primary disabled:text-fg-muted" :class="inputClass" @keyup="keyup" />
<div v-if="prependIcon" class="absolute top-0 left-0 h-full px-2 flex items-center justify-center">
<span class="material-symbols text-lg">{{ prependIcon }}</span>
</div>
@@ -22,6 +22,10 @@ export default {
disabled: Boolean,
readonly: Boolean,
borderless: Boolean,
autofocus: {
type: Boolean,
default: true
},
bg: {
type: String,
default: 'bg'
+7 -2
View File
@@ -1,7 +1,7 @@
<template>
<div class="w-full">
<p class="pb-0.5 text-sm font-semibold">{{ label }}</p>
<ui-text-input v-model="inputValue" ref="input" :disabled="disabled" :type="type" text-size="base" class="w-full" />
<ui-text-input v-model="inputValue" ref="input" :disabled="disabled" :type="type" :placeholder="placeholder" :autofocus="autofocus" text-size="base" class="w-full" />
</div>
</template>
@@ -14,7 +14,12 @@ export default {
type: String,
default: 'text'
},
disabled: Boolean
disabled: Boolean,
placeholder: String,
autofocus: {
type: Boolean,
default: true
}
},
data() {
return {}
+68
View File
@@ -0,0 +1,68 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" width="12px" height="12px" viewBox="0 0 512 512" class="ml-1">
<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 372.00,392.00
C 372.00,392.00 364.02,364.00 364.02,364.00
364.02,364.00 350.72,319.00 350.72,319.00
350.72,319.00 310.42,183.00 310.42,183.00
310.42,183.00 296.86,137.00 296.86,137.00
296.86,137.00 291.30,121.99 291.30,121.99
291.30,121.99 284.00,121.00 284.00,121.00
284.00,121.00 230.00,121.00 230.00,121.00
230.00,121.00 222.51,122.02 222.51,122.02
222.51,122.02 216.86,137.00 216.86,137.00
216.86,137.00 203.28,183.00 203.28,183.00
203.28,183.00 163.28,318.00 163.28,318.00
163.28,318.00 148.71,367.00 148.71,367.00
148.71,367.00 142.00,392.00 142.00,392.00
142.00,392.00 183.00,392.00 183.00,392.00
183.00,392.00 190.86,390.43 190.86,390.43
190.86,390.43 195.86,375.00 195.86,375.00
195.86,375.00 206.00,338.00 206.00,338.00
206.00,338.00 293.00,338.00 293.00,338.00
295.64,338.01 299.26,337.65 301.30,339.60
303.23,341.43 304.80,348.22 305.58,351.00
305.58,351.00 313.00,378.00 313.00,378.00
316.91,391.63 315.20,391.98 325.00,392.00
325.00,392.00 372.00,392.00 372.00,392.00 Z
M 254.00,170.00
C 254.00,170.00 256.00,170.00 256.00,170.00
256.00,170.00 263.12,197.00 263.12,197.00
263.12,197.00 282.88,268.00 282.88,268.00
282.88,268.00 290.00,296.00 290.00,296.00
290.00,296.00 219.00,296.00 219.00,296.00
219.00,296.00 230.58,253.00 230.58,253.00
230.58,253.00 254.00,170.00 254.00,170.00 Z"
/>
</svg>
</template>
<script>
export default {
props: {},
data() {
return {}
},
computed: {},
methods: {},
mounted() {}
}
</script>
+8 -20
View File
@@ -15,20 +15,17 @@
3ABF580928059BAE005DFBE5 /* PlaybackSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3ABF580828059BAE005DFBE5 /* PlaybackSession.swift */; };
3ABF618F2804325C0070250E /* PlayerHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3ABF618E2804325C0070250E /* PlayerHandler.swift */; };
3AD4FCE528043E50006DB301 /* AbsDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AD4FCE428043E50006DB301 /* AbsDatabase.swift */; };
3AD4FCE728043E72006DB301 /* AbsDatabase.m in Sources */ = {isa = PBXBuildFile; fileRef = 3AD4FCE628043E72006DB301 /* AbsDatabase.m */; };
3AD4FCE928043FD7006DB301 /* ServerConnectionConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AD4FCE828043FD7006DB301 /* ServerConnectionConfig.swift */; };
3AD4FCEB280443DD006DB301 /* Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AD4FCEA280443DD006DB301 /* Database.swift */; };
3AD4FCED28044E6C006DB301 /* Store.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AD4FCEC28044E6C006DB301 /* Store.swift */; };
3AF1970C2806E2590096F747 /* ApiClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AF1970B2806E2590096F747 /* ApiClient.swift */; };
3AF1970E2806E3CA0096F747 /* AbsAudioPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AF1970D2806E3CA0096F747 /* AbsAudioPlayer.swift */; };
3AF197102806E3DC0096F747 /* AbsAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3AF1970F2806E3DC0096F747 /* AbsAudioPlayer.m */; };
3AFCB5E827EA240D00ECCC05 /* NowPlayingInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AFCB5E727EA240D00ECCC05 /* NowPlayingInfo.swift */; };
4D66B952282EE822008272D4 /* AbsDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D66B951282EE822008272D4 /* AbsDownloader.m */; };
4D66B954282EE87C008272D4 /* AbsDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D66B953282EE87C008272D4 /* AbsDownloader.swift */; };
4D66B956282EE951008272D4 /* AbsFileSystem.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D66B955282EE951008272D4 /* AbsFileSystem.m */; };
4D66B958282EEA14008272D4 /* AbsFileSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D66B957282EEA14008272D4 /* AbsFileSystem.swift */; };
4D91EEC62A40F28D004807ED /* EBookFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D91EEC52A40F28D004807ED /* EBookFile.swift */; };
4DABC04F2B0139CA000F6264 /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DABC04E2B0139CA000F6264 /* User.swift */; };
4DF6C7172DB58ABF004059F1 /* AbsLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DF6C7162DB58ABF004059F1 /* AbsLogger.swift */; };
4DF74912287105C600AC7814 /* DeviceSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DF74911287105C600AC7814 /* DeviceSettings.swift */; };
4DFE2DA32D345C390000B204 /* MyViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DFE2DA22D345C390000B204 /* MyViewController.swift */; };
50379B232058CBB4000EE86E /* capacitor.config.json in Resources */ = {isa = PBXBuildFile; fileRef = 50379B222058CBB4000EE86E /* capacitor.config.json */; };
@@ -90,21 +87,18 @@
3ABF580828059BAE005DFBE5 /* PlaybackSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaybackSession.swift; sourceTree = "<group>"; };
3ABF618E2804325C0070250E /* PlayerHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerHandler.swift; sourceTree = "<group>"; };
3AD4FCE428043E50006DB301 /* AbsDatabase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AbsDatabase.swift; sourceTree = "<group>"; };
3AD4FCE628043E72006DB301 /* AbsDatabase.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AbsDatabase.m; sourceTree = "<group>"; };
3AD4FCE828043FD7006DB301 /* ServerConnectionConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerConnectionConfig.swift; sourceTree = "<group>"; };
3AD4FCEA280443DD006DB301 /* Database.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Database.swift; sourceTree = "<group>"; };
3AD4FCEC28044E6C006DB301 /* Store.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Store.swift; sourceTree = "<group>"; };
3AF1970B2806E2590096F747 /* ApiClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApiClient.swift; sourceTree = "<group>"; };
3AF1970D2806E3CA0096F747 /* AbsAudioPlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AbsAudioPlayer.swift; sourceTree = "<group>"; };
3AF1970F2806E3DC0096F747 /* AbsAudioPlayer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AbsAudioPlayer.m; sourceTree = "<group>"; };
3AFCB5E727EA240D00ECCC05 /* NowPlayingInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NowPlayingInfo.swift; sourceTree = "<group>"; };
4D66B951282EE822008272D4 /* AbsDownloader.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AbsDownloader.m; sourceTree = "<group>"; };
4D66B953282EE87C008272D4 /* AbsDownloader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AbsDownloader.swift; sourceTree = "<group>"; };
4D66B955282EE951008272D4 /* AbsFileSystem.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AbsFileSystem.m; sourceTree = "<group>"; };
4D66B957282EEA14008272D4 /* AbsFileSystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AbsFileSystem.swift; sourceTree = "<group>"; };
4D8D412C26E187E400BA5F0D /* App-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "App-Bridging-Header.h"; sourceTree = "<group>"; };
4D91EEC52A40F28D004807ED /* EBookFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EBookFile.swift; sourceTree = "<group>"; };
4DABC04E2B0139CA000F6264 /* User.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = "<group>"; };
4DF6C7162DB58ABF004059F1 /* AbsLogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AbsLogger.swift; sourceTree = "<group>"; };
4DF74911287105C600AC7814 /* DeviceSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceSettings.swift; sourceTree = "<group>"; };
4DFE2DA22D345C390000B204 /* MyViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyViewController.swift; sourceTree = "<group>"; };
50379B222058CBB4000EE86E /* capacitor.config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = capacitor.config.json; sourceTree = "<group>"; };
@@ -217,13 +211,10 @@
isa = PBXGroup;
children = (
3AD4FCE428043E50006DB301 /* AbsDatabase.swift */,
3AD4FCE628043E72006DB301 /* AbsDatabase.m */,
3AF1970D2806E3CA0096F747 /* AbsAudioPlayer.swift */,
3AF1970F2806E3DC0096F747 /* AbsAudioPlayer.m */,
4D66B951282EE822008272D4 /* AbsDownloader.m */,
4D66B953282EE87C008272D4 /* AbsDownloader.swift */,
4D66B955282EE951008272D4 /* AbsFileSystem.m */,
4D66B957282EEA14008272D4 /* AbsFileSystem.swift */,
4DF6C7162DB58ABF004059F1 /* AbsLogger.swift */,
);
path = plugins;
sourceTree = "<group>";
@@ -531,7 +522,6 @@
files = (
E9D5507328AC218300C746DD /* DaoExtensions.swift in Sources */,
E9D5506228AC1CC900C746DD /* PlayerState.swift in Sources */,
3AD4FCE728043E72006DB301 /* AbsDatabase.m in Sources */,
504EC3081FED79650016851F /* AppDelegate.swift in Sources */,
EACB38122BCCA1330060DA4A /* AudioPlayerRateManager.swift in Sources */,
E9FA07E328C82848005520B0 /* Logger.swift in Sources */,
@@ -545,6 +535,7 @@
4D66B958282EEA14008272D4 /* AbsFileSystem.swift in Sources */,
E9D5504C28AC1AE000C746DD /* PodcastEpisode.swift in Sources */,
E9D5506A28AC1DF100C746DD /* LocalFile.swift in Sources */,
4DF6C7172DB58ABF004059F1 /* AbsLogger.swift in Sources */,
3AF1970E2806E3CA0096F747 /* AbsAudioPlayer.swift in Sources */,
E9D5506F28AC1E8E00C746DD /* DownloadItem.swift in Sources */,
3AD4FCE928043FD7006DB301 /* ServerConnectionConfig.swift in Sources */,
@@ -553,7 +544,6 @@
3A200C1527D64D7E00CBF02E /* AudioPlayer.swift in Sources */,
4DFE2DA32D345C390000B204 /* MyViewController.swift in Sources */,
E9D5507128AC1EC700C746DD /* DownloadItemPart.swift in Sources */,
4D66B956282EE951008272D4 /* AbsFileSystem.m in Sources */,
EACB38142BCCA1410060DA4A /* LegacyAudioPlayerRateManager.swift in Sources */,
3AFCB5E827EA240D00ECCC05 /* NowPlayingInfo.swift in Sources */,
3AB34053280829BF0039308B /* Extensions.swift in Sources */,
@@ -561,7 +551,6 @@
3AD4FCEB280443DD006DB301 /* Database.swift in Sources */,
3AD4FCE528043E50006DB301 /* AbsDatabase.swift in Sources */,
4DABC04F2B0139CA000F6264 /* User.swift in Sources */,
4D66B952282EE822008272D4 /* AbsDownloader.m in Sources */,
E9D5506828AC1DC300C746DD /* LocalPodcastEpisode.swift in Sources */,
EACB38162BCCA1500060DA4A /* DefaultedAudioPlayerRateManager.swift in Sources */,
E9D5505228AC1B5D00C746DD /* Chapter.swift in Sources */,
@@ -574,7 +563,6 @@
E9D5505C28AC1C6200C746DD /* LibraryFile.swift in Sources */,
4DF74912287105C600AC7814 /* DeviceSettings.swift in Sources */,
E9D5504A28AC1AA600C746DD /* Metadata.swift in Sources */,
3AF197102806E3DC0096F747 /* AbsAudioPlayer.m in Sources */,
E9D5507528AEF93100C746DD /* PlayerSettings.swift in Sources */,
E9D5505028AC1B3E00C746DD /* Author.swift in Sources */,
3AF1970C2806E2590096F747 /* ApiClient.swift in Sources */,
@@ -744,12 +732,12 @@
ASSETCATALOG_COMPILER_APPICON_NAME = Icons;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 36;
CURRENT_PROJECT_VERSION = 38;
DEVELOPMENT_TEAM = 7UFJ7D8V6A;
INFOPLIST_FILE = App/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 0.9.79;
MARKETING_VERSION = 0.9.81;
OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
PRODUCT_BUNDLE_IDENTIFIER = com.audiobookshelf.app.dev;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -768,12 +756,12 @@
ASSETCATALOG_COMPILER_APPICON_NAME = Icons;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 36;
CURRENT_PROJECT_VERSION = 38;
DEVELOPMENT_TEAM = 7UFJ7D8V6A;
INFOPLIST_FILE = App/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 0.9.79;
MARKETING_VERSION = 0.9.81;
PRODUCT_BUNDLE_IDENTIFIER = com.audiobookshelf.app;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "";
+1
View File
@@ -21,6 +21,7 @@ class MyViewController: CAPBridgeViewController {
bridge?.registerPluginInstance(AbsAudioPlayer())
bridge?.registerPluginInstance(AbsDownloader())
bridge?.registerPluginInstance(AbsFileSystem())
bridge?.registerPluginInstance(AbsLogger())
}
+4
View File
@@ -5,6 +5,10 @@
"plugins": {
"CapacitorHttp": {
"enabled": false
},
"StatusBar": {
"backgroundColor": "#232323",
"style": "DARK"
}
},
"server": {
-35
View File
@@ -1,35 +0,0 @@
//
// AbsAudioPlayer.m
// App
//
// Created by Rasmus Krämer on 13.04.22.
//
#import <Foundation/Foundation.h>
#import <Capacitor/Capacitor.h>
CAP_PLUGIN(AbsAudioPlayer, "AbsAudioPlayer",
CAP_PLUGIN_METHOD(onReady, CAPPluginReturnNone);
CAP_PLUGIN_METHOD(prepareLibraryItem, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(closePlayback, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(setPlaybackSpeed, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(setChapterTrack, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(playPlayer, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(pausePlayer, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(playPause, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(seek, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(seekForward, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(seekBackward, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(getCurrentTime, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(cancelSleepTimer, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(decreaseSleepTime, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(increaseSleepTime, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(getSleepTimerTime, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(setSleepTimer, CAPPluginReturnPromise);
)
+23 -1
View File
@@ -11,7 +11,29 @@ import RealmSwift
import Network
@objc(AbsAudioPlayer)
public class AbsAudioPlayer: CAPPlugin {
public class AbsAudioPlayer: CAPPlugin, CAPBridgedPlugin {
public var identifier = "AbsAudioPlayerPlugin"
public var jsName = "AbsAudioPlayer"
public let pluginMethods: [CAPPluginMethod] = [
CAPPluginMethod(name: "onReady", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "prepareLibraryItem", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "closePlayback", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "setPlaybackSpeed", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "setChapterTrack", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "playPlayer", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "pausePlayer", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "playPause", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "seek", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "seekForward", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "seekBackward", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "getCurrentTime", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "cancelSleepTimer", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "decreaseSleepTime", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "increaseSleepTime", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "getSleepTimerTime", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "setSleepTimer", returnType: CAPPluginReturnPromise)
]
private let logger = AppLogger(category: "AbsAudioPlayer")
private var initialPlayWhenReady = false
-29
View File
@@ -1,29 +0,0 @@
//
// AbsDatabase.m
// App
//
// Created by Rasmus Krämer on 11.04.22.
//
#import <Foundation/Foundation.h>
#import <Capacitor/Capacitor.h>
CAP_PLUGIN(AbsDatabase, "AbsDatabase",
CAP_PLUGIN_METHOD(setCurrentServerConnectionConfig, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(removeServerConnectionConfig, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(logout, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(getDeviceData, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(getLocalLibraryItems, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(getLocalLibraryItem, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(getLocalLibraryItemByLId, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(getLocalLibraryItemsInFolder, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(getAllLocalMediaProgress, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(removeLocalMediaProgress, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(syncServerMediaProgressWithLocalMediaProgress, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(syncLocalSessionsWithServer, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(updateLocalMediaProgressFinished, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(updateDeviceSettings, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(updateLocalEbookProgress, CAPPluginReturnPromise);
)
+21 -1
View File
@@ -27,7 +27,27 @@ extension String {
}
@objc(AbsDatabase)
public class AbsDatabase: CAPPlugin {
public class AbsDatabase: CAPPlugin, CAPBridgedPlugin {
public var identifier = "AbsDatabasePlugin"
public var jsName = "AbsDatabase"
public let pluginMethods: [CAPPluginMethod] = [
CAPPluginMethod(name: "setCurrentServerConnectionConfig", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "removeServerConnectionConfig", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "logout", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "getDeviceData", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "getLocalLibraryItems", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "getLocalLibraryItem", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "getLocalLibraryItemByLId", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "getLocalLibraryItemsInFolder", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "getAllLocalMediaProgress", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "removeLocalMediaProgress", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "syncServerMediaProgressWithLocalMediaProgress", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "syncLocalSessionsWithServer", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "updateLocalMediaProgressFinished", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "updateDeviceSettings", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "updateLocalEbookProgress", returnType: CAPPluginReturnPromise)
]
private let logger = AppLogger(category: "AbsDatabase")
@objc func setCurrentServerConnectionConfig(_ call: CAPPluginCall) {
-13
View File
@@ -1,13 +0,0 @@
//
// AbsDownloader.m
// App
//
// Created by advplyr on 5/13/22.
//
#import <Foundation/Foundation.h>
#import <Capacitor/Capacitor.h>
CAP_PLUGIN(AbsDownloader, "AbsDownloader",
CAP_PLUGIN_METHOD(downloadLibraryItem, CAPPluginReturnPromise);
)
+6 -1
View File
@@ -10,7 +10,12 @@ import Capacitor
import RealmSwift
@objc(AbsDownloader)
public class AbsDownloader: CAPPlugin, URLSessionDownloadDelegate {
public class AbsDownloader: CAPPlugin, CAPBridgedPlugin, URLSessionDownloadDelegate {
public var identifier = "AbsDownloaderPlugin"
public var jsName = "AbsDownloader"
public let pluginMethods: [CAPPluginMethod] = [
CAPPluginMethod(name: "downloadLibraryItem", returnType: CAPPluginReturnPromise)
]
static private let downloadsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
-20
View File
@@ -1,20 +0,0 @@
//
// AbsFileSystem.m
// App
//
// Created by advplyr on 5/13/22.
//
#import <Foundation/Foundation.h>
#import <Capacitor/Capacitor.h>
CAP_PLUGIN(AbsFileSystem, "AbsFileSystem",
CAP_PLUGIN_METHOD(selectFolder, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(checkFolderPermission, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(scanFolder, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(removeFolder, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(removeLocalLibraryItem, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(scanLocalLibraryItem, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(deleteItem, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(deleteTrackFromItem, CAPPluginReturnPromise);
)
+14 -1
View File
@@ -9,7 +9,20 @@ import Foundation
import Capacitor
@objc(AbsFileSystem)
public class AbsFileSystem: CAPPlugin {
public class AbsFileSystem: CAPPlugin, CAPBridgedPlugin {
public var identifier = "AbsFileSystemPlugin"
public var jsName = "AbsFileSystem"
public let pluginMethods: [CAPPluginMethod] = [
CAPPluginMethod(name: "selectFolder", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "checkFolderPermission", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "scanFolder", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "removeFolder", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "removeLocalLibraryItem", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "scanLocalLibraryItem", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "deleteItem", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "deleteTrackFromItem", returnType: CAPPluginReturnPromise)
]
private let logger = AppLogger(category: "AbsFileSystem")
@objc func selectFolder(_ call: CAPPluginCall) {
+47
View File
@@ -0,0 +1,47 @@
//
// AbsLogger.swift
// Audiobookshelf
//
// Created by advplyr on 4/20/25.
//
import Foundation
import Capacitor
@objc(AbsLogger)
public class AbsLogger: CAPPlugin, CAPBridgedPlugin {
public var identifier = "AbsLoggerPlugin"
public var jsName = "AbsLogger"
public let pluginMethods: [CAPPluginMethod] = [
CAPPluginMethod(name: "info", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "error", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "getAllLogs", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "clearLogs", returnType: CAPPluginReturnPromise)
]
private let logger = AppLogger(category: "AbsLogger")
@objc func info(_ call: CAPPluginCall) {
let message = call.getString("message") ?? ""
let tag = call.getString("tag") ?? ""
logger.log("[\(tag)] \(message)")
call.resolve()
}
@objc func error(_ call: CAPPluginCall) {
let message = call.getString("message") ?? ""
let tag = call.getString("tag") ?? ""
logger.error("[\(tag)] \(message)")
call.resolve()
}
@objc func getAllLogs(_ call: CAPPluginCall) {
call.unimplemented("Not implemented on iOS")
}
@objc func clearLogs(_ call: CAPPluginCall) {
call.unimplemented("Not implemented on iOS")
}
}
+10 -10
View File
@@ -1,5 +1,5 @@
PODS:
- Alamofire (5.8.1)
- Alamofire (5.10.2)
- Capacitor (7.2.0):
- CapacitorCordova
- CapacitorApp (7.0.1):
@@ -25,11 +25,11 @@ PODS:
- Capacitor
- CordovaPlugins (6.2.1):
- CapacitorCordova
- Realm (10.47.0):
- Realm/Headers (= 10.47.0)
- Realm/Headers (10.47.0)
- RealmSwift (10.47.0):
- Realm (= 10.47.0)
- Realm (10.54.4):
- Realm/Headers (= 10.54.4)
- Realm/Headers (10.54.4)
- RealmSwift (10.54.4):
- Realm (= 10.54.4)
- WebnativellcCapacitorFilesharer (7.0.4):
- Capacitor
@@ -88,7 +88,7 @@ EXTERNAL SOURCES:
:path: "../../node_modules/@webnativellc/capacitor-filesharer"
SPEC CHECKSUMS:
Alamofire: 3ca42e259043ee0dc5c0cdd76c4bc568b8e42af7
Alamofire: 7193b3b92c74a07f85569e1a6c4f4237291e7496
Capacitor: 106e7a4205f4618d582b886a975657c61179138d
CapacitorApp: d63334c052278caf5d81585d80b21905c6f93f39
CapacitorBrowser: 081852cf532acf77b9d2953f3a88fe5b9711fb06
@@ -102,10 +102,10 @@ SPEC CHECKSUMS:
CapacitorPreferences: cbf154e5e5519b7f5ab33817a334dda1e98387f9
CapacitorStatusBar: 275cbf2f4dfc00388f519ef80c7ec22edda342c9
CordovaPlugins: 5a72a85b45469e68556bb172409f1b6d57b27236
Realm: e43fb540ae947497e3ea8a662443256920602060
RealmSwift: 8b06ed06b5d16749ae0c4d91c0cba414a9e28189
Realm: 8b5cda39a41f17a1734da2f39c6004eb8745587a
RealmSwift: 0b4f808fed6898f1f6c26f501f740efd80dff0b4
WebnativellcCapacitorFilesharer: 10b111373d4dc49608935600dcbcc14605258c73
PODFILE CHECKSUM: 498821c0cfa2508609567fa95d7244c01cbef538
COCOAPODS: 1.12.1
COCOAPODS: 1.16.2
+21 -12
View File
@@ -16,6 +16,7 @@
<script>
import { CapacitorHttp } from '@capacitor/core'
import { AbsLogger } from '@/plugins/capacitor'
export default {
data() {
@@ -72,6 +73,9 @@ export default {
currentLibraryId() {
return this.$store.state.libraries.currentLibraryId
},
currentLibraryName() {
return this.$store.getters['libraries/getCurrentLibraryName']
},
attemptingConnection: {
get() {
return this.$store.state.attemptingConnection
@@ -114,6 +118,7 @@ export default {
console.warn('[default] attemptConnection')
if (!this.networkConnected) {
console.warn('[default] No network connection')
AbsLogger.info({ tag: 'default', message: 'attemptConnection: No network connection' })
return
}
if (this.attemptingConnection) {
@@ -134,13 +139,14 @@ export default {
if (!serverConfig) {
// No last server config set
this.attemptingConnection = false
AbsLogger.info({ tag: 'default', message: 'attemptConnection: No last server config set' })
return
}
console.log(`[default] Got server config, attempt authorize ${serverConfig.address}`)
AbsLogger.info({ tag: 'default', message: `attemptConnection: Got server config, attempt authorize (${serverConfig.name})` })
const authRes = await this.postRequest(`${serverConfig.address}/api/authorize`, null, { Authorization: `Bearer ${serverConfig.token}` }, 6000).catch((error) => {
console.error('[default] Server auth failed', error)
AbsLogger.error({ tag: 'default', message: `attemptConnection: Server auth failed (${serverConfig.name})` })
return false
})
if (!authRes) {
@@ -166,7 +172,7 @@ export default {
this.$socket.connect(serverConnectionConfig.address, serverConnectionConfig.token)
console.log('[default] Successful connection on last saved connection config', JSON.stringify(serverConnectionConfig))
AbsLogger.info({ tag: 'default', message: `attemptConnection: Successful connection to last saved server config (${serverConnectionConfig.name})` })
await this.initLibraries()
this.attemptingConnection = false
},
@@ -186,7 +192,8 @@ export default {
}
this.inittingLibraries = true
await this.$store.dispatch('libraries/load')
console.log(`[default] initLibraries loaded ${this.currentLibraryId}`)
AbsLogger.info({ tag: 'default', message: `initLibraries loading library ${this.currentLibraryName}` })
await this.$store.dispatch('libraries/fetch', this.currentLibraryId)
this.$eventBus.$emit('library-changed')
this.inittingLibraries = false
@@ -197,7 +204,7 @@ export default {
return
}
console.log('[default] Calling syncLocalSessions')
AbsLogger.info({ tag: 'default', message: 'Calling syncLocalSessions' })
const response = await this.$db.syncLocalSessionsWithServer(isFirstSync)
if (response?.error) {
console.error('[default] Failed to sync local sessions', response.error)
@@ -214,12 +221,12 @@ export default {
},
async userMediaProgressUpdated(payload) {
const prog = payload.data // MediaProgress
console.log(`[default] userMediaProgressUpdate checking for local media progress ${payload.id}`)
await AbsLogger.info({ tag: 'default', message: `userMediaProgressUpdate: Received updated media progress for current user from socket event. Media item id ${payload.id}` })
// Check if this media item is currently open in the player, paused, and this progress update is coming from a different session
const isMediaOpenInPlayer = this.$store.getters['getIsMediaStreaming'](prog.libraryItemId, prog.episodeId)
if (isMediaOpenInPlayer && this.$store.getters['getCurrentPlaybackSessionId'] !== payload.sessionId && !this.$store.state.playerIsPlaying) {
console.log('[default] userMediaProgressUpdated for current open media item', payload.data.currentTime)
await AbsLogger.info({ tag: 'default', message: `userMediaProgressUpdate: Item is currently open in player, paused and this progress update is coming from a different session. Updating playback time to ${payload.data.currentTime}` })
this.$eventBus.$emit('playback-time-update', payload.data.currentTime)
}
@@ -230,12 +237,12 @@ export default {
// Progress update is more recent then local progress
if (localProg && localProg.lastUpdate < prog.lastUpdate) {
if (localProg.currentTime == prog.currentTime && localProg.isFinished == prog.isFinished) {
console.log('[default] syncing progress server lastUpdate > local lastUpdate but currentTime and isFinished is equal')
await AbsLogger.info({ tag: 'default', message: `userMediaProgressUpdate: server lastUpdate is more recent but progress is up-to-date (libraryItemId: ${prog.libraryItemId}${prog.episodeId ? ` episodeId: ${prog.episodeId}` : ''})` })
return
}
// Server progress is more up-to-date
console.log(`[default] syncing progress from server with local item for "${prog.libraryItemId}" ${prog.episodeId ? `episode ${prog.episodeId}` : ''} | server lastUpdate=${prog.lastUpdate} > local lastUpdate=${localProg.lastUpdate}`)
await AbsLogger.info({ tag: 'default', message: `userMediaProgressUpdate: syncing progress from server with local item for "${prog.libraryItemId}" ${prog.episodeId ? `episode ${prog.episodeId}` : ''} | server lastUpdate=${prog.lastUpdate} > local lastUpdate=${localProg.lastUpdate}` })
const payload = {
localMediaProgressId: localProg.id,
mediaProgress: prog
@@ -273,7 +280,7 @@ export default {
}
if (newLocalMediaProgress?.id) {
console.log(`[default] local media progress updated for ${newLocalMediaProgress.id}`)
await AbsLogger.info({ tag: 'default', message: `userMediaProgressUpdate: local media progress updated for ${newLocalMediaProgress.id}` })
this.$store.commit('globals/updateLocalMediaProgress', newLocalMediaProgress)
}
},
@@ -310,6 +317,7 @@ export default {
this.$socket.on('user_media_progress_updated', this.userMediaProgressUpdated)
if (this.$store.state.isFirstLoad) {
AbsLogger.info({ tag: 'default', message: `mounted: initializing first load (${this.$platform} v${this.$config.version})` })
this.$store.commit('setIsFirstLoad', false)
this.loadSavedSettings()
@@ -322,17 +330,18 @@ export default {
await this.$store.dispatch('setupNetworkListener')
if (this.$store.state.user.serverConnectionConfig) {
AbsLogger.info({ tag: 'default', message: `mounted: Server connected, init libraries (${this.$store.getters['user/getServerConfigName']})` })
await this.initLibraries()
} else {
AbsLogger.info({ tag: 'default', message: `mounted: Server not connected, attempt connection` })
await this.attemptConnection()
}
console.log(`[default] finished connection attempt or already connected ${!!this.user}`)
await this.syncLocalSessions(true)
this.hasMounted = true
console.log('[default] fully initialized')
AbsLogger.info({ tag: 'default', message: 'mounted: fully initialized' })
this.$eventBus.$emit('abs-ui-ready')
}
},
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "audiobookshelf-app",
"version": "0.9.79-beta",
"version": "0.9.81-beta",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "audiobookshelf-app",
"version": "0.9.79-beta",
"version": "0.9.81-beta",
"dependencies": {
"@capacitor-community/keep-awake": "^7.0.0",
"@capacitor-community/volume-buttons": "^7.0.0",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "audiobookshelf-app",
"version": "0.9.79-beta",
"version": "0.9.81-beta",
"author": "advplyr",
"scripts": {
"dev": "nuxt --hostname 0.0.0.0 --port 1337",
+5 -1
View File
@@ -14,7 +14,7 @@
</div>
<div class="relative" @click="showFullscreenCover = true">
<covers-book-cover :library-item="libraryItem" :width="coverWidth" :book-cover-aspect-ratio="bookCoverAspectRatio" no-bg raw @imageLoaded="coverImageLoaded" />
<div v-if="!isPodcast" class="absolute bottom-0 left-0 h-1 shadow-sm z-10" :class="userIsFinished ? 'bg-success' : 'bg-yellow-400'" :style="{ width: coverWidth * progressPercent + 'px' }"></div>
<div v-if="!isPodcast" class="absolute bottom-0 left-0 h-1 z-10 box-shadow-progressbar" :class="userIsFinished ? 'bg-success' : 'bg-yellow-400'" :style="{ width: coverWidth * progressPercent + 'px' }"></div>
</div>
</div>
@@ -31,6 +31,7 @@
<div class="flex items-center justify-center">
<h1 class="text-xl font-semibold">{{ title }}</h1>
<widgets-explicit-indicator v-if="isExplicit" />
<widgets-abridged-indicator v-if="isAbridged" />
</div>
<p v-if="subtitle" class="text-fg text-base">{{ subtitle }}</p>
</div>
@@ -438,6 +439,9 @@ export default {
isExplicit() {
return !!this.mediaMetadata.explicit
},
isAbridged() {
return !!this.mediaMetadata.abridged
},
showPlay() {
return !this.isMissing && !this.isInvalid && (this.numTracks || this.episodes.length)
},
+175
View File
@@ -0,0 +1,175 @@
<template>
<div class="w-full h-full py-4">
<div class="flex items-center mb-2 space-x-2 px-4">
<p class="text-lg font-bold">{{ $strings.ButtonLogs }}</p>
<ui-icon-btn outlined borderless :icon="isCopied ? 'check' : 'content_copy'" @click="copyToClipboard" />
<ui-icon-btn outlined borderless icon="share" @click="shareLogs" />
<div class="flex-grow"></div>
<ui-icon-btn outlined borderless icon="more_vert" @click="showDialog = true" />
</div>
<div class="w-full h-[calc(100%-40px)] overflow-y-auto relative" ref="logContainer">
<div v-if="!logs.length && !isLoading" class="flex items-center justify-center h-32 p-4">
<p class="text-gray-400">{{ $strings.MessageNoLogs }}</p>
</div>
<div v-if="hasScrolled" class="sticky top-0 left-0 w-full h-10 bg-gradient-to-t from-transparent to-bg z-10 pointer-events-none"></div>
<div v-for="(log, index) in logs" :key="log.id" class="py-2 px-4" :class="{ 'bg-white/5': index % 2 === 0 }">
<div class="flex items-center space-x-4 mb-1">
<div class="text-xs uppercase font-bold" :class="{ 'text-error': log.level === 'error', 'text-blue-500': log.level === 'info' }">{{ log.level }}</div>
<div class="text-xs text-gray-400">{{ formatEpochToDatetimeString(log.timestamp) }}</div>
<div class="flex-grow"></div>
<div class="text-xs text-gray-400">{{ log.tag }}</div>
</div>
<div class="text-xs">{{ maskServerAddress ? log.maskedMessage : log.message }}</div>
</div>
</div>
<modals-dialog v-model="showDialog" :items="dialogItems" @action="dialogAction" />
</div>
</template>
<script>
import { AbsLogger } from '@/plugins/capacitor'
import { FileSharer } from '@webnativellc/capacitor-filesharer'
export default {
data() {
return {
logs: [],
isLoading: true,
isCopied: false,
hasScrolled: false,
maskServerAddress: true,
showDialog: false
}
},
computed: {
dialogItems() {
return [
{
text: this.maskServerAddress ? this.$strings.ButtonUnmaskServerAddress : this.$strings.ButtonMaskServerAddress,
value: 'toggle-mask-server-address',
icon: this.maskServerAddress ? 'remove_moderator' : 'shield'
},
{
text: this.$strings.ButtonClearLogs,
value: 'clear-logs',
icon: 'delete'
}
]
}
},
methods: {
async dialogAction(action) {
await this.$hapticsImpact()
if (action === 'clear-logs') {
await AbsLogger.clearLogs()
this.logs = []
} else if (action === 'toggle-mask-server-address') {
this.maskServerAddress = !this.maskServerAddress
}
this.showDialog = false
},
toggleMaskServerAddress() {
this.maskServerAddress = !this.maskServerAddress
},
async copyToClipboard() {
await this.$hapticsImpact()
this.$copyToClipboard(this.getLogsString()).then(() => {
this.isCopied = true
setTimeout(() => {
this.isCopied = false
}, 2000)
})
},
/**
* Formats an epoch timestamp to YYYY-MM-DD HH:mm:ss.SSS
* Use 24 hour time format
* @param {number} epoch
* @returns {string}
*/
formatEpochToDatetimeString(epoch) {
return new Date(epoch)
.toLocaleString('en-US', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
fractionalSecondDigits: 3,
hour12: false
})
.replace(',', '')
},
getLogsString() {
return this.logs
.map((log) => {
const logMessage = this.maskServerAddress ? log.maskedMessage : log.message
return `${this.formatEpochToDatetimeString(log.timestamp)} [${log.level.toUpperCase()}] ${logMessage}`
})
.join('\n')
},
async shareLogs() {
await this.$hapticsImpact()
// Share .txt file with logs
const base64Data = Buffer.from(this.getLogsString()).toString('base64')
FileSharer.share({
filename: `abs_logs_${this.$platform}_${this.$config.version}.txt`,
contentType: 'text/plain',
base64Data
}).catch((error) => {
if (error.message !== 'USER_CANCELLED') {
console.error('Failed to share', error.message)
this.$toast.error('Failed to share: ' + error.message)
}
})
},
scrollToBottom() {
this.$refs.logContainer.scrollTop = this.$refs.logContainer.scrollHeight
this.hasScrolled = this.$refs.logContainer.scrollTop > 0
},
maskLogMessage(message) {
return message.replace(/(https?:\/\/)\S+/g, '$1[SERVER_ADDRESS]')
},
loadLogs() {
this.isLoading = true
AbsLogger.getAllLogs()
.then((logData) => {
const logs = logData.value || []
this.logs = logs.map((log) => {
log.maskedMessage = this.maskLogMessage(log.message)
return log
})
this.$nextTick(() => {
this.scrollToBottom()
})
this.isLoading = false
})
.catch((error) => {
this.isLoading = false
console.error('Failed to load logs', error)
this.$toast.error('Failed to load logs: ' + error.message)
})
}
},
mounted() {
AbsLogger.addListener('onLog', (log) => {
log.maskedMessage = this.maskLogMessage(log.message)
this.logs.push(log)
this.logs.sort((a, b) => a.timestamp - b.timestamp)
this.$nextTick(() => {
this.scrollToBottom()
})
})
this.loadLogs()
},
beforeDestroy() {
AbsLogger.removeAllListeners()
}
}
</script>
+21
View File
@@ -100,6 +100,13 @@
<p class="pl-4">{{ $strings.LabelDisableVibrateOnReset }}</p>
<span class="material-symbols text-xl ml-2" @click.stop="showInfo('disableSleepTimerResetFeedback')">info</span>
</div>
<div class="flex items-center py-3">
<div class="w-10 flex justify-center" @click="toggleSleepTimerAlmostDoneChime">
<ui-toggle-switch v-model="settings.enableSleepTimerAlmostDoneChime" @input="saveSettings" />
</div>
<p class="pl-4">{{ $strings.LabelSleepTimerAlmostDoneChime }}</p>
<span class="material-symbols text-xl ml-2" @click.stop="showInfo('enableSleepTimerAlmostDoneChime')">info</span>
</div>
<div class="flex items-center py-3">
<div class="w-10 flex justify-center" @click="toggleAutoSleepTimer">
<ui-toggle-switch v-model="settings.autoSleepTimer" @input="saveSettings" />
@@ -207,6 +214,7 @@ export default {
sleepTimerLength: 900000, // 15 minutes
disableSleepTimerFadeOut: false,
disableSleepTimerResetFeedback: false,
enableSleepTimerAlmostDoneChime: false,
autoSleepTimerAutoRewind: false,
autoSleepTimerAutoRewindTime: 300000, // 5 minutes
languageCode: 'en-us',
@@ -234,6 +242,10 @@ export default {
name: this.$strings.LabelDisableVibrateOnReset,
message: this.$strings.LabelDisableVibrateOnResetHelp
},
enableSleepTimerAlmostDoneChime: {
name: this.$strings.LabelSleepTimerAlmostDoneChime,
message: this.$strings.LabelSleepTimerAlmostDoneChimeHelp
},
autoSleepTimerAutoRewind: {
name: this.$strings.LabelAutoSleepTimerAutoRewind,
message: this.$strings.LabelAutoSleepTimerAutoRewindHelp
@@ -351,6 +363,10 @@ export default {
},
themeOptionItems() {
return [
{
text: this.$strings.LabelThemeBlack,
value: 'black'
},
{
text: this.$strings.LabelThemeDark,
value: 'dark'
@@ -549,6 +565,10 @@ export default {
this.settings.disableSleepTimerResetFeedback = !this.settings.disableSleepTimerResetFeedback
this.saveSettings()
},
toggleSleepTimerAlmostDoneChime() {
this.settings.enableSleepTimerAlmostDoneChime = !this.settings.enableSleepTimerAlmostDoneChime
this.saveSettings()
},
toggleDisableAutoRewind() {
this.settings.disableAutoRewind = !this.settings.disableAutoRewind
this.saveSettings()
@@ -620,6 +640,7 @@ export default {
this.settings.sleepTimerLength = !isNaN(deviceSettings.sleepTimerLength) ? deviceSettings.sleepTimerLength : 900000 // 15 minutes
this.settings.disableSleepTimerFadeOut = !!deviceSettings.disableSleepTimerFadeOut
this.settings.disableSleepTimerResetFeedback = !!deviceSettings.disableSleepTimerResetFeedback
this.settings.enableSleepTimerAlmostDoneChime = !!deviceSettings.enableSleepTimerAlmostDoneChime
this.settings.autoSleepTimerAutoRewind = !!deviceSettings.autoSleepTimerAutoRewind
this.settings.autoSleepTimerAutoRewindTime = !isNaN(deviceSettings.autoSleepTimerAutoRewindTime) ? deviceSettings.autoSleepTimerAutoRewindTime : 300000 // 5 minutes
+4
View File
@@ -1,4 +1,5 @@
import { registerPlugin, WebPlugin } from '@capacitor/core'
import { AbsLogger } from '@/plugins/capacitor'
import { nanoid } from 'nanoid'
const { PlayerState } = require('../constants')
@@ -88,6 +89,9 @@ class AbsAudioPlayerWeb extends WebPlugin {
return
}
// For testing onLog events in web while on the logs page
AbsLogger.info({ tag: 'AbsAudioPlayer', message: 'playPause' })
if (this.player.paused) this.player.play()
else this.player.pause()
return {
+55
View File
@@ -0,0 +1,55 @@
import { registerPlugin, WebPlugin } from '@capacitor/core'
class AbsLoggerWeb extends WebPlugin {
constructor() {
super()
this.logs = []
}
saveLog(level, tag, message) {
const log = {
id: Math.random().toString(36).substring(2, 15),
tag: tag,
timestamp: Date.now(),
level: level,
message: message
}
this.logs.push(log)
this.notifyListeners('onLog', log)
}
// PluginMethod
async info(data) {
if (data?.message) {
this.saveLog('info', data.tag || '', data.message)
console.log('AbsLogger: info', `[${data.tag || ''}]:`, data.message)
}
}
// PluginMethod
async error(data) {
if (data?.message) {
this.saveLog('error', data.tag || '', data.message)
console.error('AbsLogger: error', `[${data.tag || ''}]:`, data.message)
}
}
// PluginMethod
async getAllLogs() {
return {
value: this.logs
}
}
// PluginMethod
async clearLogs() {
this.logs = []
}
}
const AbsLogger = registerPlugin('AbsLogger', {
web: () => new AbsLoggerWeb()
})
export { AbsLogger }
+2 -5
View File
@@ -2,12 +2,9 @@ import Vue from 'vue'
import { AbsAudioPlayer } from './AbsAudioPlayer'
import { AbsDownloader } from './AbsDownloader'
import { AbsFileSystem } from './AbsFileSystem'
import { AbsLogger } from './AbsLogger'
import { Capacitor } from '@capacitor/core'
Vue.prototype.$platform = Capacitor.getPlatform()
export {
AbsAudioPlayer,
AbsDownloader,
AbsFileSystem
}
export { AbsAudioPlayer, AbsDownloader, AbsFileSystem, AbsLogger }
-6
View File
@@ -16,12 +16,6 @@ if (Capacitor.getPlatform() != 'web') {
await StatusBar.setStyle({ style: Style.Dark })
}
setStatusBarStyleDark()
const setStatusBarOverlays = async () => {
// Defaults to true in capacitor v7
await StatusBar.setOverlaysWebView({ overlay: false })
}
setStatusBarOverlays()
}
Vue.prototype.$showHideStatusBar = async (show) => {
+298 -11
View File
@@ -6,12 +6,13 @@
"ButtonCancel": "إلغاء",
"ButtonCancelTimer": "إلغاء المؤقت",
"ButtonClearFilter": "تصفية الفرز",
"ButtonClearLogs": "مسح السجل",
"ButtonCloseFeed": "إغلاق",
"ButtonCollections": "المجموعات",
"ButtonConnect": "اتصل",
"ButtonConnectToServer": "اتصال بالخادم",
"ButtonCreate": "إنشاء",
"ButtonCreateBookmark": "إنشاء إشارة مرجعية",
"ButtonCreateBookmark": "إنشاء علامة مرجعية",
"ButtonCreateNewPlaylist": "إنشاء قائمة تشغيل جديدة",
"ButtonDelete": "حذف",
"ButtonDeleteLocalEpisode": "احذف الحلقة المحلية",
@@ -20,24 +21,27 @@
"ButtonDisableAutoTimer": "تعطيل المؤقت التلقائي",
"ButtonDisconnect": "فصل",
"ButtonGoToWebClient": "اذهب إلى عميل الويب",
"ButtonHistory": "تاريخ",
"ButtonHistory": "السجل التاريخي",
"ButtonHome": "الرئيسية",
"ButtonIssues": "مشاكل",
"ButtonLatest": "أحدث",
"ButtonLatest": "الأحدث",
"ButtonLibrary": "المكتبة",
"ButtonLocalMedia": "ملفات الوسائط المحلية",
"ButtonLocalMedia": "الوسائط المحلية",
"ButtonLogs": "سجلات",
"ButtonManageLocalFiles": "إدارة الملفات المحلية",
"ButtonMaskServerAddress": "إخفاء عنوان الخادم",
"ButtonNewFolder": "مجلد جديد",
"ButtonNextEpisode": "الحلقة التالية",
"ButtonOk": "موافق",
"ButtonOpenFeed": "فتح التغذية",
"ButtonOverride": "تجاوز",
"ButtonPause": "تَوَقَّف",
"ButtonPause": "إيقاف مؤقت",
"ButtonPlay": "تشغيل",
"ButtonPlayEpisode": "شغل الحلقة",
"ButtonPlayEpisode": "تشغيل الحلقة",
"ButtonPlaylists": "قوائم التشغيل",
"ButtonRead": "اقرأ",
"ButtonReadLess": "قلص",
"ButtonReadMore": "المزيد",
"ButtonReadLess": "اقرأ أقل",
"ButtonReadMore": "اقرأ أكثر",
"ButtonRemove": "إزالة",
"ButtonRemoveFromServer": "إزالة من الخادم",
"ButtonSave": "حفظ",
@@ -47,21 +51,304 @@
"ButtonSeries": "سلسلة",
"ButtonSetTimer": "اضبط مؤقت",
"ButtonStream": "بث",
"ButtonSubmit": "تقديم",
"ButtonSubmit": "إرسال",
"ButtonSwitchServerUser": "تبديل الخادم/المستخدم",
"ButtonUnmaskServerAddress": "إظهار عنوان الخادم",
"ButtonUserStats": "إحصائيات المستخدم",
"ButtonYes": "نعم",
"HeaderAccount": "الحساب",
"HeaderAdvanced": "متقدم",
"HeaderAudioTracks": "المسارات الصوتية",
"HeaderAndroidAutoSettings": "إعدادات أندرويد للسيارة",
"HeaderAudioTracks": "المقاطع الصوتية",
"HeaderChapters": "الفصول",
"HeaderCollection": "مجموعة",
"HeaderCollectionItems": "عناصر المجموعة",
"HeaderConnectionStatus": "حالة الاتصال",
"HeaderDataSettings": "إعدادات البيانات",
"HeaderDetails": "التفاصيل",
"HeaderDownloads": "التنزيلات",
"HeaderEbookFiles": "ملفات الكتب الإلكترونية",
"HeaderEpisodes": "الحلقات",
"HeaderEreaderSettings": "إعدادات القارئ الإلكتروني",
"HeaderLatestEpisodes": "أحدث الحلقات",
"HeaderLibraries": "المكتبات"
"HeaderLibraries": "المكتبات",
"HeaderLocalFolders": "المجلدات المحلية",
"HeaderLocalLibraryItems": "عناصر المكتبة المحلية",
"HeaderNewPlaylist": "قائمة تشغيل جديدة",
"HeaderOpenRSSFeed": "عرض تغذية RSS",
"HeaderPlaybackSettings": "إعدادات التشغيل",
"HeaderPlaylist": "قائمة تشغيل",
"HeaderPlaylistItems": "عناصر قائمة التشغيل",
"HeaderProgressSyncFailed": "فشلت المزامنة",
"HeaderRSSFeed": "تغذية RSS",
"HeaderRSSFeedGeneral": "تفاصيل RSS",
"HeaderRSSFeedIsOpen": "مغذي RSS مفتوح",
"HeaderSelectDownloadLocation": "حدد موقع التنزيل",
"HeaderSettings": "إعدادات",
"HeaderSleepTimer": "مؤقت النوم",
"HeaderSleepTimerSettings": "إعدادات مؤقت النوم",
"HeaderStatsMinutesListeningChart": "الدقائق المسموعة (آخر 7 أيام)",
"HeaderStatsRecentSessions": "الجلسات الأخيرة",
"HeaderTableOfContents": "جدول المحتويات",
"HeaderUserInterfaceSettings": "إعدادات واجهة المستخدم",
"HeaderYourStats": "إحصائياتك",
"LabelAddToPlaylist": "أضف إلى قائمة التشغيل",
"LabelAddedAt": "أضيفت على",
"LabelAddedDate": "تمت الإضافة",
"LabelAll": "الكل",
"LabelAllowSeekingOnMediaControls": "السماح بالبحث عن الموضع في التحكم بإشعارات الوسائط",
"LabelAlways": "دائماً",
"LabelAndroidAutoBrowseLimitForGrouping": "حد السحب الأبجدي",
"LabelAndroidAutoBrowseLimitForGroupingHelp": "لا تستخدم السحب الأبجدي عندما يكون عدد العناصر المراد عرضها أقل من هذا العدد",
"LabelAndroidAutoBrowseSeriesSequenceOrder": "ترتيب كتب السلسلة",
"LabelAskConfirmation": "اطلب التأكيد",
"LabelAuthor": "المؤلف",
"LabelAuthorFirstLast": "المؤلف (الاسم الأول الأخير)",
"LabelAuthorLastFirst": "المؤلف (الاسم الأخير، الأول)",
"LabelAuthors": "المؤلفون",
"LabelAutoDownloadEpisodes": "تنزيل الحلقات تلقائيًا",
"LabelAutoRewindTime": "إعادة الوقت تلقائياَ",
"LabelAutoSleepTimer": "مؤقت النوم التلقائي",
"LabelAutoSleepTimerAutoRewind": "مؤقتا النوم والإرجاع التلقائيين",
"LabelAutoSleepTimerAutoRewindHelp": "عندما ينتهي مؤقت النوم التلقائي، فإن تشغيل العنصر مرة أخرى سيؤدي إلى الإرجاع التلقائي.",
"LabelAutoSleepTimerHelp": "عند تشغيل الوسائط بين أوقات البداية والنهاية المحددة، سيبدأ مؤقت النوم تلقائيًا.",
"LabelBooks": "الكتب",
"LabelChapterTrack": "مسار الفصل",
"LabelChapters": "الفصول",
"LabelClosePlayer": "إغلاق المشغل",
"LabelCollapseSeries": "إخفاء المسلسلات",
"LabelComplete": "مكتمل",
"LabelContinueBooks": "استمرار الكتب",
"LabelContinueEpisodes": "استمرار الحلقات",
"LabelContinueListening": "استمرار الاستماع",
"LabelContinueReading": "استمرار القراءة",
"LabelContinueSeries": "استمرار المسلسلات",
"LabelCustomTime": "الوقت المخصص",
"LabelDescription": "الوصف",
"LabelDisableAudioFadeOut": "تعطيل التلاشي الصوتي",
"LabelDisableAudioFadeOutHelp": "سيبدأ مستوى الصوت بالانخفاض عندما يتبقى أقل من دقيقة واحدة على مؤقت النوم. فعّل هذا الإعداد لعدم التلاشي.",
"LabelDisableAutoRewind": "تعطيل الإعادة التلقائية",
"LabelDisableShakeToReset": "تعطيل الرج لإعادة الضبط",
"LabelDisableShakeToResetHelp": "سيؤدي هزّ جهازك أثناء تشغيل المؤقت أو خلال دقيقتين من انتهاءه إلى إعادة ضبط مؤقت النوم. فعّل هذا الإعداد لتعطيل الرج لإعادة الضبط.",
"LabelDisableVibrateOnReset": "تعطيل الاهتزاز عند إعادة الضبط",
"LabelDisableVibrateOnResetHelp": "عند إعادة ضبط مؤقت النوم، سيهتز جهازك. فعّل هذا الإعداد لعدم الاهتزاز عند إعادة ضبط مؤقت النوم.",
"LabelDiscover": "استكشف",
"LabelDownload": "تنزيل",
"LabelDownloadUsingCellular": "التنزيل عبر بيانات الهاتف",
"LabelDownloaded": "تم تنزيلها",
"LabelDuration": "المدة",
"LabelEbook": "الكتاب الإلكتروني",
"LabelEbooks": "الكتب الإلكترونية",
"LabelEnable": "تمكين",
"LabelEnableMp3IndexSeeking": "تمكين البحث عن فهرس mp3",
"LabelEnableMp3IndexSeekingHelp": "يجب تفعيل هذا الإعداد فقط إذا كانت ملفات MP3 لديك لا تعمل بشكل صحيح. غالبًا ما يكون البحث غير الدقيق ناتجًا عن ملفات MP3 ذات معدل البت المتغير (VBR). سيفرض هذا الإعداد البحث عن الفهرس، حيث يتم إنشاء تعيين زمني للبايت أثناء قراءة الملف. في بعض الحالات، مع ملفات MP3 كبيرة الحجم، قد يكون هناك تأخير عند البحث قرب نهاية الملف.",
"LabelEnd": "انهاء",
"LabelEndOfChapter": "نهاية الفصل",
"LabelEndTime": "وقت النهاية",
"LabelEpisode": "الحلقة",
"LabelFeedURL": "عنوان التغذية",
"LabelFile": "الملف",
"LabelFileBirthtime": "وقت انشاء الملف",
"LabelFileModified": "تم تعديل الملف",
"LabelFilename": "اسم الملف",
"LabelFinished": "المنجزة",
"LabelFolder": "المجلد",
"LabelFontBoldness": "تعريض الخط",
"LabelFontScale": "نطاق الخط",
"LabelGenre": "التصنيف",
"LabelGenres": "التصانيف",
"LabelHapticFeedback": "ردود الفعل اللمسية",
"LabelHasEbook": "يحتوي كتاب إلكتروني",
"LabelHasSupplementaryEbook": "يحتوي كتاب إلكتروني تكميلي",
"LabelHeavy": "ثقيل",
"LabelHigh": "مرتفع",
"LabelHost": "المضيف",
"LabelInProgress": "تحت التنفيذ",
"LabelIncomplete": "غير مكتمل",
"LabelInternalAppStorage": "وحدة تخزين التطبيق الداخلي",
"LabelJumpBackwardsTime": "وقت القفز للخلف",
"LabelJumpForwardsTime": "وقت القفز للأمام",
"LabelKeepScreenAwake": "إبقاء الشاشة يقظة",
"LabelLanguage": "اللغة",
"LabelLayout": "التنسيق",
"LabelLayoutAuto": "تلقائي",
"LabelLayoutSinglePage": "صفحة واحدة",
"LabelLight": "فاتح",
"LabelLineSpacing": "تباعد الأسطر",
"LabelListenAgain": "الاستماع مجدداً",
"LabelLocalBooks": "الكتب المحلية",
"LabelLocalPodcasts": "المدونات الصوتية المحلية",
"LabelLockOrientation": "قفل الاتجاه",
"LabelLockPlayer": "قفل المشغل",
"LabelLow": "منخفض",
"LabelMediaType": "نوع الوسائط",
"LabelMedium": "متوسط",
"LabelMissing": "مفقود",
"LabelMore": "أكثر",
"LabelMoreInfo": "معلومات أكثر",
"LabelName": "الاسم",
"LabelNarrator": "الراوي",
"LabelNarrators": "الرواة",
"LabelNavigateWithVolume": "التنقل بمفاتيح التحكم بالصوت",
"LabelNavigateWithVolumeMirrored": "معكوس",
"LabelNavigateWithVolumeWhilePlaying": "السماح لمفاتيح التحكم بالصوت بالتنقل أثناء التشغيل",
"LabelNavigateWithVolumeWhilePlayingDisabled": "إيقاف",
"LabelNavigateWithVolumeWhilePlayingEnabled": "مُفعَّل",
"LabelNever": "أبداً",
"LabelNewestAuthors": "أجدد المؤلفين",
"LabelNewestEpisodes": "أجدد الحلقات",
"LabelNo": "لا",
"LabelNotFinished": "لم يتم الانتهاء",
"LabelNotStarted": "لم يتم البدء",
"LabelNumEpisodes": "{0} حلقات",
"LabelNumEpisodesIncomplete": "{0} حلقات، {1} غير مكتمل",
"LabelNumberOfEpisodes": "# من الحلقات",
"LabelOff": "ايقاف",
"LabelOn": "مُفعَّل",
"LabelPassword": "كلمة المرور",
"LabelPath": "مسار",
"LabelPlaybackDirect": "مباشر",
"LabelPlaybackLocal": "محلي",
"LabelPlaybackSpeed": "سرعة التشغيل",
"LabelPlaybackTranscode": "تحويل الترميز",
"LabelPodcast": "مدونة صوتية",
"LabelPodcasts": "بودكاست",
"LabelPreventIndexing": "منع فهرسة تغذيتك بواسطة دليل آيتونز وقوقل بودكاست",
"LabelProgress": "تقدم",
"LabelPubDate": "تاريخ النشر",
"LabelPublishYear": "سنة النشر",
"LabelPublishedDate": "منشور {0}",
"LabelRSSFeedCustomOwnerEmail": "البريد الالكتروني المخصص للمالك",
"LabelRSSFeedCustomOwnerName": "الاسم المخصص للمالك",
"LabelRSSFeedOpen": "موجز RSS مفتوح",
"LabelRSSFeedPreventIndexing": "منع الفهرسة",
"LabelRSSFeedSlug": "اسم تعريف تغذية RSS",
"LabelRandomly": "عشوائياً",
"LabelRead": "اقرأ",
"LabelReadAgain": "اقرأ مرة أخرى",
"LabelRecentSeries": "المسلسلات الحديثة",
"LabelRecentlyAdded": "المضافة حديثاً",
"LabelRemoveFromPlaylist": "إزالة من قائمة التشغيل",
"LabelScaleElapsedTimeBySpeed": "تعديل الوقت المنصرم حسب السرعة",
"LabelSeason": "الموسم",
"LabelSelectADevice": "اختيار جهاز",
"LabelSequenceAscending": "تسلسل تصاعدي",
"LabelSequenceDescending": "تسلسل تنازلي",
"LabelSeries": "المسلسلات",
"LabelServerAddress": "عنوان الخادم",
"LabelSetEbookAsPrimary": "تعيين كرئيسي",
"LabelSetEbookAsSupplementary": "تعيين كتكميلي",
"LabelShakeSensitivity": "حساسية الرج",
"LabelShowAll": "إظهار الكل",
"LabelSize": "الحجم",
"LabelSleepTimer": "مؤقت النوم",
"LabelSleepTimerAlmostDoneChime": "تشغيل نغمة عند اقتراب النهاية",
"LabelSleepTimerAlmostDoneChimeHelp": "تشغيل نغمة عندما يتبقى 30 ثانية على مؤقت النوم",
"LabelStart": "ابدأ",
"LabelStartTime": "وقت البدء",
"LabelStatsBestDay": "أفضل يوم",
"LabelStatsDailyAverage": "المتوسط اليومي",
"LabelStatsDays": "أيام",
"LabelStatsDaysListened": "أيام الاستماع",
"LabelStatsInARow": "على التوالي",
"LabelStatsItemsFinished": "العناصر المنتهية",
"LabelStatsMinutes": "دقائق",
"LabelStatsMinutesListening": "دقائق الاستماع",
"LabelStatsWeekListening": "استماع هذا الأسبوع",
"LabelStreamingUsingCellular": "البث عبر شبكة الجوال",
"LabelTag": "علامة",
"LabelTags": "علامات",
"LabelTheme": "النمط",
"LabelThemeBlack": "أسود",
"LabelThemeDark": "غامق",
"LabelThemeLight": "فاتح",
"LabelTimeRemaining": "{0} متبقية",
"LabelTitle": "عنوان",
"LabelTotalSize": "الحجم الكلي",
"LabelTotalTrack": "إجمالي المسارات",
"LabelTracks": "المسارات",
"LabelType": "نوع",
"LabelUnknown": "مجهول",
"LabelUnlockPlayer": "تفعيل المشغل",
"LabelUseBookshelfView": "تفعيل عرض الرف",
"LabelUser": "مستخدم",
"LabelUsername": "اسم المستخدم",
"LabelVeryHigh": "عالي جدًا",
"LabelVeryLow": "منخفض جدًا",
"LabelYearReviewHide": "إخفاء ملخص العام",
"LabelYearReviewShow": "عرض ملخص العام",
"LabelYourBookmarks": "علاماتك المرجعية",
"LabelYourProgress": "تقدمك",
"MessageAndroid10Downloads": "سيستخدم نظام أندرويد 10 والإصدارات الأقدم وحدة التخزين الداخلية.",
"MessageAttemptingServerConnection": "جاري محاولة الاتصال بالخادم...",
"MessageAudiobookshelfServerNotConnected": "خادم Audiobookshelf غير متصل",
"MessageAudiobookshelfServerRequired": "<strong>مهم!</strong> هذا التطبيق مصمم للعمل مع خادم Audiobookshelf تستضيفه أنت أو شخص تعرفه. هذا التطبيق لا يقدم أي محتوى.",
"MessageBookshelfEmpty": "الرف فارغ",
"MessageConfirmDeleteLocalEpisode": "هل تريد بالتأكيد إزالة الحلقة المحلية \"{0}\" من جهازك؟ لن يتأثر الملف الموجود على الخادم.",
"MessageConfirmDeleteLocalFiles": "هل تريد بالتأكيد إزالة الملفات المحلية لهذا العنصر من جهازك؟ الملفات الموجودة على الخادم وتقدمك لن يتأثرا.",
"MessageConfirmDisableAutoTimer": "هل أنت متأكد أنك تريد تعطيل المؤقت التلقائي لبقية اليوم؟ سيتم إعادة تفعيل المؤقت في نهاية فترة مؤقت النوم التلقائي هذه، أو إذا قمت بإعادة تشغيل التطبيق.",
"MessageConfirmDiscardProgress": "هل أنت متأكد أنك تريد إعادة تعيين تقدمك؟",
"MessageConfirmDownloadUsingCellular": "أنت على وشك التنزيل باستخدام بيانات الجوال. قد يشمل ذلك رسوم استخدام بيانات من شركة الاتصالات. هل ترغب في المتابعة؟",
"MessageConfirmMarkAsFinished": "هل أنت متأكد أنك تريد وضع علامة \"مكتمل\" على هذا العنصر؟",
"MessageConfirmRemoveBookmark": "هل أنت متأكد أنك تريد إزالة العلامة المرجعية؟",
"MessageConfirmStreamingUsingCellular": "أنت على وشك البث باستخدام بيانات الجوال. قد يشمل ذلك رسوم استخدام بيانات من شركة الاتصالات. هل ترغب في المتابعة؟",
"MessageDiscardProgress": "إلغاء التقدم",
"MessageDownloadCompleteProcessing": "اكتمل التنزيل. جاري المعالجة...",
"MessageDownloading": "جاري التنزيل...",
"MessageDownloadingEpisode": "جاري تنزيل الحلقة",
"MessageEpisodesQueuedForDownload": "تمت إضافة {0} حلقة (حلقات) إلى قائمة انتظار التنزيل",
"MessageFeedURLWillBe": "سيكون رابط التغذية هو {0}",
"MessageFetching": "جاري الجلب...",
"MessageFollowTheProjectOnGithub": "تابع المشروع على Github",
"MessageItemDownloadCompleteFailedToCreate": "اكتمل تنزيل العنصر ولكن فشل إنشاء عنصر المكتبة",
"MessageItemMissing": "العنصر مفقود ويجب إصلاحه على الخادم. عادةً ما يتم وضع علامة \"مفقود\" على العنصر لأن مسارات الملفات غير قابلة للوصول.",
"MessageLoading": "جاري التحميل...",
"MessageLoadingServerData": "جاري تحميل بيانات الخادم...",
"MessageLocalFolderDescription": "\"وحدة تخزين التطبيق الداخلية\" لا يمكن الوصول إليها إلا بواسطة هذا التطبيق. هذا التطبيق يدعم فقط الوسائط التي تم تنزيلها مباشرةً من خلال التطبيق. يمكن استخدام مجلدات التخزين المشتركة للسماح لتطبيقات أخرى بالوصول إلى الوسائط التي تم تنزيلها بواسطة هذا التطبيق.",
"MessageMarkAsFinished": "وضع علامة \"تم الإنتهاء\"",
"MessageMediaLinkedToADifferentServer": "الوسائط مرتبطة بخادم Audiobookshelf على عنوان مختلف ({0}). ستتم مزامنة التقدم عند الاتصال بعنوان هذا الخادم.",
"MessageMediaLinkedToADifferentUser": "الوسائط مرتبطة بهذا الخادم ولكن تم تنزيلها بواسطة مستخدم مختلف. ستتم مزامنة التقدم فقط مع المستخدم الذي قام بتنزيلها.",
"MessageMediaLinkedToServer": "مرتبط بالخادم {0}",
"MessageMediaLinkedToThisServer": "الوسائط التي تم تنزيلها مرتبطة بهذا الخادم",
"MessageMediaNotLinkedToServer": "الوسائط غير مرتبطة بخادم Audiobookshelf. لن تتم مزامنة أي تقدم.",
"MessageNoBookmarks": "لا توجد علامات مرجعية",
"MessageNoChapters": "لا توجد فصول",
"MessageNoCollections": "لا توجد مجموعات",
"MessageNoItems": "لا توجد عناصر",
"MessageNoItemsFound": "لم يتم العثور على عناصر",
"MessageNoListeningSessions": "لا توجد جلسات استماع",
"MessageNoLogs": "لا توجد سجلات",
"MessageNoMediaFolders": "لا توجد مجلدات وسائط",
"MessageNoNetworkConnection": "لا يوجد اتصال بالشبكة",
"MessageNoPodcastsFound": "لم يتم العثور على أي بودكاست",
"MessageNoSeries": "لا توجد سلاسل",
"MessageNoUpdatesWereNecessary": "لا حاجة لأي تحديثات",
"MessageNoUserPlaylists": "ليس لديك أي قوائم تشغيل",
"MessageOldServerConnectionWarning": "تكوين اتصال الخادم يستخدم معرّف مستخدم قديم. يرجى حذف اتصال الخادم هذا وإعادة إضافته.",
"MessageOldServerConnectionWarningHelp": "لقد قمتَ بإعداد الاتصال بهذا الخادم قبل ترحيل قاعدة البيانات في الإصدار 2.3.0، الصادر في يونيو 2023. سيؤدي تحديث الخادم المستقبلي إلى إلغاء إمكانية تسجيل الدخول باستخدام هذا الاتصال القديم. يُرجى حذف اتصال الخادم الحالي والاتصال مرة أخرى (باستخدام نفس عنوان الخادم وبيانات الاعتماد). إذا كانت لديك أي وسائط مُنزّلة على هذا الجهاز، فيجب تنزيلها مرة أخرى لمزامنتها مع الخادم.",
"MessagePodcastSearchField": "أدخل مصطلح البحث أو عنوان URL الخاص بتغذية RSS",
"MessageProgressSyncFailed": "فشلت آخر محاولة لإرسال تقدم استماعك إلى الخادم. ستستمر محاولات مزامنة التقدم كل 15 ثانية إلى دقيقة واحدة أثناء تشغيل الوسائط.",
"MessageReportBugsAndContribute": "أبلغ عن الأخطاء، واطلب الميزات، وساهم في",
"MessageSeriesAlreadyDownloaded": "لقد قمت بالفعل بتنزيل جميع الكتب في هذه السلسلة.",
"MessageSeriesDownloadConfirm": "هل تريد تنزيل {0} كتابًا (كتب) مفقودًا (مفقودة) مع {1} ملفًا (ملفات)، بإجمالي {2} إلى المجلد {3}؟",
"MessageSeriesDownloadConfirmIos": "هل تريد تنزيل {0} كتابًا (كتب) مفقودًا (مفقودة) مع {1} ملفًا (ملفات)، بإجمالي {2}؟",
"MessageSocketConnectedOverMeteredCellular": "تم توصيل المقبس عبر شبكة الجوال ذات الاستهلاك المحدود",
"MessageSocketConnectedOverMeteredWifi": "تم توصيل المقبس عبر شبكة الواي فاي ذات الاستهلاك المحدود",
"MessageSocketConnectedOverUnmeteredCellular": "تم توصيل المقبس عبر شبكة الجوال غير ذات الاستهلاك المحدود",
"MessageSocketConnectedOverUnmeteredWifi": "المقبس متصل عبر شبكة واي فاي غير محدودة",
"MessageSocketNotConnected": "المقبس غير متصل",
"NoteRSSFeedPodcastAppsHttps": "تحذير: تتطلب معظم تطبيقات البث الصوتي أن يكون عنوان URL الخاص بتغذية RSS يستخدم HTTPS",
"NoteRSSFeedPodcastAppsPubDate": "تحذير: حلقة واحدة أو أكثر من حلقاتك ليس لها تاريخ نشر. بعض تطبيقات البودكاست تتطلب هذا.",
"ToastBookmarkCreateFailed": "فشل في إنشاء الإشارة المرجعية",
"ToastBookmarkRemoveFailed": "فشل في إزالة الإشارة المرجعية",
"ToastBookmarkUpdateFailed": "فشل في تحديث الإشارة المرجعية",
"ToastDownloadNotAllowedOnCellular": "لا يسمح بالتنزيل على البيانات الخلوية",
"ToastItemMarkedAsFinishedFailed": "فشل وضع علامة \"مكتمل\"",
"ToastItemMarkedAsNotFinishedFailed": "فشل وضع علامة \"غير مكتمل\"",
"ToastPlaylistCreateFailed": "فشل إنشاء قائمة التشغيل",
"ToastPodcastCreateFailed": "فشل إنشاء البودكاست",
"ToastPodcastCreateSuccess": "تم إنشاء البودكاست بنجاح",
"ToastRSSFeedCloseFailed": "فشل إغلاق مغذّي RSS",
"ToastRSSFeedCloseSuccess": "تم إغلاق مغذّي RSS",
"ToastStreamingNotAllowedOnCellular": "لا يُسمح بالبث عبر البيانات الخلوية"
}
+28 -13
View File
@@ -1,19 +1,20 @@
{
"ButtonAdd": "Afegir",
"ButtonAddNewServer": "Afegir un nou servidor",
"ButtonAdd": "Afegeix",
"ButtonAddNewServer": "Afegeix un servidor nou",
"ButtonAuthors": "Autors",
"ButtonBack": "Enrere",
"ButtonCancel": "Cancel·lar",
"ButtonCancelTimer": "Cancel·lar el temporitzador",
"ButtonClearFilter": "Eliminar filtres",
"ButtonCloseFeed": "Tancar font",
"ButtonCancel": "Cancel·la",
"ButtonCancelTimer": "Cancel·la el temporitzador",
"ButtonClearFilter": "Neteja el filtre",
"ButtonClearLogs": "Neteja els registres",
"ButtonCloseFeed": "Tanca el canal",
"ButtonCollections": "Col·leccions",
"ButtonConnect": "Connectar",
"ButtonConnectToServer": "Connectar al servidor",
"ButtonCreate": "Crear",
"ButtonConnect": "Connecta",
"ButtonConnectToServer": "Connecta al servidor",
"ButtonCreate": "Crea",
"ButtonCreateBookmark": "Crear marcador",
"ButtonCreateNewPlaylist": "Crear una nova llista de reproducció",
"ButtonDelete": "Eliminar",
"ButtonDelete": "Suprimeix",
"ButtonDeleteLocalEpisode": "Esborrar episodi local",
"ButtonDeleteLocalFile": "Esborrar fitxer local",
"ButtonDeleteLocalItem": "Esborrar element local",
@@ -26,7 +27,9 @@
"ButtonLatest": "Últims",
"ButtonLibrary": "Biblioteca",
"ButtonLocalMedia": "Mitjans locals",
"ButtonLogs": "Registres",
"ButtonManageLocalFiles": "Gestionar fitxers locals",
"ButtonMaskServerAddress": "Emmascara l'adreça del servidor",
"ButtonNewFolder": "Nova carpeta",
"ButtonNextEpisode": "Pròxim episodi",
"ButtonOk": "Dacord",
@@ -50,6 +53,7 @@
"ButtonStream": "En directe",
"ButtonSubmit": "Enviar",
"ButtonSwitchServerUser": "Canviar servidor/usuari",
"ButtonUnmaskServerAddress": "Desemmascara l'adreça del servidor",
"ButtonUserStats": "Estadístiques de l'usuari",
"ButtonYes": "Sí",
"HeaderAccount": "Compte",
@@ -88,7 +92,7 @@
"HeaderTableOfContents": "Sumari",
"HeaderUserInterfaceSettings": "Paràmetres de la interfície d'usuari",
"HeaderYourStats": "Les vostres estadístiques",
"LabelAddToPlaylist": "Afegit a la llista de reproducció",
"LabelAddToPlaylist": "Afegeix a la llista de reproducció",
"LabelAddedAt": "Afegit a",
"LabelAddedDate": "Afegits {0}",
"LabelAll": "Tots",
@@ -142,6 +146,7 @@
"LabelEpisode": "Episodi",
"LabelFeedURL": "Font URL",
"LabelFile": "Fitxer",
"LabelFileBirthtime": "Fitxer creat a",
"LabelFileModified": "Fitxer modificat",
"LabelFilename": "Nom del fitxer",
"LabelFinished": "Acabat",
@@ -194,9 +199,12 @@
"LabelPlaybackSpeed": "Velocitat de reproducció",
"LabelPodcast": "Pòdcast",
"LabelPodcasts": "Pòdcasts",
"LabelPreventIndexing": "Evita que el vostre canal l'indexin els directoris de pòdcasts de l'iTunes i Google",
"LabelProgress": "Progrés",
"LabelPubDate": "Data de publicació",
"LabelPublishYear": "Any de publicació",
"LabelRSSFeedPreventIndexing": "Evita la indexació",
"LabelRSSFeedSlug": "URL semàntic del canal RSS",
"LabelRandomly": "A l'atzar",
"LabelRead": "Llegit",
"LabelReadAgain": "Tornar a llegir",
@@ -204,7 +212,7 @@
"LabelRecentlyAdded": "Addicions recents",
"LabelRemoveFromPlaylist": "Eliminar de la llista de reproducció",
"LabelSelectADevice": "Seleccioneu un dispositiu",
"LabelSeries": "Sèries",
"LabelSeries": "Sèrie",
"LabelServerAddress": "Adreça del servidor",
"LabelShowAll": "Mostra-ho tot",
"LabelSize": "Mida",
@@ -242,6 +250,7 @@
"MessageDownloadCompleteProcessing": "S'ha completat la baixada. S'està processant...",
"MessageDownloading": "S'està baixant...",
"MessageDownloadingEpisode": "S'està baixant l'episodi",
"MessageFeedURLWillBe": "L'URL del canal serà {0}",
"MessageFetching": "S'està recuperant...",
"MessageFollowTheProjectOnGithub": "Seguiu el projecte al GitHub",
"MessageLoading": "S'està carregant...",
@@ -254,15 +263,21 @@
"MessageNoItems": "Cap element",
"MessageNoItemsFound": "Cap element trobat",
"MessageNoListeningSessions": "Cap sessió d'escolta",
"MessageNoLogs": "Cap registre",
"MessageNoMediaFolders": "Cap carpeta multimèdia",
"MessageNoNetworkConnection": "Cap connexió de xarxa",
"MessageNoPodcastsFound": "No s'ha trobat cap pòdcast",
"MessageNoSeries": "Cap sèrie",
"MessageNoUpdatesWereNecessary": "No calia cap actualització",
"MessageNoUserPlaylists": "No teniu cap llista de reproducció",
"MessagePodcastSearchField": "Introduïu el terme de cerca o l'URL del canal RSS",
"NoteRSSFeedPodcastAppsHttps": "Avís: la majoria d'aplicacions de pòdcast requereixen que l'URL del canal RSS utilitzi HTTPS",
"NoteRSSFeedPodcastAppsPubDate": "Avís: un o més dels vostres episodis no tenen data de publicació. Algunes aplicacions de pòdcast ho requereixen.",
"ToastItemMarkedAsFinishedFailed": "No s'ha pogut marcar com a finalitzat",
"ToastItemMarkedAsNotFinishedFailed": "No s'ha pogut marcar com a no finalitzat",
"ToastPlaylistCreateFailed": "No s'ha pogut crear la llista de reproducció",
"ToastPodcastCreateFailed": "No s'ha pogut crear el pòdcast",
"ToastPodcastCreateSuccess": "S'ha creat el pòdcast correctament"
"ToastPodcastCreateSuccess": "S'ha creat el pòdcast correctament",
"ToastRSSFeedCloseFailed": "No s'ha pogut tancar el canal RSS",
"ToastRSSFeedCloseSuccess": "Canal RSS tancat"
}
+27 -3
View File
@@ -6,6 +6,7 @@
"ButtonCancel": "Zrušit",
"ButtonCancelTimer": "Zrušit časovač",
"ButtonClearFilter": "Vymazat filtr",
"ButtonClearLogs": "Vyčistit logy",
"ButtonCloseFeed": "Zavřít kanál",
"ButtonCollections": "Kolekce",
"ButtonConnect": "Připojit",
@@ -26,7 +27,9 @@
"ButtonLatest": "Nejnovější",
"ButtonLibrary": "Knihovna",
"ButtonLocalMedia": "Místní média",
"ButtonLogs": "Logy",
"ButtonManageLocalFiles": "Spravovat místní soubory",
"ButtonMaskServerAddress": "Skrýt adresu serveru",
"ButtonNewFolder": "Nová složka",
"ButtonNextEpisode": "Další epizoda",
"ButtonOk": "Ok",
@@ -50,6 +53,7 @@
"ButtonStream": "Streamovat",
"ButtonSubmit": "Odeslat",
"ButtonSwitchServerUser": "Přepnout server/uživatele",
"ButtonUnmaskServerAddress": "Odkrýt adresu serveru",
"ButtonUserStats": "Statistiky uživatele",
"ButtonYes": "Ano",
"HeaderAccount": "Účet",
@@ -66,7 +70,7 @@
"HeaderEbookFiles": "Soubory e-knih",
"HeaderEpisodes": "Epizody",
"HeaderEreaderSettings": "Nastavení čtečky e-knih",
"HeaderLatestEpisodes": "Nejnovější epizody",
"HeaderLatestEpisodes": "Nové epizody",
"HeaderLibraries": "Knihovny",
"HeaderLocalFolders": "Místní složky",
"HeaderLocalLibraryItems": "Místní položky knihovny",
@@ -75,7 +79,7 @@
"HeaderPlaybackSettings": "Nastavení přehrávání",
"HeaderPlaylist": "Seznam skladeb",
"HeaderPlaylistItems": "Položky seznamu přehrávání",
"HeaderProgressSyncFailed": "Chyba při synchronizaci",
"HeaderProgressSyncFailed": "Chyba při synchronizaci pokroku",
"HeaderRSSFeed": "RSS kanál",
"HeaderRSSFeedGeneral": "Detaily RSS",
"HeaderRSSFeedIsOpen": "Kanál RSS je otevřen",
@@ -94,6 +98,9 @@
"LabelAll": "Vše",
"LabelAllowSeekingOnMediaControls": "Povolit vyhledávání polohy v ovládacích prvcích oznámení médií",
"LabelAlways": "Vždy",
"LabelAndroidAutoBrowseLimitForGrouping": "Omezení abecedního rozbalovacího seznamu",
"LabelAndroidAutoBrowseLimitForGroupingHelp": "Nepoužívejte abecední řazení, pokud je k zobrazení méně než tento počet položek",
"LabelAndroidAutoBrowseSeriesSequenceOrder": "Řazení sérií knih",
"LabelAskConfirmation": "Požádat o potvrzení",
"LabelAuthor": "Autor",
"LabelAuthorFirstLast": "Autor (jméno a příjmení)",
@@ -134,7 +141,7 @@
"LabelEbooks": "E-knihy",
"LabelEnable": "Povolit",
"LabelEnableMp3IndexSeeking": "Povolit indexové vyhledávání mp3",
"LabelEnableMp3IndexSeekingHelp": "Toto nastavení by mělo být povoleno pouze v případě, že soubory MP3 nejsou správně vyhledávány. Nepřesné vyhledávání je s největší pravděpodobností způsobeno soubory MP3 s proměnlivým datovým tokem (VBR). Toto nastavení vynutí indexové vyhledávání, při kterém se při čtení souboru vytváří mapování času na bajty. V některých případech u velkých souborů MP3 dochází ke zpoždění při vyhledávání ke konci souboru.",
"LabelEnableMp3IndexSeekingHelp": "Toto nastavení by mělo být povoleno pouze v případě, že v souborech MP3 nelze přeskakovat. Nepřesné přeskakování je s největší pravděpodobností způsobeno soubory MP3 s proměnlivým datovým tokem (VBR). Toto nastavení vynutí indexové vyhledávání, při kterém se při čtení souboru vytváří mapování času na bajty. V některých případech u velkých souborů MP3 dochází ke zpoždění při vyhledávání ke konci souboru.",
"LabelEnd": "Konec",
"LabelEndOfChapter": "Konec kapitoly",
"LabelEndTime": "Do",
@@ -161,6 +168,7 @@
"LabelInternalAppStorage": "Interní úložiště aplikace",
"LabelJumpBackwardsTime": "Délka skoku zpět v čase",
"LabelJumpForwardsTime": "Délka skoku vpřed v čase",
"LabelKeepScreenAwake": "Nezhasínat obrazovku",
"LabelLanguage": "Jazyk",
"LabelLayout": "Rozvržení",
"LabelLayoutAuto": "Automatické",
@@ -175,6 +183,7 @@
"LabelLow": "Nízké",
"LabelMediaType": "Typ média",
"LabelMedium": "Střední",
"LabelMissing": "Chybějící",
"LabelMore": "Více",
"LabelMoreInfo": "Více informací",
"LabelName": "Jméno",
@@ -192,6 +201,8 @@
"LabelNotFinished": "Nedokončeno",
"LabelNotStarted": "Nezahájeno",
"LabelNumEpisodes": "{0} epizod",
"LabelNumEpisodesIncomplete": "{0} epizod, {1} nekompletní",
"LabelNumberOfEpisodes": "Počet epizod",
"LabelOff": "Vypnout",
"LabelOn": "Zapnuto",
"LabelPassword": "Heslo",
@@ -209,6 +220,7 @@
"LabelPublishedDate": "Vydáno {0}",
"LabelRSSFeedCustomOwnerEmail": "Vlastní e-mail vlastníka",
"LabelRSSFeedCustomOwnerName": "Vlastní jméno vlastníka",
"LabelRSSFeedOpen": "RSS kanál otevřen",
"LabelRSSFeedPreventIndexing": "Zabránit indexování",
"LabelRSSFeedSlug": "Klíčové slovo kanálu RSS",
"LabelRandomly": "Náhodně",
@@ -220,6 +232,8 @@
"LabelScaleElapsedTimeBySpeed": "Škálovat uplynulý čas podle rychlosti",
"LabelSeason": "Sezóna",
"LabelSelectADevice": "Vyberte zařízení",
"LabelSequenceAscending": "Řadit vzestupně",
"LabelSequenceDescending": "Řadit sestupně",
"LabelSeries": "Série",
"LabelServerAddress": "Adresa serveru",
"LabelSetEbookAsPrimary": "Nastavit jako primární",
@@ -228,6 +242,8 @@
"LabelShowAll": "Zobrazit vše",
"LabelSize": "Velikost",
"LabelSleepTimer": "Spánek po",
"LabelSleepTimerAlmostDoneChime": "Přehrát zvukové upozornění téměř před dokončením",
"LabelSleepTimerAlmostDoneChimeHelp": "Přehrát zvukové upozornění 30 sekund před uplynutím časovače spánku",
"LabelStart": "Spustit",
"LabelStartTime": "Od",
"LabelStatsBestDay": "Nejlepší den",
@@ -243,6 +259,7 @@
"LabelTag": "Štítek",
"LabelTags": "Štítky",
"LabelTheme": "Téma",
"LabelThemeBlack": "Černé",
"LabelThemeDark": "Tmavé",
"LabelThemeLight": "Světlé",
"LabelTimeRemaining": "{0} zbývá",
@@ -269,6 +286,7 @@
"MessageBookshelfEmpty": "Knihovna je prázdná",
"MessageConfirmDeleteLocalEpisode": "Odebrat místní epizodu „{0}“ ze zařízení? Soubor na serveru zůstane nezměněný.",
"MessageConfirmDeleteLocalFiles": "Odebrat místní soubory této položky ze zařízení? Soubory na serveru a váš pokrok nebudou ovlivněny.",
"MessageConfirmDisableAutoTimer": "Určitě chcete vypnout automatický časovač pro zbytek dnešního dne? Časovač bude opět aktivován po uběhnutí doby automatického spánku nebo po restartování aplikace.",
"MessageConfirmDiscardProgress": "Opravdu chcete zahodit svůj pokrok?",
"MessageConfirmDownloadUsingCellular": "Chystáte se stahovat přes mobilní data. Toto může zahrnovat poplatky za mobilní data. Chcete pokračovat?",
"MessageConfirmMarkAsFinished": "Opravdu chcete tuto položku označit jako dokončenou?",
@@ -283,8 +301,10 @@
"MessageFetching": "Načítání...",
"MessageFollowTheProjectOnGithub": "Sledujte projekt na GitHubu",
"MessageItemDownloadCompleteFailedToCreate": "Stahování položky bylo dokončeno, ale nepodařilo se vytvořit položku v knihovně",
"MessageItemMissing": "Položka chybí a musí být opravena na serveru. Typicky je položka označena jako chybějící, protože cesty k souborům nejsou přístupné.",
"MessageLoading": "Načítá se...",
"MessageLoadingServerData": "Načítání dat ze serveru...",
"MessageLocalFolderDescription": "„Interní úložiště aplikace“ je přístupné pouze této aplikaci. Tato aplikace podporuje pouze média stažená přímo prostřednictvím aplikace. Složky sdíleného úložiště lze použít k tomu, aby ostatní aplikace měly přístup k médiím staženým touto aplikací.",
"MessageMarkAsFinished": "Označit jako dokončené",
"MessageMediaLinkedToADifferentServer": "Média jsou propojena se serverem Audiobookshelf na jiné adrese ({0}). Pokrok bude synchronizován, když budete připojeni k této adrese serveru.",
"MessageMediaLinkedToADifferentUser": "Média jsou propojena se serverem, ale byla stažena jiným uživatelem. Pokrok bude synchronizován pouze s uživatelem, který je stáhl.",
@@ -297,13 +317,17 @@
"MessageNoItems": "Žádné položky",
"MessageNoItemsFound": "Nebyly nalezeny žádné položky",
"MessageNoListeningSessions": "Žádné poslechové relace",
"MessageNoLogs": "Žádné záznamy událostí",
"MessageNoMediaFolders": "Žádné složky médií",
"MessageNoNetworkConnection": "Žádné připojení k síti",
"MessageNoPodcastsFound": "Nebyly nalezeny žádné podcasty",
"MessageNoSeries": "Žádné série",
"MessageNoUpdatesWereNecessary": "Nebyly nutné žádné aktualizace",
"MessageNoUserPlaylists": "Nemáte žádné seznamy skladeb",
"MessageOldServerConnectionWarning": "Konfigurace připojení k serveru používá staré ID uživatele. Odstraňte a znovu přidejte toto připojení k serveru.",
"MessageOldServerConnectionWarningHelp": "Připojení k tomuto serveru jste původně nastavili před migrací databáze ve verzi 2.3.0 vydané v červnu 2023. Budoucí aktualizace serveru odstraní možnost přihlášení pomocí tohoto starého připojení. Odstraňte prosím stávající připojení k serveru a připojte se znovu (pomocí stejné adresy serveru a přihlašovacích údajů). Pokud máte v tomto zařízení stažená média, bude nutné je pro synchronizaci se serverem stáhnout znovu.",
"MessagePodcastSearchField": "Zadejte hledaný pojem pro RSS feed URL",
"MessageProgressSyncFailed": "Poslední pokus o nahlášení průběhu poslechu na server se nezdařil. Během přehrávání médií se budou požadavky na synchronizaci pokroku nadále pokoušet každých 15 až 60 sekund.",
"MessageReportBugsAndContribute": "Nahlašte chyby, vyžádejte si funkce a přispěte na",
"MessageSeriesAlreadyDownloaded": "Všechny knihy v této sérii jste již stáhli.",
"MessageSeriesDownloadConfirm": "Stáhnout chybějící {0} knihu(y) s {1} souborem(y), celkem {2} do složky {3}?",
+1
View File
@@ -216,6 +216,7 @@
"LabelPublishedDate": "Publiceret {0}",
"LabelRSSFeedCustomOwnerEmail": "Brugerdefineret ejerens e-mail",
"LabelRSSFeedCustomOwnerName": "Brugerdefineret ejerens navn",
"LabelRSSFeedOpen": "RSS-feed åbent",
"LabelRSSFeedPreventIndexing": "Forhindrer indeksering",
"LabelRSSFeedSlug": "RSS-feed-slug",
"LabelRandomly": "Tilfældigt",
+15 -7
View File
@@ -6,6 +6,7 @@
"ButtonCancel": "Abbrechen",
"ButtonCancelTimer": "Timer abbrechen",
"ButtonClearFilter": "Filter löschen",
"ButtonClearLogs": "Protokolle löschen",
"ButtonCloseFeed": "Feed schließen",
"ButtonCollections": "Sammlungen",
"ButtonConnect": "Verbinden",
@@ -16,17 +17,19 @@
"ButtonDelete": "Löschen",
"ButtonDeleteLocalEpisode": "Lösche lokale Episode",
"ButtonDeleteLocalFile": "Lösche lokale Datei",
"ButtonDeleteLocalItem": "Lösche lokales Element",
"ButtonDisableAutoTimer": "Deaktiviere automatischen Timer",
"ButtonDeleteLocalItem": "Lokales Element löschen",
"ButtonDisableAutoTimer": "Automatischen Timer deaktivieren",
"ButtonDisconnect": "Trennen",
"ButtonGoToWebClient": "Gehe zum Web Client",
"ButtonHistory": "Historie",
"ButtonGoToWebClient": "Gehe zum Webclient",
"ButtonHistory": "Verlauf",
"ButtonHome": "Startseite",
"ButtonIssues": "Probleme",
"ButtonLatest": "Neueste",
"ButtonLibrary": "Bibliothek",
"ButtonLocalMedia": "Lokale Medien",
"ButtonManageLocalFiles": "Verwalte lokale Dateien",
"ButtonLogs": "Protokolle",
"ButtonManageLocalFiles": "Lokale Dateien verwalten",
"ButtonMaskServerAddress": "Server Adresse verstecken",
"ButtonNewFolder": "Neuer Ordner",
"ButtonNextEpisode": "Nächste Episode",
"ButtonOk": "Einverstanden",
@@ -49,7 +52,8 @@
"ButtonSetTimer": "Setze Timer",
"ButtonStream": "Streamen",
"ButtonSubmit": "Ok",
"ButtonSwitchServerUser": "Wechsle Server/Benutzer",
"ButtonSwitchServerUser": "Server/Benutzer wechseln",
"ButtonUnmaskServerAddress": "Server Adresse anzeigen",
"ButtonUserStats": "Nutzerstatistiken",
"ButtonYes": "Ja",
"HeaderAccount": "Konto",
@@ -216,6 +220,7 @@
"LabelPublishedDate": "Veröffentlicht {0}",
"LabelRSSFeedCustomOwnerEmail": "Benutzerdefinierte Eigentümer-E-Mail",
"LabelRSSFeedCustomOwnerName": "Benutzerdefinierter Name des Eigentümers",
"LabelRSSFeedOpen": "RSS Feed öffnen",
"LabelRSSFeedPreventIndexing": "Indizierung verhindern",
"LabelRSSFeedSlug": "RSS-Feed-Schlagwort",
"LabelRandomly": "Zufällig",
@@ -237,6 +242,8 @@
"LabelShowAll": "Alles anzeigen",
"LabelSize": "Größe",
"LabelSleepTimer": "Schlummerfunktion",
"LabelSleepTimerAlmostDoneChime": "Spiel ein Ton kurz vor dem Ende",
"LabelSleepTimerAlmostDoneChimeHelp": "Spiel ein Ton wenn 30 Sekunden auf dem Timer verbleiben",
"LabelStart": "Start",
"LabelStartTime": "Startzeit",
"LabelStatsBestDay": "Bester Tag",
@@ -310,7 +317,8 @@
"MessageNoItems": "Keine Medien",
"MessageNoItemsFound": "Keine Medien gefunden",
"MessageNoListeningSessions": "Keine Hörsitzungen",
"MessageNoMediaFolders": "Keine Medien Ordner",
"MessageNoLogs": "Keine Protokolle",
"MessageNoMediaFolders": "Keine Medien-Ordner",
"MessageNoNetworkConnection": "Keine Netzwerkverbindung",
"MessageNoPodcastsFound": "Keine Podcasts gefunden",
"MessageNoSeries": "Keine Serie",
+8
View File
@@ -6,6 +6,7 @@
"ButtonCancel": "Cancel",
"ButtonCancelTimer": "Cancel Timer",
"ButtonClearFilter": "Clear Filter",
"ButtonClearLogs": "Clear Logs",
"ButtonCloseFeed": "Close Feed",
"ButtonCollections": "Collections",
"ButtonConnect": "Connect",
@@ -26,7 +27,9 @@
"ButtonLatest": "Latest",
"ButtonLibrary": "Library",
"ButtonLocalMedia": "Local Media",
"ButtonLogs": "Logs",
"ButtonManageLocalFiles": "Manage Local Files",
"ButtonMaskServerAddress": "Mask server address",
"ButtonNewFolder": "New Folder",
"ButtonNextEpisode": "Next Episode",
"ButtonOk": "Ok",
@@ -50,6 +53,7 @@
"ButtonStream": "Stream",
"ButtonSubmit": "Submit",
"ButtonSwitchServerUser": "Switch Server/User",
"ButtonUnmaskServerAddress": "Unmask server address",
"ButtonUserStats": "User Stats",
"ButtonYes": "Yes",
"HeaderAccount": "Account",
@@ -216,6 +220,7 @@
"LabelPublishedDate": "Published {0}",
"LabelRSSFeedCustomOwnerEmail": "Custom owner Email",
"LabelRSSFeedCustomOwnerName": "Custom owner Name",
"LabelRSSFeedOpen": "RSS Feed Open",
"LabelRSSFeedPreventIndexing": "Prevent Indexing",
"LabelRSSFeedSlug": "RSS Feed Slug",
"LabelRandomly": "Randomly",
@@ -237,6 +242,8 @@
"LabelShowAll": "Show All",
"LabelSize": "Size",
"LabelSleepTimer": "Sleep timer",
"LabelSleepTimerAlmostDoneChime": "Play a chime when almost finished",
"LabelSleepTimerAlmostDoneChimeHelp": "Play a chime when the sleep timer has 30 seconds remaining",
"LabelStart": "Start",
"LabelStartTime": "Start time",
"LabelStatsBestDay": "Best Day",
@@ -310,6 +317,7 @@
"MessageNoItems": "No Items",
"MessageNoItemsFound": "No items found",
"MessageNoListeningSessions": "No Listening Sessions",
"MessageNoLogs": "No logs",
"MessageNoMediaFolders": "No Media Folders",
"MessageNoNetworkConnection": "No network connection",
"MessageNoPodcastsFound": "No podcasts found",
+44 -34
View File
@@ -6,6 +6,7 @@
"ButtonCancel": "Cancelar",
"ButtonCancelTimer": "Cancelar temporizador",
"ButtonClearFilter": "Quitar filtros",
"ButtonClearLogs": "Vaciar registros",
"ButtonCloseFeed": "Cerrar suministro",
"ButtonCollections": "Colecciones",
"ButtonConnect": "Conectar",
@@ -26,7 +27,9 @@
"ButtonLatest": "Más recientes",
"ButtonLibrary": "Biblioteca",
"ButtonLocalMedia": "Medios locales",
"ButtonLogs": "Registros",
"ButtonManageLocalFiles": "Gestionar archivos locales",
"ButtonMaskServerAddress": "Enmascarar dirección de servidor",
"ButtonNewFolder": "Carpeta nueva",
"ButtonNextEpisode": "Próximo episodio",
"ButtonOk": "Aceptar",
@@ -50,6 +53,7 @@
"ButtonStream": "En directo",
"ButtonSubmit": "Enviar",
"ButtonSwitchServerUser": "Cambiar servidor/usuario",
"ButtonUnmaskServerAddress": "Desenmascarar dirección de servidor",
"ButtonUserStats": "Estadísticas de usuario",
"ButtonYes": "Sí",
"HeaderAccount": "Cuenta",
@@ -137,7 +141,7 @@
"LabelEbooks": "Libros electrónicos",
"LabelEnable": "Activar",
"LabelEnableMp3IndexSeeking": "Activar la búsqueda de índices mp3",
"LabelEnableMp3IndexSeekingHelp": "Esta configuración solo debe habilitarse si tienes archivos mp3 que no se están buscando correctamente. La búsqueda inexacta probablemente se deba a archivos MP3 de tasa de bits variable (VBR). Esta configuración forzará la búsqueda de índice, en la que se construye un mapeo de tiempo a bytes mientras se lee el archivo. En algunos casos, con archivos MP3 grandes, puede haber un retraso al buscar hacia el final del archivo.",
"LabelEnableMp3IndexSeekingHelp": "Esta configuración solo debe activarse si tiene archivos MP3 en los que no se puede buscar correctamente. La búsqueda inexacta probablemente se deba a archivos MP3 con tasas de bits variables (VBR). Esta configuración forzará la búsqueda de índice, en la que se construye una asignación de tiempo a bytes mientras se lee el archivo. En algunos casos, con archivos MP3 grandes, puede haber un retraso al buscar hacia el final del archivo.",
"LabelEnd": "Fin",
"LabelEndOfChapter": "Fin del capítulo",
"LabelEndTime": "Hora de finalización",
@@ -216,38 +220,40 @@
"LabelPublishedDate": "Publicado {0}",
"LabelRSSFeedCustomOwnerEmail": "Correo electrónico de dueño personalizado",
"LabelRSSFeedCustomOwnerName": "Nombre de dueño personalizado",
"LabelRSSFeedPreventIndexing": "Prevenir indexado",
"LabelRSSFeedPreventIndexing": "Evitar indización",
"LabelRSSFeedSlug": "«Slug» de suministro RSS",
"LabelRandomly": "Aleatorio",
"LabelRead": "Leído",
"LabelReadAgain": "Volver a leer",
"LabelRecentSeries": "Series recientes",
"LabelRecentlyAdded": "Añadidos recientemente",
"LabelRemoveFromPlaylist": "Eliminar de la Lista de Reproducción",
"LabelRemoveFromPlaylist": "Quitar de la lista de reproducción",
"LabelScaleElapsedTimeBySpeed": "Escala el tiempo transcurrido según la velocidad",
"LabelSeason": "Temporada",
"LabelSelectADevice": "Selecciona un dispositivo",
"LabelSequenceAscending": "Secuencia Ascendente",
"LabelSequenceDescending": "Secuencia Descendente",
"LabelSelectADevice": "Seleccione un dispositivo",
"LabelSequenceAscending": "Secuencia ascendente",
"LabelSequenceDescending": "Secuencia descendente",
"LabelSeries": "Serie",
"LabelServerAddress": "Dirección del servidor",
"LabelSetEbookAsPrimary": "Establecer como primario",
"LabelSetEbookAsSupplementary": "Establecer como suplementario",
"LabelShakeSensitivity": "Sensibilidad a la sacudida",
"LabelShowAll": "Mostrar Todos",
"LabelShowAll": "Mostrar todo",
"LabelSize": "Tamaño",
"LabelSleepTimer": "Temporizador de apagado",
"LabelSleepTimerAlmostDoneChime": "Timbrar casi al terminar",
"LabelSleepTimerAlmostDoneChimeHelp": "Reproducir una señal acústica cuando queden 30 segundos en el temporizador",
"LabelStart": "Iniciar",
"LabelStartTime": "Tiempo de Inicio",
"LabelStatsBestDay": "Mejor Día",
"LabelStatsDailyAverage": "Promedio Diario",
"LabelStartTime": "Tiempo de inicio",
"LabelStatsBestDay": "Mejor día",
"LabelStatsDailyAverage": "Promedio diario",
"LabelStatsDays": "Días",
"LabelStatsDaysListened": "Días Escuchando",
"LabelStatsDaysListened": "Días escuchando",
"LabelStatsInARow": "seguidos",
"LabelStatsItemsFinished": "Elementos Terminados",
"LabelStatsItemsFinished": "Elementos terminados",
"LabelStatsMinutes": "minutos",
"LabelStatsMinutesListening": "Minutos Escuchando",
"LabelStatsWeekListening": "Tiempo escuchando en la Semana",
"LabelStatsMinutesListening": "Minutos escuchando",
"LabelStatsWeekListening": "Tiempo escuchando en la semana",
"LabelStreamingUsingCellular": "Streaming por móvil",
"LabelTag": "Etiqueta",
"LabelTags": "Etiquetas",
@@ -263,14 +269,14 @@
"LabelType": "Tipo",
"LabelUnknown": "Desconocido",
"LabelUnlockPlayer": "Desbloquear reproductor",
"LabelUseBookshelfView": "Usar la Vista de Estantería",
"LabelUseBookshelfView": "Usar vista de estantería",
"LabelUser": "Usuario",
"LabelUsername": "Nombre de Usuario",
"LabelVeryHigh": "Muy Alto",
"LabelVeryLow": "Muy Bajo",
"LabelYearReviewHide": "Ocultar Resumen del año",
"LabelYearReviewShow": "Resumen del año",
"LabelYourBookmarks": "Tus Marcadores",
"LabelUsername": "Nombre de usuario",
"LabelVeryHigh": "Muy alto",
"LabelVeryLow": "Muy bajo",
"LabelYearReviewHide": "Ocultar resumen del año",
"LabelYearReviewShow": "Ver resumen del año",
"LabelYourBookmarks": "Sus marcadores",
"LabelYourProgress": "Su progreso",
"MessageAndroid10Downloads": "Android 10 e inferiores utilizarán el almacenamiento interno de aplicaciones para las descargas.",
"MessageAttemptingServerConnection": "Intentando conectar con el servidor...",
@@ -279,46 +285,50 @@
"MessageBookshelfEmpty": "Estantería vacía",
"MessageConfirmDeleteLocalEpisode": "¿Quiere eliminar el episodio local «{0}» del dispositivo? El archivo en el servidor no se verá afectado.",
"MessageConfirmDeleteLocalFiles": "¿Quiere quitar los archivos locales de este elemento del dispositivo? Los archivos del servidor y su progreso no se verán afectados.",
"MessageConfirmDisableAutoTimer": "¿Confirma que quiere desactivar el temporizador automático por el resto del día? El temporizador volverá a activarse al final de este periodo de temporizador de apagado automático, o si reinicia la aplicación.",
"MessageConfirmDiscardProgress": "¿Confirma que quiere restablecer su progreso?",
"MessageConfirmDownloadUsingCellular": "Estas a punto de realizar una descarga utilizando datos móviles. Esto puede incluir cargos de datos del operador. ¿Deseas continuar?",
"MessageConfirmDownloadUsingCellular": "Está a punto de efectuar una descarga con datos móviles. Esto puede conllevar tarifas de datos de la operadora. ¿Quiere continuar?",
"MessageConfirmMarkAsFinished": "¿Confirma que quiere marcar este elemento como terminado?",
"MessageConfirmRemoveBookmark": "¿Confirma que quiere quitar el marcador?",
"MessageConfirmStreamingUsingCellular": "Estás a punto de hacer streaming utilizando datos móviles. Esto puede incluir cargos de datos del operador. ¿Deseas continuar?",
"MessageConfirmStreamingUsingCellular": "Está a punto de hacer una transmisión con datos móviles. Esto puede conllevar tarifas de datos de la operadora. ¿Quiere continuar?",
"MessageDiscardProgress": "Descartar progreso",
"MessageDownloadCompleteProcessing": "Descarga Completada. Procesando...",
"MessageDownloadCompleteProcessing": "Descarga completada. Procesando...",
"MessageDownloading": "Descargando...",
"MessageDownloadingEpisode": "Descargando episodio",
"MessageEpisodesQueuedForDownload": "{0} Episodio(s) en cola para descargar",
"MessageEpisodesQueuedForDownload": "{0} episodio(s) en cola para descargar",
"MessageFeedURLWillBe": "El URL del suministro será {0}",
"MessageFetching": "Buscando...",
"MessageFollowTheProjectOnGithub": "Sigue el proyecto en GitHub",
"MessageFetching": "Recuperando...",
"MessageFollowTheProjectOnGithub": "Siga el proyecto en GitHub",
"MessageItemDownloadCompleteFailedToCreate": "Se ha completado la descarga del elemento, pero no se ha podido crear el elemento de la biblioteca",
"MessageItemMissing": "Falta un elemento y debe corregirse en el servidor. Normalmente, un elemento se marca como faltante porque no se puede acceder a las rutas de los archivos.",
"MessageLoading": "Cargando...",
"MessageLoadingServerData": "Cargando datos del servidor...",
"MessageLocalFolderDescription": "Solo se puede acceder al «Almacenamiento interno de la aplicación» a través de esta aplicación. Esta aplicación solo admite multimedia descargada directamente a través de ella. Las carpetas de almacenamiento compartido se pueden utilizar para permitir que otras aplicaciones accedan a los archivos descargados por esta aplicación.",
"MessageMarkAsFinished": "Marcar como terminado",
"MessageMediaLinkedToADifferentServer": "El contenido está vinculado a un servidor de Audiobookshelf en una dirección diferente ({0}). El progreso se sincronizará cuando se conecte a esta dirección de servidor.",
"MessageMediaLinkedToADifferentUser": "El contenido está vinculado a este servidor pero fue descargado por otro usuario. El progreso solo se sincronizará con el usuario que lo descargó.",
"MessageMediaLinkedToServer": "Vinculado al servidor {0}",
"MessageMediaLinkedToServer": "Enlazado al servidor {0}",
"MessageMediaLinkedToThisServer": "El contenido descargado está vinculado a este servidor",
"MessageMediaNotLinkedToServer": "El contenido multimedia no está vinculado a un servidor de Audiobookshelf. No se sincronizará ningún progreso.",
"MessageNoBookmarks": "Sin marcadores",
"MessageNoChapters": "Sin capítulos",
"MessageNoCollections": "Sin colecciones",
"MessageNoItems": "Sin elementos",
"MessageNoItems": "Ningún elemento",
"MessageNoItemsFound": "Ningún elemento encontrado",
"MessageNoListeningSessions": "Ninguna sesión escuchada",
"MessageNoListeningSessions": "Ninguna sesión de escucha",
"MessageNoLogs": "Ningún registro",
"MessageNoMediaFolders": "Sin carpetas multimedia",
"MessageNoNetworkConnection": "Sin conexión de red",
"MessageNoPodcastsFound": "No se encontró ningún pódcast",
"MessageNoSeries": "Ninguna serie",
"MessageNoUpdatesWereNecessary": "No fue necesario actualizar",
"MessageNoUserPlaylists": "No tiene ninguna lista de reproducción",
"MessageOldServerConnectionWarning": "La configuración de la conexión al servidor está utilizando un ID de usuario antiguo. Por favor, elimine y vuelva a añadir esta conexión al servidor.",
"MessageOldServerConnectionWarning": "La configuración de la conexión al servidor utiliza un identificador de usuario antiguo. Elimine y vuelva a añadir esta conexión al servidor.",
"MessageOldServerConnectionWarningHelp": "Usted configuró originalmente la conexión a este servidor antes de la migración de la base de datos en la versión 2.3.0, publicada en junio de 2023. Una futura actualización del servidor eliminará la posibilidad de iniciar sesión con esta conexión antigua. Por favor, elimine la conexión existente al servidor y conéctese de nuevo (utilizando la misma dirección del servidor y las mismas credenciales). Si tiene algún medio descargado en este dispositivo, será necesario descargarlo de nuevo para sincronizarlo con el servidor.",
"MessagePodcastSearchField": "Introduzca el término de búsqueda o el URL del suministro RSS",
"MessageProgressSyncFailed": "El último intento de informar al servidor sobre el progreso de la escucha ha fallado. Las solicitudes de sincronización de progreso seguirán intentándose cada 15 segundos a 1 minuto mientras se reproduce el contenido multimedia.",
"MessageReportBugsAndContribute": "Reporte erres, solicite funciones y contribuya en",
"MessageSeriesAlreadyDownloaded": "Ya has descargado todos los libros de esta serie.",
"MessageReportBugsAndContribute": "Informe de defectos, solicite funciones y contribuya en",
"MessageSeriesAlreadyDownloaded": "Ya ha descargado todos los libros de esta serie.",
"MessageSeriesDownloadConfirm": "¿Descargar {0} libro(s) faltante(s) con {1} archivo(s), totalizando {2} a la carpeta {3}?",
"MessageSeriesDownloadConfirmIos": "¿Descargar {0} libro(s) faltantes con {1} archivo(s), con un total de {2}?",
"MessageSocketConnectedOverMeteredCellular": "Conexión de socket a través de red celular de tarifa por consumo",
@@ -328,7 +338,7 @@
"MessageSocketNotConnected": "Socket no conectado",
"NoteRSSFeedPodcastAppsHttps": "Atención: la mayoría de las aplicaciones de pódcast requieren que el URL del suministro RSS use HTTPS",
"NoteRSSFeedPodcastAppsPubDate": "Advertencia: 1 o más de sus episodios no tienen fecha de publicación. Algunas aplicaciones de podcast lo requieren.",
"ToastBookmarkCreateFailed": "Error al crear marcador",
"ToastBookmarkCreateFailed": "No se pudo crear el marcador",
"ToastBookmarkRemoveFailed": "Error al eliminar marcador",
"ToastBookmarkUpdateFailed": "Error al actualizar el marcador",
"ToastDownloadNotAllowedOnCellular": "Las descargas no están permitidas con datos móviles",
+1
View File
@@ -6,6 +6,7 @@
"ButtonCancel": "Peruuta",
"ButtonCancelTimer": "Peruuta ajastin",
"ButtonClearFilter": "Poista suodatus",
"ButtonClearLogs": "Tyhjennä lokit",
"ButtonCloseFeed": "Sulje syöte",
"ButtonCollections": "Kokoelmat",
"ButtonConnect": "Yhdistä",
+9 -2
View File
@@ -6,6 +6,7 @@
"ButtonCancel": "Annuler",
"ButtonCancelTimer": "Annuler la minuterie",
"ButtonClearFilter": "Effacer le filtre",
"ButtonClearLogs": "Effacer les registres",
"ButtonCloseFeed": "Fermer le flux",
"ButtonCollections": "Collections",
"ButtonConnect": "Connecter",
@@ -26,7 +27,9 @@
"ButtonLatest": "Dernière version",
"ButtonLibrary": "Bibliothèque",
"ButtonLocalMedia": "Médias locaux",
"ButtonLogs": "Registres",
"ButtonManageLocalFiles": "Gérer les fichiers locaux",
"ButtonMaskServerAddress": "Masquer l'adresse du serveur",
"ButtonNewFolder": "Nouveau dossier",
"ButtonNextEpisode": "Prochain épisode",
"ButtonOk": "D'accord",
@@ -50,6 +53,7 @@
"ButtonStream": "Flux",
"ButtonSubmit": "Soumettre",
"ButtonSwitchServerUser": "Changer de serveur / utilisateur",
"ButtonUnmaskServerAddress": "Afficher l'adresse du serveur",
"ButtonUserStats": "Statistiques utilisateur",
"ButtonYes": "Oui",
"HeaderAccount": "Compte",
@@ -116,7 +120,7 @@
"LabelComplete": "Complet",
"LabelContinueBooks": "Continuer les Livres",
"LabelContinueEpisodes": "Continuer les épisodes",
"LabelContinueListening": "Continuer la lecture",
"LabelContinueListening": "Continuer l'écoute",
"LabelContinueReading": "Continuer la lecture",
"LabelContinueSeries": "Continuer les séries",
"LabelCustomTime": "Temps personalisé",
@@ -129,7 +133,7 @@
"LabelDisableVibrateOnReset": "Désactiver la vibration au redémarrage",
"LabelDisableVibrateOnResetHelp": "Lorsque le minuteur est redémarré, l'appareil vibre. Sélectionner pour désactiver les vibrations.",
"LabelDiscover": "Découvrir",
"LabelDownload": "Téléchargement",
"LabelDownload": "Télécharger",
"LabelDownloadUsingCellular": "Télécharger via les données mobiles",
"LabelDownloaded": "Téléchargé",
"LabelDuration": "Durée",
@@ -237,6 +241,8 @@
"LabelShowAll": "Tout afficher",
"LabelSize": "Taille",
"LabelSleepTimer": "Minuterie",
"LabelSleepTimerAlmostDoneChime": "Jouer un son quand c'est presque fini",
"LabelSleepTimerAlmostDoneChimeHelp": "Jouer un son quand il reste 30 s au minuteur de veille",
"LabelStart": "Démarrer",
"LabelStartTime": "Heure de démarrage",
"LabelStatsBestDay": "Meilleur jour",
@@ -310,6 +316,7 @@
"MessageNoItems": "Aucun élément",
"MessageNoItemsFound": "Aucun élément trouvé",
"MessageNoListeningSessions": "Aucune session d’écoute en cours",
"MessageNoLogs": "Aucun registre",
"MessageNoMediaFolders": "Aucun dossier multimédia",
"MessageNoNetworkConnection": "Pas de connexion réseau",
"MessageNoPodcastsFound": "Aucun podcast trouvé",
+322 -2
View File
@@ -6,6 +6,7 @@
"ButtonCancel": "ביטול",
"ButtonCancelTimer": "בטל טיימר",
"ButtonClearFilter": "נקה סינון",
"ButtonClearLogs": "נקה לוגים",
"ButtonCloseFeed": "סגור ערוץ",
"ButtonCollections": "אוספים",
"ButtonConnect": "התחבר",
@@ -25,9 +26,328 @@
"ButtonIssues": "בעיות",
"ButtonLatest": "אחרון",
"ButtonLibrary": "ספרייה",
"ButtonLocalMedia": "מדיה מקומית",
"ButtonLogs": "לוגים",
"ButtonManageLocalFiles": "נהל קבצים מקומיים",
"ButtonMaskServerAddress": "הסתר כתובת שרת",
"ButtonNewFolder": "תיקייה חדשה",
"ButtonNextEpisode": "הפרק הבא",
"ButtonOk": "אישור",
"ButtonOpenFeed": "פתח פיד",
"ButtonOverride": "עקוף",
"ButtonPause": "השהה",
"ButtonPlay": "נגן",
"ButtonPlayEpisode": "נגן פרק",
"ButtonPlaylists": "רשימת השמעה",
"ButtonPlaylists": "רשימות השמעה",
"ButtonRead": "קרא",
"ButtonReadLess": "קרא פחות",
"ButtonReadMore": "קרא עוד",
"ButtonRemove": "הסר",
"ButtonRemoveFromServer": "הסר מהשרת",
"ButtonSave": "שמור",
"ButtonSaveOrder": "שמור פקודה",
"ButtonSearch": "חיפוש",
"ButtonSendEbookToDevice": "שלח ספר אלקטרוני למכשיר",
"ButtonSeries": "סדרה",
"ButtonSetTimer": "הפעל טיימר",
"ButtonStream": "הזרם",
"ButtonSubmit": "שליחה",
"ButtonSwitchServerUser": "החלף שרת/משתמש",
"ButtonUnmaskServerAddress": "גלה כתובת שרת",
"ButtonUserStats": "נתוני משתמש",
"ButtonYes": "כן",
"HeaderAccount": "חשבון",
"HeaderAdvanced": "מתקדם",
"HeaderAndroidAutoSettings": "הגדרות Android Auto",
"HeaderAudioTracks": "רצועות קול",
"HeaderChapters": "פרקים",
"HeaderCollection": "אוסף",
"HeaderCollectionItems": "פרטי אוסף",
"HeaderConnectionStatus": "מצב החיבור",
"HeaderDataSettings": "הגדרות נתונים",
"HeaderDetails": "פרטים",
"HeaderDownloads": "הורדות",
"HeaderEbookFiles": "קבצי Ebook",
"HeaderEpisodes": "פרקים",
"HeaderEreaderSettings": "הגדרות קורא אלקטרוני",
"HeaderLatestEpisodes": "פרקים אחרונים",
"HeaderLibraries": "ספריות",
"HeaderLocalFolders": "תיקיות מקומיות",
"HeaderLocalLibraryItems": "פריטי ספרייה מקומית",
"HeaderNewPlaylist": "רשימת השמעה חדשה",
"HeaderOpenRSSFeed": "פתח ערוץ RSS",
"LabelAddedDate": "נוסף ב-{0}"
"HeaderPlaybackSettings": "הגדרות ניגון",
"HeaderPlaylist": "רשימת השמעה",
"HeaderPlaylistItems": "פריטי רשימת השמעה",
"HeaderProgressSyncFailed": "סנכרון ההתקדמות נכשל",
"HeaderRSSFeed": "ערוץ RSS",
"HeaderRSSFeedGeneral": "פרטי RSS",
"HeaderRSSFeedIsOpen": "ערוץ RSS פתוח",
"HeaderSelectDownloadLocation": "בחר מיקום להורדה",
"HeaderSettings": "הגדרות",
"HeaderSleepTimer": "טיימר שינה",
"HeaderSleepTimerSettings": "הגדרות טיימר שינה",
"HeaderStatsMinutesListeningChart": "דקות האזנה (7 ימים אחרונים)",
"HeaderStatsRecentSessions": "האזנות אחרונות",
"HeaderTableOfContents": "תוכן עניינים",
"HeaderUserInterfaceSettings": "הגדרות ממשק משתמש",
"HeaderYourStats": "הסטטיסטיקות שלך",
"LabelAddToPlaylist": "הוסף לרשימת השמעה",
"LabelAddedAt": "נוסף ב-",
"LabelAddedDate": "נוסף ב-{0}",
"LabelAll": "הכל",
"LabelAllowSeekingOnMediaControls": "אפשר לשנות מיקום בבקר התראות מדיה",
"LabelAlways": "תמיד",
"LabelAndroidAutoBrowseLimitForGrouping": "מגבלת משיכה אלפביתית",
"LabelAndroidAutoBrowseLimitForGroupingHelp": "אל תשתמש במשיכה אלפביתית כאשר יש פחות מכמות פריטים זו להציג",
"LabelAndroidAutoBrowseSeriesSequenceOrder": "סדר הספרים בסדרה",
"LabelAskConfirmation": "בקש אישור",
"LabelAuthor": "סופר",
"LabelAuthorFirstLast": "סופר (שם, משפחה)",
"LabelAuthorLastFirst": "סופר (משפחה, שם)",
"LabelAuthors": "סופרים",
"LabelAutoDownloadEpisodes": "הורד פרקים באופן אוטומטי",
"LabelAutoRewindTime": "החזרה לאחור באופן אוטומטי",
"LabelAutoSleepTimer": "טיימר שינה אוטומטי",
"LabelAutoSleepTimerAutoRewind": "החזרת זמן אוטומטית לאחור בטיימר שינה",
"LabelAutoSleepTimerAutoRewindHelp": "כאשר טיימר השינה האוטומטי מסתיים, הפעלה נוספת של הפריט תגרום אוטומטית להריץ את מיקומך אחורה.",
"LabelAutoSleepTimerHelp": "בעת הפעלת מדיה בין שעות ההתחלה והסיום שצוינו, טיימר שינה יופעל אוטומטית.",
"LabelBooks": "ספרים",
"LabelChapterTrack": "רצועת פרק",
"LabelChapters": "פרקים",
"LabelClosePlayer": "סגור נגן",
"LabelCollapseSeries": "הסתר סדרה",
"LabelComplete": "הושלם",
"LabelContinueBooks": "המשך ספרים",
"LabelContinueEpisodes": "המשך פרקים",
"LabelContinueListening": "המשך האזנה",
"LabelContinueReading": "המשך קריאה",
"LabelContinueSeries": "המשך סדרה",
"LabelCustomTime": "זמן מותאם אישית",
"LabelDescription": "תיאור",
"LabelDisableAudioFadeOut": "השבתת דהיית שמע",
"LabelDisableAudioFadeOutHelp": "עוצמת השמע תתחיל לרדת כאשר נותרה פחות מדקה אחת בטיימר השינה. הפעל הגדרה זו כדי לא לדעוך.",
"LabelDisableAutoRewind": "השבתת הרצה אוטומטית אחורה",
"LabelDisableShakeToReset": "השבתת ניעור לאיפוס",
"LabelDisableShakeToResetHelp": "ניעור המכשיר בזמן שהטיימר פועל או תוך 2 דקות ממועד סופו יאפס את טיימר השינה. הפעל הגדרה זו כדי להשבית את הניעור לצורך איפוס.",
"LabelDisableVibrateOnReset": "השבתת רטט באיפוס",
"LabelDisableVibrateOnResetHelp": "כאשר טיימר השינה מתאפס, המכשיר ירטוט. הפעל הגדרה זו כדי לא לרטוט כאשר טיימר השינה מתאפס.",
"LabelDiscover": "גלה",
"LabelDownload": "הורדה",
"LabelDownloadUsingCellular": "הורדה באמצעות נתונים סלולריים",
"LabelDownloaded": "הורד",
"LabelDuration": "משך",
"LabelEbook": "ספר אלקטרוני",
"LabelEbooks": "ספרים אלקטרוניים",
"LabelEnable": "אפשר",
"LabelEnableMp3IndexSeeking": "אפשר חיפוש באינדקס mp3",
"LabelEnableMp3IndexSeekingHelp": "יש להפעיל הגדרה זו רק אם יש לכם קבצי mp3 שאינם מחפשים כראוי. חיפוש לא מדויק נובע ככל הנראה מקבצי MP3 בעלי קצב סיביות משתנה (VBR). הגדרה זו תכריח חיפוש אינדקס, שבו נבנה מיפוי זמן-לבייט בעת קריאת הקובץ. במקרים מסוימים, עם קבצי MP3 גדולים, יהיה עיכוב בחיפוש לקראת סוף הקובץ.",
"LabelEnd": "סוף",
"LabelEndOfChapter": "סוף הפרק",
"LabelEndTime": "זמן סיום",
"LabelEpisode": "פרק",
"LabelFeedURL": "כתובת ערוץ",
"LabelFile": "קובץ",
"LabelFileBirthtime": "זמן יצירת הקובץ",
"LabelFileModified": "קובץ נערך",
"LabelFilename": "שם קובץ",
"LabelFinished": "הושלם",
"LabelFolder": "תיקייה",
"LabelFontBoldness": "עובי פונט",
"LabelFontScale": "גודל פונט",
"LabelGenre": "סגנון",
"LabelGenres": "סגנונות",
"LabelHapticFeedback": "משוב מגע",
"LabelHasEbook": "קיים ספר אלקטרוני",
"LabelHasSupplementaryEbook": "קיים ספר אלקטרוני משלים",
"LabelHeavy": "כבד",
"LabelHigh": "גבוה",
"LabelHost": "מארח",
"LabelInProgress": "בתהליך",
"LabelIncomplete": "לא הושלם",
"LabelInternalAppStorage": "אחסון אפליקציה פנימי",
"LabelJumpBackwardsTime": "הרץ לאחור",
"LabelJumpForwardsTime": "הרץ קדימה",
"LabelKeepScreenAwake": "השאר מסך דלוק",
"LabelLanguage": "שפה",
"LabelLayout": "Layout",
"LabelLayoutAuto": "אוטומטי",
"LabelLayoutSinglePage": "עמוד יחיד",
"LabelLight": "בהיר",
"LabelLineSpacing": "מרווח שורה",
"LabelListenAgain": "האזן שוב",
"LabelLocalBooks": "ספרים מקומיים",
"LabelLocalPodcasts": "פודקאסטים מקומיים",
"LabelLockOrientation": "נעילת כיוון",
"LabelLockPlayer": "נעילת נגן",
"LabelLow": "נמוך",
"LabelMediaType": "סוג מדיה",
"LabelMedium": "בינוני",
"LabelMissing": "חסר",
"LabelMore": "עוד",
"LabelMoreInfo": "מידע נוסף",
"LabelName": "שם",
"LabelNarrator": "מספר",
"LabelNarrators": "מספרים",
"LabelNavigateWithVolume": "ניווט באמצעות כפתורי ווליום",
"LabelNavigateWithVolumeMirrored": "מראה",
"LabelNavigateWithVolumeWhilePlaying": "אפשר למקשי ווליום לנווט בזמן ניגון",
"LabelNavigateWithVolumeWhilePlayingDisabled": "כיבוי",
"LabelNavigateWithVolumeWhilePlayingEnabled": "הדלקה",
"LabelNever": "אף פעם",
"LabelNewestAuthors": "הסופרים האחרונים",
"LabelNewestEpisodes": "הפרקים החדשים ביותר",
"LabelNo": "לא",
"LabelNotFinished": "לא הושלם",
"LabelNotStarted": "לא התחיל",
"LabelNumEpisodes": "{0} פרקים",
"LabelNumEpisodesIncomplete": "{0} פרקים, {1} לא הושלם",
"LabelNumberOfEpisodes": "# פרקים",
"LabelOff": "כיבוי",
"LabelOn": "הדלקה",
"LabelPassword": "סיסמה",
"LabelPath": "נתיב",
"LabelPlaybackDirect": "ישיר",
"LabelPlaybackLocal": "מקומי",
"LabelPlaybackSpeed": "מהירות השמעה",
"LabelPlaybackTranscode": "קידוד מחדש",
"LabelPodcast": "פודקאסט",
"LabelPodcasts": "פודקאסטים",
"LabelPreventIndexing": "מנע רישום של הערוץ שלך על ידי ספריות אייטונס וגוגל פודקאסט",
"LabelProgress": "התקדמות",
"LabelPubDate": "תאריך פרסום",
"LabelPublishYear": "שנת הפרסום",
"LabelPublishedDate": "פורסם {0}",
"LabelRSSFeedCustomOwnerEmail": "אימייל בעלים מותאם אישית",
"LabelRSSFeedCustomOwnerName": "שם בעלים מותאם אישית",
"LabelRSSFeedPreventIndexing": "מנע רישום",
"LabelRSSFeedSlug": "Slug של ערוץ ה-RSS",
"LabelRandomly": "באופן אקראי",
"LabelRead": "קריאה",
"LabelReadAgain": "קרא שוב",
"LabelRecentSeries": "סדרות אחרונות",
"LabelRecentlyAdded": "נוסף לאחרונה",
"LabelRemoveFromPlaylist": "הסרה מרשימת השמעה",
"LabelScaleElapsedTimeBySpeed": "שנה קנה מידה של זמן שחלף לפי מהירות ההשמעה",
"LabelSeason": "עונה",
"LabelSelectADevice": "בחר מכשיר",
"LabelSequenceAscending": "רצף עולה",
"LabelSequenceDescending": "רצף יורד",
"LabelSeries": "סדרה",
"LabelServerAddress": "כתובת שרת",
"LabelSetEbookAsPrimary": "קבע כראשי",
"LabelSetEbookAsSupplementary": "קבע כמשלים",
"LabelShakeSensitivity": "רגישות ניעור",
"LabelShowAll": "הצג הכל",
"LabelSize": "גודל",
"LabelSleepTimer": "טיימר שינה",
"LabelSleepTimerAlmostDoneChime": "השמע פעמון כאשר כמעט הסתיים",
"LabelSleepTimerAlmostDoneChimeHelp": "השמע פעמון כאשר נשארו 30 שניות לסיום טיימר השינה",
"LabelStart": "התחל",
"LabelStartTime": "זמן התחלה",
"LabelStatsBestDay": "היום הטוב ביותר",
"LabelStatsDailyAverage": "ממוצע יומי",
"LabelStatsDays": "ימים",
"LabelStatsDaysListened": "מספר ימים בהם נשמע ספר",
"LabelStatsInARow": "ברצף",
"LabelStatsItemsFinished": "פריטים שסיימת",
"LabelStatsMinutes": "דקות",
"LabelStatsMinutesListening": "דקות האזנה",
"LabelStatsWeekListening": "האזנה שבועית",
"LabelStreamingUsingCellular": "הזרמת באמצעות נתונים סלולריים",
"LabelTag": "תג",
"LabelTags": "תגיות",
"LabelTheme": "ערכת נושא",
"LabelThemeBlack": "שחור",
"LabelThemeDark": "כהה",
"LabelThemeLight": "בהיר",
"LabelTimeRemaining": "{0} נותרו",
"LabelTitle": "כותרת",
"LabelTotalSize": "סה״כ גודל",
"LabelTotalTrack": "סה״כ רצועות",
"LabelTracks": "רצועות",
"LabelType": "סוג",
"LabelUnknown": "לא ידוע",
"LabelUnlockPlayer": "בטל נעילת נגן",
"LabelUseBookshelfView": "שימוש בתצוגת מדף ספרים",
"LabelUser": "משתמש",
"LabelUsername": "שם משתמש",
"LabelVeryHigh": "גבוה מאוד",
"LabelVeryLow": "נמוך מאוד",
"LabelYearReviewHide": "הסתר סקירת שנה",
"LabelYearReviewShow": "הצג סקירת שנה",
"LabelYourBookmarks": "הסימניות שלך",
"LabelYourProgress": "ההתקדמות שלך",
"MessageAndroid10Downloads": "מכשירי אנדרואיד 10 או נמוך יותר ישתמשו באחסון היישום הפנימי להורדות.",
"MessageAttemptingServerConnection": "מנסה להתחבר לשרת...",
"MessageAudiobookshelfServerNotConnected": "לא מחובר לשרת Audiobookshelf",
"MessageAudiobookshelfServerRequired": "<strong>חשוב!</strong> אפליקציה זו מתוכננת לעבוד עם שרת Audiobookshelf שאת/ה או מישהו שאת/ה מכיר/ה מארח/ת. האפליקציה בפני עצמה לא מספקת שום תוכן.",
"MessageBookshelfEmpty": "ספריה ריקה",
"MessageConfirmDeleteLocalEpisode": "להסיר את הפרק המקומי \"{0}\" מהמכשיר שלך? הקובץ בשרת לא יושפע.",
"MessageConfirmDeleteLocalFiles": "להסיר קבצים מקומיים של פריט זה מהמכשיר שלך? הקבצים בשרת והתקדמותך לא יושפעו.",
"MessageConfirmDisableAutoTimer": "האם אתה בטוח שאתה רוצה להשבית את הטיימר האוטומי עד סוף היום? הטיימר יופעל מחדש לאחר הטיימר השינה הנוכחי יסתיים, או לאחר הפעלה מחדש של האפליקציה.",
"MessageConfirmDiscardProgress": "אתה בטוח שאתה רוצה לאפס את ההתקדמות שלך?",
"MessageConfirmDownloadUsingCellular": "אתה עומד להוריד באמצעות נתונים סלולריים. ספק הסלולר עשוי לחייב על שימוש בנתונים סלולריים, האם להמשיך?",
"MessageConfirmMarkAsFinished": "אתה בטוח שאתה רוצה לסמן את הפריט הזה כהושלם?",
"MessageConfirmRemoveBookmark": "האם להסיר את הסימניה?",
"MessageConfirmStreamingUsingCellular": "אתה עומד להזרים באמצעות נתונים סלולריים. ספק הסלולר עשוי לחייב על שימוש בנתונים סלולריים, האם להמשיך?",
"MessageDiscardProgress": "איפוס התקדמות",
"MessageDownloadCompleteProcessing": "ההורדה הושלמה. מעבד...",
"MessageDownloading": "מוריד...",
"MessageDownloadingEpisode": "מוריד פרק",
"MessageEpisodesQueuedForDownload": "{0} פרק/ים בתור להורדה",
"MessageFeedURLWillBe": "כתובת ה- URL של הערוץ תהיה {0}",
"MessageFetching": "מושך...",
"MessageFollowTheProjectOnGithub": "עקבו אחרי הפרוייקט ב-Github",
"MessageItemDownloadCompleteFailedToCreate": "הורדת הפריט הושלמה אך יצירת פריט בספריה נכשלה",
"MessageItemMissing": "הפריט חסר ונדרש תיקונו בשרת. בדרך כלל פריט מסומן כחסר כי נתיבי הקובץ הקיימים לא נגישים.",
"MessageLoading": "טוען...",
"MessageLoadingServerData": "טוען נתוני שרת...",
"MessageLocalFolderDescription": "\"אחסון אפליקציה פנימי\" זמין רק על ידי אפליקציה זו. אפליקציה זו תומכת רק במדיה שהורדה ישירות ע״י האפליקציה עצמה. ניתן להשתמש בתיקיות אחסון משותפות בכדי לאפשר ליישומים אחרים לגשת מדיה שהורדה ע״י אפליקציה זו.",
"MessageMarkAsFinished": "סמן כהושלם",
"MessageMediaLinkedToADifferentServer": "מדיה מקושרת לשרת Audiobookshelf בכתובת אחרת ({0}). ההתקדמות תהיה מסונכרנת כאשר היא האפליקציה תהיה מחוברת לכתובת שרת זו.",
"MessageMediaLinkedToADifferentUser": "מדיה מקושרת לשרת זה אבל הורדה ע״י משתמש אחר. התקדמות תסונכרן רק למשתמש שהוריד אותה.",
"MessageMediaLinkedToServer": "מקושר לשרת {0}",
"MessageMediaLinkedToThisServer": "המדיה שהורדה מקושרת לשרת זה",
"MessageMediaNotLinkedToServer": "מדיה לא מקושרת לשרת Audiobookshelf. התקדמות לא תהיה מסונכרנת.",
"MessageNoBookmarks": "אין סימניות",
"MessageNoChapters": "אין פרקים",
"MessageNoCollections": "אין אוספים",
"MessageNoItems": "אין פריטים",
"MessageNoItemsFound": "לא נמצאו פריטים",
"MessageNoListeningSessions": "אין הפעלות האזנה",
"MessageNoLogs": "אין לוגים",
"MessageNoMediaFolders": "אין תיקיות מדיה",
"MessageNoNetworkConnection": "אין חיבור לרשת",
"MessageNoPodcastsFound": "לא נמצאו פודקאסטים",
"MessageNoSeries": "אין סדרות",
"MessageNoUpdatesWereNecessary": "לא נדרש עדכון",
"MessageNoUserPlaylists": "אין לך רשימות השמעה",
"MessageOldServerConnectionWarning": "תצורת חיבור שרת משתמשת במזהה משתמש ישן. נא למחוק ולהתחבר מחדש לשרת זה.",
"MessageOldServerConnectionWarningHelp": "הגדרת במקור את החיבור לשרת זה לפני העברת מסד הנתונים בגרסה 2.3.0, שיצאה ביוני 2023. עדכון שרת עתידי יסיר את היכולת להתחבר באמצעות חיבור ישן זה. אנא מחק את חיבור השרת הקיים והתחבר שוב (תוך שימוש באותה כתובת שרת ופרטי גישה). אם הורדת מדיה כלשהי במכשיר זה, יהיה צורך להוריד אותה שוב כדי שתסתנכרן עם השרת.",
"MessagePodcastSearchField": "הזן מונח חיפוש או כתובת URL של ערוץ RSS",
"MessageProgressSyncFailed": "הניסיון האחרון לדווח על התקדמות ההאזנה שלך לשרת נכשל. בקשות סנכרון התקדמות ימשיכו להתבצע כל 15 שניות עד דקה בזמן שהמדיה מופעלת.",
"MessageReportBugsAndContribute": "דווח על באגים, בקש תכונות חדשות, ותרום ב-",
"MessageSeriesAlreadyDownloaded": "כבר הורדת את כל הספרים בסדרה זו.",
"MessageSeriesDownloadConfirm": "להוריד את הספר החסר {0} עם {1} קבצים ,סה״כ {2} לתיקיה {3}?",
"MessageSeriesDownloadConfirmIos": "להוריד את הספר החסר {0} עם {1} קבצים ,סה״כ {2}?",
"MessageSocketConnectedOverMeteredCellular": "מחובר באמצעות רשת סלולרית",
"MessageSocketConnectedOverMeteredWifi": "מחוברת באמצעות רשת WiFi מדודה",
"MessageSocketConnectedOverUnmeteredCellular": "מחובר באמצעות רשת סלולרית לא מדודה",
"MessageSocketConnectedOverUnmeteredWifi": "מחוברת באמצעות רשת WiFi לא מדודה",
"MessageSocketNotConnected": "לא מחובר",
"NoteRSSFeedPodcastAppsHttps": "אזהרה: רוב אפליקציות הפודקאסטים ידרשו שכתובת האתר של ערוץ ה-RSS תשתמש ב-HTTPS",
"NoteRSSFeedPodcastAppsPubDate": "אזהרה: פרק אחד או יותר לא מכילים תאריך פרסום. חלק מיישומי הפודקאסט דורשים זאת.",
"ToastBookmarkCreateFailed": "יצירת סימניה נכשלה",
"ToastBookmarkRemoveFailed": "הסרת הסימניה נכשלה",
"ToastBookmarkUpdateFailed": "עדכון הסימניה נכשל",
"ToastDownloadNotAllowedOnCellular": "הורדה אינה מותרת באמצעות נתונים סלולריים",
"ToastItemMarkedAsFinishedFailed": "סימון כפריט שהושלם נכשל",
"ToastItemMarkedAsNotFinishedFailed": "סימון כפריט שלא הושלם נכשל",
"ToastPlaylistCreateFailed": "יצירת רשימת השמעה נכשלה",
"ToastPodcastCreateFailed": "יצירת הפודקאסט נכשלה",
"ToastPodcastCreateSuccess": "הפודקאסט נוצר בהצלחה",
"ToastRSSFeedCloseFailed": "סגירת ערוץ ה-RSS נכשלה",
"ToastRSSFeedCloseSuccess": "ערוץ ה-RSS נסגר בהצלחה",
"ToastStreamingNotAllowedOnCellular": "הזרמה אינה מותרת באמצעות נתונים סלולריים"
}
+8
View File
@@ -6,6 +6,7 @@
"ButtonCancel": "Odustani",
"ButtonCancelTimer": "Poništi timer",
"ButtonClearFilter": "Poništi filter",
"ButtonClearLogs": "Izbriši zapisnike",
"ButtonCloseFeed": "Zatvori izvor",
"ButtonCollections": "Zbirke",
"ButtonConnect": "Povezivanje",
@@ -26,7 +27,9 @@
"ButtonLatest": "Najnovije",
"ButtonLibrary": "Knjižnica",
"ButtonLocalMedia": "Preuzeti medijski zapisi",
"ButtonLogs": "Zapisnici",
"ButtonManageLocalFiles": "Upravljanje preuzetim datotekama",
"ButtonMaskServerAddress": "Maskiraj adresu poslužitelja",
"ButtonNewFolder": "Nova mapa",
"ButtonNextEpisode": "Sljedeći nastavak",
"ButtonOk": "U redu",
@@ -50,6 +53,7 @@
"ButtonStream": "Reproduciraj strujanjem",
"ButtonSubmit": "Pošalji",
"ButtonSwitchServerUser": "Promijeni poslužitelj/korisnika",
"ButtonUnmaskServerAddress": "Prikaži adresu poslužitelja",
"ButtonUserStats": "Statistika korisnika",
"ButtonYes": "Da",
"HeaderAccount": "Korisnički račun",
@@ -216,6 +220,7 @@
"LabelPublishedDate": "Objavljeno {0}",
"LabelRSSFeedCustomOwnerEmail": "Prilagođena adresa e-pošte vlasnika",
"LabelRSSFeedCustomOwnerName": "Prilagođeno ime vlasnika",
"LabelRSSFeedOpen": "RSS izvor otvoren",
"LabelRSSFeedPreventIndexing": "Onemogući indeksiranje",
"LabelRSSFeedSlug": "Slug RSS izvora",
"LabelRandomly": "Nasumično",
@@ -237,6 +242,8 @@
"LabelShowAll": "Prikaži sve",
"LabelSize": "Veličina",
"LabelSleepTimer": "Timer za spavanje",
"LabelSleepTimerAlmostDoneChime": "Zvučno upozorenje prije isteka",
"LabelSleepTimerAlmostDoneChimeHelp": "Reproduciraj zvučno upozorenje 30 sekundi prije isteka timera za spavanje",
"LabelStart": "Početak",
"LabelStartTime": "Vrijeme pokretanja",
"LabelStatsBestDay": "Najbolji dan",
@@ -310,6 +317,7 @@
"MessageNoItems": "Nema stavki",
"MessageNoItemsFound": "Nema pronađenih stavki",
"MessageNoListeningSessions": "Nema sesija slušanja",
"MessageNoLogs": "Nema zapisnika",
"MessageNoMediaFolders": "Nema medijskih mapa",
"MessageNoNetworkConnection": "Nema mrežne veze",
"MessageNoPodcastsFound": "Nije pronađen niti jedan podcast",
+14 -2
View File
@@ -6,6 +6,7 @@
"ButtonCancel": "Mégsem",
"ButtonCancelTimer": "Időzítő megszakítása",
"ButtonClearFilter": "Szűrő törlése",
"ButtonClearLogs": "Naplók tisztítása",
"ButtonCloseFeed": "Hírcsatorna bezárása",
"ButtonCollections": "Gyűjtemények",
"ButtonConnect": "Csatlakozás",
@@ -26,7 +27,9 @@
"ButtonLatest": "Legújabb",
"ButtonLibrary": "Könyvtár",
"ButtonLocalMedia": "Helyi média",
"ButtonLogs": "Naplók",
"ButtonManageLocalFiles": "Helyi fájlok kezelése",
"ButtonMaskServerAddress": "Kiszolgáló címének maszkolása",
"ButtonNewFolder": "Új mappa",
"ButtonNextEpisode": "Következő epizód",
"ButtonOk": "Ok",
@@ -50,6 +53,7 @@
"ButtonStream": "Streamelés",
"ButtonSubmit": "Küldés",
"ButtonSwitchServerUser": "Szerver/Felhasználó váltása",
"ButtonUnmaskServerAddress": "Kiszolgáló címének maszkolásának törlése",
"ButtonUserStats": "Felhasználói statisztikák",
"ButtonYes": "Igen",
"HeaderAccount": "Fiók",
@@ -95,6 +99,7 @@
"LabelAllowSeekingOnMediaControls": "Pozíció keresés engedélyezése a média értesítési vezérlőkön",
"LabelAlways": "Mindig",
"LabelAndroidAutoBrowseLimitForGrouping": "Ábécé szerinti lehívási korlát",
"LabelAndroidAutoBrowseLimitForGroupingHelp": "Ne használja az ábécé szerinti lehívási korlátot, ha ennél kevesebb elemet kell megjeleníteni",
"LabelAndroidAutoBrowseSeriesSequenceOrder": "A sorozat könyveinek sorrendje",
"LabelAskConfirmation": "Kérjen megerősítést",
"LabelAuthor": "Szerző",
@@ -136,7 +141,7 @@
"LabelEbooks": "E-könyvek",
"LabelEnable": "Engedélyezés",
"LabelEnableMp3IndexSeeking": "Mp3 indexkeresés engedélyezése",
"LabelEnableMp3IndexSeekingHelp": "Ezt a beállítást csak akkor kell engedélyezni, ha vannak mp3 fájljai, amelyek nem megfelelően keresnek. A pontatlan keresés leginkább a változó bitráta (VBR) mp3 fájlok miatt lehetséges. Ez a beállítás indexkeresést fog kényszeríteni, amely során egy idő-bájt leképezés jön létre, ahogy a fájlt olvassák. Nagy mp3 fájlok esetén előfordulhat késedelem a fájl végéhez való kereséskor.",
"LabelEnableMp3IndexSeekingHelp": "Ezt a beállítást csak akkor kell engedélyezni, ha vannak mp3 fájljai, amelyek nem megfelelően keresnek. A pontatlan keresés leginkább a változó bitráta (VBR) mp3 fájlok miatt lehetséges. Ez a beállítás indexkeresést fog kényszeríteni, amely során egy idő-bájt leképezés jön létre, ahogy a fájlt olvassák. Nagy mp3 fájlok esetén előfordulhat késedelem a fájl végénél történő kereséskor.",
"LabelEnd": "Vége",
"LabelEndOfChapter": "Fejezet vége",
"LabelEndTime": "Befejezés ideje",
@@ -178,6 +183,7 @@
"LabelLow": "Alacsony",
"LabelMediaType": "Média típus",
"LabelMedium": "Közepes",
"LabelMissing": "Hiányzik",
"LabelMore": "Több",
"LabelMoreInfo": "Több információ",
"LabelName": "Név",
@@ -214,6 +220,7 @@
"LabelPublishedDate": "Kiadva {0}",
"LabelRSSFeedCustomOwnerEmail": "Egyéni tulajdonos e-mail",
"LabelRSSFeedCustomOwnerName": "Egyéni tulajdonos neve",
"LabelRSSFeedOpen": "RSS-hírcsatorna nyitva",
"LabelRSSFeedPreventIndexing": "Indexelés megakadályozása",
"LabelRSSFeedSlug": "RSS hírcsatorna rövid cím",
"LabelRandomly": "Véletlenszerűen",
@@ -235,12 +242,14 @@
"LabelShowAll": "Összes megjelenítése",
"LabelSize": "Méret",
"LabelSleepTimer": "Alvásidőzítő",
"LabelSleepTimerAlmostDoneChime": "Jelezze hanggal, ha majdnem lejárt",
"LabelSleepTimerAlmostDoneChimeHelp": "Jelezze hanggal, ha az elalvásidőzítőből 30 másodperc maradt",
"LabelStart": "Kezdés",
"LabelStartTime": "Kezdési idő",
"LabelStatsBestDay": "Legjobb nap",
"LabelStatsDailyAverage": "Napi átlag",
"LabelStatsDays": "Napok",
"LabelStatsDaysListened": "Hallgatott napok",
"LabelStatsDaysListened": "Hallgatással töltött napok",
"LabelStatsInARow": "egymás után",
"LabelStatsItemsFinished": "Befejezett elemek",
"LabelStatsMinutes": "perc",
@@ -250,6 +259,7 @@
"LabelTag": "Címke",
"LabelTags": "Címkék",
"LabelTheme": "Téma",
"LabelThemeBlack": "Fekete",
"LabelThemeDark": "Sötét",
"LabelThemeLight": "Világos",
"LabelTimeRemaining": "{0} maradt",
@@ -294,6 +304,7 @@
"MessageItemMissing": "Az elem hiányzik, és a szerveren kell javítani. Egy elemet általában azért jelölnek hiányzónak, mert a fájl elérési útvonalai nem elérhetőek.",
"MessageLoading": "Betöltés...",
"MessageLoadingServerData": "Szerveradatok betöltése...",
"MessageLocalFolderDescription": "A „Belső alkalmazás-tároló” csak ezzel az alkalmazással érhető el. Ez az alkalmazás csak a közvetlenül az alkalmazáson keresztül letöltött médiát támogatja. A megosztott tároló mappák segítségével más alkalmazások is hozzáférhetnek az alkalmazás által letöltött médiához.",
"MessageMarkAsFinished": "Befejezettnek jelölés",
"MessageMediaLinkedToADifferentServer": "A média egy másik címen található Audiobookshelf szerverhez kapcsolódik ({0}). A haladás szinkronizálva lesz, amikor csatlakozik ehhez a szervercímhez.",
"MessageMediaLinkedToADifferentUser": "A média ehhez a szerverhez kapcsolódik, de egy másik felhasználó töltötte le. A haladás csak a letöltést végrehajtó felhasználóhoz lesz szinkronizálva.",
@@ -306,6 +317,7 @@
"MessageNoItems": "Nincsenek elemek",
"MessageNoItemsFound": "Nincs találat",
"MessageNoListeningSessions": "Nincsenek hallgatási munkamenetek",
"MessageNoLogs": "Nincsenek naplók",
"MessageNoMediaFolders": "Nincsenek médiamappák",
"MessageNoNetworkConnection": "Nincs hálózati kapcsolat",
"MessageNoPodcastsFound": "Nem találhatók podcastok",
+14 -6
View File
@@ -3,9 +3,10 @@
"ButtonAddNewServer": "Aggiungi un nuovo server",
"ButtonAuthors": "Autori",
"ButtonBack": "Indietro",
"ButtonCancel": "Cancella",
"ButtonCancel": "Annulla",
"ButtonCancelTimer": "Annulla il timer",
"ButtonClearFilter": "Elimina filtri",
"ButtonClearLogs": "Cancella i registri",
"ButtonCloseFeed": "Chiudi flusso",
"ButtonCollections": "Raccolte",
"ButtonConnect": "Connetti",
@@ -26,7 +27,9 @@
"ButtonLatest": "Ultimi",
"ButtonLibrary": "Biblioteca",
"ButtonLocalMedia": "Media locali",
"ButtonLogs": "Registri",
"ButtonManageLocalFiles": "Gestisci file locali",
"ButtonMaskServerAddress": "Nascondi l'indirizzo server",
"ButtonNewFolder": "Nuova cartella",
"ButtonNextEpisode": "Prossimo episodio",
"ButtonOk": "D'accordo",
@@ -50,6 +53,7 @@
"ButtonStream": "Stream",
"ButtonSubmit": "Invia",
"ButtonSwitchServerUser": "Cambia Server/Utente",
"ButtonUnmaskServerAddress": "Mostra l'indirizzo server",
"ButtonUserStats": "Statistiche utente",
"ButtonYes": "Sì",
"HeaderAccount": "Account",
@@ -114,10 +118,10 @@
"LabelClosePlayer": "Chiudi player",
"LabelCollapseSeries": "Comprimi Serie",
"LabelComplete": "Completo",
"LabelContinueBooks": "Continua Libri",
"LabelContinueEpisodes": "Continua Episodi",
"LabelContinueListening": "Continua Ascolto",
"LabelContinueReading": "Continua Lettura",
"LabelContinueBooks": "Continua i libri",
"LabelContinueEpisodes": "Continua gli episodi",
"LabelContinueListening": "Continua l'ascolto",
"LabelContinueReading": "Continua la lettura",
"LabelContinueSeries": "Continua serie",
"LabelCustomTime": "Personalizza tempo",
"LabelDescription": "Descrizione",
@@ -137,7 +141,7 @@
"LabelEbooks": "Libri digitali",
"LabelEnable": "Abilita",
"LabelEnableMp3IndexSeeking": "Abilita la ricerca dell'indice mp3",
"LabelEnableMp3IndexSeekingHelp": "Questa impostazione dovrebbe essere abilitata solo se hai file mp3 che non vengono ricercati correttamente. La ricerca imprecisa è molto probabilmente dovuta ai file MP3 a birate variabile (VBR). Questa impostazione imporrà la ricerca dell'indice, in cui viene creata una mappatura tempo-byte durante la lettura del file. In alcuni casi, con file MP3 di grandi dimensioni, si verificherà un ritardo durante la ricerca verso la fine del file.",
"LabelEnableMp3IndexSeekingHelp": "Questa impostazione dovrebbe essere abilitata solo se si dispone di file mp3 la cui ricerca non viene eseguita correttamente. Una ricerca imprecisa è molto probabilmente dovuta a file MP3 con bitrate variabile (VBR). Questa impostazione forza la ricerca dell'indice, in cui viene creata una mappatura tempo-byte durante la lettura del file. In alcuni casi, con file MP3 di grandi dimensioni, si verificherà un ritardo nella ricerca verso la fine del file.",
"LabelEnd": "Fine",
"LabelEndOfChapter": "Fine Capitolo",
"LabelEndTime": "Tempo alla fine",
@@ -216,6 +220,7 @@
"LabelPublishedDate": "Pubblicati {0}",
"LabelRSSFeedCustomOwnerEmail": "E-mail del proprietario personalizzato",
"LabelRSSFeedCustomOwnerName": "Nome del proprietario personalizzato",
"LabelRSSFeedOpen": "Feed RSS aperto",
"LabelRSSFeedPreventIndexing": "Impedisci l'indicizzazione",
"LabelRSSFeedSlug": "Parole chiave del flusso RSS",
"LabelRandomly": "Casualmente",
@@ -237,6 +242,8 @@
"LabelShowAll": "Mostra tutto",
"LabelSize": "Dimensione",
"LabelSleepTimer": "Temporizzatore",
"LabelSleepTimerAlmostDoneChime": "Riproduci un suono quando è quasi finito",
"LabelSleepTimerAlmostDoneChimeHelp": "Riproduci un suono quando mancano 30 secondi al timer di spegnimento",
"LabelStart": "Inizo",
"LabelStartTime": "Tempo di inizio",
"LabelStatsBestDay": "Giorno migliore",
@@ -310,6 +317,7 @@
"MessageNoItems": "Nessun oggetto",
"MessageNoItemsFound": "Nessun oggetto trovato",
"MessageNoListeningSessions": "Nessuna sessione di ascolto",
"MessageNoLogs": "Nessun registro",
"MessageNoMediaFolders": "Nessuna cartella media",
"MessageNoNetworkConnection": "Nessuna connessione di rete",
"MessageNoPodcastsFound": "Nessun podcast trovato",
+23 -2
View File
@@ -6,6 +6,7 @@
"ButtonCancel": "Annuleren",
"ButtonCancelTimer": "Timer annuleren",
"ButtonClearFilter": "Filter verwijderen",
"ButtonClearLogs": "Log bestanden verwijderen",
"ButtonCloseFeed": "Feed sluiten",
"ButtonCollections": "Collecties",
"ButtonConnect": "Verbinden",
@@ -26,9 +27,12 @@
"ButtonLatest": "Meest recent",
"ButtonLibrary": "Bibliotheek",
"ButtonLocalMedia": "Lokale Media",
"ButtonLogs": "Log bestanden",
"ButtonManageLocalFiles": "Beheer Lokale Bestanden",
"ButtonMaskServerAddress": "Server adres maskeren",
"ButtonNewFolder": "Nieuwe map",
"ButtonNextEpisode": "Volgende aflevering",
"ButtonOk": "Akkoord",
"ButtonOpenFeed": "Feed openen",
"ButtonOverride": "Overschrijven",
"ButtonPause": "Pauze",
@@ -49,6 +53,7 @@
"ButtonStream": "Streamen",
"ButtonSubmit": "Indienen",
"ButtonSwitchServerUser": "Verwissel server/gebruiker",
"ButtonUnmaskServerAddress": "Ontmasker server adres",
"ButtonUserStats": "Gebruiker statistieken",
"ButtonYes": "Ja",
"HeaderAccount": "Account",
@@ -74,6 +79,7 @@
"HeaderPlaybackSettings": "Afspeel instellingen",
"HeaderPlaylist": "Afspeellijst",
"HeaderPlaylistItems": "Onderdelen in afspeellijst",
"HeaderProgressSyncFailed": "Voortgang synchronisatie mislukt",
"HeaderRSSFeed": "RSS Feed",
"HeaderRSSFeedGeneral": "RSS-details",
"HeaderRSSFeedIsOpen": "RSS-feed is open",
@@ -103,7 +109,7 @@
"LabelAutoDownloadEpisodes": "Afleveringen automatisch downloaden",
"LabelAutoRewindTime": "Automatisch Terugspoelen",
"LabelAutoSleepTimer": "Automatische sleep timer",
"LabelAutoSleepTimerAutoRewind": "Automatische slaap timer automatisch terugspoelen.",
"LabelAutoSleepTimerAutoRewind": "Automatische slaap timer automatisch terugspoelen",
"LabelAutoSleepTimerAutoRewindHelp": "Wanneer de automatische slaap timer afloop zal het item terugspoelen naar de vorige positie.",
"LabelAutoSleepTimerHelp": "Wanneer er tussen de opgegeven begin- en eindtijd media wordt afgespeeld, start er automatisch een slaaptimer.",
"LabelBooks": "Boeken",
@@ -162,6 +168,7 @@
"LabelInternalAppStorage": "Interne App Opslag",
"LabelJumpBackwardsTime": "Terug in tijd springen",
"LabelJumpForwardsTime": "Verder in tijd springen",
"LabelKeepScreenAwake": "Scherm actief houden",
"LabelLanguage": "Taal",
"LabelLayout": "Layout",
"LabelLayoutAuto": "Automatisch",
@@ -176,6 +183,7 @@
"LabelLow": "Laag",
"LabelMediaType": "Mediatype",
"LabelMedium": "Medium",
"LabelMissing": "Missende",
"LabelMore": "Meer",
"LabelMoreInfo": "Meer info",
"LabelName": "Naam",
@@ -193,6 +201,8 @@
"LabelNotFinished": "Niet Voltooid",
"LabelNotStarted": "Niet Gestart",
"LabelNumEpisodes": "{0} afleveringen",
"LabelNumEpisodesIncomplete": "{0} afleveringen, {1} incompleet",
"LabelNumberOfEpisodes": "# Afleveringen",
"LabelOff": "Uit",
"LabelOn": "Aan",
"LabelPassword": "Wachtwoord",
@@ -210,6 +220,7 @@
"LabelPublishedDate": "{0} gepubliceerd",
"LabelRSSFeedCustomOwnerEmail": "Aangepast e-mailadres eigenaar",
"LabelRSSFeedCustomOwnerName": "Aangepaste naam eigenaar",
"LabelRSSFeedOpen": "RSS Feed Open",
"LabelRSSFeedPreventIndexing": "Voorkom indexering",
"LabelRSSFeedSlug": "RSS-feed slug",
"LabelRandomly": "Willekeurig",
@@ -221,7 +232,7 @@
"LabelScaleElapsedTimeBySpeed": "Schaal verstreken tijd per snelheid",
"LabelSeason": "Seizoen",
"LabelSelectADevice": "Apparaat Selecteren",
"LabelSequenceAscending": "Sequentie opflopend",
"LabelSequenceAscending": "Sequentie Oplopend",
"LabelSequenceDescending": "Sequentie Aflopend",
"LabelSeries": "Serie",
"LabelServerAddress": "Server adres",
@@ -231,6 +242,8 @@
"LabelShowAll": "Toon alle",
"LabelSize": "Grootte",
"LabelSleepTimer": "Slaaptimer",
"LabelSleepTimerAlmostDoneChime": "Speel een belsignaal indien bijna klaar",
"LabelSleepTimerAlmostDoneChimeHelp": "Speel een belsignaal af wanneer slaaptimer nog 30 seconden over heeft",
"LabelStart": "Start",
"LabelStartTime": "Starttijd",
"LabelStatsBestDay": "Beste dag",
@@ -246,6 +259,7 @@
"LabelTag": "Tag",
"LabelTags": "Tags",
"LabelTheme": "Thema",
"LabelThemeBlack": "Zwart",
"LabelThemeDark": "Donker",
"LabelThemeLight": "Licht",
"LabelTimeRemaining": "{0} te gaan",
@@ -272,6 +286,7 @@
"MessageBookshelfEmpty": "Boekenplank leeg",
"MessageConfirmDeleteLocalEpisode": "Lokale aflevering \"{0}\" van uw apparaat verwijderen? Het bestand op de server blijft onaangetast.",
"MessageConfirmDeleteLocalFiles": "Lokale bestanden van dit item van uw apparaat verwijderen? De bestanden op de server en uw voortgang worden niet beïnvloed.",
"MessageConfirmDisableAutoTimer": "Weet u zeker dat je de automatische timer voor de rest van vandaag wilt uitschakelen? De timer wordt automatisch weer ingeschakeld aan het einde van deze sluimerperiode of als u de app opnieuw start.",
"MessageConfirmDiscardProgress": "Weet u zeker dat u uw voortgang wilt resetten?",
"MessageConfirmDownloadUsingCellular": "U staat op het punt om te downloaden met behulp van mobiele data. Dit kan kosten voor data van de provider met zich meebrengen. Wilt u doorgaan?",
"MessageConfirmMarkAsFinished": "Weet u zeker dat u dit item als voltooid wilt markeren?",
@@ -286,8 +301,10 @@
"MessageFetching": "Aan het ophalen...",
"MessageFollowTheProjectOnGithub": "Volg dit project op Github",
"MessageItemDownloadCompleteFailedToCreate": "Itemdownload voltooid, maar het aanmaken van een bibliotheekitem is mislukt",
"MessageItemMissing": "Item ontbreekt en moet opgelost worden op de server. Een item is typisch gemarkeerd als ontbrekend wanneer het file pad niet toegankelijk is.",
"MessageLoading": "Aan het laden...",
"MessageLoadingServerData": "Server data laden...",
"MessageLocalFolderDescription": "'Interne app-opslag' is alleen toegankelijk voor deze app. Deze app ondersteunt alleen media die rechtstreeks via de app is gedownload. Gedeelde opslagmappen kunnen worden gebruikt om andere apps toegang te geven tot media die door deze app zijn gedownload.",
"MessageMarkAsFinished": "Markeer als Voltooid",
"MessageMediaLinkedToADifferentServer": "Media is gekoppeld aan een Audiobookshelf-server op een ander adres ({0}). De voortgang wordt gesynchroniseerd wanneer er verbinding is met dit serveradres.",
"MessageMediaLinkedToADifferentUser": "Media is gekoppeld aan deze server, maar is gedownload door een andere gebruiker. De voortgang wordt alleen gesynchroniseerd met de gebruiker die het heeft gedownload.",
@@ -300,13 +317,17 @@
"MessageNoItems": "Geen onderdelen",
"MessageNoItemsFound": "Geen onderdelen gevonden",
"MessageNoListeningSessions": "Geen luistersessies",
"MessageNoLogs": "Geen logbestanden",
"MessageNoMediaFolders": "Geen Media Folders",
"MessageNoNetworkConnection": "Geen netwerk connectie",
"MessageNoPodcastsFound": "Geen podcasts gevonden",
"MessageNoSeries": "Geen series",
"MessageNoUpdatesWereNecessary": "Geen bijwerkingen waren noodzakelijk",
"MessageNoUserPlaylists": "Je hebt geen afspeellijsten",
"MessageOldServerConnectionWarning": "Server connectie configuratie gebruikt een oud user ID. Gelieve deze server connectie te verwijderen en opnieuw toe te voegen.",
"MessageOldServerConnectionWarningHelp": "U hebt de verbinding met deze server oorspronkelijk ingesteld vóór de databasemigratie in versie 2.3.0, uitgebracht in juni 2023. Een toekomstige serverupdate zal de mogelijkheid om in te loggen met deze oude verbinding verwijderen. Verwijder de bestaande serververbinding en maak opnieuw verbinding (met hetzelfde serveradres en dezelfde inloggegevens). Als u gedownloade media op dit apparaat hebt, moet u deze opnieuw downloaden om te synchroniseren met de server.",
"MessagePodcastSearchField": "Zoekterm of RSS feed URL invullen",
"MessageProgressSyncFailed": "De meest recente poging om je luistervoortgang aan de server te rapporteren is mislukt. Verzoeken om voortgangssynchronisatie worden nog steeds elke 15 seconden tot 1 minuut uitgevoerd terwijl de media wordt afgespeeld.",
"MessageReportBugsAndContribute": "Rapporteer bugs, vraag functionaliteiten aan en draag bij op",
"MessageSeriesAlreadyDownloaded": "Je hebt alle boeken in deze serie al gedownload.",
"MessageSeriesDownloadConfirm": "Ontbrekende {0} boek(en) met {1} bestand(en), in totaal {2}, downloaden naar map {3}?",
+16 -2
View File
@@ -1,11 +1,12 @@
{
"ButtonAdd": "Legg til",
"ButtonAddNewServer": "Legg til ny tjener",
"ButtonAuthors": "Forfatter",
"ButtonAuthors": "Forfattere",
"ButtonBack": "Tilbake",
"ButtonCancel": "Avbryt",
"ButtonCancelTimer": "Avbryt tidsur",
"ButtonClearFilter": "Bytt filter",
"ButtonClearFilter": "Fjern filter",
"ButtonClearLogs": "Tøm logger",
"ButtonCloseFeed": "Lukk Feed",
"ButtonCollections": "Samlinger",
"ButtonConnect": "Koble til",
@@ -15,14 +16,20 @@
"ButtonCreateNewPlaylist": "Opprett ny spilleliste",
"ButtonDelete": "Slett",
"ButtonDeleteLocalEpisode": "Slett episode på enheten",
"ButtonDeleteLocalFile": "Slett fil på enheten",
"ButtonDeleteLocalItem": "Slett element på enheten",
"ButtonDisableAutoTimer": "Skru av automatisk tidsur",
"ButtonDisconnect": "Koble fra",
"ButtonGoToWebClient": "Gå til webklient",
"ButtonHistory": "Historikk",
"ButtonHome": "Hjem",
"ButtonIssues": "Problemer",
"ButtonLatest": "Siste",
"ButtonLibrary": "Bibliotek",
"ButtonLocalMedia": "Lokal media",
"ButtonLogs": "Logger",
"ButtonManageLocalFiles": "Administrer Lokale Filer",
"ButtonMaskServerAddress": "Skjul serveradresse",
"ButtonNewFolder": "Ny mappe",
"ButtonNextEpisode": "Neste episode",
"ButtonOk": "Ok",
@@ -33,6 +40,8 @@
"ButtonPlayEpisode": "Spill episode",
"ButtonPlaylists": "Spillelister",
"ButtonRead": "Les",
"ButtonReadLess": "Vis mindre",
"ButtonReadMore": "Vis mer",
"ButtonRemove": "Fjern",
"ButtonRemoveFromServer": "Fjern fra tjeneren",
"ButtonSave": "Lagre",
@@ -40,12 +49,16 @@
"ButtonSearch": "Søk",
"ButtonSendEbookToDevice": "Send e-bok til enhet",
"ButtonSeries": "Serier",
"ButtonSetTimer": "Sett tidsur",
"ButtonStream": "Strøm",
"ButtonSubmit": "Send inn",
"ButtonSwitchServerUser": "Bytt tjener/bruker",
"ButtonUnmaskServerAddress": "Vis serveradresse",
"ButtonUserStats": "Brukerstatistikk",
"ButtonYes": "Ja",
"HeaderAccount": "Konto",
"HeaderAdvanced": "Avansert",
"HeaderAndroidAutoSettings": "Android Auto-innstillinger",
"HeaderAudioTracks": "Lydspor",
"HeaderChapters": "Kapittel",
"HeaderCollection": "Samlinger",
@@ -53,6 +66,7 @@
"HeaderConnectionStatus": "Tilkoblingsstatus",
"HeaderDataSettings": "Datainnstillinger",
"HeaderDetails": "Detaljer",
"HeaderDownloads": "Nedlastinger",
"HeaderEbookFiles": "Ebook filer",
"HeaderEpisodes": "Episoder",
"HeaderEreaderSettings": "Ereader innstillinger",
+13 -1
View File
@@ -6,6 +6,7 @@
"ButtonCancel": "Anuluj",
"ButtonCancelTimer": "Anuluj wyłącznik",
"ButtonClearFilter": "Wyczyść filtr",
"ButtonClearLogs": "Wyczyść Logi",
"ButtonCloseFeed": "Zamknij kanał",
"ButtonCollections": "Kolekcje",
"ButtonConnect": "Połącz",
@@ -26,7 +27,9 @@
"ButtonLatest": "Aktualna wersja",
"ButtonLibrary": "Biblioteka",
"ButtonLocalMedia": "Media lokalne",
"ButtonLogs": "Logi",
"ButtonManageLocalFiles": "Zarządzaj lokalnymi plikami",
"ButtonMaskServerAddress": "Ukryj adres serwera",
"ButtonNewFolder": "Nowy folder",
"ButtonNextEpisode": "Następny odcinek",
"ButtonOk": "Ok",
@@ -50,6 +53,7 @@
"ButtonStream": "Strumieniuj",
"ButtonSubmit": "Zapisz",
"ButtonSwitchServerUser": "Przełącz serwer/użytkownika",
"ButtonUnmaskServerAddress": "Pokaż adres serwera",
"ButtonUserStats": "Statystyki użytkownika",
"ButtonYes": "Tak",
"HeaderAccount": "Konto",
@@ -94,6 +98,8 @@
"LabelAll": "Wszystkie",
"LabelAllowSeekingOnMediaControls": "Zezwól na wyszukiwanie pozycji na ekranie blokady",
"LabelAlways": "Zawsze",
"LabelAndroidAutoBrowseLimitForGrouping": "Limit podziału listy alfabetycznej",
"LabelAndroidAutoBrowseLimitForGroupingHelp": "Nie używaj podziału alfabetycznego, jeśli liczba pozycji do pokazania jest mniejsza niż podana",
"LabelAndroidAutoBrowseSeriesSequenceOrder": "Kolejność książek w serii",
"LabelAskConfirmation": "Pytaj o potwierdzenie",
"LabelAuthor": "Autor",
@@ -211,9 +217,10 @@
"LabelProgress": "Postęp",
"LabelPubDate": "Data publikacji",
"LabelPublishYear": "Rok publikacji",
"LabelPublishedDate": "Opublikowane",
"LabelPublishedDate": "Opublikowano {0}",
"LabelRSSFeedCustomOwnerEmail": "Własny email",
"LabelRSSFeedCustomOwnerName": "Własna nazwa",
"LabelRSSFeedOpen": "Otwarty Kanał RSS",
"LabelRSSFeedPreventIndexing": "Zapobiegaj indeksowaniu",
"LabelRSSFeedSlug": "Numer Kanału RSS",
"LabelRandomly": "Losowo",
@@ -235,6 +242,8 @@
"LabelShowAll": "Pokaż wszystko",
"LabelSize": "Rozmiar",
"LabelSleepTimer": "Wyłącznik czasowy",
"LabelSleepTimerAlmostDoneChime": "Odtwórz dźwięk tuż przed zakończeniem",
"LabelSleepTimerAlmostDoneChimeHelp": "Odtwórz dźwięk 30 sekund przed zakończeniem czasu uśpienia",
"LabelStart": "Rozpocznij",
"LabelStartTime": "Czas rozpoczęcia",
"LabelStatsBestDay": "Najlepszy dzień",
@@ -250,6 +259,7 @@
"LabelTag": "Znacznik",
"LabelTags": "Znaczniki",
"LabelTheme": "Motyw",
"LabelThemeBlack": "Czarny",
"LabelThemeDark": "Ciemny",
"LabelThemeLight": "Jasny",
"LabelTimeRemaining": "Pozostało {0}",
@@ -276,6 +286,7 @@
"MessageBookshelfEmpty": "Półka pusta",
"MessageConfirmDeleteLocalEpisode": "Usunąć lokalny odcinek \"{0}\" ze swojego urządzenia? Nie będzie to miało wpływu na plik na serwerze.",
"MessageConfirmDeleteLocalFiles": "Usunąć lokalne pliki tego elementu ze swojego urządzenia? Nie będzie to miało wpływu na pliki na serwerze i Twoje postępy.",
"MessageConfirmDisableAutoTimer": "Czy na pewno chcesz wyłączyć automatyczny timer na resztę dnia? Timer zostanie ponownie aktywowany po upływie czasu automatycznego uśpienia lub po ponownym uruchomieniu aplikacji..",
"MessageConfirmDiscardProgress": "Na pewno chcesz zresetować postęp?",
"MessageConfirmDownloadUsingCellular": "Zamierzasz pobrać poprzez dane komórkowe. Może to wpłynąć na wysokość rachunku. Czy chcesz kontynuować?",
"MessageConfirmMarkAsFinished": "Na pewno chcesz oznaczyć ten element jako ukończony?",
@@ -290,6 +301,7 @@
"MessageFetching": "Pobieranie...",
"MessageFollowTheProjectOnGithub": "Obserwuj projekt na Github'ie",
"MessageItemDownloadCompleteFailedToCreate": "Pobieranie elementu zostało zakończone, ale nie udało się utworzyć elementu biblioteki",
"MessageItemMissing": "Brakujący element, należy go naprawić na serwerze. Zazwyczaj element jest oznaczany jako brakujący, ponieważ ścieżki do plików nie są dostępne.",
"MessageLoading": "Ładowanie...",
"MessageLoadingServerData": "Ładowanie danych serwera...",
"MessageMarkAsFinished": "Oznacz jako ukończone",
+9 -1
View File
@@ -6,6 +6,7 @@
"ButtonCancel": "Отмена",
"ButtonCancelTimer": "Отмена таймера",
"ButtonClearFilter": "Очистить фильтр",
"ButtonClearLogs": "Очистить журнал",
"ButtonCloseFeed": "Закрыть канал",
"ButtonCollections": "Коллекции",
"ButtonConnect": "Подключение",
@@ -26,7 +27,9 @@
"ButtonLatest": "Последнее",
"ButtonLibrary": "Библиотека",
"ButtonLocalMedia": "Локальные медиа",
"ButtonLogs": "Журнал",
"ButtonManageLocalFiles": "Управление локальными файлами",
"ButtonMaskServerAddress": "Скрывать адрес сервера",
"ButtonNewFolder": "Новая папка",
"ButtonNextEpisode": "Следующий эпизод",
"ButtonOk": "Ок",
@@ -50,6 +53,7 @@
"ButtonStream": "Стрим",
"ButtonSubmit": "Применить",
"ButtonSwitchServerUser": "Изменить Сервер/Пользователя",
"ButtonUnmaskServerAddress": "Не скрывать адрес сервера",
"ButtonUserStats": "Статистика пользователя",
"ButtonYes": "Да",
"HeaderAccount": "Учетная запись",
@@ -132,7 +136,7 @@
"LabelDownload": "Скачать",
"LabelDownloadUsingCellular": "Загрузка с помощью сотовой связи",
"LabelDownloaded": "Загружено",
"LabelDuration": "Продолжительность",
"LabelDuration": "Длительность",
"LabelEbook": "E-книга",
"LabelEbooks": "E-книги",
"LabelEnable": "Включить",
@@ -216,6 +220,7 @@
"LabelPublishedDate": "Опубликовано {0}",
"LabelRSSFeedCustomOwnerEmail": "Пользовательский Email владельца",
"LabelRSSFeedCustomOwnerName": "Пользовательское Имя владельца",
"LabelRSSFeedOpen": "Открыть RSS-ленту",
"LabelRSSFeedPreventIndexing": "Запретить индексирование",
"LabelRSSFeedSlug": "Встроить RSS-канал",
"LabelRandomly": "Случайно",
@@ -237,6 +242,8 @@
"LabelShowAll": "Показать все",
"LabelSize": "Размер",
"LabelSleepTimer": "Таймер сна",
"LabelSleepTimerAlmostDoneChime": "Звуковое предупреждение перед истечением срока",
"LabelSleepTimerAlmostDoneChimeHelp": "Воспроизвести звуковой сигнал за 30 секунд до истечения таймера сна",
"LabelStart": "Начало",
"LabelStartTime": "Время начала",
"LabelStatsBestDay": "Лучший День",
@@ -310,6 +317,7 @@
"MessageNoItems": "Нет элементов",
"MessageNoItemsFound": "Элементы не найдены",
"MessageNoListeningSessions": "Нет сеансов прослушивания",
"MessageNoLogs": "Нет записей",
"MessageNoMediaFolders": "Нет папок мультимедиа",
"MessageNoNetworkConnection": "Нет подключения к сети",
"MessageNoPodcastsFound": "Подкасты не найдены",
+354
View File
@@ -0,0 +1,354 @@
{
"ButtonAdd": "Pridať",
"ButtonAddNewServer": "Pridať nový server",
"ButtonAuthors": "Autori",
"ButtonBack": "Späť",
"ButtonCancel": "Zrušiť",
"ButtonCancelTimer": "Zrušiť časovač",
"ButtonClearFilter": "Zrušiť filter",
"ButtonClearLogs": "Zmazať záznamy logovania",
"ButtonCloseFeed": "Zatvoriť zdroj",
"ButtonCollections": "Kolekcie",
"ButtonConnect": "Pripojiť",
"ButtonConnectToServer": "Pripojte sa k serveru",
"ButtonCreate": "Vytvoriť",
"ButtonCreateBookmark": "Vytvoriť záložku",
"ButtonCreateNewPlaylist": "Vytvoriť nový playlist",
"ButtonDelete": "Zmazať",
"ButtonDeleteLocalEpisode": "Odstrániť lokálnu epizódu",
"ButtonDeleteLocalFile": "Odstrániť lokálny súbor",
"ButtonDeleteLocalItem": "Odstrániť lokálnu položku",
"ButtonDisableAutoTimer": "Vypnúť automatický časovač",
"ButtonDisconnect": "Odpojiť",
"ButtonGoToWebClient": "Prejsť na webové rozhranie",
"ButtonHistory": "História",
"ButtonHome": "Domov",
"ButtonIssues": "Problémy",
"ButtonLatest": "Najnovšie",
"ButtonLibrary": "Knižnica",
"ButtonLocalMedia": "Lokálne médiá",
"ButtonLogs": "Záznamy logovania",
"ButtonManageLocalFiles": "Spravovať lokálne súbory",
"ButtonMaskServerAddress": "Maska adresy servera",
"ButtonNewFolder": "Nový priečinok",
"ButtonNextEpisode": "Ďalšia epizóda",
"ButtonOk": "OK",
"ButtonOpenFeed": "Otvoriť zdroj",
"ButtonOverride": "Uprednostniť",
"ButtonPause": "Pozastaviť",
"ButtonPlay": "Prehrať",
"ButtonPlayEpisode": "Prehrať epizódu",
"ButtonPlaylists": "Playlisty",
"ButtonRead": "Načítať",
"ButtonReadLess": "Načítať menej",
"ButtonReadMore": "Načítať viac",
"ButtonRemove": "Odstrániť",
"ButtonRemoveFromServer": "Odstrániť zo servera",
"ButtonSave": "Uložiť",
"ButtonSaveOrder": "Uložiť poradie",
"ButtonSearch": "Vyhľadať",
"ButtonSendEbookToDevice": "Poslať e-knihu do zariadenia",
"ButtonSeries": "Série",
"ButtonSetTimer": "Nastaviť časovač",
"ButtonStream": "Všeobecný",
"ButtonSubmit": "Odoslať",
"ButtonSwitchServerUser": "Zmeniť server/používateľa",
"ButtonUnmaskServerAddress": "Odmaskovať adresu servera",
"ButtonUserStats": "Štatistiky používateľov",
"ButtonYes": "Áno",
"HeaderAccount": "Účet",
"HeaderAdvanced": "Pokročilé",
"HeaderAndroidAutoSettings": "Nastavenia Android Auto",
"HeaderAudioTracks": "Zvukové stopy",
"HeaderChapters": "Kapitoly",
"HeaderCollection": "Zbierky",
"HeaderCollectionItems": "Položky zbierky",
"HeaderConnectionStatus": "Stav pripojenia",
"HeaderDataSettings": "Nastavenie dát",
"HeaderDetails": "Podrobnosti",
"HeaderDownloads": "Stiahnuté súbory",
"HeaderEbookFiles": "Súbory e-kníh",
"HeaderEpisodes": "Epizódy",
"HeaderEreaderSettings": "Nastavenia čítačky",
"HeaderLatestEpisodes": "Posledné epizódy",
"HeaderLibraries": "Knižnice",
"HeaderLocalFolders": "Lokálne priečinky",
"HeaderLocalLibraryItems": "Položky lokálnej knižnice",
"HeaderNewPlaylist": "Nový playlist",
"HeaderOpenRSSFeed": "Otvoriť RSS zdroj",
"HeaderPlaybackSettings": "Nastavenie prehrávania",
"HeaderPlaylist": "Playlist",
"HeaderPlaylistItems": "Položky playlistu",
"HeaderProgressSyncFailed": "Synchronizovanie aktuálneho stavu zlyhalo",
"HeaderRSSFeed": "RSS zdroj",
"HeaderRSSFeedGeneral": "Detaily RSS",
"HeaderRSSFeedIsOpen": "RSS zdroj je otvorený",
"HeaderSelectDownloadLocation": "Vyberte miesto na stiahnutie",
"HeaderSettings": "Nastavenia",
"HeaderSleepTimer": "Časovač spánku",
"HeaderSleepTimerSettings": "Nastavenia časovaču spánku",
"HeaderStatsMinutesListeningChart": "Vypočutých minút (za posledných 7 dní)",
"HeaderStatsRecentSessions": "Nedávne relácie",
"HeaderTableOfContents": "Obsah",
"HeaderUserInterfaceSettings": "Nastavenia používateľského rozhrania",
"HeaderYourStats": "Vaše štatistiky",
"LabelAddToPlaylist": "Pridať do playlistu",
"LabelAddedAt": "Pridané",
"LabelAddedDate": "Pridané {0}",
"LabelAll": "Všetko",
"LabelAllowSeekingOnMediaControls": "Povoliť zmenu pozície prehrávania v mediálnych notifikáciách",
"LabelAlways": "Vždy",
"LabelAndroidAutoBrowseLimitForGrouping": "Limit abecedného posunu",
"LabelAndroidAutoBrowseLimitForGroupingHelp": "Nezobrazí možnosť abecedného posunu, ak je počet zobrazených položiek menší ako limit",
"LabelAndroidAutoBrowseSeriesSequenceOrder": "Poradie kníh série",
"LabelAskConfirmation": "Požiadať o potvrdenie",
"LabelAuthor": "Autor",
"LabelAuthorFirstLast": "Autor (Meno Priezvisko)",
"LabelAuthorLastFirst": "Autor (Priezvisko, Meno)",
"LabelAuthors": "Autori",
"LabelAutoDownloadEpisodes": "Automaticky sťahovať epizódy",
"LabelAutoRewindTime": "Automatické presunutie času",
"LabelAutoSleepTimer": "Auto časovač spánku",
"LabelAutoSleepTimerAutoRewind": "Automatické posunutie času pre Auto časovač spánku",
"LabelAutoSleepTimerAutoRewindHelp": "Keď Auto časovač spánku skončí, pred nasledujúcim prehratím položky sa prehrávanie automaticky posunie.",
"LabelAutoSleepTimerHelp": "keď sa prehrávanie začne vo vymedzenom časovom intervale, časovač spánku sa automaticky spustí tiež.",
"LabelBooks": "Knihy",
"LabelChapterTrack": "Zvuková stopa kapitoly",
"LabelChapters": "Kapitoly",
"LabelClosePlayer": "Zavrieť prehrávač",
"LabelCollapseSeries": "Zbaliť série",
"LabelComplete": "Hotovo",
"LabelContinueBooks": "Pokračovať v knihách",
"LabelContinueEpisodes": "Pokračovať v epizódach",
"LabelContinueListening": "Pokračovať v počúvaní",
"LabelContinueReading": "Pokračovať v čítaní",
"LabelContinueSeries": "Pokračovať v sérii",
"LabelCustomTime": "Vlastný čas",
"LabelDescription": "Popis",
"LabelDisableAudioFadeOut": "Vypnúť fade out",
"LabelDisableAudioFadeOutHelp": "Hlasitosť prehrávania sa automaticky začne znižovať, ak zostáva menej ako 1 minúta na časovači spánku. Povolením tejto voľby sa fade out efekt vypne.",
"LabelDisableAutoRewind": "Vypnúť automatické presúvanie",
"LabelDisableShakeToReset": "Vypnúť reštart potrasením",
"LabelDisableShakeToResetHelp": "Potrasením vášho zariadenia v prípade, ak časovač beží ALEBO na ňom zostáva menej ako 2 minúty, dôjde k rešttartovaniu časovača. Povolením tejto voľby reštart zatrasením vypnete.",
"LabelDisableVibrateOnReset": "Vypnúť vybrovanie pri reštarte",
"LabelDisableVibrateOnResetHelp": "Keď sa čas na časovači spánku uplynie, časovač spánku sa reštartuje a vaše zariadenie zavibruje. Povolením tejto voľby vybrovanie vypnete.",
"LabelDiscover": "Objaviť",
"LabelDownload": "Stiahnuť",
"LabelDownloadUsingCellular": "Stiahnuť cez mobilné dáta",
"LabelDownloaded": "Stiahnuté",
"LabelDuration": "Dĺžka",
"LabelEbook": "E-kniha",
"LabelEbooks": "E-knihy",
"LabelEnable": "Povoliť",
"LabelEnableMp3IndexSeeking": "Povoliť vyhľadávanie v MP3 indexe",
"LabelEnableMp3IndexSeekingHelp": "Táto voľba by mala byť zapnutá iba v prípade, ak vaše MP3 súbory nie sú vyhľadané správne. Príčinou nesprávneho vyhľadania je najčastejšie meniaci sa bitrate (VBR) MP3 súborov. Toto nastavenie vynúti vyhľadávanie na báze indexu, v ktorom je počas načítania súboru vytvorené time-to-byte mapovanie. V prípade niektorých veľkých MP3 súborov sa pri čítaní ku koncu súboru môže objaviť dlhšia pauza.",
"LabelEnd": "Ukončiť",
"LabelEndOfChapter": "Koniec kapitoly",
"LabelEndTime": "Čas ukončenia",
"LabelEpisode": "Epizóda",
"LabelFeedURL": "URL zdroja",
"LabelFile": "Súbor",
"LabelFileBirthtime": "Čas vytvorenia súboru",
"LabelFileModified": "Súbor zmenený",
"LabelFilename": "Názov súboru",
"LabelFinished": "Ukončené",
"LabelFolder": "Priečinok",
"LabelFontBoldness": "Hrúbka písma",
"LabelFontScale": "Veľkosť písma",
"LabelGenre": "Žáner",
"LabelGenres": "Žánre",
"LabelHapticFeedback": "Haptická spätná väzba",
"LabelHasEbook": "Má e-knihu",
"LabelHasSupplementaryEbook": "Má doplnkovú e-knihu",
"LabelHeavy": "Ťažký",
"LabelHigh": "Vysoký",
"LabelHost": "Host",
"LabelInProgress": "Prebieha",
"LabelIncomplete": "Nekompletné",
"LabelInternalAppStorage": "Interné úložisko aplikácie",
"LabelJumpBackwardsTime": "Časový skok dozadu",
"LabelJumpForwardsTime": "Časový skok dopredu",
"LabelKeepScreenAwake": "Ponechať displej zapnutý",
"LabelLanguage": "Jazyk",
"LabelLayout": "Rozloženie",
"LabelLayoutAuto": "Auto",
"LabelLayoutSinglePage": "Jedna stránka",
"LabelLight": "Svetlá",
"LabelLineSpacing": "Riadkovanie",
"LabelListenAgain": "Počúvať znova",
"LabelLocalBooks": "Lokálne knihy",
"LabelLocalPodcasts": "Lokálne podcasty",
"LabelLockOrientation": "Uzamknúť orientáciu",
"LabelLockPlayer": "Uzamknúť prehrávač",
"LabelLow": "Nízky",
"LabelMediaType": "Typ média",
"LabelMedium": "Stredný",
"LabelMissing": "Chýbajúce",
"LabelMore": "Viac",
"LabelMoreInfo": "Viac informácií",
"LabelName": "Meno",
"LabelNarrator": "Interpret",
"LabelNarrators": "Interpreti",
"LabelNavigateWithVolume": "Navigovať tlačítkami hlasitosti",
"LabelNavigateWithVolumeMirrored": "Zrkadlový",
"LabelNavigateWithVolumeWhilePlaying": "Povoliť navigáciu tlačítkami hlasitosti počas prehrávania",
"LabelNavigateWithVolumeWhilePlayingDisabled": "Vypnuté",
"LabelNavigateWithVolumeWhilePlayingEnabled": "Zapnuté",
"LabelNever": "Nikdy",
"LabelNewestAuthors": "Najnovší autori",
"LabelNewestEpisodes": "Najnovšie epizódy",
"LabelNo": "Nie",
"LabelNotFinished": "Nedokončené",
"LabelNotStarted": "Nezačaté",
"LabelNumEpisodes": "{0} epizód",
"LabelNumEpisodesIncomplete": "{0} epizód, {1} nekompletných",
"LabelNumberOfEpisodes": "# z epizód",
"LabelOff": "Vypnuté",
"LabelOn": "Zapnuté",
"LabelPassword": "Heslo",
"LabelPath": "Cesta",
"LabelPlaybackDirect": "Priamy",
"LabelPlaybackLocal": "Lokálny",
"LabelPlaybackSpeed": "Rýchlosť prehrávania",
"LabelPlaybackTranscode": "Transkódovať",
"LabelPodcast": "Podcast",
"LabelPodcasts": "Podcasty",
"LabelPreventIndexing": "Zabráni indexácii vašich zdrojov službami iTunes a Google podcast directories",
"LabelProgress": "Stav",
"LabelPubDate": "Dátum publikovania",
"LabelPublishYear": "Rok vydania",
"LabelPublishedDate": "Vydané {0}",
"LabelRSSFeedCustomOwnerEmail": "Vlastný e-mail vlastníka",
"LabelRSSFeedCustomOwnerName": "Vlastné meno vlastníka",
"LabelRSSFeedOpen": "RSS zdroj otvorený",
"LabelRSSFeedPreventIndexing": "Zakázať indexovanie",
"LabelRSSFeedSlug": "Slug RSS zdroja",
"LabelRandomly": "Náhodne",
"LabelRead": "Načítať",
"LabelReadAgain": "Čítať znova",
"LabelRecentSeries": "Posledné série",
"LabelRecentlyAdded": "Posledné pridané",
"LabelRemoveFromPlaylist": "Odstrániť z playlistu",
"LabelScaleElapsedTimeBySpeed": "Zmeniť ubehnutý čas podľa rýchlosti",
"LabelSeason": "Sezóna",
"LabelSelectADevice": "Vyberte zariadenie",
"LabelSequenceAscending": "Vzostupné poradie",
"LabelSequenceDescending": "Zostupné poradie",
"LabelSeries": "Série",
"LabelServerAddress": "Adresa servera",
"LabelSetEbookAsPrimary": "Nastaviť ako primárny",
"LabelSetEbookAsSupplementary": "Nastaviť ako doplnkový",
"LabelShakeSensitivity": "Citlivosť na trasenie",
"LabelShowAll": "Zobraziť všetko",
"LabelSize": "Veľkosť",
"LabelSleepTimer": "Časovač spánku",
"LabelSleepTimerAlmostDoneChime": "Zahrať akord pred dokončením",
"LabelSleepTimerAlmostDoneChimeHelp": "Zahrá akord, keď na časovači spánku zostáva 30 sekúnd",
"LabelStart": "Spustiť",
"LabelStartTime": "Čas spustenia",
"LabelStatsBestDay": "Najlepší deň",
"LabelStatsDailyAverage": "Denný priemer",
"LabelStatsDays": "Dní",
"LabelStatsDaysListened": "Dní počúvania",
"LabelStatsInARow": "v rade",
"LabelStatsItemsFinished": "Dokončených položiek",
"LabelStatsMinutes": "minút",
"LabelStatsMinutesListening": "Minút počúvania",
"LabelStatsWeekListening": "Týždňov počúvania",
"LabelStreamingUsingCellular": "Streamovanie na mobilných dátach",
"LabelTag": "Štítok",
"LabelTags": "Štítky",
"LabelTheme": "Téma",
"LabelThemeBlack": "Čierna",
"LabelThemeDark": "Tmavá",
"LabelThemeLight": "Svetlá",
"LabelTimeRemaining": "Zostáva {0}",
"LabelTitle": "Názov",
"LabelTotalSize": "Celková veľkosť",
"LabelTotalTrack": "Celková stopa",
"LabelTracks": "Stopy",
"LabelType": "Typ",
"LabelUnknown": "Neznámy",
"LabelUnlockPlayer": "Odomknúť prehrávač",
"LabelUseBookshelfView": "Použiť zobrazenie poličiek",
"LabelUser": "Používateľ",
"LabelUsername": "Prihlasovacie meno",
"LabelVeryHigh": "Veľmi vysoká",
"LabelVeryLow": "Veľmi nízka",
"LabelYearReviewHide": "Skryť rok v prehľade",
"LabelYearReviewShow": "Zobraziť rok v prehľade",
"LabelYourBookmarks": "Vaše záložky",
"LabelYourProgress": "Váš aktuálny stav",
"MessageAndroid10Downloads": "Android 10 a nižšie používajú na sťahovanie lokálny odkladací priestor aplikácie.",
"MessageAttemptingServerConnection": "Pokus o pripojenie servera...",
"MessageAudiobookshelfServerNotConnected": "Audiobookshelf server nie je pripojený",
"MessageAudiobookshelfServerRequired": "<strong>Dôležité!</strong> Táto aplikácia je navrhnutá na fungovanie so Audiobookshelf serverom, ktorý patrí vám alebo niekomu inému. Táto aplikácia sama o sebe neposkytuje žiadny obsah.",
"MessageBookshelfEmpty": "Polička je prázdna",
"MessageConfirmDeleteLocalEpisode": "Želáte si odstrániť lokálnu epizódu \"{0}\" z vášho zariadenia? Súbor na serveri zostane nezmenený.",
"MessageConfirmDeleteLocalFiles": "Želáte si odstrániť z vášho zariadenia lokálne súbory patriace k tejto položke? Súbory na serveri a váš aktuálny stav počúvania zostanú nezmenené.",
"MessageConfirmDisableAutoTimer": "Ste si istí, že chcete vypnúť automatický časovač pre zvyšok dnešného dňa? Časovač sa znova zapne na konci nastavenej doby pre automatický časovač spánku alebo pri reštarte aplikácie.",
"MessageConfirmDiscardProgress": "Ste si istý, že chcete resetovať váš aktuálny stav počúvania?",
"MessageConfirmDownloadUsingCellular": "Chystáte sa sťahovať pri používaní mobilných dát. Toto môže mať za následok zvýšené poplatky u vášho poskytovateľ mobilnej siete. Chcete pokračovať?",
"MessageConfirmMarkAsFinished": "Ste si istý, že chcete označiť túto položku ako dokončenú?",
"MessageConfirmRemoveBookmark": "Ste si istý, že chcete odstrániť túto záložku?",
"MessageConfirmStreamingUsingCellular": "Chystáte sa streamovať pri používaní mobilných dát. To môže mať za následok zvýšené poplatky za využité dáta. Chcete pokračovať?",
"MessageDiscardProgress": "Odstrániť aktuálny stav počúvania",
"MessageDownloadCompleteProcessing": "Sťahovanie dokončené. Spracovávam...",
"MessageDownloading": "Sťahujem...",
"MessageDownloadingEpisode": "Sťahovanie epizódy",
"MessageEpisodesQueuedForDownload": "{0} epizód(a) v zozname na sťahovanie",
"MessageFeedURLWillBe": "URL zdroja bude {0}",
"MessageFetching": "Získavam...",
"MessageFollowTheProjectOnGithub": "Sledujte projekt na Github-e",
"MessageItemDownloadCompleteFailedToCreate": "Stiahnutie položky prebehlo úspešne, ale zlyhalo vytvorenie položky v knižnici",
"MessageItemMissing": "Položka neexistuje, chybu je nutné opraviť na serveri. Najčastejšou príčinou označenia položky za chýbajúcu je nedostupnosť jej umiestnenia.",
"MessageLoading": "Načítavam...",
"MessageLoadingServerData": "Načítavam údaje zo servera...",
"MessageLocalFolderDescription": "'Lokálny odkladací pristor aplikácie' je prístupný len cez aplikáciu. Aplikáciou je možné prehrávať iba médiá stiahnuté cez aplikáciu. Zdieľanie priečinkov aplikácie umožňuje iným aplikáciám pristupovať k médiám stiahnutým aplikáciou Audiobookshelf.",
"MessageMarkAsFinished": "Označiť ako dokončené",
"MessageMediaLinkedToADifferentServer": "Médiá majú prepojenie na Audiobookshelf server bežiaci na odlišnej adrese ({0}). Aktuálny stav počúvania bude synchronizovaný po pripojení k danému serveru.",
"MessageMediaLinkedToADifferentUser": "Média majú prepojenie na aktuálny server, ale boli stiahnuté odlišným používateľom. Stav počúvania bude synchronizovaný iba pre používateľa, ktorý ich stiahol.",
"MessageMediaLinkedToServer": "Prepojené na server {0}",
"MessageMediaLinkedToThisServer": "Stiahnuté médiá sú prepojené s týmto serverom",
"MessageMediaNotLinkedToServer": "Médiá nie sú prepojené na Audiobookshelf server. Stav počúvania nebude synchronizovaný.",
"MessageNoBookmarks": "Žiadne záložky",
"MessageNoChapters": "Žiadne kapitoly",
"MessageNoCollections": "Žiadne zbierky",
"MessageNoItems": "Žiadne položky",
"MessageNoItemsFound": "Žiadne položky neboli nájdené",
"MessageNoListeningSessions": "Žiadne relácie",
"MessageNoLogs": "Žiadne záznamy udalostí",
"MessageNoMediaFolders": "Žiadne priečinky médií",
"MessageNoNetworkConnection": "Žiadne sieťové pripojenie",
"MessageNoPodcastsFound": "Žiadne podcasty neboli nájdené",
"MessageNoSeries": "Žiadne série",
"MessageNoUpdatesWereNecessary": "Neboli potrebné žiadne aktualizácie",
"MessageNoUserPlaylists": "Nemáte žiadny playlist",
"MessageOldServerConnectionWarning": "Konfigurácia pripojenia na server používa staré ID používateľa. Prosím, odstráňte a nanovo pridajte dané pripojenie.",
"MessageOldServerConnectionWarningHelp": "Pripojenie na tento server bolo nakonfigurované pred migráciou databázy vo verzii 2.3.0, vydanej v júni 2023. V budúcej aktualizácii servera bude možnosť prihlasovania pomocou tohto starého pripojenia odstránená. Prosím, odstráňte aktuálne pripojenie na server a vytvorte nové (pomocou rovnakej adresy a prihlasovacích údajov). V prípade, ak máte na zariadení lokálne stiahnuté akékoľvek médiá, bude potrebné ich stiahnuť nanovo, aby bola možná serverová synchronizácia.",
"MessagePodcastSearchField": "Zadajte hľadaný výraz alebo URL RSS zdroja",
"MessageProgressSyncFailed": "Posledný pokus o odoslanie vášho stavu počúvania na server zlyhal. Aplikácia sa pokúsi odoslať váš stav každých 15 sekúnd až 1 minúty počas prehrávania média.",
"MessageReportBugsAndContribute": "Nahlásiť chyby, požiadavky na funkcie, a prispievať na",
"MessageSeriesAlreadyDownloaded": "Už ste si stiahli všetky knihy v tejto sérii.",
"MessageSeriesDownloadConfirm": "Stiahnuť chýbajúce: {0} knihu(-íh) obsahujúce {1} súbor(-ov), celkovo {2} do priečinka {3}?",
"MessageSeriesDownloadConfirmIos": "Stiahnuť chýbajúce: {0} knihu(-íh) s {1} súborom(-mi), celkovo {2}?",
"MessageSocketConnectedOverMeteredCellular": "Socket pripojený cez merané mobilné dáta",
"MessageSocketConnectedOverMeteredWifi": "Socket pripojený cez meranú wifi",
"MessageSocketConnectedOverUnmeteredCellular": "Socket pripojený cez nemerané mobilné dáta",
"MessageSocketConnectedOverUnmeteredWifi": "Socket pripojený cez nemeranú wifi",
"MessageSocketNotConnected": "Socket nie je pripojený",
"NoteRSSFeedPodcastAppsHttps": "Varovanie: Väčšina podcastových aplikácií požaduje URL RSS zdroja s HTTPS",
"NoteRSSFeedPodcastAppsPubDate": "Varovanie: 1 alebo viac vašich epizód neobsahuje infomáciu o dátum vydania. Niektoré podcastové ju vyžadujú.",
"ToastBookmarkCreateFailed": "Vytvorenie záložky zlyhalo",
"ToastBookmarkRemoveFailed": "Odstránenie záložky zlyhalo",
"ToastBookmarkUpdateFailed": "Aktualizácia záložky zlyhala",
"ToastDownloadNotAllowedOnCellular": "Sťahovanie cez mobilné dáta nie je povolené",
"ToastItemMarkedAsFinishedFailed": "Označenie za Dokončené zlyhalo",
"ToastItemMarkedAsNotFinishedFailed": "Označenie za Nedokončené zlyhalo",
"ToastPlaylistCreateFailed": "Vytvorenie playlistu zlyhalo",
"ToastPodcastCreateFailed": "Vytvorenie podcastu zlyhalo",
"ToastPodcastCreateSuccess": "Podcast bol vytvorený",
"ToastRSSFeedCloseFailed": "Odstránenie RSS zdroja zlyhalo",
"ToastRSSFeedCloseSuccess": "RSS zdroj bol odstránený",
"ToastStreamingNotAllowedOnCellular": "Streamovanie cez mobilné dáta nie je povolené"
}
+8
View File
@@ -6,6 +6,7 @@
"ButtonCancel": "Prekliči",
"ButtonCancelTimer": "Prekliči časovnik",
"ButtonClearFilter": "Počisti filter",
"ButtonClearLogs": "Počisti dnevnike",
"ButtonCloseFeed": "Zapri vir",
"ButtonCollections": "Zbirke",
"ButtonConnect": "Poveži",
@@ -26,7 +27,9 @@
"ButtonLatest": "Najnovejše",
"ButtonLibrary": "Knjižnica",
"ButtonLocalMedia": "Lokalni mediji",
"ButtonLogs": "Dnevniki",
"ButtonManageLocalFiles": "Upravljanje lokalnih datotek",
"ButtonMaskServerAddress": "Zakrij naslov strežnika",
"ButtonNewFolder": "Nova mapa",
"ButtonNextEpisode": "Naslednja epizoda",
"ButtonOk": "V redu",
@@ -50,6 +53,7 @@
"ButtonStream": "Pretakaj",
"ButtonSubmit": "Potrdi",
"ButtonSwitchServerUser": "Preklopi strežnik/uporabnik",
"ButtonUnmaskServerAddress": "Odkrij naslov strežnika",
"ButtonUserStats": "Uporabniška statistika",
"ButtonYes": "Da",
"HeaderAccount": "Račun",
@@ -216,6 +220,7 @@
"LabelPublishedDate": "Objavljeno {0}",
"LabelRSSFeedCustomOwnerEmail": "E-pošta lastnika po meri",
"LabelRSSFeedCustomOwnerName": "Ime lastnika po meri",
"LabelRSSFeedOpen": "RSS vir je odprt",
"LabelRSSFeedPreventIndexing": "Prepreči indeksiranje",
"LabelRSSFeedSlug": "Slug RSS vira",
"LabelRandomly": "Naključno",
@@ -237,6 +242,8 @@
"LabelShowAll": "Prikaži vse",
"LabelSize": "Velikost",
"LabelSleepTimer": "Časovnik za spanje",
"LabelSleepTimerAlmostDoneChime": "Predvajaj zvonec tik pred koncem",
"LabelSleepTimerAlmostDoneChimeHelp": "Predvajaj zvonec, ko časovnik za spanje preostane še 30 sekund",
"LabelStart": "Začetek",
"LabelStartTime": "Začetni čas",
"LabelStatsBestDay": "Najboljši dan",
@@ -310,6 +317,7 @@
"MessageNoItems": "Ni elementov",
"MessageNoItemsFound": "Ni najdenih elementov",
"MessageNoListeningSessions": "Ni sej poslušanja",
"MessageNoLogs": "Ni dnevnikov",
"MessageNoMediaFolders": "Brez medijskih map",
"MessageNoNetworkConnection": "Ni omrežne povezave",
"MessageNoPodcastsFound": "Ni podcastov",
+23 -2
View File
@@ -6,6 +6,7 @@
"ButtonCancel": "Avbryt",
"ButtonCancelTimer": "Inaktivera Timer",
"ButtonClearFilter": "Rensa filter",
"ButtonClearLogs": "Rensa Loggar",
"ButtonCloseFeed": "Stäng flöde",
"ButtonCollections": "Samlingar",
"ButtonConnect": "Anslut",
@@ -20,13 +21,15 @@
"ButtonDisableAutoTimer": "Inaktivera Automatisk Timer",
"ButtonDisconnect": "Koppla ur",
"ButtonGoToWebClient": "Öppna i webbläsare",
"ButtonHistory": "Histora",
"ButtonHistory": "Historik",
"ButtonHome": "Hem",
"ButtonIssues": "Objekt med problem",
"ButtonLatest": "Senaste",
"ButtonLibrary": "Bibliotek",
"ButtonLocalMedia": "Lokal media",
"ButtonLogs": "Loggar",
"ButtonManageLocalFiles": "Hantera Lokal Filer",
"ButtonMaskServerAddress": "Dölj server adress",
"ButtonNewFolder": "Ny Katalog",
"ButtonNextEpisode": "Ny Episod",
"ButtonOk": "OK",
@@ -50,6 +53,7 @@
"ButtonStream": "Ström",
"ButtonSubmit": "Skicka",
"ButtonSwitchServerUser": "Byt Server/Användare",
"ButtonUnmaskServerAddress": "Visa server adress",
"ButtonUserStats": "Användarstatistik",
"ButtonYes": "Ja",
"HeaderAccount": "Konto",
@@ -94,7 +98,9 @@
"LabelAll": "Alla",
"LabelAllowSeekingOnMediaControls": "Tillåt positionssökning på medieaviseringskontroller",
"LabelAlways": "Alltid",
"LabelAndroidAutoBrowseLimitForGrouping": "Alfabetisk neddragningsgräns",
"LabelAndroidAutoBrowseLimitForGroupingHelp": "Använd inte alfabetisk neddragning när det finns mindre än denna mängd objekt att visa",
"LabelAndroidAutoBrowseSeriesSequenceOrder": "Serier bokföljd",
"LabelAskConfirmation": "Fråga efter bekräftelse",
"LabelAuthor": "Författare",
"LabelAuthorFirstLast": "Författare (Förnamn Efternamn)",
@@ -226,6 +232,7 @@
"LabelSeason": "Säsong",
"LabelSelectADevice": "Välj en enhet",
"LabelSequenceAscending": "Stigande",
"LabelSequenceDescending": "Sekvens Fallande",
"LabelSeries": "Serie",
"LabelServerAddress": "Server-adress",
"LabelSetEbookAsPrimary": "Ange som primär",
@@ -234,6 +241,8 @@
"LabelShowAll": "Visa alla",
"LabelSize": "Storlek",
"LabelSleepTimer": "Sovtimer",
"LabelSleepTimerAlmostDoneChime": "Spela ett ljud när det är nästan klart",
"LabelSleepTimerAlmostDoneChimeHelp": "Spela ett ljud när sovtimern har 30 sekunder kvar",
"LabelStart": "Start",
"LabelStartTime": "Starttid",
"LabelStatsBestDay": "Bästa dag",
@@ -249,6 +258,7 @@
"LabelTag": "Tagg",
"LabelTags": "Taggar",
"LabelTheme": "Tema",
"LabelThemeBlack": "Svart",
"LabelThemeDark": "Mörkt",
"LabelThemeLight": "Ljust",
"LabelTimeRemaining": "{0} kvar",
@@ -290,8 +300,10 @@
"MessageFetching": "Hämtar...",
"MessageFollowTheProjectOnGithub": "Följ projektet på Github",
"MessageItemDownloadCompleteFailedToCreate": "Objektet laddades ned men det gick inte att skapa ett biblioteksobjekt",
"MessageItemMissing": "Objekt saknas och måste fixas på servern. Vanligast när ett objekt är makerad som saknad beror det på att sökvägen inte är nåbar.",
"MessageLoading": "Laddar...",
"MessageLoadingServerData": "Läser in serverdata...",
"MessageLocalFolderDescription": "'Intern lagring för appen' är endast tillgänglig för denna app. Denna app stöder endast media som har laddats ner direkt via appen. Delade lagringsmappar kan användas för att tillåta andra appar att få åtkomst till media som laddats ner av denna app.",
"MessageMarkAsFinished": "Markera som avslutad",
"MessageMediaLinkedToADifferentServer": "Detta media är länkat till en Audiobookshelf-server på annan adress ({0}). Uppspelningspositioner kommer synkas nästa gång appen kan ansluta till servern.",
"MessageMediaLinkedToADifferentUser": "Detta media är länkat till den här servern men laddades ned av en annan användare. Uppspelningspositioner kommer endast synkas för den användaren som laddade ned objektet.",
@@ -304,17 +316,26 @@
"MessageNoItems": "Inga objekt",
"MessageNoItemsFound": "Inga objekt hittades",
"MessageNoListeningSessions": "Inga lyssningstillfällen",
"MessageNoLogs": "Inga loggar",
"MessageNoMediaFolders": "Inga Mediamappar",
"MessageNoNetworkConnection": "Ingen nätverksanslutning",
"MessageNoPodcastsFound": "Inga podcasts hittade",
"MessageNoSeries": "Inga serier",
"MessageNoUpdatesWereNecessary": "Inga uppdateringar var nödvändiga",
"MessageNoUserPlaylists": "Du har inga spellistor",
"MessageOldServerConnectionWarning": "Serveranslutningskonfigurationen använder ett gammalt användar-ID. Vänligen ta bort och lägg till denna serveranslutning igen.",
"MessageOldServerConnectionWarningHelp": "Du ställde ursprungligen in anslutningen till denna server före databasflytten i version 2.3.0, som släpptes i juni 2023. En framtida serveruppdatering kommer att ta bort möjligheten att logga in med denna gamla anslutning. Vänligen ta bort den befintliga serveranslutningen och anslut igen (med samma serveradress och inloggningsuppgifter). Om du har nedladdad media på den här enheten måste den laddas ner igen för att synkroniseras med servern.",
"MessagePodcastSearchField": "Skriv sökfrågan eller URL-adressen för RSS-flödet",
"MessageProgressSyncFailed": "Det senaste försöket att rapportera din lyssningsprogress till servern misslyckades. Försök att synkronisera progressen kommer att fortsätta göras var 15:e sekund till 1 minut medan media spelas.",
"MessageReportBugsAndContribute": "Rapportera buggar, begär funktioner och bidra på",
"MessageSeriesAlreadyDownloaded": "Du har redan laddat ner alla böcker i den här serien.",
"MessageSeriesDownloadConfirm": "Vill du ladda ner de saknade {0} boken/böckerna med {1} fil(er), totalt {2}, till mappen {3}?",
"MessageSeriesDownloadConfirmIos": "Vill du ladda ner de saknade {0} boken/böckerna med {1} fil(er), totalt {2}?",
"MessageSocketConnectedOverMeteredCellular": "Socket ansluten via mätad mobilanslutning",
"MessageSocketConnectedOverMeteredWifi": "Socket connected over metered Wi-Fi",
"MessageSocketConnectedOverUnmeteredWifi": "Socket connected over unmetered Wi-Fi",
"MessageSocketConnectedOverUnmeteredCellular": "Socket ansluten via omättad mobilanslutning",
"MessageSocketConnectedOverUnmeteredWifi": "Socket ansluten via omättat Wi-Fi",
"MessageSocketNotConnected": "Socket inte ansluten",
"NoteRSSFeedPodcastAppsHttps": "VARNING: De flesta applikationer för podcasts kräver att URL:en för RSS-flödet använder HTTPS",
"NoteRSSFeedPodcastAppsPubDate": "VARNING: Ett eller flera av dina avsnitt saknar publiceringsdatum. Vissa applikationer för podcasts kräver detta.",
"ToastBookmarkCreateFailed": "Det gick inte att skapa bokmärket",
+5
View File
@@ -6,6 +6,7 @@
"ButtonCancel": "İptal",
"ButtonCancelTimer": "İptal Zamanlayıcısı",
"ButtonClearFilter": "Filtreyi Temizle",
"ButtonClearLogs": "Günlükleri Temizle",
"ButtonCloseFeed": "Akışı Kapat",
"ButtonCollections": "Koleksiyonlar",
"ButtonConnect": "Bağlan",
@@ -26,7 +27,9 @@
"ButtonLatest": "En yeni",
"ButtonLibrary": "Kütüphane",
"ButtonLocalMedia": "Yerel Medya",
"ButtonLogs": "Günlükler",
"ButtonManageLocalFiles": "Yerel Dosyaları Yönet",
"ButtonMaskServerAddress": "Sunucu adresini maskele",
"ButtonNewFolder": "Yeni Klasör",
"ButtonNextEpisode": "Sonraki Bölüm",
"ButtonOk": "Tamam",
@@ -50,6 +53,7 @@
"ButtonStream": "Yayın",
"ButtonSubmit": "Gönder",
"ButtonSwitchServerUser": "Sunucu/Kullanıcı Değiştir",
"ButtonUnmaskServerAddress": "Sunucu adresinin maskesini kaldır",
"ButtonUserStats": "Kullanıcı İstatistikleri",
"ButtonYes": "Evet",
"HeaderAccount": "Hesap",
@@ -202,6 +206,7 @@
"LabelOn": "Açık",
"LabelPassword": "Şifre",
"LabelPath": "Yol",
"LabelPlaybackDirect": "Doğrudan",
"LabelPlaybackLocal": "Yerel",
"LabelPlaybackSpeed": "Oynatma Hızı",
"LabelPlaybackTranscode": "Transcode",
+8
View File
@@ -6,6 +6,7 @@
"ButtonCancel": "Скасувати",
"ButtonCancelTimer": "Скасувати таймер",
"ButtonClearFilter": "Скинути фільтри",
"ButtonClearLogs": "Очистити журнали",
"ButtonCloseFeed": "Закрити стрічку",
"ButtonCollections": "Добірки",
"ButtonConnect": "Підключитися",
@@ -26,7 +27,9 @@
"ButtonLatest": "Останні",
"ButtonLibrary": "Бібліотека",
"ButtonLocalMedia": "Локальні файли",
"ButtonLogs": "Журнали",
"ButtonManageLocalFiles": "Керування локальними файлами",
"ButtonMaskServerAddress": "Маска адреси сервера",
"ButtonNewFolder": "Нова тека",
"ButtonNextEpisode": "Наступний епізод",
"ButtonOk": "Добре",
@@ -50,6 +53,7 @@
"ButtonStream": "Транслювати",
"ButtonSubmit": "Ввести",
"ButtonSwitchServerUser": "Змінити сервер/користувача",
"ButtonUnmaskServerAddress": "Розкрити адресу сервера",
"ButtonUserStats": "Статистика",
"ButtonYes": "Так",
"HeaderAccount": "Профіль",
@@ -216,6 +220,7 @@
"LabelPublishedDate": "Опубліковано {0}",
"LabelRSSFeedCustomOwnerEmail": "Користувацька електронна адреса власника",
"LabelRSSFeedCustomOwnerName": "Користувацьке ім'я власника",
"LabelRSSFeedOpen": "RSS-канал відкритий",
"LabelRSSFeedPreventIndexing": "Запобігати індексації",
"LabelRSSFeedSlug": "Назва RSS-каналу",
"LabelRandomly": "Випадково",
@@ -237,6 +242,8 @@
"LabelShowAll": "Показати все",
"LabelSize": "Розмір",
"LabelSleepTimer": "Таймер вимкнення",
"LabelSleepTimerAlmostDoneChime": "Увімкніть дзвінок, коли майже закінчите",
"LabelSleepTimerAlmostDoneChimeHelp": "Увімкніть дзвінок, коли на таймері вимкнення залишиться 30 секунд",
"LabelStart": "Початок",
"LabelStartTime": "Час Початку",
"LabelStatsBestDay": "Найкращий день",
@@ -310,6 +317,7 @@
"MessageNoItems": "Елементи відсутні",
"MessageNoItemsFound": "Елементів не знайдено",
"MessageNoListeningSessions": "Сеанси прослуховування відсутні",
"MessageNoLogs": "Без журнал",
"MessageNoMediaFolders": "Теки медіа відсутні",
"MessageNoNetworkConnection": "Немає підключення до мережі",
"MessageNoPodcastsFound": "Подкастів не знайдено",
+8
View File
@@ -6,6 +6,7 @@
"ButtonCancel": "取消",
"ButtonCancelTimer": "取消计时器",
"ButtonClearFilter": "清除过滤器",
"ButtonClearLogs": "清除日志",
"ButtonCloseFeed": "关闭源",
"ButtonCollections": "收藏",
"ButtonConnect": "连接",
@@ -26,7 +27,9 @@
"ButtonLatest": "最新",
"ButtonLibrary": "媒体库",
"ButtonLocalMedia": "本地媒体",
"ButtonLogs": "日志",
"ButtonManageLocalFiles": "管理本地文件",
"ButtonMaskServerAddress": "屏蔽服务器地址",
"ButtonNewFolder": "新建文件夹",
"ButtonNextEpisode": "下一集",
"ButtonOk": "确定",
@@ -50,6 +53,7 @@
"ButtonStream": "串流播放",
"ButtonSubmit": "提交",
"ButtonSwitchServerUser": "切换服务器/用户",
"ButtonUnmaskServerAddress": "取消屏蔽服务器地址",
"ButtonUserStats": "用户统计信息",
"ButtonYes": "确定",
"HeaderAccount": "帐户",
@@ -216,6 +220,7 @@
"LabelPublishedDate": "已发布 {0}",
"LabelRSSFeedCustomOwnerEmail": "自定义所有者电子邮件",
"LabelRSSFeedCustomOwnerName": "自定义所有者名称",
"LabelRSSFeedOpen": "打开 RSS 源",
"LabelRSSFeedPreventIndexing": "防止索引",
"LabelRSSFeedSlug": "RSS 源段",
"LabelRandomly": "随机",
@@ -237,6 +242,8 @@
"LabelShowAll": "全部显示",
"LabelSize": "文件大小",
"LabelSleepTimer": "睡眠定时",
"LabelSleepTimerAlmostDoneChime": "快结束时播放铃声",
"LabelSleepTimerAlmostDoneChimeHelp": "当睡眠定时器还剩30秒时播放铃声",
"LabelStart": "开始",
"LabelStartTime": "开始时间",
"LabelStatsBestDay": "最好的一天",
@@ -310,6 +317,7 @@
"MessageNoItems": "无项目",
"MessageNoItemsFound": "未找到任何项目",
"MessageNoListeningSessions": "无收听会话",
"MessageNoLogs": "无日志",
"MessageNoMediaFolders": "没有媒体文件夹",
"MessageNoNetworkConnection": "无网络连接",
"MessageNoPodcastsFound": "未找到播客",