1
0
mirror of https://github.com/TeamNewPipe/NewPipe synced 2026-03-28 18:41:23 +00:00

Compare commits

...

72 Commits

Author SHA1 Message Date
tobigr
da76ddbf19 Remove French (Lousiana) frc from app locales 2026-03-27 08:35:49 +01:00
TobiGr
75ba70ab41 Deleted translation using Weblate (Aymara (Southern)) 2026-03-27 08:30:49 +01:00
TobiGr
6d50fe79b8 Deleted translation using Weblate (Mainfränkisch) 2026-03-27 08:23:30 +01:00
TobiGr
f8c9ab8b11 Deleted translation using Weblate (Azerbaijani (Southern)) 2026-03-27 08:22:23 +01:00
TobiGr
949f0f3448 Deleted translation using Weblate (Azerbaijani (Southern)) 2026-03-27 08:22:22 +01:00
TobiGr
af08ddcf04 Deleted translation using Weblate (Kashmiri) 2026-03-27 08:19:25 +01:00
TobiGr
09c96159d1 Deleted translation using Weblate (Sicilian) 2026-03-27 08:19:05 +01:00
TobiGr
2dda39205d Deleted translation using Weblate (Aymara) 2026-03-27 08:18:48 +01:00
TobiGr
3112eefb99 Deleted translation using Weblate (Luri (Bakhtiari)) 2026-03-27 08:18:29 +01:00
TobiGr
cf0d7016ec Deleted translation using Weblate (Yiddish) 2026-03-27 08:18:05 +01:00
TobiGr
b0f2d509e6 Deleted translation using Weblate (Romany) 2026-03-27 08:17:48 +01:00
TobiGr
db61af15e8 Deleted translation using Weblate (Corsican) 2026-03-27 08:17:29 +01:00
TobiGr
80a47be218 Deleted translation using Weblate (Gaelic) 2026-03-27 08:17:11 +01:00
TobiGr
179a713561 Deleted translation using Weblate (Arabic (Tunisian)) 2026-03-27 08:16:35 +01:00
TobiGr
fa6412a9aa Deleted translation using Weblate (French (Louisiana)) 2026-03-27 08:15:57 +01:00
TobiGr
3f8d26d33e Deleted translation using Weblate (German (Low)) 2026-03-27 08:15:23 +01:00
TobiGr
2fec3a3c58 Deleted translation using Weblate (English (Old)) 2026-03-27 08:15:07 +01:00
TobiGr
08326c64cb Deleted translation using Weblate (English (Middle)) 2026-03-27 08:14:50 +01:00
TobiGr
831425a742 Deleted translation using Weblate (Arabic (Najdi)) 2026-03-27 08:14:12 +01:00
Hosted Weblate
fbf3b7a905 Translated using Weblate (Galician)
Currently translated at 94.9% (734 of 773 strings)

Translated using Weblate (Estonian)

Currently translated at 100.0% (773 of 773 strings)

Translated using Weblate (Vietnamese)

Currently translated at 98.3% (760 of 773 strings)

Translated using Weblate (Dutch)

Currently translated at 99.0% (766 of 773 strings)

Translated using Weblate (Chinese (Traditional Han script))

Currently translated at 100.0% (773 of 773 strings)

Translated using Weblate (Bulgarian)

Currently translated at 100.0% (773 of 773 strings)

Translated using Weblate (Chinese (Traditional Han script))

Currently translated at 100.0% (773 of 773 strings)

Translated using Weblate (Azerbaijani)

Currently translated at 100.0% (773 of 773 strings)

Translated using Weblate (Slovak)

Currently translated at 100.0% (773 of 773 strings)

Translated using Weblate (Czech)

Currently translated at 100.0% (773 of 773 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (773 of 773 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (773 of 773 strings)

Translated using Weblate (Greek)

Currently translated at 100.0% (773 of 773 strings)

Translated using Weblate (Hungarian)

Currently translated at 100.0% (773 of 773 strings)

Translated using Weblate (German)

Currently translated at 100.0% (773 of 773 strings)

Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 100.0% (773 of 773 strings)

Translated using Weblate (Turkish)

Currently translated at 99.0% (766 of 773 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (773 of 773 strings)

Translated using Weblate (French)

Currently translated at 100.0% (773 of 773 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (773 of 773 strings)

Translated using Weblate (Hindi)

Currently translated at 98.9% (765 of 773 strings)

Translated using Weblate (Korean)

Currently translated at 100.0% (773 of 773 strings)

Translated using Weblate (Punjabi)

Currently translated at 100.0% (773 of 773 strings)

Translated using Weblate (Bulgarian)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Somali)

Currently translated at 73.3% (561 of 765 strings)

Translated using Weblate (Latvian)

Currently translated at 97.5% (746 of 765 strings)

Translated using Weblate (Latvian)

Currently translated at 97.6% (747 of 765 strings)

Translated using Weblate (Portuguese (Portugal))

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Punjabi)

Currently translated at 100.0% (90 of 90 strings)

Translated using Weblate (Hindi)

Currently translated at 100.0% (90 of 90 strings)

Translated using Weblate (Punjabi)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Hindi)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Turkish)

Currently translated at 34.4% (31 of 90 strings)

Translated using Weblate (Korean)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Romanian)

Currently translated at 12.2% (11 of 90 strings)

Translated using Weblate (Vietnamese)

Currently translated at 99.3% (760 of 765 strings)

Translated using Weblate (Vietnamese)

Currently translated at 73.3% (66 of 90 strings)

Translated using Weblate (Estonian)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Chinese (Traditional Han script))

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (765 of 765 strings)

Added translation using Weblate (Corsican)

Translated using Weblate (Indonesian)

Currently translated at 86.6% (78 of 90 strings)

Translated using Weblate (German)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (French)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Indonesian)

Currently translated at 99.7% (763 of 765 strings)

Translated using Weblate (Greek)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Italian)

Currently translated at 64.4% (58 of 90 strings)

Translated using Weblate (Hungarian)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Azerbaijani)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Slovak)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Czech)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Kabyle)

Currently translated at 27.9% (214 of 765 strings)

Translated using Weblate (German)

Currently translated at 99.8% (764 of 765 strings)

Co-authored-by: Agnieszka C <aga_04@o2.pl>
Co-authored-by: ButterflyOfFire <boffire@users.noreply.hosted.weblate.org>
Co-authored-by: Cabdi Waaxid Siciid <cabdiwaaxidsiciid100@gmail.com>
Co-authored-by: David Bol <CapybarGooner2@proton.me>
Co-authored-by: Dot Max <ahmadfadil.original@outlook.com>
Co-authored-by: EESF-2 <eesf-2@users.noreply.hosted.weblate.org>
Co-authored-by: Emin Tufan Çetin <etcetin@gmail.com>
Co-authored-by: Erenay <erenaydev@proton.me>
Co-authored-by: Femini <nizamismidov4@gmail.com>
Co-authored-by: Fjuro <fjuro@users.noreply.hosted.weblate.org>
Co-authored-by: Ghost of Sparta <makesocialfoss32@keemail.me>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Hosted Weblate user 142171 <traaduttore@users.noreply.hosted.weblate.org>
Co-authored-by: Igor Rückert <igorruckert@yahoo.com.br>
Co-authored-by: Jeff Huang <s8321414@gmail.com>
Co-authored-by: Mickaël Binos <mickaelbinos@outlook.com>
Co-authored-by: Milan <mobrcian@hotmail.com>
Co-authored-by: Philip Goto <philip.goto@gmail.com>
Co-authored-by: Priit Jõerüüt <jrthwlate@users.noreply.hosted.weblate.org>
Co-authored-by: Quý <quycodergithub@gmail.com>
Co-authored-by: Random <random-r@users.noreply.hosted.weblate.org>
Co-authored-by: Stéphanie Olier <olier.stephanie130@gmail.com>
Co-authored-by: TXRdev Archive <lckphanaf9999@gmail.com>
Co-authored-by: Trunars <trunars@abv.bg>
Co-authored-by: Vasilis K. <skyhirules@gmail.com>
Co-authored-by: VfBFan <vfbfan@users.noreply.hosted.weblate.org>
Co-authored-by: WB <wb@users.noreply.hosted.weblate.org>
Co-authored-by: codetabsite <info.codetabteknofest@gmail.com>
Co-authored-by: justcontributor <kty5663@gmail.com>
Co-authored-by: rehork <cooky@e.email>
Co-authored-by: ssantos <ssantos@web.de>
Co-authored-by: whistlingwoods <72640314+whistlingwoods@users.noreply.github.com>
Co-authored-by: ℂ𝕠𝕠𝕠𝕝 (𝕘𝕚𝕥𝕙𝕦𝕓.𝕔𝕠𝕞/ℂ𝕠𝕠𝕠𝕝) <coool@mail.lv>
Co-authored-by: 大王叫我来巡山 <hamburger2048@users.noreply.hosted.weblate.org>
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/hi/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/id/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/it/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pa/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ro/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/tr/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/vi/
Translation: NewPipe/Metadata
2026-03-27 00:09:53 +00:00
Tobi
515bb6e94d Merge pull request #13363 from theimpulson/depUpdate
Update dependencies and Gradle to latest stable release
2026-03-18 10:16:47 +01:00
Aayush Gupta
349000857a Update dependencies and Gradle to latest stable release
Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
2026-03-18 15:52:23 +08:00
Aayush Gupta
f1c608b396 Merge pull request #13352 from theimpulson/path
Port path related changes from refactor
2026-03-18 15:45:45 +08:00
Isira Seneviratne
5f1a270ca4 Fix database import 2026-03-16 14:48:23 +08:00
Isira Seneviratne
aba2a385fd Inline variable 2026-03-16 14:47:24 +08:00
Isira Seneviratne
71a3bf2855 Use InputStream#transferTo() 2026-03-16 14:47:17 +08:00
Isira Seneviratne
ebb937934a Fix DB import/export issue 2026-03-16 14:47:08 +08:00
Isira Seneviratne
223b240299 Refactor zip import/export using Path 2026-03-16 14:46:09 +08:00
Aayush Gupta
668af4fc3e Merge pull request #13347 from theimpulson/subscriptions
Port subscriptions related changes from refactor
2026-03-16 09:23:16 +08:00
evermind
bfcc31ec89 BackupRestoreSettingsFragment: add UI options to import/export subscriptions
* create SubscriptionsImportExportHelper to share common code used in
  SubscriptionFragment and BackupRestoreSettingsFragment
* Add UI options for import/export in BackupRestoreSettingsFragment
2026-03-15 20:54:58 +08:00
Aayush Gupta
6fa97e17f5 subscription: Port subscription import-export to workers from refactor
Please see https://github.com/TeamNewPipe/NewPipe/pull/11759/ for the original change

Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
2026-03-15 20:51:29 +08:00
Aayush Gupta
0d65733e53 Merge pull request #13207 from TobiGr/small-fixes
Small improvements to Image handling
2026-03-15 19:21:06 +08:00
Aayush Gupta
9cc6f9fd68 Merge pull request #13305 from dustdfg/remove_freedroid_license
Remove freedroidwarn license
2026-03-15 19:18:32 +08:00
tobigr
79767f95f7 Merge branch 'master' into dev 2026-03-08 21:19:30 +01:00
Tobi
21b37b5fa4 Merge pull request #13296 from TeamNewPipe/release-0.28.4
Release 0.28.4
2026-03-08 11:07:54 -07:00
Tobi
675d15686d Merge pull request #13324 from TeamNewPipe/backport-13310-to-release-0.28.4
[Backport release-0.28.4] Add link to FAQ entry to "Sign in to confirm not a bot" exception message
2026-03-08 11:01:41 -07:00
tobigr
54021a96ea Complete sentence.
(cherry picked from commit 47624a575a)
2026-03-08 18:01:10 +00:00
AbsurdlyLongUsername
7c88f06196 Change to FAQ entry instead
(cherry picked from commit 3b3348e7a1)
2026-03-08 18:01:10 +00:00
AbsurdlyLongUsername
93f9a52e3e Change URL to FAQ
(cherry picked from commit 521f60af85)
2026-03-08 18:01:10 +00:00
AbsurdlyLongUsername
d9fd1bf003 Maybe this fix ktlint errors?
(cherry picked from commit b8ec9bf412)
2026-03-08 18:01:10 +00:00
AbsurdlyLongUsername
dc2e4aaea5 Add Sign in confirm not a bot issue URL to the exception error message
Make error panel and error activity exception message URLs clickable via extension method

Change ErrorMessage.getString to getText and return CharSequence, and use getText with formatArgs to preserve styling (i.e. URLs)

(cherry picked from commit e173bf4252)
2026-03-08 18:01:10 +00:00
Hosted Weblate
d5f941ff3d Translated using Weblate (Vietnamese)
Currently translated at 70.0% (63 of 90 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (765 of 765 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Nicolás Pérez <nicoperez241@proton.me>
Co-authored-by: Quý <quycodergithub@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/vi/
Translation: NewPipe/Metadata
2026-03-08 18:00:50 +00:00
Tobi
05f09c94d1 Merge pull request #13310 from absurdlylongusername/add-issue-url-sign-in-not-bot-exception
Add link to FAQ entry to "Sign in to confirm not a bot" exception message
2026-03-08 11:00:37 -07:00
Hosted Weblate
816f5f9aba Translated using Weblate (Vietnamese)
Currently translated at 70.0% (63 of 90 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (765 of 765 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Nicolás Pérez <nicoperez241@proton.me>
Co-authored-by: Quý <quycodergithub@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/vi/
Translation: NewPipe/Metadata
2026-03-08 18:57:50 +01:00
tobigr
47624a575a Complete sentence. 2026-03-08 18:54:56 +01:00
AbsurdlyLongUsername
3b3348e7a1 Change to FAQ entry instead 2026-03-07 23:38:51 +00:00
AbsurdlyLongUsername
521f60af85 Change URL to FAQ 2026-03-07 19:13:02 +00:00
Hosted Weblate
d497f1d88e Translated using Weblate (Latvian)
Currently translated at 97.9% (749 of 765 strings)

Translated using Weblate (Latvian)

Currently translated at 97.9% (749 of 765 strings)

Translated using Weblate (Latvian)

Currently translated at 18.8% (17 of 90 strings)

Translated using Weblate (Latvian)

Currently translated at 96.9% (742 of 765 strings)

Translated using Weblate (Latvian)

Currently translated at 97.3% (745 of 765 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Latvian)

Currently translated at 17.7% (16 of 90 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Armenian)

Currently translated at 31.6% (242 of 765 strings)

Translated using Weblate (Portuguese (Portugal))

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Slovak)

Currently translated at 76.6% (69 of 90 strings)

Translated using Weblate (Azerbaijani)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Slovak)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Japanese)

Currently translated at 13.3% (12 of 90 strings)

Translated using Weblate (Czech)

Currently translated at 100.0% (90 of 90 strings)

Translated using Weblate (Korean)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (French)

Currently translated at 98.8% (89 of 90 strings)

Translated using Weblate (Japanese)

Currently translated at 95.5% (731 of 765 strings)

Translated using Weblate (Polish)

Currently translated at 56.6% (51 of 90 strings)

Translated using Weblate (Bulgarian)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 100.0% (90 of 90 strings)

Translated using Weblate (Tamil)

Currently translated at 48.8% (44 of 90 strings)

Translated using Weblate (Hungarian)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (German)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (German)

Currently translated at 100.0% (90 of 90 strings)

Co-authored-by: 439JBYL80IGQTF25UXNR0X1BG <439jbyl80igqtf25uxnr0x1bg@users.noreply.hosted.weblate.org>
Co-authored-by: Agnieszka C <aga_04@o2.pl>
Co-authored-by: Davit Mayilyan <davit.mayilyan@protonmail.ch>
Co-authored-by: Erenay <erenaydev@proton.me>
Co-authored-by: Femini <nizamismidov4@gmail.com>
Co-authored-by: Fjuro <fjuro@users.noreply.hosted.weblate.org>
Co-authored-by: Ghost of Sparta <makesocialfoss32@keemail.me>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Mickaël Binos <mickaelbinos@outlook.com>
Co-authored-by: Milan <mobrcian@hotmail.com>
Co-authored-by: Random <random-r@users.noreply.hosted.weblate.org>
Co-authored-by: Trunars <trunars@abv.bg>
Co-authored-by: VfBFan <vfbfan@users.noreply.hosted.weblate.org>
Co-authored-by: justcontributor <kty5663@gmail.com>
Co-authored-by: kuragehime <kuragehime641@gmail.com>
Co-authored-by: ssantos <ssantos@web.de>
Co-authored-by: தமிழ்நேரம் <tamilneram247@gmail.com>
Co-authored-by: ℂ𝕠𝕠𝕠𝕝 (𝕘𝕚𝕥𝕙𝕦𝕓.𝕔𝕠𝕞/ℂ𝕠𝕠𝕠𝕝) <coool@mail.lv>
Co-authored-by: 大王叫我来巡山 <hamburger2048@users.noreply.hosted.weblate.org>
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/cs/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/de/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/fr/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ja/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/lv/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pl/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/sk/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ta/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/zh_Hans/
Translation: NewPipe/Metadata
2026-03-07 17:44:37 +01:00
Hosted Weblate
dda219a9e9 Translated using Weblate (Latvian)
Currently translated at 97.9% (749 of 765 strings)

Translated using Weblate (Latvian)

Currently translated at 97.9% (749 of 765 strings)

Translated using Weblate (Latvian)

Currently translated at 18.8% (17 of 90 strings)

Translated using Weblate (Latvian)

Currently translated at 96.9% (742 of 765 strings)

Translated using Weblate (Latvian)

Currently translated at 97.3% (745 of 765 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Latvian)

Currently translated at 17.7% (16 of 90 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Armenian)

Currently translated at 31.6% (242 of 765 strings)

Translated using Weblate (Portuguese (Portugal))

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Slovak)

Currently translated at 76.6% (69 of 90 strings)

Translated using Weblate (Azerbaijani)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Slovak)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Japanese)

Currently translated at 13.3% (12 of 90 strings)

Translated using Weblate (Czech)

Currently translated at 100.0% (90 of 90 strings)

Translated using Weblate (Korean)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (French)

Currently translated at 98.8% (89 of 90 strings)

Translated using Weblate (Japanese)

Currently translated at 95.5% (731 of 765 strings)

Translated using Weblate (Polish)

Currently translated at 56.6% (51 of 90 strings)

Translated using Weblate (Bulgarian)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 100.0% (90 of 90 strings)

Translated using Weblate (Tamil)

Currently translated at 48.8% (44 of 90 strings)

Translated using Weblate (Hungarian)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (German)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (German)

Currently translated at 100.0% (90 of 90 strings)

Co-authored-by: 439JBYL80IGQTF25UXNR0X1BG <439jbyl80igqtf25uxnr0x1bg@users.noreply.hosted.weblate.org>
Co-authored-by: Agnieszka C <aga_04@o2.pl>
Co-authored-by: Davit Mayilyan <davit.mayilyan@protonmail.ch>
Co-authored-by: Erenay <erenaydev@proton.me>
Co-authored-by: Femini <nizamismidov4@gmail.com>
Co-authored-by: Fjuro <fjuro@users.noreply.hosted.weblate.org>
Co-authored-by: Ghost of Sparta <makesocialfoss32@keemail.me>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Mickaël Binos <mickaelbinos@outlook.com>
Co-authored-by: Milan <mobrcian@hotmail.com>
Co-authored-by: Random <random-r@users.noreply.hosted.weblate.org>
Co-authored-by: Trunars <trunars@abv.bg>
Co-authored-by: VfBFan <vfbfan@users.noreply.hosted.weblate.org>
Co-authored-by: justcontributor <kty5663@gmail.com>
Co-authored-by: kuragehime <kuragehime641@gmail.com>
Co-authored-by: ssantos <ssantos@web.de>
Co-authored-by: தமிழ்நேரம் <tamilneram247@gmail.com>
Co-authored-by: ℂ𝕠𝕠𝕠𝕝 (𝕘𝕚𝕥𝕙𝕦𝕓.𝕔𝕠𝕞/ℂ𝕠𝕠𝕠𝕝) <coool@mail.lv>
Co-authored-by: 大王叫我来巡山 <hamburger2048@users.noreply.hosted.weblate.org>
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/cs/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/de/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/fr/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ja/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/lv/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pl/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/sk/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ta/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/zh_Hans/
Translation: NewPipe/Metadata
2026-03-06 20:30:04 +01:00
AbsurdlyLongUsername
b8ec9bf412 Maybe this fix ktlint errors? 2026-03-06 12:55:09 +00:00
AbsurdlyLongUsername
e173bf4252 Add Sign in confirm not a bot issue URL to the exception error message
Make error panel and error activity exception message URLs clickable via extension method

Change ErrorMessage.getString to getText and return CharSequence, and use getText with formatArgs to preserve styling (i.e. URLs)
2026-03-06 12:35:19 +00:00
Yevhen Babiichuk (DustDFG)
9f45aa571c Remove freedroidwarn license 2026-03-04 22:45:07 +02:00
Stypox
e6e5fc70f2 Merge pull request #13299 from TeamNewPipe/backport-13298-to-release-0.28.4 2026-03-02 09:27:38 +01:00
Yevhen Babiichuk (DustDFG)
8fa6f9670d Apply suggestion
(cherry picked from commit 0020a02a28)
2026-03-02 08:27:17 +00:00
Stypox
0cdf40cd5f Merge pull request #13298 from dustdfg/shareutils_kao 2026-03-02 09:26:52 +01:00
Yevhen Babiichuk (DustDFG)
0020a02a28 Apply suggestion 2026-03-02 08:42:07 +02:00
tobigr
1fbf9fc025 Bump version to 0.28.4 (1009) 2026-02-28 10:06:03 +01:00
tobigr
8b500c7b83 Add changelog for NewPipe 0.28.4 (1009) 2026-02-28 10:06:03 +01:00
tobigr
98a883d377 Update NewPipe Extractor to 0.26.0 2026-02-28 10:06:03 +01:00
Hosted Weblate
6dddcf3805 Translated using Weblate (French)
Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Greek)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Czech)

Currently translated at 100.0% (89 of 89 strings)

Translated using Weblate (Greek)

Currently translated at 99.8% (764 of 765 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Estonian)

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 100.0% (765 of 765 strings)

Translated using Weblate (Swedish)

Currently translated at 96.6% (86 of 89 strings)

Co-authored-by: Agnieszka C <aga_04@o2.pl>
Co-authored-by: Fjuro <fjuro@users.noreply.hosted.weblate.org>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Mickaël Binos <mickaelbinos@outlook.com>
Co-authored-by: Mona Lisa <nickwick@users.noreply.hosted.weblate.org>
Co-authored-by: Priit Jõerüüt <jrthwlate@users.noreply.hosted.weblate.org>
Co-authored-by: Vasilis K. <skyhirules@gmail.com>
Co-authored-by: delvani <del.cidrak@users.noreply.hosted.weblate.org>
Co-authored-by: 大王叫我来巡山 <hamburger2048@users.noreply.hosted.weblate.org>
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/cs/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/sv/
Translation: NewPipe/Metadata
2026-02-28 10:03:02 +01:00
Tobi
bf1633265c Merge pull request #13293 from TeamNewPipe/getQuantity-inconsistency
Fix inconsistency in getQuantity and add docs
2026-02-26 11:45:41 -08:00
Stypox
e22b046326 Fix inconsistency in getQuantity and add docs
`getQuantity()` was being called in a couple of places with `zeroCaseStringId=0`, but that wasn't documented anywhere, and if `count==0` then `getString(zeroCaseStringId /* == 0 */)` would be returned which doesn't make sense
2026-02-26 19:08:33 +01:00
Stypox
56fb31d0fd Merge pull request #13292 from dustdfg/kao_release_only 2026-02-26 11:01:56 +01:00
Yevhen Babiichuk (DustDFG)
042f9460b0 Don't show Keep Android Open popup on debug builds 2026-02-26 11:39:10 +02:00
Tobi
9f1e2c6fd0 Merge pull request #13282 from dustdfg/keep_android_open
Add warning banner about ongoing google certification for android apps
2026-02-25 17:08:49 -08:00
tobigr
66237abb3c KeepAndroidOpen: Choose website language from list of supported languages 2026-02-26 01:27:36 +01:00
Tobi
dd65db56a9 Merge pull request #13290 from dustdfg/correct_download_fragment
Correctly retrieve menu item inside download dialog
2026-02-25 15:42:05 -08:00
Yevhen Babiichuk (DustDFG)
195a76bb08 Correctly retrieve menu item inside download dialog 2026-02-26 01:09:07 +02:00
Yevhen Babiichuk (DustDFG)
06e4548c14 Add warning banner about ongoing google certification for android apps 2026-02-25 18:35:41 +02:00
Hosted Weblate
9a292e33f9 Translated using Weblate (Albanian)
Currently translated at 2.2% (2 of 89 strings)

Translated using Weblate (Georgian)

Currently translated at 55.0% (49 of 89 strings)

Translated using Weblate (Latvian)

Currently translated at 97.9% (748 of 764 strings)

Translated using Weblate (Georgian)

Currently translated at 96.5% (738 of 764 strings)

Co-authored-by: Flavjo Avdiu <flavjoavdiu10@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Nikoloz <nukushatugushi@gmail.com>
Co-authored-by: ℂ𝕠𝕠𝕠𝕝 (𝕘𝕚𝕥𝕙𝕦𝕓.𝕔𝕠𝕞/ℂ𝕠𝕠𝕠𝕝) <coool@mail.lv>
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ka/
Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/sq/
Translation: NewPipe/Metadata
2026-02-22 11:32:29 +01:00
tobigr
e358867da8 Use dedicated constants for unknown image dimensions in ImageStrategy 2026-02-07 15:34:48 +01:00
TobiGr
e6daf45c83 [DescriptionFragment] Fix thumbnail size: width x height
height x width was used before which is an uncommon order.
2026-02-07 12:36:09 +01:00
197 changed files with 2742 additions and 2221 deletions

View File

@@ -11,6 +11,7 @@ plugins {
alias(libs.plugins.jetbrains.kotlin.kapt) alias(libs.plugins.jetbrains.kotlin.kapt)
alias(libs.plugins.google.ksp) alias(libs.plugins.google.ksp)
alias(libs.plugins.jetbrains.kotlin.parcelize) alias(libs.plugins.jetbrains.kotlin.parcelize)
alias(libs.plugins.jetbrains.kotlinx.serialization)
alias(libs.plugins.sonarqube) alias(libs.plugins.sonarqube)
checkstyle checkstyle
} }
@@ -44,9 +45,9 @@ configure<ApplicationExtension> {
minSdk = 21 minSdk = 21
targetSdk = 35 targetSdk = 35
versionCode = System.getProperty("versionCodeOverride")?.toInt() ?: 1008 versionCode = System.getProperty("versionCodeOverride")?.toInt() ?: 1009
versionName = "0.28.3" versionName = "0.28.4"
System.getProperty("versionNameSuffix")?.let { versionNameSuffix = it } System.getProperty("versionNameSuffix")?.let { versionNameSuffix = it }
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
@@ -246,6 +247,12 @@ dependencies {
implementation(libs.google.android.material) implementation(libs.google.android.material)
implementation(libs.androidx.webkit) implementation(libs.androidx.webkit)
// Coroutines interop
implementation(libs.kotlinx.coroutines.rx3)
// Kotlinx Serialization
implementation(libs.kotlinx.serialization.json)
/** Third-party libraries **/ /** Third-party libraries **/
implementation(libs.livefront.bridge) implementation(libs.livefront.bridge)
implementation(libs.evernote.statesaver.core) implementation(libs.evernote.statesaver.core)

View File

@@ -44,3 +44,18 @@
-keepclassmembers class * extends com.google.protobuf.GeneratedMessageLite { -keepclassmembers class * extends com.google.protobuf.GeneratedMessageLite {
<fields>; <fields>;
} }
## Keep Kotlinx Serialization classes
-keepclassmembers class kotlinx.serialization.json.** {
*** Companion;
}
-keepclasseswithmembers class kotlinx.serialization.json.** {
kotlinx.serialization.KSerializer serializer(...);
}
-keep,includedescriptorclasses class org.schabi.newpipe.**$$serializer { *; }
-keepclassmembers class org.schabi.newpipe.** {
*** Companion;
}
-keepclasseswithmembers class org.schabi.newpipe.** {
kotlinx.serialization.KSerializer serializer(...);
}

View File

@@ -96,14 +96,6 @@
android:exported="false" android:exported="false"
android:label="@string/title_activity_about" /> android:label="@string/title_activity_about" />
<service
android:name=".local.subscription.services.SubscriptionsImportService"
android:foregroundServiceType="dataSync" />
<service
android:name=".local.subscription.services.SubscriptionsExportService"
android:foregroundServiceType="dataSync" />
<service <service
android:name=".local.feed.service.FeedLoadService" android:name=".local.feed.service.FeedLoadService"
android:foregroundServiceType="dataSync" /> android:foregroundServiceType="dataSync" />

View File

@@ -20,6 +20,7 @@
package org.schabi.newpipe; package org.schabi.newpipe;
import android.app.AlertDialog;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@@ -96,6 +97,8 @@ import org.schabi.newpipe.util.ThemeHelper;
import org.schabi.newpipe.util.external_communication.ShareUtils; import org.schabi.newpipe.util.external_communication.ShareUtils;
import org.schabi.newpipe.views.FocusOverlayView; import org.schabi.newpipe.views.FocusOverlayView;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@@ -196,6 +199,12 @@ public class MainActivity extends AppCompatActivity {
UpdateSettingsFragment.askForConsentToUpdateChecks(this); UpdateSettingsFragment.askForConsentToUpdateChecks(this);
} }
// ReleaseVersionUtil.INSTANCE.isReleaseApk() will be true only for main official build
// We want every release build (nightly, nightly-refactor) to show the popup
if (!DEBUG) {
showKeepAndroidDialog();
}
MigrationManager.showUserInfoIfPresent(this); MigrationManager.showUserInfoIfPresent(this);
} }
@@ -973,4 +982,57 @@ public class MainActivity extends AppCompatActivity {
|| sheetState == BottomSheetBehavior.STATE_COLLAPSED; || sheetState == BottomSheetBehavior.STATE_COLLAPSED;
} }
private void showKeepAndroidDialog() {
final var prefs = PreferenceManager.getDefaultSharedPreferences(this);
final var now = Instant.now();
final var kaoLastCheck = Instant.ofEpochMilli(prefs.getLong(
getString(R.string.kao_last_checked_key),
0
));
final var supportedLannguages = List.of("fr", "de", "ca", "es", "id", "it", "pl",
"pt", "cs", "sk", "fa", "ar", "tr", "el", "th", "ru", "uk", "ko", "zh", "ja");
final var locale = Localization.getAppLocale();
final String kaoBaseUrl = "https://keepandroidopen.org/";
final String kaoURI;
if (supportedLannguages.contains(locale.getLanguage())) {
if ("zh".equals(locale.getLanguage())) {
kaoURI = kaoBaseUrl + ("TW".equals(locale.getCountry()) ? "zh-TW" : "zh-CN");
} else {
kaoURI = kaoBaseUrl + locale.getLanguage();
}
} else {
kaoURI = kaoBaseUrl;
}
final var solutionURI =
"https://github.com/woheller69/FreeDroidWarn?tab=readme-ov-file#solutions";
if (kaoLastCheck.plus(30, ChronoUnit.DAYS).isBefore(now)) {
final var dialog = new AlertDialog.Builder(this)
.setTitle("Keep Android Open")
.setCancelable(false)
.setMessage(this.getString(R.string.kao_dialog_warning))
.setPositiveButton(this.getString(android.R.string.ok), (d, w) -> {
prefs.edit()
.putLong(
getString(R.string.kao_last_checked_key),
now.toEpochMilli()
)
.apply();
})
.setNeutralButton(this.getString(R.string.kao_solution), null)
.setNegativeButton(this.getString(R.string.kao_dialog_more_info), null)
.show();
// If we use setNeutralButton and etc. dialog will close after pressing the buttons,
// but we want it to close only when positive button is pressed
dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(v ->
ShareUtils.openUrlInBrowser(this, kaoURI)
);
dialog.getButton(AlertDialog.BUTTON_NEUTRAL).setOnClickListener(v ->
ShareUtils.openUrlInBrowser(this, solutionURI)
);
}
}
} }

View File

@@ -344,7 +344,7 @@ public class DownloadDialog extends DialogFragment
toolbar.setNavigationOnClickListener(v -> dismiss()); toolbar.setNavigationOnClickListener(v -> dismiss());
toolbar.setNavigationContentDescription(R.string.cancel); toolbar.setNavigationContentDescription(R.string.cancel);
okButton = toolbar.findViewById(R.id.okay); okButton = toolbar.getMenu().findItem(R.id.okay);
okButton.setEnabled(false); // disable until the download service connection is done okButton.setEnabled(false); // disable until the download service connection is done
toolbar.setOnMenuItemClickListener(item -> { toolbar.setOnMenuItemClickListener(item -> {

View File

@@ -25,6 +25,7 @@ import org.schabi.newpipe.databinding.ActivityErrorBinding
import org.schabi.newpipe.util.Localization import org.schabi.newpipe.util.Localization
import org.schabi.newpipe.util.ThemeHelper import org.schabi.newpipe.util.ThemeHelper
import org.schabi.newpipe.util.external_communication.ShareUtils import org.schabi.newpipe.util.external_communication.ShareUtils
import org.schabi.newpipe.util.text.setTextWithLinks
/** /**
* This activity is used to show error details and allow reporting them in various ways. * This activity is used to show error details and allow reporting them in various ways.
@@ -100,7 +101,7 @@ class ErrorActivity : AppCompatActivity() {
// normal bugreport // normal bugreport
buildInfo(errorInfo) buildInfo(errorInfo)
binding.errorMessageView.text = errorInfo.getMessage(this) binding.errorMessageView.setTextWithLinks(errorInfo.getMessage(this))
binding.errorView.text = formErrorText(errorInfo.stackTraces) binding.errorView.text = formErrorText(errorInfo.stackTraces)
// print stack trace once again for debugging: // print stack trace once again for debugging:

View File

@@ -29,6 +29,7 @@ import org.schabi.newpipe.extractor.exceptions.YoutubeMusicPremiumContentExcepti
import org.schabi.newpipe.ktx.isNetworkRelated import org.schabi.newpipe.ktx.isNetworkRelated
import org.schabi.newpipe.player.mediasource.FailedMediaSource import org.schabi.newpipe.player.mediasource.FailedMediaSource
import org.schabi.newpipe.player.resolver.PlaybackResolver import org.schabi.newpipe.player.resolver.PlaybackResolver
import org.schabi.newpipe.util.text.getText
/** /**
* An error has occurred in the app. This class contains plain old parcelable data that can be used * An error has occurred in the app. This class contains plain old parcelable data that can be used
@@ -135,8 +136,8 @@ class ErrorInfo private constructor(
return getServiceName(serviceId) return getServiceName(serviceId)
} }
fun getMessage(context: Context): String { fun getMessage(context: Context): CharSequence {
return message.getString(context) return message.getText(context)
} }
companion object { companion object {
@@ -146,20 +147,23 @@ class ErrorInfo private constructor(
private val stringRes: Int, private val stringRes: Int,
private vararg val formatArgs: String private vararg val formatArgs: String
) : Parcelable { ) : Parcelable {
fun getString(context: Context): String { fun getText(context: Context): CharSequence {
// Ensure locale aware context via ContextCompat.getContextForLanguage() (just in case context is not AppCompatActivity)
val ctx = ContextCompat.getContextForLanguage(context)
return if (formatArgs.isEmpty()) { return if (formatArgs.isEmpty()) {
// use ContextCompat.getString() just in case context is not AppCompatActivity ctx.getText(stringRes)
ContextCompat.getString(context, stringRes)
} else { } else {
// ContextCompat.getString() with formatArgs does not exist, so we just // ContextCompat.getString() with formatArgs does not exist, so we just
// replicate its source code but with formatArgs // replicate its source code but with formatArgs
ContextCompat.getContextForLanguage(context).getString(stringRes, *formatArgs) ctx.resources.getText(stringRes, *formatArgs)
} }
} }
} }
const val SERVICE_NONE = "<unknown_service>" const val SERVICE_NONE = "<unknown_service>"
const val YOUTUBE_IP_BAN_FAQ_URL = "https://newpipe.net/FAQ/#ip-banned-youtube"
private fun getServiceName(serviceId: Int?) = // not using getNameOfServiceById since we want to accept a nullable serviceId and we private fun getServiceName(serviceId: Int?) = // not using getNameOfServiceById since we want to accept a nullable serviceId and we
// want to default to SERVICE_NONE // want to default to SERVICE_NONE
ServiceList.all().firstOrNull { it.serviceId == serviceId }?.serviceInfo?.name ServiceList.all().firstOrNull { it.serviceId == serviceId }?.serviceInfo?.name
@@ -247,7 +251,11 @@ class ErrorInfo private constructor(
ErrorMessage(R.string.youtube_music_premium_content) ErrorMessage(R.string.youtube_music_premium_content)
throwable is SignInConfirmNotBotException -> throwable is SignInConfirmNotBotException ->
ErrorMessage(R.string.sign_in_confirm_not_bot_error, getServiceName(serviceId)) ErrorMessage(
R.string.sign_in_confirm_not_bot_error,
getServiceName(serviceId),
YOUTUBE_IP_BAN_FAQ_URL
)
throwable is ContentNotAvailableException -> throwable is ContentNotAvailableException ->
ErrorMessage(R.string.content_not_available) ErrorMessage(R.string.content_not_available)

View File

@@ -16,6 +16,7 @@ import org.schabi.newpipe.MainActivity
import org.schabi.newpipe.R import org.schabi.newpipe.R
import org.schabi.newpipe.ktx.animate import org.schabi.newpipe.ktx.animate
import org.schabi.newpipe.util.external_communication.ShareUtils import org.schabi.newpipe.util.external_communication.ShareUtils
import org.schabi.newpipe.util.text.setTextWithLinks
class ErrorPanelHelper( class ErrorPanelHelper(
private val fragment: Fragment, private val fragment: Fragment,
@@ -64,7 +65,7 @@ class ErrorPanelHelper(
fun showError(errorInfo: ErrorInfo) { fun showError(errorInfo: ErrorInfo) {
ensureDefaultVisibility() ensureDefaultVisibility()
errorTextView.text = errorInfo.getMessage(context) errorTextView.setTextWithLinks(errorInfo.getMessage(context))
if (errorInfo.recaptchaUrl != null) { if (errorInfo.recaptchaUrl != null) {
showAndSetErrorButtonAction(R.string.recaptcha_solve) { showAndSetErrorButtonAction(R.string.recaptcha_solve) {
@@ -109,7 +110,7 @@ class ErrorPanelHelper(
fun showTextError(errorString: String) { fun showTextError(errorString: String) {
ensureDefaultVisibility() ensureDefaultVisibility()
errorTextView.text = errorString errorTextView.setTextWithLinks(errorString)
setRootVisible() setRootVisible()
} }

View File

@@ -216,9 +216,9 @@ public abstract class BaseDescriptionFragment extends BaseFragment {
|| image.getWidth() != Image.WIDTH_UNKNOWN || image.getWidth() != Image.WIDTH_UNKNOWN
// if even the resolution level is unknown, ?x? will be shown // if even the resolution level is unknown, ?x? will be shown
|| image.getEstimatedResolutionLevel() == Image.ResolutionLevel.UNKNOWN) { || image.getEstimatedResolutionLevel() == Image.ResolutionLevel.UNKNOWN) {
urls.append(imageSizeToText(image.getHeight()));
urls.append('x');
urls.append(imageSizeToText(image.getWidth())); urls.append(imageSizeToText(image.getWidth()));
urls.append('x');
urls.append(imageSizeToText(image.getHeight()));
} else { } else {
switch (image.getEstimatedResolutionLevel()) { switch (image.getEstimatedResolutionLevel()) {
case LOW -> urls.append(getString(R.string.image_quality_low)); case LOW -> urls.append(getString(R.string.image_quality_low));

View File

@@ -1,41 +1,63 @@
package org.schabi.newpipe.local.subscription; package org.schabi.newpipe.local.subscription;
import android.app.Dialog; import android.app.Dialog;
import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.core.os.BundleCompat;
import androidx.fragment.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.work.Constraints;
import androidx.work.ExistingWorkPolicy;
import androidx.work.NetworkType;
import androidx.work.OneTimeWorkRequest;
import androidx.work.OutOfQuotaPolicy;
import androidx.work.WorkManager;
import com.livefront.bridge.Bridge; import com.livefront.bridge.Bridge;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
import org.schabi.newpipe.local.subscription.workers.SubscriptionImportInput;
import org.schabi.newpipe.local.subscription.workers.SubscriptionImportWorker;
public class ImportConfirmationDialog extends DialogFragment { public class ImportConfirmationDialog extends DialogFragment {
protected Intent resultServiceIntent; private static final String INPUT = "input";
private static final String EXTRA_RESULT_SERVICE_INTENT = "extra_result_service_intent";
public static void show(@NonNull final Fragment fragment, public static void show(@NonNull final Fragment fragment, final SubscriptionImportInput input) {
@NonNull final Intent resultServiceIntent) { final var confirmationDialog = new ImportConfirmationDialog();
final ImportConfirmationDialog confirmationDialog = new ImportConfirmationDialog(); final var arguments = new Bundle();
final Bundle args = new Bundle(); arguments.putParcelable(INPUT, input);
args.putParcelable(EXTRA_RESULT_SERVICE_INTENT, resultServiceIntent); confirmationDialog.setArguments(arguments);
confirmationDialog.setArguments(args);
confirmationDialog.show(fragment.getParentFragmentManager(), null); confirmationDialog.show(fragment.getParentFragmentManager(), null);
} }
@NonNull @NonNull
@Override @Override
public Dialog onCreateDialog(@Nullable final Bundle savedInstanceState) { public Dialog onCreateDialog(@Nullable final Bundle savedInstanceState) {
return new AlertDialog.Builder(requireContext()) final var context = requireContext();
return new AlertDialog.Builder(context)
.setMessage(R.string.import_network_expensive_warning) .setMessage(R.string.import_network_expensive_warning)
.setCancelable(true) .setCancelable(true)
.setNegativeButton(R.string.cancel, null) .setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.ok, (dialogInterface, i) -> { .setPositiveButton(R.string.ok, (dialogInterface, i) -> {
requireContext().startService(resultServiceIntent); final var constraints = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build();
final var input = BundleCompat.getParcelable(requireArguments(), INPUT,
SubscriptionImportInput.class);
final var req = new OneTimeWorkRequest.Builder(SubscriptionImportWorker.class)
.setInputData(input.toData())
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
.setConstraints(constraints)
.build();
WorkManager.getInstance(context)
.enqueueUniqueWork(SubscriptionImportWorker.WORK_NAME,
ExistingWorkPolicy.APPEND_OR_REPLACE, req);
dismiss(); dismiss();
}) })
.create(); .create();
@@ -45,7 +67,7 @@ public class ImportConfirmationDialog extends DialogFragment {
public void onCreate(@Nullable final Bundle savedInstanceState) { public void onCreate(@Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
resultServiceIntent = requireArguments().getParcelable(EXTRA_RESULT_SERVICE_INTENT); Bridge.restoreInstanceState(this, savedInstanceState);
} }
@Override @Override

View File

@@ -1,9 +1,7 @@
package org.schabi.newpipe.local.subscription package org.schabi.newpipe.local.subscription
import android.app.Activity
import android.content.Context import android.content.Context
import android.content.DialogInterface import android.content.DialogInterface
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.os.Parcelable import android.os.Parcelable
import android.view.LayoutInflater import android.view.LayoutInflater
@@ -15,8 +13,6 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.webkit.MimeTypeMap import android.webkit.MimeTypeMap
import android.widget.Toast import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
@@ -27,9 +23,6 @@ import com.xwray.groupie.GroupAdapter
import com.xwray.groupie.Section import com.xwray.groupie.Section
import com.xwray.groupie.viewbinding.GroupieViewHolder import com.xwray.groupie.viewbinding.GroupieViewHolder
import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.disposables.CompositeDisposable
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import org.schabi.newpipe.R import org.schabi.newpipe.R
import org.schabi.newpipe.database.feed.model.FeedGroupEntity.Companion.GROUP_ALL_ID import org.schabi.newpipe.database.feed.model.FeedGroupEntity.Companion.GROUP_ALL_ID
import org.schabi.newpipe.databinding.DialogTitleBinding import org.schabi.newpipe.databinding.DialogTitleBinding
@@ -53,13 +46,6 @@ import org.schabi.newpipe.local.subscription.item.FeedGroupCarouselItem
import org.schabi.newpipe.local.subscription.item.GroupsHeader import org.schabi.newpipe.local.subscription.item.GroupsHeader
import org.schabi.newpipe.local.subscription.item.Header import org.schabi.newpipe.local.subscription.item.Header
import org.schabi.newpipe.local.subscription.item.ImportSubscriptionsHintPlaceholderItem import org.schabi.newpipe.local.subscription.item.ImportSubscriptionsHintPlaceholderItem
import org.schabi.newpipe.local.subscription.services.SubscriptionsExportService
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.KEY_MODE
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.KEY_VALUE
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.PREVIOUS_EXPORT_MODE
import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard
import org.schabi.newpipe.streams.io.StoredFileHelper
import org.schabi.newpipe.util.NavigationHelper import org.schabi.newpipe.util.NavigationHelper
import org.schabi.newpipe.util.OnClickGesture import org.schabi.newpipe.util.OnClickGesture
import org.schabi.newpipe.util.ServiceHelper import org.schabi.newpipe.util.ServiceHelper
@@ -72,6 +58,7 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
private lateinit var viewModel: SubscriptionViewModel private lateinit var viewModel: SubscriptionViewModel
private lateinit var subscriptionManager: SubscriptionManager private lateinit var subscriptionManager: SubscriptionManager
private lateinit var importExportHelper: SubscriptionsImportExportHelper
private val disposables: CompositeDisposable = CompositeDisposable() private val disposables: CompositeDisposable = CompositeDisposable()
private val groupAdapter = GroupAdapter<GroupieViewHolder<FeedItemCarouselBinding>>() private val groupAdapter = GroupAdapter<GroupieViewHolder<FeedItemCarouselBinding>>()
@@ -80,11 +67,6 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
private lateinit var feedGroupsSortMenuItem: GroupsHeader private lateinit var feedGroupsSortMenuItem: GroupsHeader
private val subscriptionsSection = Section() private val subscriptionsSection = Section()
private val requestExportLauncher =
registerForActivityResult(StartActivityForResult(), this::requestExportResult)
private val requestImportLauncher =
registerForActivityResult(StartActivityForResult(), this::requestImportResult)
@State @State
@JvmField @JvmField
var itemsListState: Parcelable? = null var itemsListState: Parcelable? = null
@@ -104,6 +86,7 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
override fun onAttach(context: Context) { override fun onAttach(context: Context) {
super.onAttach(context) super.onAttach(context)
subscriptionManager = SubscriptionManager(requireContext()) subscriptionManager = SubscriptionManager(requireContext())
importExportHelper = SubscriptionsImportExportHelper(this)
} }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
@@ -143,7 +126,7 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
// -- Import -- // -- Import --
val importSubMenu = menu.addSubMenu(R.string.import_from) val importSubMenu = menu.addSubMenu(R.string.import_from)
addMenuItemToSubmenu(importSubMenu, R.string.previous_export) { onImportPreviousSelected() } addMenuItemToSubmenu(importSubMenu, R.string.previous_export) { importExportHelper.onImportPreviousSelected() }
.setIcon(R.drawable.ic_backup) .setIcon(R.drawable.ic_backup)
for (service in ServiceList.all()) { for (service in ServiceList.all()) {
@@ -161,7 +144,7 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
// -- Export -- // -- Export --
val exportSubMenu = menu.addSubMenu(R.string.export_to) val exportSubMenu = menu.addSubMenu(R.string.export_to)
addMenuItemToSubmenu(exportSubMenu, R.string.file) { onExportSelected() } addMenuItemToSubmenu(exportSubMenu, R.string.file) { importExportHelper.onExportSelected() }
.setIcon(R.drawable.ic_save) .setIcon(R.drawable.ic_save)
} }
@@ -197,51 +180,10 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
NavigationHelper.openSubscriptionsImportFragment(fragmentManager, serviceId) NavigationHelper.openSubscriptionsImportFragment(fragmentManager, serviceId)
} }
private fun onImportPreviousSelected() {
NoFileManagerSafeGuard.launchSafe(
requestImportLauncher,
StoredFileHelper.getPicker(activity, JSON_MIME_TYPE),
TAG,
requireContext()
)
}
private fun onExportSelected() {
val date = SimpleDateFormat("yyyyMMddHHmm", Locale.ENGLISH).format(Date())
val exportName = "newpipe_subscriptions_$date.json"
NoFileManagerSafeGuard.launchSafe(
requestExportLauncher,
StoredFileHelper.getNewPicker(activity, exportName, JSON_MIME_TYPE, null),
TAG,
requireContext()
)
}
private fun openReorderDialog() { private fun openReorderDialog() {
FeedGroupReorderDialog().show(parentFragmentManager, null) FeedGroupReorderDialog().show(parentFragmentManager, null)
} }
private fun requestExportResult(result: ActivityResult) {
if (result.data != null && result.resultCode == Activity.RESULT_OK) {
activity.startService(
Intent(activity, SubscriptionsExportService::class.java)
.putExtra(SubscriptionsExportService.KEY_FILE_PATH, result.data?.data)
)
}
}
private fun requestImportResult(result: ActivityResult) {
if (result.data != null && result.resultCode == Activity.RESULT_OK) {
ImportConfirmationDialog.show(
this,
Intent(activity, SubscriptionsImportService::class.java)
.putExtra(KEY_MODE, PREVIOUS_EXPORT_MODE)
.putExtra(KEY_VALUE, result.data?.data)
)
}
}
// //////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////
// Fragment Views // Fragment Views
// //////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////

View File

@@ -1,7 +1,6 @@
package org.schabi.newpipe.local.subscription package org.schabi.newpipe.local.subscription
import android.content.Context import android.content.Context
import android.util.Pair
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Completable import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Flowable import io.reactivex.rxjava3.core.Flowable
@@ -51,23 +50,16 @@ class SubscriptionManager(context: Context) {
} }
} }
fun upsertAll(infoList: List<Pair<ChannelInfo, List<ChannelTabInfo>>>): List<SubscriptionEntity> { fun upsertAll(infoList: List<Pair<ChannelInfo, ChannelTabInfo>>) {
val listEntities = subscriptionTable.upsertAll( val listEntities = infoList.map { SubscriptionEntity.from(it.first) }
infoList.map { SubscriptionEntity.from(it.first) } subscriptionTable.upsertAll(listEntities)
)
database.runInTransaction { database.runInTransaction {
infoList.forEachIndexed { index, info -> infoList.forEachIndexed { index, info ->
info.second.forEach { val streams = info.second.relatedItems.filterIsInstance<StreamInfoItem>()
feedDatabaseManager.upsertAll( feedDatabaseManager.upsertAll(listEntities[index].uid, streams)
listEntities[index].uid,
it.relatedItems.filterIsInstance<StreamInfoItem>()
)
}
} }
} }
return listEntities
} }
fun updateChannelInfo(info: ChannelInfo): Completable = subscriptionTable.getSubscription(info.serviceId, info.url) fun updateChannelInfo(info: ChannelInfo): Completable = subscriptionTable.getSubscription(info.serviceId, info.url)

View File

@@ -0,0 +1,82 @@
package org.schabi.newpipe.local.subscription
import android.app.Activity
import android.content.Context
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
import androidx.fragment.app.Fragment
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import org.schabi.newpipe.local.subscription.SubscriptionFragment.Companion.JSON_MIME_TYPE
import org.schabi.newpipe.local.subscription.workers.SubscriptionExportWorker
import org.schabi.newpipe.local.subscription.workers.SubscriptionImportInput
import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard
import org.schabi.newpipe.streams.io.StoredFileHelper
/**
* This class has to be created in onAttach() or onCreate().
*
* It contains registerForActivityResult calls and those
* calls are only allowed before a fragment/activity is created.
*/
class SubscriptionsImportExportHelper(
val fragment: Fragment
) {
val context: Context = fragment.requireContext()
companion object {
val TAG: String =
SubscriptionsImportExportHelper::class.java.simpleName + "@" + Integer.toHexString(
hashCode()
)
}
private val requestExportLauncher =
fragment.registerForActivityResult(StartActivityForResult(), this::requestExportResult)
private val requestImportLauncher =
fragment.registerForActivityResult(StartActivityForResult(), this::requestImportResult)
private fun requestExportResult(result: ActivityResult) {
val data = result.data?.data
if (data != null && result.resultCode == Activity.RESULT_OK) {
SubscriptionExportWorker.schedule(context, data)
}
}
private fun requestImportResult(result: ActivityResult) {
val data = result.data?.dataString
if (data != null && result.resultCode == Activity.RESULT_OK) {
ImportConfirmationDialog.show(
fragment,
SubscriptionImportInput.PreviousExportMode(data)
)
}
}
fun onExportSelected() {
val date = SimpleDateFormat("yyyyMMddHHmm", Locale.ENGLISH).format(Date())
val exportName = "newpipe_subscriptions_$date.json"
NoFileManagerSafeGuard.launchSafe(
requestExportLauncher,
StoredFileHelper.getNewPicker(
context,
exportName,
JSON_MIME_TYPE,
null
),
TAG,
context
)
}
fun onImportPreviousSelected() {
NoFileManagerSafeGuard.launchSafe(
requestImportLauncher,
StoredFileHelper.getPicker(context, JSON_MIME_TYPE),
TAG,
context
)
}
}

View File

@@ -1,10 +1,6 @@
package org.schabi.newpipe.local.subscription; package org.schabi.newpipe.local.subscription;
import static org.schabi.newpipe.extractor.subscription.SubscriptionExtractor.ContentSource.CHANNEL_URL; import static org.schabi.newpipe.extractor.subscription.SubscriptionExtractor.ContentSource.CHANNEL_URL;
import static org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.CHANNEL_URL_MODE;
import static org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.INPUT_STREAM_MODE;
import static org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.KEY_MODE;
import static org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.KEY_VALUE;
import android.app.Activity; import android.app.Activity;
import android.content.Intent; import android.content.Intent;
@@ -37,7 +33,7 @@ import org.schabi.newpipe.error.UserAction;
import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.subscription.SubscriptionExtractor; import org.schabi.newpipe.extractor.subscription.SubscriptionExtractor;
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService; import org.schabi.newpipe.local.subscription.workers.SubscriptionImportInput;
import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard; import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard;
import org.schabi.newpipe.streams.io.StoredFileHelper; import org.schabi.newpipe.streams.io.StoredFileHelper;
import org.schabi.newpipe.util.Constants; import org.schabi.newpipe.util.Constants;
@@ -168,10 +164,8 @@ public class SubscriptionsImportFragment extends BaseFragment {
} }
public void onImportUrl(final String value) { public void onImportUrl(final String value) {
ImportConfirmationDialog.show(this, new Intent(activity, SubscriptionsImportService.class) ImportConfirmationDialog.show(this,
.putExtra(KEY_MODE, CHANNEL_URL_MODE) new SubscriptionImportInput.ChannelUrlMode(currentServiceId, value));
.putExtra(KEY_VALUE, value)
.putExtra(Constants.KEY_SERVICE_ID, currentServiceId));
} }
public void onImportFile() { public void onImportFile() {
@@ -186,16 +180,10 @@ public class SubscriptionsImportFragment extends BaseFragment {
} }
private void requestImportFileResult(final ActivityResult result) { private void requestImportFileResult(final ActivityResult result) {
if (result.getData() == null) { final String data = result.getData() != null ? result.getData().getDataString() : null;
return; if (result.getResultCode() == Activity.RESULT_OK && data != null) {
}
if (result.getResultCode() == Activity.RESULT_OK && result.getData().getData() != null) {
ImportConfirmationDialog.show(this, ImportConfirmationDialog.show(this,
new Intent(activity, SubscriptionsImportService.class) new SubscriptionImportInput.InputStreamMode(currentServiceId, data));
.putExtra(KEY_MODE, INPUT_STREAM_MODE)
.putExtra(KEY_VALUE, result.getData().getData())
.putExtra(Constants.KEY_SERVICE_ID, currentServiceId));
} }
} }

View File

@@ -1,238 +0,0 @@
/*
* Copyright 2018 Mauricio Colli <mauriciocolli@outlook.com>
* BaseImportExportService.java is part of NewPipe
*
* License: GPL-3.0+
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.schabi.newpipe.local.subscription.services;
import android.app.Service;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.text.TextUtils;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.app.ServiceCompat;
import org.reactivestreams.Publisher;
import org.schabi.newpipe.R;
import org.schabi.newpipe.error.ErrorInfo;
import org.schabi.newpipe.error.ErrorUtil;
import org.schabi.newpipe.error.UserAction;
import org.schabi.newpipe.extractor.subscription.SubscriptionExtractor;
import org.schabi.newpipe.ktx.ExceptionUtils;
import org.schabi.newpipe.local.subscription.SubscriptionManager;
import java.io.FileNotFoundException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Flowable;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
import io.reactivex.rxjava3.functions.Function;
import io.reactivex.rxjava3.processors.PublishProcessor;
public abstract class BaseImportExportService extends Service {
protected final String TAG = this.getClass().getSimpleName();
protected final CompositeDisposable disposables = new CompositeDisposable();
protected final PublishProcessor<String> notificationUpdater = PublishProcessor.create();
protected NotificationManagerCompat notificationManager;
protected NotificationCompat.Builder notificationBuilder;
protected SubscriptionManager subscriptionManager;
private static final int NOTIFICATION_SAMPLING_PERIOD = 2500;
protected final AtomicInteger currentProgress = new AtomicInteger(-1);
protected final AtomicInteger maxProgress = new AtomicInteger(-1);
protected final ImportExportEventListener eventListener = new ImportExportEventListener() {
@Override
public void onSizeReceived(final int size) {
maxProgress.set(size);
currentProgress.set(0);
}
@Override
public void onItemCompleted(final String itemName) {
currentProgress.incrementAndGet();
notificationUpdater.onNext(itemName);
}
};
protected Toast toast;
@Nullable
@Override
public IBinder onBind(final Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
subscriptionManager = new SubscriptionManager(this);
setupNotification();
}
@Override
public void onDestroy() {
super.onDestroy();
disposeAll();
}
protected void disposeAll() {
disposables.clear();
}
/*//////////////////////////////////////////////////////////////////////////
// Notification Impl
//////////////////////////////////////////////////////////////////////////*/
protected abstract int getNotificationId();
@StringRes
public abstract int getTitle();
protected void setupNotification() {
notificationManager = NotificationManagerCompat.from(this);
notificationBuilder = createNotification();
startForeground(getNotificationId(), notificationBuilder.build());
final Function<Flowable<String>, Publisher<String>> throttleAfterFirstEmission = flow ->
flow.take(1).concatWith(flow.skip(1)
.throttleLast(NOTIFICATION_SAMPLING_PERIOD, TimeUnit.MILLISECONDS));
disposables.add(notificationUpdater
.filter(s -> !s.isEmpty())
.publish(throttleAfterFirstEmission)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::updateNotification));
}
protected void updateNotification(final String text) {
notificationBuilder
.setProgress(maxProgress.get(), currentProgress.get(), maxProgress.get() == -1);
final String progressText = currentProgress + "/" + maxProgress;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
if (!TextUtils.isEmpty(text)) {
notificationBuilder.setContentText(text + " (" + progressText + ")");
}
} else {
notificationBuilder.setContentInfo(progressText);
notificationBuilder.setContentText(text);
}
if (notificationManager.areNotificationsEnabled()) {
notificationManager.notify(getNotificationId(), notificationBuilder.build());
}
}
protected void stopService() {
postErrorResult(null, null);
}
protected void stopAndReportError(final Throwable throwable, final String request) {
stopService();
ErrorUtil.createNotification(this, new ErrorInfo(
throwable, UserAction.SUBSCRIPTION_IMPORT_EXPORT, request));
}
protected void postErrorResult(final String title, final String text) {
disposeAll();
ServiceCompat.stopForeground(this, ServiceCompat.STOP_FOREGROUND_REMOVE);
stopSelf();
if (title == null) {
return;
}
final String textOrEmpty = text == null ? "" : text;
notificationBuilder = new NotificationCompat
.Builder(this, getString(R.string.notification_channel_id))
.setSmallIcon(R.drawable.ic_newpipe_triangle_white)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setContentTitle(title)
.setStyle(new NotificationCompat.BigTextStyle().bigText(textOrEmpty))
.setContentText(textOrEmpty);
if (notificationManager.areNotificationsEnabled()) {
notificationManager.notify(getNotificationId(), notificationBuilder.build());
}
}
protected NotificationCompat.Builder createNotification() {
return new NotificationCompat.Builder(this, getString(R.string.notification_channel_id))
.setOngoing(true)
.setProgress(-1, -1, true)
.setSmallIcon(R.drawable.ic_newpipe_triangle_white)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setContentTitle(getString(getTitle()));
}
/*//////////////////////////////////////////////////////////////////////////
// Toast
//////////////////////////////////////////////////////////////////////////*/
protected void showToast(@StringRes final int message) {
showToast(getString(message));
}
protected void showToast(final String message) {
if (toast != null) {
toast.cancel();
}
toast = Toast.makeText(this, message, Toast.LENGTH_SHORT);
toast.show();
}
/*//////////////////////////////////////////////////////////////////////////
// Error handling
//////////////////////////////////////////////////////////////////////////*/
protected void handleError(@StringRes final int errorTitle, @NonNull final Throwable error) {
String message = getErrorMessage(error);
if (TextUtils.isEmpty(message)) {
final String errorClassName = error.getClass().getName();
message = getString(R.string.error_occurred_detail, errorClassName);
}
showToast(errorTitle);
postErrorResult(getString(errorTitle), message);
}
protected String getErrorMessage(final Throwable error) {
String message = null;
if (error instanceof SubscriptionExtractor.InvalidSourceException) {
message = getString(R.string.invalid_source);
} else if (error instanceof FileNotFoundException) {
message = getString(R.string.invalid_file);
} else if (ExceptionUtils.isNetworkRelated(error)) {
message = getString(R.string.network_error);
}
return message;
}
}

View File

@@ -1,17 +0,0 @@
package org.schabi.newpipe.local.subscription.services;
public interface ImportExportEventListener {
/**
* Called when the size has been resolved.
*
* @param size how many items there are to import/export
*/
void onSizeReceived(int size);
/**
* Called every time an item has been parsed/resolved.
*
* @param itemName the name of the subscription item
*/
void onItemCompleted(String itemName);
}

View File

@@ -1,158 +0,0 @@
/*
* Copyright 2018 Mauricio Colli <mauriciocolli@outlook.com>
* ImportExportJsonHelper.java is part of NewPipe
*
* License: GPL-3.0+
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.schabi.newpipe.local.subscription.services;
import androidx.annotation.Nullable;
import com.grack.nanojson.JsonAppendableWriter;
import com.grack.nanojson.JsonArray;
import com.grack.nanojson.JsonObject;
import com.grack.nanojson.JsonParser;
import com.grack.nanojson.JsonWriter;
import org.schabi.newpipe.BuildConfig;
import org.schabi.newpipe.extractor.subscription.SubscriptionExtractor.InvalidSourceException;
import org.schabi.newpipe.extractor.subscription.SubscriptionItem;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
/**
* A JSON implementation capable of importing and exporting subscriptions, it has the advantage
* of being able to transfer subscriptions to any device.
*/
public final class ImportExportJsonHelper {
/*//////////////////////////////////////////////////////////////////////////
// Json implementation
//////////////////////////////////////////////////////////////////////////*/
private static final String JSON_APP_VERSION_KEY = "app_version";
private static final String JSON_APP_VERSION_INT_KEY = "app_version_int";
private static final String JSON_SUBSCRIPTIONS_ARRAY_KEY = "subscriptions";
private static final String JSON_SERVICE_ID_KEY = "service_id";
private static final String JSON_URL_KEY = "url";
private static final String JSON_NAME_KEY = "name";
private ImportExportJsonHelper() { }
/**
* Read a JSON source through the input stream.
*
* @param in the input stream (e.g. a file)
* @param eventListener listener for the events generated
* @return the parsed subscription items
*/
public static List<SubscriptionItem> readFrom(
final InputStream in, @Nullable final ImportExportEventListener eventListener)
throws InvalidSourceException {
if (in == null) {
throw new InvalidSourceException("input is null");
}
final List<SubscriptionItem> channels = new ArrayList<>();
try {
final JsonObject parentObject = JsonParser.object().from(in);
if (!parentObject.has(JSON_SUBSCRIPTIONS_ARRAY_KEY)) {
throw new InvalidSourceException("Channels array is null");
}
final JsonArray channelsArray = parentObject.getArray(JSON_SUBSCRIPTIONS_ARRAY_KEY);
if (eventListener != null) {
eventListener.onSizeReceived(channelsArray.size());
}
for (final Object o : channelsArray) {
if (o instanceof JsonObject) {
final JsonObject itemObject = (JsonObject) o;
final int serviceId = itemObject.getInt(JSON_SERVICE_ID_KEY, 0);
final String url = itemObject.getString(JSON_URL_KEY);
final String name = itemObject.getString(JSON_NAME_KEY);
if (url != null && name != null && !url.isEmpty() && !name.isEmpty()) {
channels.add(new SubscriptionItem(serviceId, url, name));
if (eventListener != null) {
eventListener.onItemCompleted(name);
}
}
}
}
} catch (final Throwable e) {
throw new InvalidSourceException("Couldn't parse json", e);
}
return channels;
}
/**
* Write the subscriptions items list as JSON to the output.
*
* @param items the list of subscriptions items
* @param out the output stream (e.g. a file)
* @param eventListener listener for the events generated
*/
public static void writeTo(final List<SubscriptionItem> items, final OutputStream out,
@Nullable final ImportExportEventListener eventListener) {
final JsonAppendableWriter writer = JsonWriter.on(out);
writeTo(items, writer, eventListener);
writer.done();
}
/**
* @see #writeTo(List, OutputStream, ImportExportEventListener)
* @param items the list of subscriptions items
* @param writer the output {@link JsonAppendableWriter}
* @param eventListener listener for the events generated
*/
public static void writeTo(final List<SubscriptionItem> items,
final JsonAppendableWriter writer,
@Nullable final ImportExportEventListener eventListener) {
if (eventListener != null) {
eventListener.onSizeReceived(items.size());
}
writer.object();
writer.value(JSON_APP_VERSION_KEY, BuildConfig.VERSION_NAME);
writer.value(JSON_APP_VERSION_INT_KEY, BuildConfig.VERSION_CODE);
writer.array(JSON_SUBSCRIPTIONS_ARRAY_KEY);
for (final SubscriptionItem item : items) {
writer.object();
writer.value(JSON_SERVICE_ID_KEY, item.getServiceId());
writer.value(JSON_URL_KEY, item.getUrl());
writer.value(JSON_NAME_KEY, item.getName());
writer.end();
if (eventListener != null) {
eventListener.onItemCompleted(item.getName());
}
}
writer.end();
writer.end();
}
}

View File

@@ -1,171 +0,0 @@
/*
* Copyright 2018 Mauricio Colli <mauriciocolli@outlook.com>
* SubscriptionsExportService.java is part of NewPipe
*
* License: GPL-3.0+
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.schabi.newpipe.local.subscription.services;
import static org.schabi.newpipe.MainActivity.DEBUG;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
import androidx.core.content.IntentCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
import org.schabi.newpipe.App;
import org.schabi.newpipe.R;
import org.schabi.newpipe.database.subscription.SubscriptionEntity;
import org.schabi.newpipe.extractor.subscription.SubscriptionItem;
import org.schabi.newpipe.streams.io.SharpOutputStream;
import org.schabi.newpipe.streams.io.StoredFileHelper;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.functions.Function;
import io.reactivex.rxjava3.schedulers.Schedulers;
public class SubscriptionsExportService extends BaseImportExportService {
public static final String KEY_FILE_PATH = "key_file_path";
/**
* A {@link LocalBroadcastManager local broadcast} will be made with this action
* when the export is successfully completed.
*/
public static final String EXPORT_COMPLETE_ACTION = App.PACKAGE_NAME + ".local.subscription"
+ ".services.SubscriptionsExportService.EXPORT_COMPLETE";
private Subscription subscription;
private StoredFileHelper outFile;
private OutputStream outputStream;
@Override
public int onStartCommand(final Intent intent, final int flags, final int startId) {
if (intent == null || subscription != null) {
return START_NOT_STICKY;
}
final Uri path = IntentCompat.getParcelableExtra(intent, KEY_FILE_PATH, Uri.class);
if (path == null) {
stopAndReportError(new IllegalStateException(
"Exporting to a file, but the path is null"),
"Exporting subscriptions");
return START_NOT_STICKY;
}
try {
outFile = new StoredFileHelper(this, path, "application/json");
// truncate the file before writing to it, otherwise if the new content is smaller than
// the previous file size, the file will retain part of the previous content and be
// corrupted
outputStream = new SharpOutputStream(outFile.openAndTruncateStream());
} catch (final IOException e) {
handleError(e);
return START_NOT_STICKY;
}
startExport();
return START_NOT_STICKY;
}
@Override
protected int getNotificationId() {
return 4567;
}
@Override
public int getTitle() {
return R.string.export_ongoing;
}
@Override
protected void disposeAll() {
super.disposeAll();
if (subscription != null) {
subscription.cancel();
}
}
private void startExport() {
showToast(R.string.export_ongoing);
subscriptionManager.subscriptionTable().getAll().take(1)
.map(subscriptionEntities -> {
final List<SubscriptionItem> result =
new ArrayList<>(subscriptionEntities.size());
for (final SubscriptionEntity entity : subscriptionEntities) {
result.add(new SubscriptionItem(entity.getServiceId(), entity.getUrl(),
entity.getName()));
}
return result;
})
.map(exportToFile())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getSubscriber());
}
private Subscriber<StoredFileHelper> getSubscriber() {
return new Subscriber<StoredFileHelper>() {
@Override
public void onSubscribe(final Subscription s) {
subscription = s;
s.request(1);
}
@Override
public void onNext(final StoredFileHelper file) {
if (DEBUG) {
Log.d(TAG, "startExport() success: file = " + file);
}
}
@Override
public void onError(final Throwable error) {
Log.e(TAG, "onError() called with: error = [" + error + "]", error);
handleError(error);
}
@Override
public void onComplete() {
LocalBroadcastManager.getInstance(SubscriptionsExportService.this)
.sendBroadcast(new Intent(EXPORT_COMPLETE_ACTION));
showToast(R.string.export_complete_toast);
stopService();
}
};
}
private Function<List<SubscriptionItem>, StoredFileHelper> exportToFile() {
return subscriptionItems -> {
ImportExportJsonHelper.writeTo(subscriptionItems, outputStream, eventListener);
return outFile;
};
}
protected void handleError(final Throwable error) {
super.handleError(R.string.subscriptions_export_unsuccessful, error);
}
}

View File

@@ -1,327 +0,0 @@
/*
* Copyright 2018 Mauricio Colli <mauriciocolli@outlook.com>
* SubscriptionsImportService.java is part of NewPipe
*
* License: GPL-3.0+
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.schabi.newpipe.local.subscription.services;
import static org.schabi.newpipe.MainActivity.DEBUG;
import static org.schabi.newpipe.streams.io.StoredFileHelper.DEFAULT_MIME;
import android.content.Intent;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.IntentCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
import org.schabi.newpipe.App;
import org.schabi.newpipe.R;
import org.schabi.newpipe.database.subscription.SubscriptionEntity;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.channel.ChannelInfo;
import org.schabi.newpipe.extractor.channel.tabs.ChannelTabInfo;
import org.schabi.newpipe.extractor.subscription.SubscriptionItem;
import org.schabi.newpipe.ktx.ExceptionUtils;
import org.schabi.newpipe.streams.io.SharpInputStream;
import org.schabi.newpipe.streams.io.StoredFileHelper;
import org.schabi.newpipe.util.Constants;
import org.schabi.newpipe.util.ExtractorHelper;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Flowable;
import io.reactivex.rxjava3.core.Notification;
import io.reactivex.rxjava3.functions.Consumer;
import io.reactivex.rxjava3.functions.Function;
import io.reactivex.rxjava3.schedulers.Schedulers;
public class SubscriptionsImportService extends BaseImportExportService {
public static final int CHANNEL_URL_MODE = 0;
public static final int INPUT_STREAM_MODE = 1;
public static final int PREVIOUS_EXPORT_MODE = 2;
public static final String KEY_MODE = "key_mode";
public static final String KEY_VALUE = "key_value";
/**
* A {@link LocalBroadcastManager local broadcast} will be made with this action
* when the import is successfully completed.
*/
public static final String IMPORT_COMPLETE_ACTION = App.PACKAGE_NAME + ".local.subscription"
+ ".services.SubscriptionsImportService.IMPORT_COMPLETE";
/**
* How many extractions running in parallel.
*/
public static final int PARALLEL_EXTRACTIONS = 8;
/**
* Number of items to buffer to mass-insert in the subscriptions table,
* this leads to a better performance as we can then use db transactions.
*/
public static final int BUFFER_COUNT_BEFORE_INSERT = 50;
private Subscription subscription;
private int currentMode;
private int currentServiceId;
@Nullable
private String channelUrl;
@Nullable
private InputStream inputStream;
@Nullable
private String inputStreamType;
@Override
public int onStartCommand(final Intent intent, final int flags, final int startId) {
if (intent == null || subscription != null) {
return START_NOT_STICKY;
}
currentMode = intent.getIntExtra(KEY_MODE, -1);
currentServiceId = intent.getIntExtra(Constants.KEY_SERVICE_ID, Constants.NO_SERVICE_ID);
if (currentMode == CHANNEL_URL_MODE) {
channelUrl = intent.getStringExtra(KEY_VALUE);
} else {
final Uri uri = IntentCompat.getParcelableExtra(intent, KEY_VALUE, Uri.class);
if (uri == null) {
stopAndReportError(new IllegalStateException(
"Importing from input stream, but file path is null"),
"Importing subscriptions");
return START_NOT_STICKY;
}
try {
final StoredFileHelper fileHelper = new StoredFileHelper(this, uri, DEFAULT_MIME);
inputStream = new SharpInputStream(fileHelper.getStream());
inputStreamType = fileHelper.getType();
if (inputStreamType == null || inputStreamType.equals(DEFAULT_MIME)) {
// mime type could not be determined, just take file extension
final String name = fileHelper.getName();
final int pointIndex = name.lastIndexOf('.');
if (pointIndex == -1 || pointIndex >= name.length() - 1) {
inputStreamType = DEFAULT_MIME; // no extension, will fail in the extractor
} else {
inputStreamType = name.substring(pointIndex + 1);
}
}
} catch (final IOException e) {
handleError(e);
return START_NOT_STICKY;
}
}
if (currentMode == -1 || currentMode == CHANNEL_URL_MODE && channelUrl == null) {
final String errorDescription = "Some important field is null or in illegal state: "
+ "currentMode=[" + currentMode + "], "
+ "channelUrl=[" + channelUrl + "], "
+ "inputStream=[" + inputStream + "]";
stopAndReportError(new IllegalStateException(errorDescription),
"Importing subscriptions");
return START_NOT_STICKY;
}
startImport();
return START_NOT_STICKY;
}
@Override
protected int getNotificationId() {
return 4568;
}
@Override
public int getTitle() {
return R.string.import_ongoing;
}
@Override
protected void disposeAll() {
super.disposeAll();
if (subscription != null) {
subscription.cancel();
}
}
/*//////////////////////////////////////////////////////////////////////////
// Imports
//////////////////////////////////////////////////////////////////////////*/
private void startImport() {
showToast(R.string.import_ongoing);
Flowable<List<SubscriptionItem>> flowable = null;
switch (currentMode) {
case CHANNEL_URL_MODE:
flowable = importFromChannelUrl();
break;
case INPUT_STREAM_MODE:
flowable = importFromInputStream();
break;
case PREVIOUS_EXPORT_MODE:
flowable = importFromPreviousExport();
break;
}
if (flowable == null) {
final String message = "Flowable given by \"importFrom\" is null "
+ "(current mode: " + currentMode + ")";
stopAndReportError(new IllegalStateException(message), "Importing subscriptions");
return;
}
flowable.doOnNext(subscriptionItems ->
eventListener.onSizeReceived(subscriptionItems.size()))
.flatMap(Flowable::fromIterable)
.parallel(PARALLEL_EXTRACTIONS)
.runOn(Schedulers.io())
.map((Function<SubscriptionItem, Notification<Pair<ChannelInfo,
List<ChannelTabInfo>>>>) subscriptionItem -> {
try {
final ChannelInfo channelInfo = ExtractorHelper
.getChannelInfo(subscriptionItem.getServiceId(),
subscriptionItem.getUrl(), true)
.blockingGet();
return Notification.createOnNext(new Pair<>(channelInfo,
Collections.singletonList(
ExtractorHelper.getChannelTab(
subscriptionItem.getServiceId(),
channelInfo.getTabs().get(0), true).blockingGet()
)));
} catch (final Throwable e) {
return Notification.createOnError(e);
}
})
.sequential()
.observeOn(Schedulers.io())
.doOnNext(getNotificationsConsumer())
.buffer(BUFFER_COUNT_BEFORE_INSERT)
.map(upsertBatch())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getSubscriber());
}
private Subscriber<List<SubscriptionEntity>> getSubscriber() {
return new Subscriber<>() {
@Override
public void onSubscribe(final Subscription s) {
subscription = s;
s.request(Long.MAX_VALUE);
}
@Override
public void onNext(final List<SubscriptionEntity> successfulInserted) {
if (DEBUG) {
Log.d(TAG, "startImport() " + successfulInserted.size()
+ " items successfully inserted into the database");
}
}
@Override
public void onError(final Throwable error) {
Log.e(TAG, "Got an error!", error);
handleError(error);
}
@Override
public void onComplete() {
LocalBroadcastManager.getInstance(SubscriptionsImportService.this)
.sendBroadcast(new Intent(IMPORT_COMPLETE_ACTION));
showToast(R.string.import_complete_toast);
stopService();
}
};
}
private Consumer<Notification<Pair<ChannelInfo,
List<ChannelTabInfo>>>> getNotificationsConsumer() {
return notification -> {
if (notification.isOnNext()) {
final String name = notification.getValue().first.getName();
eventListener.onItemCompleted(!TextUtils.isEmpty(name) ? name : "");
} else if (notification.isOnError()) {
final Throwable error = notification.getError();
final Throwable cause = error.getCause();
if (error instanceof IOException) {
throw error;
} else if (cause instanceof IOException) {
throw cause;
} else if (ExceptionUtils.isNetworkRelated(error)) {
throw new IOException(error);
}
eventListener.onItemCompleted("");
}
};
}
private Function<List<Notification<Pair<ChannelInfo, List<ChannelTabInfo>>>>,
List<SubscriptionEntity>> upsertBatch() {
return notificationList -> {
final List<Pair<ChannelInfo, List<ChannelTabInfo>>> infoList =
new ArrayList<>(notificationList.size());
for (final Notification<Pair<ChannelInfo, List<ChannelTabInfo>>> n : notificationList) {
if (n.isOnNext()) {
infoList.add(n.getValue());
}
}
return subscriptionManager.upsertAll(infoList);
};
}
private Flowable<List<SubscriptionItem>> importFromChannelUrl() {
return Flowable.fromCallable(() -> NewPipe.getService(currentServiceId)
.getSubscriptionExtractor()
.fromChannelUrl(channelUrl));
}
private Flowable<List<SubscriptionItem>> importFromInputStream() {
Objects.requireNonNull(inputStream);
Objects.requireNonNull(inputStreamType);
return Flowable.fromCallable(() -> NewPipe.getService(currentServiceId)
.getSubscriptionExtractor()
.fromInputStream(inputStream, inputStreamType));
}
private Flowable<List<SubscriptionItem>> importFromPreviousExport() {
return Flowable.fromCallable(() -> ImportExportJsonHelper.readFrom(inputStream, null));
}
protected void handleError(@NonNull final Throwable error) {
super.handleError(R.string.subscriptions_import_unsuccessful, error);
}
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright 2018 Mauricio Colli <mauriciocolli@outlook.com>
* ImportExportJsonHelper.java is part of NewPipe
*
* License: GPL-3.0+
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.schabi.newpipe.local.subscription.workers
import java.io.InputStream
import java.io.OutputStream
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromStream
import kotlinx.serialization.json.encodeToStream
import org.schabi.newpipe.extractor.subscription.SubscriptionExtractor.InvalidSourceException
/**
* A JSON implementation capable of importing and exporting subscriptions, it has the advantage
* of being able to transfer subscriptions to any device.
*/
object ImportExportJsonHelper {
private val json = Json { encodeDefaults = true }
/**
* Read a JSON source through the input stream.
*
* @param in the input stream (e.g. a file)
* @return the parsed subscription items
*/
@JvmStatic
@Throws(InvalidSourceException::class)
fun readFrom(`in`: InputStream?): List<SubscriptionItem> {
if (`in` == null) {
throw InvalidSourceException("input is null")
}
try {
@OptIn(ExperimentalSerializationApi::class)
return json.decodeFromStream<SubscriptionData>(`in`).subscriptions
} catch (e: Throwable) {
throw InvalidSourceException("Couldn't parse json", e)
}
}
/**
* Write the subscriptions items list as JSON to the output.
*
* @param items the list of subscriptions items
* @param out the output stream (e.g. a file)
*/
@OptIn(ExperimentalSerializationApi::class)
@JvmStatic
fun writeTo(
items: List<SubscriptionItem>,
out: OutputStream
) {
json.encodeToStream(SubscriptionData(items), out)
}
}

View File

@@ -0,0 +1,24 @@
package org.schabi.newpipe.local.subscription.workers
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import org.schabi.newpipe.BuildConfig
@Serializable
class SubscriptionData(
val subscriptions: List<SubscriptionItem>
) {
@SerialName("app_version")
private val appVersion = BuildConfig.VERSION_NAME
@SerialName("app_version_int")
private val appVersionInt = BuildConfig.VERSION_CODE
}
@Serializable
data class SubscriptionItem(
@SerialName("service_id")
val serviceId: Int,
val url: String,
val name: String
)

View File

@@ -0,0 +1,119 @@
package org.schabi.newpipe.local.subscription.workers
import android.content.Context
import android.content.pm.ServiceInfo
import android.net.Uri
import android.os.Build
import android.util.Log
import android.widget.Toast
import androidx.core.app.NotificationCompat
import androidx.core.net.toUri
import androidx.work.CoroutineWorker
import androidx.work.ExistingWorkPolicy
import androidx.work.ForegroundInfo
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.OutOfQuotaPolicy
import androidx.work.WorkManager
import androidx.work.WorkerParameters
import androidx.work.workDataOf
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.reactive.awaitFirst
import kotlinx.coroutines.withContext
import org.schabi.newpipe.BuildConfig
import org.schabi.newpipe.NewPipeDatabase
import org.schabi.newpipe.R
class SubscriptionExportWorker(
appContext: Context,
params: WorkerParameters
) : CoroutineWorker(appContext, params) {
// This is needed for API levels < 31 (Android S).
override suspend fun getForegroundInfo(): ForegroundInfo {
return createForegroundInfo(applicationContext.getString(R.string.export_ongoing))
}
override suspend fun doWork(): Result {
return try {
val uri = inputData.getString(EXPORT_PATH)!!.toUri()
val table = NewPipeDatabase.getInstance(applicationContext).subscriptionDAO()
val subscriptions =
table.getAll()
.awaitFirst()
.map { SubscriptionItem(it.serviceId, it.url ?: "", it.name ?: "") }
val qty = subscriptions.size
val title = applicationContext.resources.getQuantityString(R.plurals.export_subscriptions, qty, qty)
setForeground(createForegroundInfo(title))
withContext(Dispatchers.IO) {
// Truncate file if it already exists
applicationContext.contentResolver.openOutputStream(uri, "wt")?.use {
ImportExportJsonHelper.writeTo(subscriptions, it)
}
}
if (BuildConfig.DEBUG) {
Log.i(TAG, "Exported $qty subscriptions")
}
withContext(Dispatchers.Main) {
Toast
.makeText(applicationContext, R.string.export_complete_toast, Toast.LENGTH_SHORT)
.show()
}
Result.success()
} catch (e: Exception) {
if (BuildConfig.DEBUG) {
Log.e(TAG, "Error while exporting subscriptions", e)
}
withContext(Dispatchers.Main) {
Toast
.makeText(applicationContext, R.string.subscriptions_export_unsuccessful, Toast.LENGTH_SHORT)
.show()
}
return Result.failure()
}
}
private fun createForegroundInfo(title: String): ForegroundInfo {
val notification =
NotificationCompat
.Builder(applicationContext, NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_newpipe_triangle_white)
.setOngoing(true)
.setProgress(-1, -1, true)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setForegroundServiceBehavior(NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE)
.setContentTitle(title)
.build()
val serviceType = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC else 0
return ForegroundInfo(NOTIFICATION_ID, notification, serviceType)
}
companion object {
private const val TAG = "SubscriptionExportWork"
private const val NOTIFICATION_ID = 4567
private const val NOTIFICATION_CHANNEL_ID = "newpipe"
private const val WORK_NAME = "exportSubscriptions"
private const val EXPORT_PATH = "exportPath"
fun schedule(
context: Context,
uri: Uri
) {
val data = workDataOf(EXPORT_PATH to uri.toString())
val workRequest =
OneTimeWorkRequestBuilder<SubscriptionExportWorker>()
.setInputData(data)
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
.build()
WorkManager
.getInstance(context)
.enqueueUniqueWork(WORK_NAME, ExistingWorkPolicy.APPEND_OR_REPLACE, workRequest)
}
}
}

View File

@@ -0,0 +1,242 @@
package org.schabi.newpipe.local.subscription.workers
import android.content.Context
import android.content.pm.ServiceInfo
import android.os.Build
import android.os.Parcelable
import android.util.Log
import android.webkit.MimeTypeMap
import android.widget.Toast
import androidx.core.app.NotificationCompat
import androidx.core.net.toUri
import androidx.work.CoroutineWorker
import androidx.work.Data
import androidx.work.ForegroundInfo
import androidx.work.WorkManager
import androidx.work.WorkerParameters
import androidx.work.workDataOf
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.rx3.await
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
import kotlinx.parcelize.Parcelize
import org.schabi.newpipe.BuildConfig
import org.schabi.newpipe.R
import org.schabi.newpipe.extractor.NewPipe
import org.schabi.newpipe.local.subscription.SubscriptionManager
import org.schabi.newpipe.util.ExtractorHelper
class SubscriptionImportWorker(
appContext: Context,
params: WorkerParameters
) : CoroutineWorker(appContext, params) {
// This is needed for API levels < 31 (Android S).
override suspend fun getForegroundInfo(): ForegroundInfo {
return createForegroundInfo(applicationContext.getString(R.string.import_ongoing), null, 0, 0)
}
override suspend fun doWork(): Result {
val subscriptions =
try {
loadSubscriptionsFromInput(SubscriptionImportInput.fromData(inputData))
} catch (e: Exception) {
if (BuildConfig.DEBUG) {
Log.e(TAG, "Error while loading subscriptions from path", e)
}
withContext(Dispatchers.Main) {
Toast
.makeText(applicationContext, R.string.subscriptions_import_unsuccessful, Toast.LENGTH_SHORT)
.show()
}
return Result.failure()
}
val mutex = Mutex()
var index = 1
val qty = subscriptions.size
var title =
applicationContext.resources.getQuantityString(R.plurals.load_subscriptions, qty, qty)
val channelInfoList =
try {
withContext(Dispatchers.IO.limitedParallelism(PARALLEL_EXTRACTIONS)) {
subscriptions
.map {
async {
val channelInfo =
ExtractorHelper.getChannelInfo(it.serviceId, it.url, true).await()
val channelTab =
ExtractorHelper.getChannelTab(it.serviceId, channelInfo.tabs[0], true).await()
val currentIndex = mutex.withLock { index++ }
setForeground(createForegroundInfo(title, channelInfo.name, currentIndex, qty))
channelInfo to channelTab
}
}.awaitAll()
}
} catch (e: Exception) {
if (BuildConfig.DEBUG) {
Log.e(TAG, "Error while loading subscription data", e)
}
withContext(Dispatchers.Main) {
Toast.makeText(applicationContext, R.string.subscriptions_import_unsuccessful, Toast.LENGTH_SHORT)
.show()
}
return Result.failure()
}
title = applicationContext.resources.getQuantityString(R.plurals.import_subscriptions, qty, qty)
setForeground(createForegroundInfo(title, null, 0, 0))
index = 0
val subscriptionManager = SubscriptionManager(applicationContext)
for (chunk in channelInfoList.chunked(BUFFER_COUNT_BEFORE_INSERT)) {
withContext(Dispatchers.IO) {
subscriptionManager.upsertAll(chunk)
}
index += chunk.size
setForeground(createForegroundInfo(title, null, index, qty))
}
withContext(Dispatchers.Main) {
Toast.makeText(applicationContext, R.string.import_complete_toast, Toast.LENGTH_SHORT)
.show()
}
return Result.success()
}
private suspend fun loadSubscriptionsFromInput(input: SubscriptionImportInput): List<SubscriptionItem> {
return withContext(Dispatchers.IO) {
when (input) {
is SubscriptionImportInput.ChannelUrlMode ->
NewPipe.getService(input.serviceId).subscriptionExtractor
.fromChannelUrl(input.url)
.map { SubscriptionItem(it.serviceId, it.url, it.name) }
is SubscriptionImportInput.InputStreamMode ->
applicationContext.contentResolver.openInputStream(input.url.toUri())?.use {
val contentType =
MimeTypeMap.getFileExtensionFromUrl(input.url).ifEmpty { DEFAULT_MIME }
NewPipe.getService(input.serviceId).subscriptionExtractor
.fromInputStream(it, contentType)
.map { SubscriptionItem(it.serviceId, it.url, it.name) }
}
is SubscriptionImportInput.PreviousExportMode ->
applicationContext.contentResolver.openInputStream(input.url.toUri())?.use {
ImportExportJsonHelper.readFrom(it)
}
} ?: emptyList()
}
}
private fun createForegroundInfo(
title: String,
text: String?,
currentProgress: Int,
maxProgress: Int
): ForegroundInfo {
val notification =
NotificationCompat
.Builder(applicationContext, NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_newpipe_triangle_white)
.setOngoing(true)
.setProgress(maxProgress, currentProgress, currentProgress == 0)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setForegroundServiceBehavior(NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE)
.setContentTitle(title)
.setContentText(text)
.addAction(
R.drawable.ic_close,
applicationContext.getString(R.string.cancel),
WorkManager.getInstance(applicationContext).createCancelPendingIntent(id)
).apply {
if (currentProgress > 0 && maxProgress > 0) {
val progressText = "$currentProgress/$maxProgress"
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
setSubText(progressText)
} else {
setContentInfo(progressText)
}
}
}.build()
val serviceType = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC else 0
return ForegroundInfo(NOTIFICATION_ID, notification, serviceType)
}
companion object {
// Log tag length is limited to 23 characters on API levels < 24.
private const val TAG = "SubscriptionImport"
private const val NOTIFICATION_ID = 4568
private const val NOTIFICATION_CHANNEL_ID = "newpipe"
private const val DEFAULT_MIME = "application/octet-stream"
private const val PARALLEL_EXTRACTIONS = 8
private const val BUFFER_COUNT_BEFORE_INSERT = 50
const val WORK_NAME = "SubscriptionImportWorker"
}
}
sealed class SubscriptionImportInput : Parcelable {
@Parcelize
data class ChannelUrlMode(val serviceId: Int, val url: String) : SubscriptionImportInput()
@Parcelize
data class InputStreamMode(val serviceId: Int, val url: String) : SubscriptionImportInput()
@Parcelize
data class PreviousExportMode(val url: String) : SubscriptionImportInput()
fun toData(): Data {
val (mode, serviceId, url) = when (this) {
is ChannelUrlMode -> Triple(CHANNEL_URL_MODE, serviceId, url)
is InputStreamMode -> Triple(INPUT_STREAM_MODE, serviceId, url)
is PreviousExportMode -> Triple(PREVIOUS_EXPORT_MODE, null, url)
}
return workDataOf("mode" to mode, "service_id" to serviceId, "url" to url)
}
companion object {
private const val CHANNEL_URL_MODE = 0
private const val INPUT_STREAM_MODE = 1
private const val PREVIOUS_EXPORT_MODE = 2
fun fromData(data: Data): SubscriptionImportInput {
val mode = data.getInt("mode", PREVIOUS_EXPORT_MODE)
when (mode) {
CHANNEL_URL_MODE -> {
val serviceId = data.getInt("service_id", -1)
if (serviceId == -1) {
throw IllegalArgumentException("No service id provided")
}
val url = data.getString("url")!!
return ChannelUrlMode(serviceId, url)
}
INPUT_STREAM_MODE -> {
val serviceId = data.getInt("service_id", -1)
if (serviceId == -1) {
throw IllegalArgumentException("No service id provided")
}
val url = data.getString("url")!!
return InputStreamMode(serviceId, url)
}
PREVIOUS_EXPORT_MODE -> {
val url = data.getString("url")!!
return PreviousExportMode(url)
}
else -> throw IllegalArgumentException("Unknown mode: $mode")
}
}
}
}

View File

@@ -49,7 +49,7 @@ import org.schabi.newpipe.util.NavigationHelper
*/ */
class MediaBrowserPlaybackPreparer( class MediaBrowserPlaybackPreparer(
private val context: Context, private val context: Context,
private val setMediaSessionError: BiConsumer<String, Int>, // error string, error code private val setMediaSessionError: BiConsumer<CharSequence, Int>, // error string, error code
private val clearMediaSessionError: Runnable, private val clearMediaSessionError: Runnable,
private val onPrepare: Consumer<Boolean> private val onPrepare: Consumer<Boolean>
) : PlaybackPreparer { ) : PlaybackPreparer {
@@ -118,7 +118,7 @@ class MediaBrowserPlaybackPreparer(
private fun onPrepareError(throwable: Throwable) { private fun onPrepareError(throwable: Throwable) {
setMediaSessionError.accept( setMediaSessionError.accept(
ErrorInfo.getMessage(throwable, null, null).getString(context), ErrorInfo.getMessage(throwable, null, null).getText(context),
PlaybackStateCompat.ERROR_CODE_APP_ERROR PlaybackStateCompat.ERROR_CODE_APP_ERROR
) )
} }

View File

@@ -16,7 +16,6 @@ import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts; import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceManager; import androidx.preference.PreferenceManager;
@@ -27,6 +26,7 @@ import org.schabi.newpipe.R;
import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.ErrorInfo;
import org.schabi.newpipe.error.ErrorUtil; import org.schabi.newpipe.error.ErrorUtil;
import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.error.UserAction;
import org.schabi.newpipe.local.subscription.SubscriptionsImportExportHelper;
import org.schabi.newpipe.settings.export.BackupFileLocator; import org.schabi.newpipe.settings.export.BackupFileLocator;
import org.schabi.newpipe.settings.export.ImportExportManager; import org.schabi.newpipe.settings.export.ImportExportManager;
import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard; import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard;
@@ -34,12 +34,10 @@ import org.schabi.newpipe.streams.io.StoredFileHelper;
import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.ZipHelper; import org.schabi.newpipe.util.ZipHelper;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.Locale; import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
@@ -57,18 +55,22 @@ public class BackupRestoreSettingsFragment extends BasePreferenceFragment {
private final ActivityResultLauncher<Intent> requestExportPathLauncher = private final ActivityResultLauncher<Intent> requestExportPathLauncher =
registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
this::requestExportPathResult); this::requestExportPathResult);
private SubscriptionsImportExportHelper importExportHelper;
@Override
public void onAttach(@NonNull final Context context) {
super.onAttach(context);
importExportHelper = new SubscriptionsImportExportHelper(this);
}
@Override @Override
public void onCreatePreferences(@Nullable final Bundle savedInstanceState, public void onCreatePreferences(@Nullable final Bundle savedInstanceState,
@Nullable final String rootKey) { @Nullable final String rootKey) {
final File homeDir = ContextCompat.getDataDir(requireContext()); manager = new ImportExportManager(new BackupFileLocator(requireContext()));
Objects.requireNonNull(homeDir);
manager = new ImportExportManager(new BackupFileLocator(homeDir));
importExportDataPathKey = getString(R.string.import_export_data_path); importExportDataPathKey = getString(R.string.import_export_data_path);
addPreferencesFromResourceRegistry(); addPreferencesFromResourceRegistry();
final Preference importDataPreference = requirePreference(R.string.import_data); final Preference importDataPreference = requirePreference(R.string.import_data);
@@ -123,6 +125,21 @@ public class BackupRestoreSettingsFragment extends BasePreferenceFragment {
alertDialog.show(); alertDialog.show();
return true; return true;
}); });
final Preference exportSubsPreference =
requirePreference(R.string.export_subscriptions_key);
exportSubsPreference.setOnPreferenceClickListener(reference -> {
importExportHelper.onExportSelected();
return true;
});
final Preference importSubsPreference =
requirePreference(R.string.import_subscriptions_key);
importSubsPreference.setOnPreferenceClickListener(preference -> {
importExportHelper.onImportPreviousSelected();
return true;
});
} }
private void requestExportPathResult(final ActivityResult result) { private void requestExportPathResult(final ActivityResult result) {
@@ -181,9 +198,7 @@ public class BackupRestoreSettingsFragment extends BasePreferenceFragment {
} }
try { try {
if (!manager.ensureDbDirectoryExists()) { manager.ensureDbDirectoryExists();
throw new IOException("Could not create databases dir");
}
// replace the current database // replace the current database
if (!manager.extractDb(file)) { if (!manager.extractDb(file)) {

View File

@@ -1,11 +1,13 @@
package org.schabi.newpipe.settings.export package org.schabi.newpipe.settings.export
import java.io.File import android.content.Context
import java.nio.file.Path
import kotlin.io.path.div
/** /**
* Locates specific files of NewPipe based on the home directory of the app. * Locates specific files of NewPipe based on the home directory of the app.
*/ */
class BackupFileLocator(private val homeDir: File) { class BackupFileLocator(context: Context) {
companion object { companion object {
const val FILE_NAME_DB = "newpipe.db" const val FILE_NAME_DB = "newpipe.db"
@@ -17,13 +19,8 @@ class BackupFileLocator(private val homeDir: File) {
const val FILE_NAME_JSON_PREFS = "preferences.json" const val FILE_NAME_JSON_PREFS = "preferences.json"
} }
val dbDir by lazy { File(homeDir, "/databases") } val db: Path = context.getDatabasePath(FILE_NAME_DB).toPath()
val dbJournal: Path = db.resolveSibling("$FILE_NAME_DB-journal")
val db by lazy { File(dbDir, FILE_NAME_DB) } val dbShm: Path = db.resolveSibling("$FILE_NAME_DB-shm")
val dbWal: Path = db.resolveSibling("$FILE_NAME_DB-wal")
val dbJournal by lazy { File(dbDir, "$FILE_NAME_DB-journal") }
val dbShm by lazy { File(dbDir, "$FILE_NAME_DB-shm") }
val dbWal by lazy { File(dbDir, "$FILE_NAME_DB-wal") }
} }

View File

@@ -9,6 +9,8 @@ import java.io.FileNotFoundException
import java.io.IOException import java.io.IOException
import java.io.ObjectOutputStream import java.io.ObjectOutputStream
import java.util.zip.ZipOutputStream import java.util.zip.ZipOutputStream
import kotlin.io.path.createParentDirectories
import kotlin.io.path.deleteIfExists
import org.schabi.newpipe.streams.io.SharpOutputStream import org.schabi.newpipe.streams.io.SharpOutputStream
import org.schabi.newpipe.streams.io.StoredFileHelper import org.schabi.newpipe.streams.io.StoredFileHelper
import org.schabi.newpipe.util.ZipHelper import org.schabi.newpipe.util.ZipHelper
@@ -28,11 +30,8 @@ class ImportExportManager(private val fileLocator: BackupFileLocator) {
// previous file size, the file will retain part of the previous content and be corrupted // previous file size, the file will retain part of the previous content and be corrupted
ZipOutputStream(SharpOutputStream(file.openAndTruncateStream()).buffered()).use { outZip -> ZipOutputStream(SharpOutputStream(file.openAndTruncateStream()).buffered()).use { outZip ->
// add the database // add the database
ZipHelper.addFileToZip( val name = BackupFileLocator.FILE_NAME_DB
outZip, ZipHelper.addFileToZip(outZip, name, fileLocator.db)
BackupFileLocator.FILE_NAME_DB,
fileLocator.db.path
)
// add the legacy vulnerable serialized preferences (will be removed in the future) // add the legacy vulnerable serialized preferences (will be removed in the future)
ZipHelper.addFileToZip( ZipHelper.addFileToZip(
@@ -61,11 +60,10 @@ class ImportExportManager(private val fileLocator: BackupFileLocator) {
/** /**
* Tries to create database directory if it does not exist. * Tries to create database directory if it does not exist.
*
* @return Whether the directory exists afterwards.
*/ */
fun ensureDbDirectoryExists(): Boolean { @Throws(IOException::class)
return fileLocator.dbDir.exists() || fileLocator.dbDir.mkdir() fun ensureDbDirectoryExists() {
fileLocator.db.createParentDirectories()
} }
/** /**
@@ -75,16 +73,13 @@ class ImportExportManager(private val fileLocator: BackupFileLocator) {
* @return true if the database was successfully extracted, false otherwise * @return true if the database was successfully extracted, false otherwise
*/ */
fun extractDb(file: StoredFileHelper): Boolean { fun extractDb(file: StoredFileHelper): Boolean {
val success = ZipHelper.extractFileFromZip( val name = BackupFileLocator.FILE_NAME_DB
file, val success = ZipHelper.extractFileFromZip(file, name, fileLocator.db)
BackupFileLocator.FILE_NAME_DB,
fileLocator.db.path
)
if (success) { if (success) {
fileLocator.dbJournal.delete() fileLocator.dbJournal.deleteIfExists()
fileLocator.dbWal.delete() fileLocator.dbWal.deleteIfExists()
fileLocator.dbShm.delete() fileLocator.dbShm.deleteIfExists()
} }
return success return success

View File

@@ -426,12 +426,24 @@ public final class Localization {
return new BigDecimal(value).setScale(scale, RoundingMode.HALF_UP).doubleValue(); return new BigDecimal(value).setScale(scale, RoundingMode.HALF_UP).doubleValue();
} }
/**
* A wrapper around {@code context.getResources().getQuantityString()} with some safeguard.
*
* @param context the Android context
* @param pluralId the ID of the plural resource
* @param zeroCaseStringId the resource ID of the string to use in case {@code count=0},
* or 0 if the plural resource should be used in the zero case too
* @param count the number that should be used to pick the correct plural form
* @param formattedCount the formatting parameter to substitute inside the plural resource,
* ideally just {@code count} converted to string
* @return the formatted string with the correct pluralization
*/
private static String getQuantity(@NonNull final Context context, private static String getQuantity(@NonNull final Context context,
@PluralsRes final int pluralId, @PluralsRes final int pluralId,
@StringRes final int zeroCaseStringId, @StringRes final int zeroCaseStringId,
final long count, final long count,
final String formattedCount) { final String formattedCount) {
if (count == 0) { if (count == 0 && zeroCaseStringId != 0) {
return context.getString(zeroCaseStringId); return context.getString(zeroCaseStringId);
} }

View File

@@ -6,12 +6,12 @@ import org.schabi.newpipe.streams.io.StoredFileHelper;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream; import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream; import java.util.zip.ZipOutputStream;
@@ -37,9 +37,6 @@ import java.util.zip.ZipOutputStream;
*/ */
public final class ZipHelper { public final class ZipHelper {
private static final int BUFFER_SIZE = 2048;
@FunctionalInterface @FunctionalInterface
public interface InputStreamConsumer { public interface InputStreamConsumer {
void acceptStream(InputStream inputStream) throws IOException; void acceptStream(InputStream inputStream) throws IOException;
@@ -55,17 +52,17 @@ public final class ZipHelper {
/** /**
* This function helps to create zip files. Caution this will overwrite the original file. * This function helps to create zip files. Caution, this will overwrite the original file.
* *
* @param outZip the ZipOutputStream where the data should be stored in * @param outZip the ZipOutputStream where the data should be stored in
* @param nameInZip the path of the file inside the zip * @param nameInZip the path of the file inside the zip
* @param fileOnDisk the path of the file on the disk that should be added to zip * @param path the path of the file on the disk that should be added to zip
*/ */
public static void addFileToZip(final ZipOutputStream outZip, public static void addFileToZip(final ZipOutputStream outZip,
final String nameInZip, final String nameInZip,
final String fileOnDisk) throws IOException { final Path path) throws IOException {
try (FileInputStream fi = new FileInputStream(fileOnDisk)) { try (var inputStream = Files.newInputStream(path)) {
addFileToZip(outZip, nameInZip, fi); addFileToZip(outZip, nameInZip, inputStream);
} }
} }
@@ -80,13 +77,13 @@ public final class ZipHelper {
final String nameInZip, final String nameInZip,
final OutputStreamConsumer streamConsumer) throws IOException { final OutputStreamConsumer streamConsumer) throws IOException {
final byte[] bytes; final byte[] bytes;
try (ByteArrayOutputStream byteOutput = new ByteArrayOutputStream()) { try (var byteOutput = new ByteArrayOutputStream()) {
streamConsumer.acceptStream(byteOutput); streamConsumer.acceptStream(byteOutput);
bytes = byteOutput.toByteArray(); bytes = byteOutput.toByteArray();
} }
try (ByteArrayInputStream byteInput = new ByteArrayInputStream(bytes)) { try (var byteInput = new ByteArrayInputStream(bytes)) {
ZipHelper.addFileToZip(outZip, nameInZip, byteInput); addFileToZip(outZip, nameInZip, byteInput);
} }
} }
@@ -97,49 +94,26 @@ public final class ZipHelper {
* @param nameInZip the path of the file inside the zip * @param nameInZip the path of the file inside the zip
* @param inputStream the content to put inside the file * @param inputStream the content to put inside the file
*/ */
public static void addFileToZip(final ZipOutputStream outZip, private static void addFileToZip(final ZipOutputStream outZip,
final String nameInZip, final String nameInZip,
final InputStream inputStream) throws IOException { final InputStream inputStream) throws IOException {
final byte[] data = new byte[BUFFER_SIZE]; outZip.putNextEntry(new ZipEntry(nameInZip));
try (BufferedInputStream bufferedInputStream = inputStream.transferTo(outZip);
new BufferedInputStream(inputStream, BUFFER_SIZE)) {
final ZipEntry entry = new ZipEntry(nameInZip);
outZip.putNextEntry(entry);
int count;
while ((count = bufferedInputStream.read(data, 0, BUFFER_SIZE)) != -1) {
outZip.write(data, 0, count);
}
}
} }
/** /**
* This will extract data from ZipInputStream. Caution this will overwrite the original file. * This will extract data from ZipInputStream. Caution, this will overwrite the original file.
* *
* @param zipFile the zip file to extract from * @param zipFile the zip file to extract from
* @param nameInZip the path of the file inside the zip * @param nameInZip the path of the file inside the zip
* @param fileOnDisk the path of the file on the disk where the data should be extracted to * @param path the path of the file on the disk where the data should be extracted to
* @return will return true if the file was found within the zip file * @return will return true if the file was found within the zip file
*/ */
public static boolean extractFileFromZip(final StoredFileHelper zipFile, public static boolean extractFileFromZip(final StoredFileHelper zipFile,
final String nameInZip, final String nameInZip,
final String fileOnDisk) throws IOException { final Path path) throws IOException {
return extractFileFromZip(zipFile, nameInZip, input -> { return extractFileFromZip(zipFile, nameInZip, input ->
// delete old file first Files.copy(input, path, StandardCopyOption.REPLACE_EXISTING));
final File oldFile = new File(fileOnDisk);
if (oldFile.exists()) {
if (!oldFile.delete()) {
throw new IOException("Could not delete " + fileOnDisk);
}
}
final byte[] data = new byte[BUFFER_SIZE];
try (FileOutputStream outFile = new FileOutputStream(fileOnDisk)) {
int count;
while ((count = input.read(data)) != -1) {
outFile.write(data, 0, count);
}
}
});
} }
/** /**

View File

@@ -186,7 +186,15 @@ object ImageStrategy {
fun dbUrlToImageList(url: String?): List<Image> { fun dbUrlToImageList(url: String?): List<Image> {
return when (url) { return when (url) {
null -> listOf() null -> listOf()
else -> listOf(Image(url, -1, -1, ResolutionLevel.UNKNOWN))
else -> listOf(
Image(
url,
Image.HEIGHT_UNKNOWN,
Image.WIDTH_UNKNOWN,
ResolutionLevel.UNKNOWN
)
)
} }
} }
} }

View File

@@ -0,0 +1,29 @@
package org.schabi.newpipe.util.text
import android.content.res.Resources
import android.text.SpannableString
import android.text.method.LinkMovementMethod
import android.text.util.Linkify
import android.util.Patterns
import android.widget.TextView
import androidx.annotation.StringRes
import androidx.core.text.parseAsHtml
import androidx.core.text.toHtml
import androidx.core.text.toSpanned
/**
* Takes in a CharSequence [text]
* and makes raw HTTP URLs and HTML anchor tags clickable
*/
fun TextView.setTextWithLinks(text: CharSequence) {
val spanned = SpannableString(text)
// Using the pattern overload of addLinks since the one with the int masks strips all spans from the text before applying new ones
Linkify.addLinks(spanned, Patterns.WEB_URL, null)
this.text = spanned
this.movementMethod = LinkMovementMethod.getInstance()
}
/**
* Gets text from string resource with [id] while preserving styling and allowing string format value substitution of [formatArgs]
*/
fun Resources.getText(@StringRes id: Int, vararg formatArgs: Any?): CharSequence = getText(id).toSpanned().toHtml().format(*formatArgs).parseAsHtml()

View File

@@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

View File

@@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

View File

@@ -903,4 +903,7 @@
<string name="youtube_player_http_403">تم تلقي خطأ HTTP 403 من الخادم أثناء التشغيل، ويرجح أن يكون السبب هو حظر عنوان IP أو مشكلات في إزالة التعتيم عن عنوان URL للبث</string> <string name="youtube_player_http_403">تم تلقي خطأ HTTP 403 من الخادم أثناء التشغيل، ويرجح أن يكون السبب هو حظر عنوان IP أو مشكلات في إزالة التعتيم عن عنوان URL للبث</string>
<string name="sign_in_confirm_not_bot_error">رفض %1$s تقديم البيانات، وطلب تسجيل الدخول للتأكد من أن الطالب ليس روبوتًا.\n\nربما تم حظر عنوان IP الخاص بك مؤقتًا من قبل %1$s، يمكنك الانتظار بعض الوقت أو التبديل إلى عنوان IP مختلف (على سبيل المثال عن طريق تشغيل/إيقاف تشغيل VPN، أو التبديل من WiFi إلى بيانات الهاتف المحمول).</string> <string name="sign_in_confirm_not_bot_error">رفض %1$s تقديم البيانات، وطلب تسجيل الدخول للتأكد من أن الطالب ليس روبوتًا.\n\nربما تم حظر عنوان IP الخاص بك مؤقتًا من قبل %1$s، يمكنك الانتظار بعض الوقت أو التبديل إلى عنوان IP مختلف (على سبيل المثال عن طريق تشغيل/إيقاف تشغيل VPN، أو التبديل من WiFi إلى بيانات الهاتف المحمول).</string>
<string name="unsupported_content_in_country">هذا المحتوى غير متاح للبلد المحدد حاليًا.\n\nقم بتغيير اختيارك من ”الإعدادات &gt; المحتوى &gt; البلد الافتراضي للمحتوى“.</string> <string name="unsupported_content_in_country">هذا المحتوى غير متاح للبلد المحدد حاليًا.\n\nقم بتغيير اختيارك من ”الإعدادات &gt; المحتوى &gt; البلد الافتراضي للمحتوى“.</string>
<string name="kao_dialog_warning">أعلنت Google أنه ابتداءً من عام 2026/2027، ستتطلب جميع التطبيقات على الأجهزة المعتمدة من Android من المطورين تقديم معلومات هويتهم الشخصية مباشرةً إلى Google. بما أن مطوري هذا التطبيق لا يوافقون على هذا الشرط، فلن يعمل هذا التطبيق على أجهزة Android المعتمدة بعد ذلك الوقت.</string>
<string name="kao_dialog_more_info">تفاصيل</string>
<string name="kao_solution">حل</string>
</resources> </resources>

View File

@@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

View File

@@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="main_bg_subtitle">Uka luparu challtaña qalltañataki.</string>
</resources>

View File

@@ -823,6 +823,26 @@
<string name="player_http_403">Oynadarkən serverdən alınan HTTP xətası 403, çox güman ki, yayım URL-si müddətinin bitməsi və ya IP qadağası ilə bağlıdır</string> <string name="player_http_403">Oynadarkən serverdən alınan HTTP xətası 403, çox güman ki, yayım URL-si müddətinin bitməsi və ya IP qadağası ilə bağlıdır</string>
<string name="player_http_invalid_status">HTTP xətası %1$s oynadarkən serverdən alındı</string> <string name="player_http_invalid_status">HTTP xətası %1$s oynadarkən serverdən alındı</string>
<string name="youtube_player_http_403">HTTP xətası 403 oynadarkən serverdən alındı, ehtimal ki, IP qadağası və ya yayım URL-nin deobfuscation problemləri ilə bağlıdır</string> <string name="youtube_player_http_403">HTTP xətası 403 oynadarkən serverdən alındı, ehtimal ki, IP qadağası və ya yayım URL-nin deobfuscation problemləri ilə bağlıdır</string>
<string name="sign_in_confirm_not_bot_error">%1$s sorğuçunun bot olmadığını təsdiqləmək üçün giriş tələb edərək data təmin etməkdən imtina etdi.\n\nIP-niz %1$s tərəfindən müvəqqəti şəkildə qadağan oluna bilər, bir müddət gözləyə və ya başqa IP-yə keçə bilərsiniz (məsələn, VPN-i açıb/qapatmaqla və ya WiFi-dan mobil dataya keçməklə).</string> <string name="sign_in_confirm_not_bot_error">%1$s sorğuçunun bot olmadığını təsdiqləmək üçün giriş tələb edərək data təmin etməkdən imtina etdi.\n\nIP-niz %1$s tərəfindən müvəqqəti şəkildə qadağan oluna bilər, bir müddət gözləyə və ya başqa IP-yə keçə bilərsiniz (məsələn, VPN-i açıb/qapatmaqla və ya WiFi-dan mobil dataya keçməklə).\n\nDaha çox məlumat üçün xahiş olunur <a href="%2$s">bu Tez-tez Verilən Suallar qeydinə</a> baxın.</string>
<string name="unsupported_content_in_country">Bu məzmun hazırda seçilən məzmun ölkəsi üçün əlçatan deyil. \n\nSeçiminizi \"Tənzimləmələr &gt; Məzmun &gt; İlkin məzmun ölkəsi\"- dən dəyişin.</string> <string name="unsupported_content_in_country">Bu məzmun hazırda seçilən məzmun ölkəsi üçün əlçatan deyil. \n\nSeçiminizi \"Tənzimləmələr &gt; Məzmun &gt; İlkin məzmun ölkəsi\"- dən dəyişin.</string>
<string name="kao_dialog_warning">2025 avqustunda, Google 2026-cı ilin sentyabrından etibarən tətbiqlərin quraşdırılması Play Store xaricində quraşdırılanlar daxil olmaqla, sertifikatlaşdırılan cihazlardakı bütün Android tətbiqləri üçün tərtibatçı təsdiqlənməsini tələb edəcək deyə bəyan etdi. NewPipe tərtibatçıları bu tələblə razılaşmadığı üçün NewPipe bu vaxtdan sonra artıq sertifikatlaşdırılan Android cihazlarında işləməyəcək.</string>
<string name="kao_dialog_more_info">Təfərrüatlar</string>
<string name="kao_solution">Həll olunma</string>
<plurals name="export_subscriptions">
<item quantity="one">%d abunəlik ixrac olunur…</item>
<item quantity="other">%d abunəlik ixrac olunur…</item>
</plurals>
<plurals name="load_subscriptions">
<item quantity="one">%d abunəlik yüklənilir…</item>
<item quantity="other">%d abunəlik yüklənilir…</item>
</plurals>
<plurals name="import_subscriptions">
<item quantity="one">%d abunəlik idxal olunur…</item>
<item quantity="other">%d abunəlik idxal olunur…</item>
</plurals>
<string name="import_subscriptions_title">Abunəlikləri idxal et</string>
<string name="export_subscriptions_title">Abunəlikləri ixrac et</string>
<string name="import_subscriptions_summary">Əvvəlki .json ixracından abunəlikləri idxal et</string>
<string name="export_subscriptions_summary">Abunəliklərinizi .json faylına köçürün</string>
<string name="import_from_previous_export">Əvvəlki köçürmədən idxal et</string>
</resources> </resources>

View File

@@ -1,3 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
</resources>

View File

@@ -830,6 +830,26 @@
<string name="player_http_403">HTTP грешка 403, получена от сървъра по време на възпроизвеждане, вероятно причинена от изтичане на URL адреса за стрийминг или забрана на IP адреса</string> <string name="player_http_403">HTTP грешка 403, получена от сървъра по време на възпроизвеждане, вероятно причинена от изтичане на URL адреса за стрийминг или забрана на IP адреса</string>
<string name="player_http_invalid_status">HTTP грешка %1$s получена от сървъра по време на възпроизвеждане</string> <string name="player_http_invalid_status">HTTP грешка %1$s получена от сървъра по време на възпроизвеждане</string>
<string name="youtube_player_http_403">HTTP грешка 403, получена от сървъра по време на възпроизвеждане, вероятно причинена от забрана на IP адреса или проблеми с деобфускацията на URL адреси за стрийминг</string> <string name="youtube_player_http_403">HTTP грешка 403, получена от сървъра по време на възпроизвеждане, вероятно причинена от забрана на IP адреса или проблеми с деобфускацията на URL адреси за стрийминг</string>
<string name="sign_in_confirm_not_bot_error">%1$s отказа да предостави данни, като поиска вход, за да потвърди, че заявителят не е бот.\n\nВашият IP адрес може да е временно забранен от %1$s. Можете да изчакате известно време или да превключите към друг IP адрес (например като включите/изключите VPN или като превключите от WiFi към мобилни данни).</string> <string name="sign_in_confirm_not_bot_error">%1$s отказа да предостави данни, като поиска вход, за да потвърди, че заявителят не е бот.\n\nВашият IP адрес може да е временно забранен от %1$s. Можете да изчакате известно време или да превключите към друг IP адрес (например като включите/изключите VPN или като превключите от WiFi към мобилни данни).\n\nМоля, вижте <a href="%2$s">тази статия с ЧЗВ</a> за повече информация.</string>
<string name="unsupported_content_in_country">Това съдържание не е налично за текущо избраната държава на съдържанието.\n\nПроменете избора си от \"Настройки &gt; Съдържание &gt; Държава на съдържанието по подразбиране\".</string> <string name="unsupported_content_in_country">Това съдържание не е налично за текущо избраната държава на съдържанието.\n\nПроменете избора си от \"Настройки &gt; Съдържание &gt; Държава на съдържанието по подразбиране\".</string>
<string name="kao_dialog_warning">През август 2025 г. Google обяви, че от септември 2026 г. инсталирането на приложения ще изисква проверка от разработчика за всички приложения за Android на сертифицирани устройства, включително тези, инсталирани извън Play Store. Тъй като разработчиците на NewPipe не са съгласни с това изискване, NewPipe вече няма да работи на сертифицирани устройства с Android след този период.</string>
<string name="kao_dialog_more_info">Детайли</string>
<string name="kao_solution">Решение</string>
<plurals name="export_subscriptions">
<item quantity="one">Изнасяне на %d абонамент…</item>
<item quantity="other">Изнасяне на %d абонаменти…</item>
</plurals>
<plurals name="load_subscriptions">
<item quantity="one">Зареждане на %d абонамент…</item>
<item quantity="other">Зареждане на %d абонаменти…</item>
</plurals>
<plurals name="import_subscriptions">
<item quantity="one">Внасяне на %d абонамент…</item>
<item quantity="other">Внасяне на %d абонаменти…</item>
</plurals>
<string name="import_subscriptions_title">Внасяне на абонаменти</string>
<string name="export_subscriptions_title">Изнасяне на абонаменти</string>
<string name="import_subscriptions_summary">Внасяне на абонаменти от предишен .json файл</string>
<string name="export_subscriptions_summary">Изнесете абонаментите си в .json файл</string>
<string name="import_from_previous_export">Внасяне от предишно изнасяне</string>
</resources> </resources>

View File

@@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

View File

@@ -859,6 +859,32 @@
<string name="player_http_403">Během přehrávání byla ze serveru přijata chyba HTTP 403, pravděpodobně způsobená vypršením platnosti streamingové adresy URL nebo zákazem IP adresy</string> <string name="player_http_403">Během přehrávání byla ze serveru přijata chyba HTTP 403, pravděpodobně způsobená vypršením platnosti streamingové adresy URL nebo zákazem IP adresy</string>
<string name="player_http_invalid_status">Chyba HTTP %1$s obdržená ze serveru během přehrávání</string> <string name="player_http_invalid_status">Chyba HTTP %1$s obdržená ze serveru během přehrávání</string>
<string name="youtube_player_http_403">Chyba HTTP 403 obdržená od serveru během přehrávání, pravděpodobně způsobená zákazem IP adresy nebo problémy s deobfuskací streamovací adresy URL</string> <string name="youtube_player_http_403">Chyba HTTP 403 obdržená od serveru během přehrávání, pravděpodobně způsobená zákazem IP adresy nebo problémy s deobfuskací streamovací adresy URL</string>
<string name="sign_in_confirm_not_bot_error">%1$s odmítl poskytnout data, žádá o přihlášení k potvrzení, že žadatel není bot.\n\nVaše IP adresa mohla být dočasně zakázána %1$s, můžete nějakou dobu počkat nebo přepnout na jinou IP adresu (například zapnutím/vypnutím VPN nebo přepnutím z WiFi na mobilní data).</string> <string name="sign_in_confirm_not_bot_error">%1$s odmítl poskytnout data, žádá o přihlášení k potvrzení, že žadatel není bot.\n\nVaše IP adresa mohla být dočasně zablokována službou %1$s, můžete nějakou dobu počkat nebo přepnout na jinou IP adresu (například zapnutím/vypnutím VPN nebo přepnutím z Wi-Fi na mobilní data).\n\nPro více informací si přečtěte <a href="%2$s">tento záznam v FAQ</a>.</string>
<string name="unsupported_content_in_country">Tento obsah není pro aktuálně vybranou zemi obsahu dostupný.\n\nZměňte výběr v nabídce \"Nastavení &gt; Obsah &gt; Výchozí země obsahu\".</string> <string name="unsupported_content_in_country">Tento obsah není pro aktuálně vybranou zemi obsahu dostupný.\n\nZměňte výběr v nabídce \"Nastavení &gt; Obsah &gt; Výchozí země obsahu\".</string>
<string name="kao_dialog_warning">Společnost Google oznámila, že od roku 2026/2027 budou všechny aplikace na certifikovaných zařízeních Android vyžadovat, aby vývojář odeslal své osobní identifikační údaje přímo společnosti Google. Jelikož vývojáři této aplikace s tímto požadavkem nesouhlasí, aplikace po tomto datu přestane na certifikovaných zařízeních Android fungovat.</string>
<string name="kao_dialog_more_info">Podrobnosti</string>
<string name="kao_solution">Řešení</string>
<plurals name="export_subscriptions">
<item quantity="one">Exportování %d odběru…</item>
<item quantity="few">Exportování %d odběrů…</item>
<item quantity="many">Exportování %d odběrů…</item>
<item quantity="other">Exportování %d odběrů…</item>
</plurals>
<plurals name="load_subscriptions">
<item quantity="one">Načítání %d odběru…</item>
<item quantity="few">Načítání %d odběrů…</item>
<item quantity="many">Načítání %d odběrů…</item>
<item quantity="other">Načítání %d odběrů…</item>
</plurals>
<plurals name="import_subscriptions">
<item quantity="one">Importování %d odběru…</item>
<item quantity="few">Importování %d odběrů…</item>
<item quantity="many">Importování %d odběrů…</item>
<item quantity="other">Importování %d odběrů…</item>
</plurals>
<string name="import_subscriptions_title">Importovat odběry</string>
<string name="export_subscriptions_title">Exportovat odběry</string>
<string name="import_subscriptions_summary">Importovat odběry z předchozího exportu .json</string>
<string name="export_subscriptions_summary">Exportovat odběry do souboru .json</string>
<string name="import_from_previous_export">Importovat z předchozího exportu</string>
</resources> </resources>

View File

@@ -242,8 +242,8 @@
<string name="caption_auto_generated">Automatisch erzeugt</string> <string name="caption_auto_generated">Automatisch erzeugt</string>
<string name="import_from">Import von</string> <string name="import_from">Import von</string>
<string name="export_to">Export nach</string> <string name="export_to">Export nach</string>
<string name="import_ongoing">Importiere …</string> <string name="import_ongoing">Wird importiert …</string>
<string name="export_ongoing">Exportiere …</string> <string name="export_ongoing">Wird exportiert …</string>
<string name="import_file_title">Datei importieren</string> <string name="import_file_title">Datei importieren</string>
<string name="previous_export">Vorheriger Export</string> <string name="previous_export">Vorheriger Export</string>
<string name="import_network_expensive_warning">Beachte, dass diese Aktion das Netzwerk stark belasten kann. <string name="import_network_expensive_warning">Beachte, dass diese Aktion das Netzwerk stark belasten kann.
@@ -845,6 +845,26 @@
<string name="player_http_403">HTTP-Fehler 403 vom Server während der Wiedergabe erhalten, wahrscheinlich verursacht durch Ablauf der Streaming-URL oder eine IP-Sperre</string> <string name="player_http_403">HTTP-Fehler 403 vom Server während der Wiedergabe erhalten, wahrscheinlich verursacht durch Ablauf der Streaming-URL oder eine IP-Sperre</string>
<string name="player_http_invalid_status">HTTP-Fehler %1$s vom Server während der Wiedergabe erhalten</string> <string name="player_http_invalid_status">HTTP-Fehler %1$s vom Server während der Wiedergabe erhalten</string>
<string name="youtube_player_http_403">HTTP-Fehler 403 vom Server während der Wiedergabe erhalten, wahrscheinlich verursacht durch eine IP-Sperre oder Probleme beim Entschlüsseln der Streaming-URL</string> <string name="youtube_player_http_403">HTTP-Fehler 403 vom Server während der Wiedergabe erhalten, wahrscheinlich verursacht durch eine IP-Sperre oder Probleme beim Entschlüsseln der Streaming-URL</string>
<string name="sign_in_confirm_not_bot_error">%1$s hat die Datenbereitstellung verweigert und verlangt eine Anmeldung, um zu bestätigen, dass es sich bei dem Anfragenden nicht um einen Bot handelt.\n\nDeine IP-Adresse wurde möglicherweise vorübergehend von %1$s gesperrt. Du kannst einige Zeit warten oder zu einer anderen IP-Adresse wechseln (z. B. durch Ein- und Ausschalten eines VPNs oder durch Wechseln von WLAN zu mobilen Daten).</string> <string name="sign_in_confirm_not_bot_error">%1$s hat die Datenbereitstellung verweigert und verlangt eine Anmeldung, um zu bestätigen, dass es sich bei dem Anfragenden nicht um einen Bot handelt.\n\nDeine IP-Adresse wurde möglicherweise vorübergehend von %1$s gesperrt. Du kannst einige Zeit warten oder zu einer anderen IP-Adresse wechseln (z. B. durch Ein- und Ausschalten eines VPNs oder durch Wechseln von WLAN zu mobilen Daten).\n\nWeitere Informationen findest du unter <a href="%2$s">diesem FAQ-Eintrag</a>.</string>
<string name="unsupported_content_in_country">Dieser Inhalt ist für das aktuell ausgewählte Land des Inhalts nicht verfügbar.\n\nÄndere die Auswahl unter „Einstellungen &gt; Inhalt &gt; Bevorzugtes Land des Inhalts“.</string> <string name="unsupported_content_in_country">Dieser Inhalt ist für das aktuell ausgewählte Land des Inhalts nicht verfügbar.\n\nÄndere die Auswahl unter „Einstellungen &gt; Inhalt &gt; Bevorzugtes Land des Inhalts“.</string>
<string name="kao_dialog_warning">Im August 2025 gab Google bekannt, dass ab September 2026 für die Installation von Apps eine Entwicklerüberprüfung für alle Android-Apps auf zertifizierten Geräten erforderlich sein wird, einschließlich derjenigen, die außerhalb des Play Store installiert wurden. Da die Entwickler von NewPipe dieser Forderung nicht nachkommen, wird NewPipe nach diesem Zeitpunkt auf zertifizierten Android-Geräten nicht mehr funktionieren.</string>
<string name="kao_dialog_more_info">Details</string>
<string name="kao_solution">Lösung</string>
<plurals name="export_subscriptions">
<item quantity="one">%d Abonnement wird exportiert </item>
<item quantity="other">%d Abonnements werden exportiert </item>
</plurals>
<plurals name="load_subscriptions">
<item quantity="one">%d Abonnement wird geladen </item>
<item quantity="other">%d Abonnements werden geladen </item>
</plurals>
<plurals name="import_subscriptions">
<item quantity="one">%d Abonnement wird importiert </item>
<item quantity="other">%d Abonnements werden importiert </item>
</plurals>
<string name="import_subscriptions_title">Abonnements importieren</string>
<string name="export_subscriptions_title">Abonnements exportieren</string>
<string name="import_subscriptions_summary">Importieren von Abonnements aus einem früheren .json-Export</string>
<string name="export_subscriptions_summary">Exportiere deine Abonnements in eine .json-Datei</string>
<string name="import_from_previous_export">Aus vorherigem Export importieren</string>
</resources> </resources>

View File

@@ -845,6 +845,26 @@
<string name="player_http_403">Σφάλμα HTTP 403 που ελήφθη από τον διακομιστή κατά την αναπαραγωγή, πιθανώς λόγω λήξης διεύθυνσης URL ροής ή αποκλεισμού IP</string> <string name="player_http_403">Σφάλμα HTTP 403 που ελήφθη από τον διακομιστή κατά την αναπαραγωγή, πιθανώς λόγω λήξης διεύθυνσης URL ροής ή αποκλεισμού IP</string>
<string name="player_http_invalid_status">Σφάλμα HTTP %1$s ελήφθη από τον διακομιστή κατά την αναπαραγωγή</string> <string name="player_http_invalid_status">Σφάλμα HTTP %1$s ελήφθη από τον διακομιστή κατά την αναπαραγωγή</string>
<string name="youtube_player_http_403">Σφάλμα HTTP 403 ελήφθη από τον διακομιστή κατά την αναπαραγωγή, πιθανώς λόγω αποκλεισμού IP ή προβλημάτων απεμπλοκής URL ροής</string> <string name="youtube_player_http_403">Σφάλμα HTTP 403 ελήφθη από τον διακομιστή κατά την αναπαραγωγή, πιθανώς λόγω αποκλεισμού IP ή προβλημάτων απεμπλοκής URL ροής</string>
<string name="sign_in_confirm_not_bot_error">Ο %1$s αρνήθηκε να παράσχει δεδομένα, ζητώντας σύνδεση για να επιβεβαιώσει ότι ο αιτών δεν είναι bot.\n\nΗ IP σας ενδέχεται να έχει αποκλειστεί προσωρινά από τον %1$s. Μπορείτε να περιμένετε λίγο ή να αλλάξετε IP (για παράδειγμα, ενεργοποιώντας/απενεργοποιώντας ένα VPN ή αλλάζοντας από WiFi σε δεδομένα κινητής τηλεφωνίας).</string> <string name="sign_in_confirm_not_bot_error">Ο %1$s αρνήθηκε να παράσχει δεδομένα, ζητώντας σύνδεση για να επιβεβαιώσει ότι ο αιτών δεν είναι bot.\n\nΗ IP σας ενδέχεται να έχει αποκλειστεί προσωρινά από τον %1$s. Μπορείτε να περιμένετε λίγο ή να αλλάξετε IP (για παράδειγμα, ενεργοποιώντας/απενεργοποιώντας ένα VPN ή αλλάζοντας από WiFi σε δεδομένα κινητής τηλεφωνίας).\n\nΑνατρέξτε σε<a href="%2$s">αυτήν την καταχώρηση στις Συχνές Ερωτήσεις</a> για περισσότερες πληροφορίες.</string>
<string name="unsupported_content_in_country">Αυτό το περιεχόμενο δεν είναι διαθέσιμο για την τρέχουσα επιλεγμένη χώρα περιεχομένου.\n\nΑλλάξτε την επιλογή σας από \"Ρυθμίσεις &gt; Περιεχόμενο &gt; Προεπιλεγμένη χώρα περιεχομένου\".</string> <string name="unsupported_content_in_country">Αυτό το περιεχόμενο δεν είναι διαθέσιμο για την τρέχουσα επιλεγμένη χώρα περιεχομένου.\n\nΑλλάξτε την επιλογή σας από \"Ρυθμίσεις &gt; Περιεχόμενο &gt; Προεπιλεγμένη χώρα περιεχομένου\".</string>
<string name="kao_dialog_more_info">Λεπτομέρειες</string>
<string name="kao_solution">Λύση</string>
<string name="kao_dialog_warning">Τον Αύγουστο του 2025, η Google ανακοίνωσε ότι από τον Σεπτέμβριο του 2026, η εγκατάσταση εφαρμογών θα απαιτεί επαλήθευση προγραμματιστή για όλες τις εφαρμογές Android σε πιστοποιημένες συσκευές, συμπεριλαμβανομένων εκείνων που είναι εγκατεστημένες εκτός του Play Store. Δεδομένου ότι οι προγραμματιστές του NewPipe δεν συμφωνούν με αυτήν την απαίτηση, το NewPipe δεν θα λειτουργεί πλέον σε πιστοποιημένες συσκευές Android μετά από αυτό το χρονικό διάστημα.</string>
<plurals name="export_subscriptions">
<item quantity="one">Εξαγωγή %d συνδρομής…</item>
<item quantity="other">Εξαγωγή %d συνδρομών…</item>
</plurals>
<plurals name="load_subscriptions">
<item quantity="one">Φόρτωση %d συνδρομής…</item>
<item quantity="other">Φόρτωση %d συνδρομών…</item>
</plurals>
<plurals name="import_subscriptions">
<item quantity="one">Εισαγωγή %d συνδρομής…</item>
<item quantity="other">Εισαγωγή %d συνδρομών…</item>
</plurals>
<string name="import_subscriptions_title">Εισαγωγή συνδρομών</string>
<string name="export_subscriptions_title">Εξαγωγή συνδρομών</string>
<string name="import_subscriptions_summary">Εισαγωγή συνδρομών από προηγούμενη εξαγωγή</string>
<string name="export_subscriptions_summary">Εξαγωγή των συνδρομών σας σε αρχείο .json</string>
<string name="import_from_previous_export">Εισαγωγή από προηγούμενη εξαγωγή</string>
</resources> </resources>

View File

@@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

View File

@@ -851,4 +851,7 @@
<string name="short_billion">%sMM</string> <string name="short_billion">%sMM</string>
<string name="unsupported_content_in_country">Este contenido no está disponible para el país seleccionado actualmente.\n\nCambia tu selección en «Ajustes &gt; Contenido &gt; País predefinido del contenido».</string> <string name="unsupported_content_in_country">Este contenido no está disponible para el país seleccionado actualmente.\n\nCambia tu selección en «Ajustes &gt; Contenido &gt; País predefinido del contenido».</string>
<string name="permission_display_over_apps_message">Para usar el reproductor emergente, seleccione %1$s en el siguiente menú de la configuración de Android y habilite %2$s.</string> <string name="permission_display_over_apps_message">Para usar el reproductor emergente, seleccione %1$s en el siguiente menú de la configuración de Android y habilite %2$s.</string>
<string name="kao_dialog_warning">En Agosto de 2025, Google ha anunciado que, a partir de 2026/2027, todas las aplicaciones en dispositivos Android certificados requerirán que los desarrolladores envíen sus datos personales de identidad directamente a Google. Como los desarrolladores de NewPipe no están de acuerdo con este requisito, la aplicación dejará de funcionar en dispositivos Android certificados después de esa fecha.</string>
<string name="kao_dialog_more_info">Detalles</string>
<string name="kao_solution">Solución</string>
</resources> </resources>

View File

@@ -831,5 +831,25 @@
<string name="player_http_invalid_status">Esitamise ajal lisas server andmevoogu HTTP oleku %1$s</string> <string name="player_http_invalid_status">Esitamise ajal lisas server andmevoogu HTTP oleku %1$s</string>
<string name="youtube_player_http_403">Esitamise ajal lisas server andmevoogu HTTP oleku 403 ning tavaliselt tähendab see, et sinu seadme IP-aadress on keelatud või voogedastuse võrguaadressi hägustamisvastastes meetmetes on viga</string> <string name="youtube_player_http_403">Esitamise ajal lisas server andmevoogu HTTP oleku 403 ning tavaliselt tähendab see, et sinu seadme IP-aadress on keelatud või voogedastuse võrguaadressi hägustamisvastastes meetmetes on viga</string>
<string name="unsupported_content_in_country">See sisu pole saadaval hetkel kehtvas riigis.\n\nRiiki saad muuta: Seadistused &gt; Sisu &gt; Sisu vaikimisi riik.</string> <string name="unsupported_content_in_country">See sisu pole saadaval hetkel kehtvas riigis.\n\nRiiki saad muuta: Seadistused &gt; Sisu &gt; Sisu vaikimisi riik.</string>
<string name="sign_in_confirm_not_bot_error">%1$s keeldus andmete edastamisest ning eeldab sisselogimist tuvastamaks, et tegemist pole robotiga.\n\nLisaks võib olla juhtunud, et %1$s on lisanud sinu seadme ip-aadressi ajutisse keelunimekirja. Sa võid oodata natuke aega või vahetada võrguühendus viisi (näiteks lülitades VPN sisse/välja või kasutades WiFi asemel mobiilset internetiühendust).</string> <string name="sign_in_confirm_not_bot_error">%1$s keeldus andmete edastamisest ning eeldab sisselogimist tuvastamaks, et tegemist pole robotiga.\n\nLisaks võib olla juhtunud, et %1$s on lisanud sinu seadme ip-aadressi ajutisse keelunimekirja. Sa võid oodata natuke aega või vahetada võrguühendus viisi (näiteks lülitades VPN sisse/välja või kasutades WiFi asemel mobiilset internetiühendust).\n\nLisateavet leiad <a href="%2$s">siit korduva kippumate küsimuste</a> alajaotusest.</string>
<string name="kao_dialog_warning">2025. aasta augustis teatas Google, et alates septembrist 2026 uute rakenduste paigaldamine kõikides uutes Androidi seadmetes eeldab arendajate verifitseerimist, sealhulgas juhtudel, kui selline rakendus on paigaldatud väljastpoolt Google Play rakendustepoodi. Kuna NewPipe\'i arendajad pole sellise nõudmisega nõus, siis sellise aja saabumisel NewPipe enam ei toimi sertifitseeritud Androidi seadmetes.</string>
<string name="kao_dialog_more_info">Üksikasjad</string>
<string name="kao_solution">Lahendus</string>
<plurals name="export_subscriptions">
<item quantity="one">Eksportimisel on %d tellimus…</item>
<item quantity="other">Eksportimisel on %d tellimust…</item>
</plurals>
<plurals name="load_subscriptions">
<item quantity="one">Laadimisel on %d tellimus…</item>
<item quantity="other">Laadimisel on %d tellimust…</item>
</plurals>
<plurals name="import_subscriptions">
<item quantity="one">Importimisel on %d tellimus…</item>
<item quantity="other">Importimisel on %d tellimust…</item>
</plurals>
<string name="import_subscriptions_title">Impordi tellimusi</string>
<string name="export_subscriptions_title">Ekspordi tellimusi</string>
<string name="import_subscriptions_summary">Impordi tellimusi varasemeksporditud json-failist</string>
<string name="export_subscriptions_summary">Ekspirdi oma tellimused json-faili</string>
<string name="import_from_previous_export">Impordi tellimusi varasemeksporditud failist</string>
</resources> </resources>

View File

@@ -861,6 +861,29 @@
<string name="player_http_403">Erreur HTTP 403 reçue du serveur pendant la lecture, probablement causée par l\'expiration de l\'URL de streaming ou une interdiction d\'IP</string> <string name="player_http_403">Erreur HTTP 403 reçue du serveur pendant la lecture, probablement causée par l\'expiration de l\'URL de streaming ou une interdiction d\'IP</string>
<string name="player_http_invalid_status">Erreur HTTP %1$s reçue du serveur pendant la lecture</string> <string name="player_http_invalid_status">Erreur HTTP %1$s reçue du serveur pendant la lecture</string>
<string name="youtube_player_http_403">Erreur HTTP 403 reçue du serveur pendant la lecture, probablement causée par un bannissement d\'IP ou des problèmes de désobfuscation de l\'URL de streaming</string> <string name="youtube_player_http_403">Erreur HTTP 403 reçue du serveur pendant la lecture, probablement causée par un bannissement d\'IP ou des problèmes de désobfuscation de l\'URL de streaming</string>
<string name="sign_in_confirm_not_bot_error">%1$s a refusé de fournir des données et a demandé un identifiant pour confirmer que le demandeur n\'est pas un robot.\n\nVotre adresse IP a peut-être été temporairement bannie par %1$s. Vous pouvez patienter un peu ou changer d\'adresse IP (par exemple en activant/désactivant un VPN, ou en passant du Wi-Fi aux données mobiles).</string> <string name="sign_in_confirm_not_bot_error">%1$s a refusé de fournir des données et a demandé un identifiant pour confirmer que l\'auteur de la requête n\'est pas un robot.\n\nVotre adresse IP a peut-être été temporairement bloquée par %1$s. Vous pouvez patienter ou essayer une autre adresse IP (par exemple, en activant/désactivant un VPN ou en passant du Wi-Fi aux données mobiles).\n\nPour plus d\'informations, veuillez consulter <a href="%2$s">cette FAQ</a>.</string>
<string name="unsupported_content_in_country">Ce contenu n\'est pas disponible pour le pays actuellement sélectionné.\n\nModifiez votre sélection dans « Paramètres &gt; Contenu &gt; Pays par défaut ».</string> <string name="unsupported_content_in_country">Ce contenu n\'est pas disponible pour le pays actuellement sélectionné.\n\nModifiez votre sélection dans « Paramètres &gt; Contenu &gt; Pays par défaut ».</string>
<string name="kao_dialog_warning">En août 2025, Google a annoncé qu\'à compter de septembre 2026, l\'installation d\'applications nécessiterait une vérification par le développeur pour toutes les applications Android sur les appareils certifiés, y compris celles installées en dehors du Play Store. Les développeurs de NewPipe refusant cette exigence, NewPipe ne fonctionnera plus sur les appareils Android certifiés après cette date.</string>
<string name="kao_dialog_more_info">Détails</string>
<string name="kao_solution">Solution</string>
<plurals name="export_subscriptions">
<item quantity="one">Exportation de l\'abonnement %d…</item>
<item quantity="many">Exportation de %d abonnements…</item>
<item quantity="other">Exportation de %d abonnements…</item>
</plurals>
<plurals name="load_subscriptions">
<item quantity="one">Chargement de l\'abonnement %d…</item>
<item quantity="many">Chargement de %d abonnements…</item>
<item quantity="other">Chargement de %d abonnements…</item>
</plurals>
<plurals name="import_subscriptions">
<item quantity="one">Importation de l\'abonnement %d…</item>
<item quantity="many">Importation de %d abonnements…</item>
<item quantity="other">Importation de %d abonnements…</item>
</plurals>
<string name="import_subscriptions_title">Importer des abonnements</string>
<string name="export_subscriptions_title">Exporter les abonnements</string>
<string name="import_subscriptions_summary">Importer des abonnements à partir d\'une exportation .json précédente</string>
<string name="export_subscriptions_summary">Exportez vos abonnements dans un fichier .json</string>
<string name="import_from_previous_export">Importer à partir d\'une exportation précédente</string>
</resources> </resources>

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="no_player_found">aucun streamer trouvé . Installez VLC?</string>
<string name="no">non</string>
<string name="open_in_browser">ouvrir dans le browser</string>
<string name="open_in_popup_mode">ouvrir dans le popup mode</string>
<string name="open_with">ouvrir avec</string>
<string name="share">partagez</string>
<string name="controls_download_desc">installer le fichier stream</string>
<string name="search">chercher</string>
<string name="settings">parameters</string>
<string name="download">installer</string>
<string name="install">Installer</string>
<string name="mark_as_watched">marquer comme vu</string>
<string name="upload_date_text">"publié le %1$s"</string>
<string name="no_player_found_toast">aucun joueur de stream n\'est trouvé ( vous pouvez installez VLC pour jouer)</string>
<string name="cancel">Annuler</string>
<string name="ok">OK</string>
<string name="yes">Oui</string>
</resources>

View File

@@ -1,3 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
</resources>

View File

@@ -369,7 +369,7 @@
<string name="feed_notification_loading">Cargando transmisión…</string> <string name="feed_notification_loading">Cargando transmisión…</string>
<string name="feed_subscription_not_loaded_count">Non se cargou: %d</string> <string name="feed_subscription_not_loaded_count">Non se cargou: %d</string>
<string name="feed_oldest_subscription_update">Actualizada a última información: %s</string> <string name="feed_oldest_subscription_update">Actualizada a última información: %s</string>
<string name="feed_groups_header_title">Grupos da canle</string> <string name="feed_groups_header_title">Grupos da canles</string>
<plurals name="days"> <plurals name="days">
<item quantity="one">%d día</item> <item quantity="one">%d día</item>
<item quantity="other">%d días</item> <item quantity="other">%d días</item>
@@ -388,7 +388,7 @@
</plurals> </plurals>
<string name="new_seek_duration_toast">Debido ás restricións de ExoPlayer, a duración da busca estableceuse en %d segundos</string> <string name="new_seek_duration_toast">Debido ás restricións de ExoPlayer, a duración da busca estableceuse en %d segundos</string>
<string name="remove_watched_popup_partially_watched_streams">Si, e visualizou parcialmente estes vídeos</string> <string name="remove_watched_popup_partially_watched_streams">Si, e visualizou parcialmente estes vídeos</string>
<string name="remove_watched_popup_warning">Eliminaranse os vídeos vistos antes e despois de seren engadidos á lista de reprodución. \nEstás seguro? Isto non se pode desfacer.!</string> <string name="remove_watched_popup_warning">Eliminaranse as emisións vistas antes e despois de seren engadidas á lista de reprodución.\nEstás seguro?</string>
<string name="remove_watched_popup_title">Borrar todos os vídeos vistos?</string> <string name="remove_watched_popup_title">Borrar todos os vídeos vistos?</string>
<string name="remove_watched">Eliminar o visto</string> <string name="remove_watched">Eliminar o visto</string>
<string name="systems_language">Sistema predeterminado</string> <string name="systems_language">Sistema predeterminado</string>
@@ -812,4 +812,11 @@
<string name="channel_tab_tracks">Pistas</string> <string name="channel_tab_tracks">Pistas</string>
<string name="feed_fetch_channel_tabs_summary">Lapelas a recuperar ao actualizar o feed. Esta opción non ten efecto se a canle se actualiza no modo rápido.</string> <string name="feed_fetch_channel_tabs_summary">Lapelas a recuperar ao actualizar o feed. Esta opción non ten efecto se a canle se actualiza no modo rápido.</string>
<string name="always_use_exoplayer_set_output_surface_workaround_summary">Esta solución alternativa libera os códecs de video e os re-instancia cando muda a máscara, no canto de configurar a máscara directamente no códec. ExoPlayer xa emprega esta configuración nalgúns dispositivos con este problema e só afecta a Android 6 e versións posteriores.\n\nActivar esta opción pode minimizar erros de reprodución ao mudar o reprodutor de video actual ou mudar ao modo de pantalla completa</string> <string name="always_use_exoplayer_set_output_surface_workaround_summary">Esta solución alternativa libera os códecs de video e os re-instancia cando muda a máscara, no canto de configurar a máscara directamente no códec. ExoPlayer xa emprega esta configuración nalgúns dispositivos con este problema e só afecta a Android 6 e versións posteriores.\n\nActivar esta opción pode minimizar erros de reprodución ao mudar o reprodutor de video actual ou mudar ao modo de pantalla completa</string>
<string name="short_thousand">%sK</string>
<string name="short_million">%sM</string>
<string name="short_billion">%sMM</string>
<string name="search_with_service_name">Procurar %1$s</string>
<string name="search_with_service_name_and_filter">Procurar %1$s (%2$s)</string>
<string name="tab_bookmarks_short">Listas de reprodución</string>
<string name="feed_group_page_summary">Páxina do grupo de canles</string>
</resources> </resources>

View File

@@ -483,7 +483,7 @@
<item quantity="one">%d सेकेंड</item> <item quantity="one">%d सेकेंड</item>
<item quantity="other">%d सेकंड्स</item> <item quantity="other">%d सेकंड्स</item>
</plurals> </plurals>
<string name="remove_watched_popup_title">देखे गए वीडियो हटायें?</string> <string name="remove_watched_popup_title">देखे गए स्ट्रीम्स हटाएँ?</string>
<string name="remove_watched">देखे गए को हटा दें</string> <string name="remove_watched">देखे गए को हटा दें</string>
<string name="systems_language">सिस्टम डिफ़ॉल्ट</string> <string name="systems_language">सिस्टम डिफ़ॉल्ट</string>
<string name="app_language_title">ऐप की भाषा</string> <string name="app_language_title">ऐप की भाषा</string>
@@ -529,7 +529,7 @@
<string name="auto_device_theme_title">ऑटोमैटिक (डिवाइस थीम)</string> <string name="auto_device_theme_title">ऑटोमैटिक (डिवाइस थीम)</string>
<string name="night_theme_summary">अपनी पसंदीदा नाइट थीम चुने — %s</string> <string name="night_theme_summary">अपनी पसंदीदा नाइट थीम चुने — %s</string>
<string name="select_night_theme_toast">आप अपनी पसंदीदा नाइट थीम नीचे चुन सकते हैं</string> <string name="select_night_theme_toast">आप अपनी पसंदीदा नाइट थीम नीचे चुन सकते हैं</string>
<string name="download_has_started">डाउनलोड शुरू हो गया है</string> <string name="download_has_started">डाउनलोड शुरू हुआ</string>
<string name="restricted_video_no_stream">यह वीडियो आयु-प्रतिबंधित है। <string name="restricted_video_no_stream">यह वीडियो आयु-प्रतिबंधित है।
\nयूट्यूब की नई नीतियों के कारण न्यूपाइप किसी भी आयु प्रतिबंधित वीडियो स्ट्रीम का इस्तेमाल नहीं कर सकता है और इस कारण इसे वीडियो को प्ले करने में असमर्थ है।</string> \nयूट्यूब की नई नीतियों के कारण न्यूपाइप किसी भी आयु प्रतिबंधित वीडियो स्ट्रीम का इस्तेमाल नहीं कर सकता है और इस कारण इसे वीडियो को प्ले करने में असमर्थ है।</string>
<string name="peertube_instance_url_title">पियरट्यूब इंसटैंस</string> <string name="peertube_instance_url_title">पियरट्यूब इंसटैंस</string>
@@ -669,7 +669,7 @@
<string name="show_channel_details">चैनल विवरण दिखाएं</string> <string name="show_channel_details">चैनल विवरण दिखाएं</string>
<string name="show_original_time_ago_title">आइटम्स का असल अपलोड समय दिखाएं</string> <string name="show_original_time_ago_title">आइटम्स का असल अपलोड समय दिखाएं</string>
<string name="show_original_time_ago_summary">सेवाओं से मूल पाठ स्ट्रीम आइटम में दिखाई देंगे</string> <string name="show_original_time_ago_summary">सेवाओं से मूल पाठ स्ट्रीम आइटम में दिखाई देंगे</string>
<string name="remove_watched_popup_warning">प्लेलिस्ट में शामिल, पहले और बाद में देख जा चुके वीडियो हटा दि जाएंगे। \nक्या यक़ीनन आप ऐसा चाह्ते हैं? इसे असंपादित नहीं किया जा सकेगा!</string> <string name="remove_watched_popup_warning">जो स्ट्रीम्स प्लेलिस्ट में जोड़ने से पहले या बाद में देख जा चुकी हैं, उन्हें हटा दिया जाएगा।\nक्या यक़ीनन आप ऐसा चाह्ते हैं?</string>
<plurals name="minutes"> <plurals name="minutes">
<item quantity="one">%d मिनट</item> <item quantity="one">%d मिनट</item>
<item quantity="other">%d मिनट्स</item> <item quantity="other">%d मिनट्स</item>
@@ -845,6 +845,9 @@
<string name="player_http_403">पले करते समय सर्वर से HTTP error 403 मिला, शायद स्ट्रीमिंग URL एक्सपायर होने या IP बैन की वजह से हुआ</string> <string name="player_http_403">पले करते समय सर्वर से HTTP error 403 मिला, शायद स्ट्रीमिंग URL एक्सपायर होने या IP बैन की वजह से हुआ</string>
<string name="player_http_invalid_status">पले करते समय सर्वर से HTTP error %1$s मिला</string> <string name="player_http_invalid_status">पले करते समय सर्वर से HTTP error %1$s मिला</string>
<string name="youtube_player_http_403">पले करते समय सर्वर से HTTP error 403 मिला, जो शायद IP बैन या स्ट्रीमिंग URL डीओबफस्केशन की दिक्कतों की वजह से हुआ है</string> <string name="youtube_player_http_403">पले करते समय सर्वर से HTTP error 403 मिला, जो शायद IP बैन या स्ट्रीमिंग URL डीओबफस्केशन की दिक्कतों की वजह से हुआ है</string>
<string name="sign_in_confirm_not_bot_error">%1$s ने डेटा देने से मना कर दिया, और यह कन्फर्म करने के लिए लॉगिन मांगा कि रिक्वेस्ट करने वाला बोट नहीं है।\n\nहो सकता है कि %1$s ने आपके IP को कुछ समय के लिए बैन कर दिया हो, आप कुछ समय इंतज़ार कर सकते हैं या किसी दूसरे IP पर स्विच कर सकते हैं (जैसे VPN ऑन/ऑफ करके, या WiFi से मोबाइल डेटा पर स्विच करके)।</string> <string name="sign_in_confirm_not_bot_error">%1$s ने डेटा देने से मना कर दिया, और यह कन्फर्म करने के लिए लॉगिन मांगा कि रिक्वेस्ट करने वाला बोट नहीं है।\n\nहो सकता है कि %1$s ने आपके IP को कुछ समय के लिए बैन कर दिया हो, आप कुछ समय इंतज़ार कर सकते हैं या किसी दूसरे IP पर स्विच कर सकते हैं (जैसे VPN ऑन/ऑफ करके, या WiFi से मोबाइल डेटा पर स्विच करके)।\n\nअधिक जानकारी के लिए कृपया <a href="%2$s">यह FAQ एंट्री</a> देखें।</string>
<string name="unsupported_content_in_country">यह कंटेंट अभी चुने गए देश के कंटेंट के लिए उपलब्ध नहीं है।\n\n\"सेटिंग्स &gt; कंटेंट &gt; डिफ़ॉल्ट कंटेंट देश\" से अपना चुनाव बदलें।</string> <string name="unsupported_content_in_country">यह कंटेंट अभी चुने गए देश के कंटेंट के लिए उपलब्ध नहीं है।\n\n\"सेटिंग्स &gt; कंटेंट &gt; डिफ़ॉल्ट कंटेंट देश\" से अपना चुनाव बदलें।</string>
<string name="kao_dialog_warning">अगस्त 2025 में, Google ने घोषणा की कि सितंबर 2026 से, सर्टिफाइड डिवाइस पर सभी Android ऐप्स जिनमें Play Store के बाहर से इंस्टॉल किए गए ऐप्स भी शामिल हैं, को इंस्टॉल करने के लिए डेवलपर वेरिफिकेशन ज़रूरी होगा। चूंकि NewPipe के डेवलपर्स इस शर्त से सहमत नहीं हैं, इसलिए उस समय के बाद NewPipe सर्टिफाइड Android डिवाइस पर काम नहीं करेगा।</string>
<string name="kao_dialog_more_info">विवरण</string>
<string name="kao_solution">समाधान</string>
</resources> </resources>

View File

@@ -816,6 +816,26 @@
<string name="player_http_403">A lejátszás közben a kiszolgáló 403-as HTTP-hibát adott vissza, valószínűleg a közvetítési hivatkozás érvényessége lejárt vagy a IP-tiltás miatt</string> <string name="player_http_403">A lejátszás közben a kiszolgáló 403-as HTTP-hibát adott vissza, valószínűleg a közvetítési hivatkozás érvényessége lejárt vagy a IP-tiltás miatt</string>
<string name="player_http_invalid_status">HTTP-hiba (%1$s) érkezett a kiszolgálótól a lejátszás során</string> <string name="player_http_invalid_status">HTTP-hiba (%1$s) érkezett a kiszolgálótól a lejátszás során</string>
<string name="youtube_player_http_403">HTTP 403-as hiba érkezett a kiszolgálótól a lejátszás közben, valószínűleg IP-tiltás vagy a közvetítési hivatkozás feloldási problémák miatt</string> <string name="youtube_player_http_403">HTTP 403-as hiba érkezett a kiszolgálótól a lejátszás közben, valószínűleg IP-tiltás vagy a közvetítési hivatkozás feloldási problémák miatt</string>
<string name="sign_in_confirm_not_bot_error">%1$s visszautasította az adatok szolgáltatását, és bejelentkezést kér annak megerősítésére, hogy a kérés nem robot által érkezik.\n\nElőfordulhat, hogy az IP-címét ideiglenesen letiltotta %1$s, várhat egy keveset, vagy váltson egy másik IP-címre (például VPN be-/kikapcsolásával, vagy Wi-Fi-ről mobiladat-forgalomra váltva).</string> <string name="sign_in_confirm_not_bot_error">%1$s visszautasította az adatok szolgáltatását, és bejelentkezést kér annak megerősítésére, hogy a kérés nem robot által érkezik.\n\nElőfordulhat, hogy az IP-címét ideiglenesen letiltotta %1$s, várhat egy keveset, vagy váltson egy másik IP-címre (például VPN be-/kikapcsolásával, vagy Wi-Fi-ről mobiladat-forgalomra váltva).\n\nTovábbi információért tekintse meg <a href="%2$s">ezt a GYIK-bejegyzést</a>.</string>
<string name="unsupported_content_in_country">Ez a tartalom a jelenleg kiválasztott tartalom országában nem elérhető.\n\nVáltoztassa meg a „Beállítások &gt; Tartalom &gt;Tartalom alapértelmezett országa” menüpontban.</string> <string name="unsupported_content_in_country">Ez a tartalom a jelenleg kiválasztott tartalom országában nem elérhető.\n\nVáltoztassa meg a „Beállítások &gt; Tartalom &gt;Tartalom alapértelmezett országa” menüpontban.</string>
<string name="kao_dialog_warning">2025 augusztusában a Google bejelentette, hogy 2026 szeptemberétől az alkalmazások telepítéséhez fejlesztői ellenőrzésre lesz szükség a tanúsított eszközökön található összes Android-alkalmazáshoz, beleértve a Play Áruházon kívül telepített alkalmazásokat is. Mivel a NewPipe fejlesztői nem értenek egyet ezzel a követelménnyel, a NewPipe ezután nem fog működni a tanúsított Android-eszközökön.</string>
<string name="kao_dialog_more_info">Részletek</string>
<string name="kao_solution">Megoldás</string>
<plurals name="export_subscriptions">
<item quantity="one">%d feliratkozás exportálása…</item>
<item quantity="other">%d feliratkozások exportálása…</item>
</plurals>
<plurals name="load_subscriptions">
<item quantity="one">%d feliratkozás betöltése…</item>
<item quantity="other">%d feliratkozások betöltése…</item>
</plurals>
<plurals name="import_subscriptions">
<item quantity="one">%d feliratkozás importálása…</item>
<item quantity="other">%d feliratkozások importálása…</item>
</plurals>
<string name="import_subscriptions_title">Feliratkozások importálása</string>
<string name="export_subscriptions_title">Feliratkozások exportálása</string>
<string name="import_subscriptions_summary">Feliratkozások importálása korábbi .json-fájlból</string>
<string name="export_subscriptions_summary">Feliratkozások exportálása .json-fájlba</string>
<string name="import_from_previous_export">Importálás korábbi exportból</string>
</resources> </resources>

View File

@@ -16,7 +16,7 @@
<string name="ok">Լավ</string> <string name="ok">Լավ</string>
<string name="delete">Ջնջել</string> <string name="delete">Ջնջել</string>
<string name="start">Սկսել</string> <string name="start">Սկսել</string>
<string name="detail_likes_img_view_description">Հավանում եմ</string> <string name="detail_likes_img_view_description">Հավանումներ</string>
<string name="detail_dislikes_img_view_description">Չեմ հավանում</string> <string name="detail_dislikes_img_view_description">Չեմ հավանում</string>
<string name="clear">Մաքրել</string> <string name="clear">Մաքրել</string>
<string name="upload_date_text">Հրապարակվել է %1$s</string> <string name="upload_date_text">Հրապարակվել է %1$s</string>
@@ -228,7 +228,7 @@
<string name="sort">Դասավորել</string> <string name="sort">Դասավորել</string>
<string name="detail_pinned_comment_view_description">Գամված մեկնաբանություն</string> <string name="detail_pinned_comment_view_description">Գամված մեկնաբանություն</string>
<string name="account_terminated">Հաշիվը կասեցված է</string> <string name="account_terminated">Հաշիվը կասեցված է</string>
<string name="channel_tab_about"/> <string name="channel_tab_about">Մասին</string>
<string name="channel_tab_albums">Ալբոմներ</string> <string name="channel_tab_albums">Ալբոմներ</string>
<string name="yes">Այո</string> <string name="yes">Այո</string>
<string name="no">Ոչ</string> <string name="no">Ոչ</string>
@@ -243,4 +243,39 @@
<string name="unknown_audio_track">Անհայտ</string> <string name="unknown_audio_track">Անհայտ</string>
<string name="did_you_mean">Նկատի ունե՞ս «%1$s»</string> <string name="did_you_mean">Նկատի ունե՞ս «%1$s»</string>
<string name="volume">Բարձրություն</string> <string name="volume">Բարձրություն</string>
<string name="kao_solution">Լուծում</string>
<string name="kao_dialog_more_info">Մանրամասներ</string>
<plurals name="replies">
<item quantity="one">%s պատասխան</item>
<item quantity="other">%s պատասխաններ</item>
</plurals>
<string name="share_playlist">Կիսվել նվագացանկով</string>
<string name="forward">Առաջ տանել</string>
<string name="play">Նվագել</string>
<string name="duration">Տևողություն</string>
<string name="rewind">Հետ տանել</string>
<string name="open_play_queue">Բացել նվագացանկը</string>
<string name="channel_tab_likes">Հավանումներ</string>
<string name="channel_tab_shorts">Կարճեր</string>
<string name="feed_show_partially_watched">Մասնակի դիտված</string>
<string name="feed_show_watched">Ամբողչովին դիտված</string>
<string name="on">Միացված</string>
<string name="off">Անջատված</string>
<string name="metadata_subscribers">Բաժանորդագրվածներ</string>
<string name="metadata_privacy_internal">Ներքին</string>
<string name="metadata_privacy_private">Անձնական</string>
<string name="downloads_storage_ask_title">Հարցնել որտեղ ներբեռնել</string>
<string name="any_network">Կամայական ցանցով</string>
<string name="playlist_creation_success">Նվագացանկը ստեղծվեց</string>
<string name="create_playlist">Նոր նվագացանկ</string>
<string name="albums">Ալբոմներ</string>
<string name="artists">Արվեստագետներ</string>
<string name="donation_title">Նվիրել</string>
<string name="dismiss">Անտեսել</string>
<string name="short_thousand">%sՀզր</string>
<string name="short_million">%sՄլն</string>
<string name="short_billion">%sԲլն</string>
<string name="error_snackbar_action">Ազդարարել</string>
<string name="invalid_directory">Այդպիսի պանակ չկա</string>
<string name="tab_bookmarks_short">Նվագացանկեր</string>
</resources> </resources>

View File

@@ -434,7 +434,7 @@
<string name="delete_downloaded_files">Hapus berkas yang diunduh</string> <string name="delete_downloaded_files">Hapus berkas yang diunduh</string>
<string name="permission_display_over_apps">Izinkan untuk ditampilkan di atas aplikasi lain</string> <string name="permission_display_over_apps">Izinkan untuk ditampilkan di atas aplikasi lain</string>
<string name="app_language_title">Bahasa apl</string> <string name="app_language_title">Bahasa apl</string>
<string name="systems_language">Default sistem</string> <string name="systems_language">Bawaan sistem</string>
<string name="done">Selesai</string> <string name="done">Selesai</string>
<string name="seek_duration_title">Durasi maju/mundur cepat</string> <string name="seek_duration_title">Durasi maju/mundur cepat</string>
<string name="subtitle_activity_recaptcha">Tekan \"Selesai\" saat selesai</string> <string name="subtitle_activity_recaptcha">Tekan \"Selesai\" saat selesai</string>
@@ -746,7 +746,7 @@
<string name="show_channel_tabs">Tab saluran</string> <string name="show_channel_tabs">Tab saluran</string>
<string name="channel_tab_shorts">Shorts</string> <string name="channel_tab_shorts">Shorts</string>
<string name="loading_metadata_title">Memuat Metadata…</string> <string name="loading_metadata_title">Memuat Metadata…</string>
<string name="feed_fetch_channel_tabs">Dapatjan tab saluran</string> <string name="feed_fetch_channel_tabs">Dapatkan tab saluran</string>
<string name="channel_tab_about">Tentang</string> <string name="channel_tab_about">Tentang</string>
<string name="channel_tab_albums">Album</string> <string name="channel_tab_albums">Album</string>
<string name="feed_fetch_channel_tabs_summary">Tab untuk didapatkan ketika memperarui umpan. Opsi ini tidak memiliki efek jika saluran diperbarui menggunakan mode cepat.</string> <string name="feed_fetch_channel_tabs_summary">Tab untuk didapatkan ketika memperarui umpan. Opsi ini tidak memiliki efek jika saluran diperbarui menggunakan mode cepat.</string>
@@ -828,9 +828,12 @@
<string name="player_http_403">Kesalahan HTTP 403 diterima dari server saat memutar, dapat disebabkan oleh URL streaming kedaluwarsa atau pemblokiran IP</string> <string name="player_http_403">Kesalahan HTTP 403 diterima dari server saat memutar, dapat disebabkan oleh URL streaming kedaluwarsa atau pemblokiran IP</string>
<string name="player_http_invalid_status">Kesalahan HTTP %1$s diterima dari server saat memutar</string> <string name="player_http_invalid_status">Kesalahan HTTP %1$s diterima dari server saat memutar</string>
<string name="youtube_player_http_403">Kesalahan HTTP 403 diterima dari server saat memutar, dapat disebabkan oleh pemblokiran IP atau masalah deobfuskasi URL streaming</string> <string name="youtube_player_http_403">Kesalahan HTTP 403 diterima dari server saat memutar, dapat disebabkan oleh pemblokiran IP atau masalah deobfuskasi URL streaming</string>
<string name="sign_in_confirm_not_bot_error">%1$s menolak memberikan data, meminta login untuk memastikan peminta bukan bot.\n\nAlamat IP Anda mungkin telah diblokir sementara oleh %1$s, Anda dapat menunggu beberapa saat atau beralih ke alamat IP yang berbeda (misalnya dengan mengaktifkan/menonaktifkan VPN, atau beralih dari WiFi ke data seluler).</string> <string name="sign_in_confirm_not_bot_error">%1$s menolak memberikan data, meminta login untuk memastikan peminta bukan bot.\n\nAlamat IP Anda mungkin telah diblokir sementara oleh %1$s, Anda dapat menunggu beberapa saat atau beralih ke alamat IP yang berbeda (misalnya dengan mengaktifkan/menonaktifkan VPN, atau beralih dari WiFi ke data seluler).\n\nHarap lihat &lt;a href=\"%2$s\"&gt;&lt;/a&gt;entri Pertanyaan ini&lt;/a&gt; untuk informasi lebih lanjut.</string>
<string name="unsupported_content_in_country">Konten ini tidak tersedia untuk negara konten yang saat ini dipilih.\n\nUbah pilihan Anda dari “Pengaturan &gt; Konten &gt; Negara konten bawaan”.</string> <string name="unsupported_content_in_country">Konten ini tidak tersedia untuk negara konten yang saat ini dipilih.\n\nUbah pilihan Anda dari “Pengaturan &gt; Konten &gt; Negara konten bawaan”.</string>
<string name="short_thousand">%sK</string> <string name="short_thousand">%sK</string>
<string name="short_million">%sM</string> <string name="short_million">%sM</string>
<string name="short_billion">%sB</string> <string name="short_billion">%sB</string>
<string name="kao_dialog_warning">Pada Agustus 2025, Google mengumumkan bahwa mulai September 2026, pemasangan aplikasi akan memerlukan verifikasi pengembang untuk semua aplikasi Android pada perangkat bersertifikasi, termasuk yang dipasang di luar Play Store. Karena pengembang NewPipe tidak menyetujui persyaratan ini, NewPipe tidak akan lagi berfungsi pada perangkat Android bersertifikasi setelah waktu tersebut.</string>
<string name="kao_dialog_more_info">Rincian</string>
<string name="kao_solution">Solusi</string>
</resources> </resources>

View File

@@ -859,6 +859,29 @@
<string name="player_http_403">Errore HTTP 403 ricevuto dal server durante la riproduzione, probabilmente causato dalla scadenza dell\'URL in streaming o da un divieto dell\'IP</string> <string name="player_http_403">Errore HTTP 403 ricevuto dal server durante la riproduzione, probabilmente causato dalla scadenza dell\'URL in streaming o da un divieto dell\'IP</string>
<string name="player_http_invalid_status">Errore HTTP %1$s ricevuto dal server durante la riproduzione</string> <string name="player_http_invalid_status">Errore HTTP %1$s ricevuto dal server durante la riproduzione</string>
<string name="youtube_player_http_403">Errore HTTP 403 ricevuto dal server durante la riproduzione, probabilmente causato da un divieto dell\'IP o problemi di de-offuscamento dell\'URL in streaming</string> <string name="youtube_player_http_403">Errore HTTP 403 ricevuto dal server durante la riproduzione, probabilmente causato da un divieto dell\'IP o problemi di de-offuscamento dell\'URL in streaming</string>
<string name="sign_in_confirm_not_bot_error">%1$s ha rifiutato di fornire i dati, chiedendo un accesso per confermare che il richiedente non sia un bot.\n\nIl tuo IP potrebbe essere stato temporaneamente vietato da %1$s, puoi aspettare un po\' di tempo o passare ad un IP diverso (ad esempio accendendo/spegnendo una VPN, o passando dal WiFi ai dati mobili).</string> <string name="sign_in_confirm_not_bot_error">%1$s ha rifiutato di fornire i dati, chiedendo un accesso per confermare che il richiedente non sia un bot.\n\nIl tuo IP potrebbe essere stato temporaneamente vietato da %1$s, puoi aspettare un po\' di tempo o passare ad un IP diverso (ad esempio accendendo/spegnendo una VPN, o passando dal WiFi ai dati mobili).\n\nLeggi <a href="%2$s">questa voce nelle FAQ</a> per maggiori informazioni.</string>
<string name="unsupported_content_in_country">Questo contenuto non è disponibile per il Paese dei contenuti attualmente selezionato.\n\nModifica la selezione da \"Impostazioni &gt; Contenuti &gt; Paese dei contenuti predefinito\".</string> <string name="unsupported_content_in_country">Questo contenuto non è disponibile per il Paese dei contenuti attualmente selezionato.\n\nModifica la selezione da \"Impostazioni &gt; Contenuti &gt; Paese dei contenuti predefinito\".</string>
<string name="kao_dialog_warning">Ad agosto 2025, Google ha annunciato che a partire da settembre 2026, l\'installazione di app richiederà la verifica dello sviluppatore per tutte le app Android su dispositivi certificati, compresi quelli installati al di fuori del Play Store. Poiché gli sviluppatori di NewPipe non sono d\'accordo con questo requisito, NewPipe non funzionerà più su dispositivi Android certificati dopo quel mese.</string>
<string name="kao_dialog_more_info">Dettagli</string>
<string name="kao_solution">Soluzione</string>
<plurals name="export_subscriptions">
<item quantity="one">Esportazione di %d iscrizione…</item>
<item quantity="many">Esportazione di %d iscrizioni…</item>
<item quantity="other">Esportazione di %d iscrizioni…</item>
</plurals>
<plurals name="load_subscriptions">
<item quantity="one">Caricamento di %d iscrizione…</item>
<item quantity="many">Caricamento di %d iscrizioni…</item>
<item quantity="other">Caricamento di %d iscrizioni…</item>
</plurals>
<plurals name="import_subscriptions">
<item quantity="one">Importazione di %d iscrizione…</item>
<item quantity="many">Importazione di %d iscrizioni…</item>
<item quantity="other">Importazione di %d iscrizioni…</item>
</plurals>
<string name="import_subscriptions_title">Importa iscrizioni</string>
<string name="export_subscriptions_title">Esporta iscrizioni</string>
<string name="import_subscriptions_summary">Importa iscrizioni da un\'esportazione .json precedente</string>
<string name="export_subscriptions_summary">Esporta le tue iscrizioni su un file .json</string>
<string name="import_from_previous_export">Importa da un\'esportazione precedente</string>
</resources> </resources>

View File

@@ -804,4 +804,8 @@
<string name="import_settings_vulnerable_format">インポートされているエクスポートの設定は、NewPipe 0.27.0以降は非推奨であった脆弱な形式を使用します。 インポートされているエクスポートは信頼できる情報源からであり、将来的にはNewPipe 0.27.0かこれより新しいバージョンから得られるエクスポートのみを優先して使用します。 この脆弱な形式で設定をインポートするための対応はすぐに完全に削除され、新しいバージョンからエクスポートの設定をインポートすることは出来ません。</string> <string name="import_settings_vulnerable_format">インポートされているエクスポートの設定は、NewPipe 0.27.0以降は非推奨であった脆弱な形式を使用します。 インポートされているエクスポートは信頼できる情報源からであり、将来的にはNewPipe 0.27.0かこれより新しいバージョンから得られるエクスポートのみを優先して使用します。 この脆弱な形式で設定をインポートするための対応はすぐに完全に削除され、新しいバージョンからエクスポートの設定をインポートすることは出来ません。</string>
<string name="share_playlist_as_youtube_temporary_playlist">YouTubeの一時的なプレイリストとして共有</string> <string name="share_playlist_as_youtube_temporary_playlist">YouTubeの一時的なプレイリストとして共有</string>
<string name="audio_track_type_secondary">二次的</string> <string name="audio_track_type_secondary">二次的</string>
<string name="kao_dialog_warning">Google は、2026/2027 年から、認定 Android デバイス上のすべてのアプリについて、開発者が個人の身元情報を直接 Google に提出することを必須にすると発表しました。本アプリの開発者はこの要件に同意していないため、このアプリはその時点以降、認定 Android デバイス上で動作しなくなります。</string>
<string name="kao_dialog_more_info">詳細</string>
<string name="kao_solution">解決</string>
<string name="short_billion">%sB</string>
</resources> </resources>

View File

@@ -1,3 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
</resources>

View File

@@ -37,7 +37,7 @@
<string name="default_audio_format_title">ნაგულისხმევი აუდიო ფორმატი</string> <string name="default_audio_format_title">ნაგულისხმევი აუდიო ფორმატი</string>
<string name="peertube_instance_url_summary">აირჩიეთ თქვენი საყვარელი PeerTube ეგზემპლარები</string> <string name="peertube_instance_url_summary">აირჩიეთ თქვენი საყვარელი PeerTube ეგზემპლარები</string>
<string name="progressive_load_interval_title">დაკვრის დატვირთვის ინტერვალის ზომა</string> <string name="progressive_load_interval_title">დაკვრის დატვირთვის ინტერვალის ზომა</string>
<string name="progressive_load_interval_summary">შეცვალეთ დატვირთვის ინტერვალის ზომა (ამჟამად %s). დაბალმა მნიშვნელობამ შეიძლება დააჩქაროს საწყისი ვიდეოს ჩატვირთვა. ცვლილებები მოითხოვს მოთამაშის გადატვირთვას</string> <string name="progressive_load_interval_summary">შეცვალეთ დატვირთვის ინტერვალის ზომა (ამჟამად %s). დაბალმა მნიშვნელობამ შეიძლება დააჩქაროს საწყისი ვიდეოს ჩატვირთვა.</string>
<string name="clear_queue_confirmation_title">მოითხოვეთ დადასტურება რიგის გასუფთავებამდე</string> <string name="clear_queue_confirmation_title">მოითხოვეთ დადასტურება რიგის გასუფთავებამდე</string>
<string name="use_inexact_seek_summary">არაზუსტი ძიება საშუალებას აძლევს მოთამაშეს უფრო სწრაფად მოიძიოს პოზიციები შემცირებული სიზუსტით. 5, 15 ან 25 წამის ძიება ამით არ მუშაობს</string> <string name="use_inexact_seek_summary">არაზუსტი ძიება საშუალებას აძლევს მოთამაშეს უფრო სწრაფად მოიძიოს პოზიციები შემცირებული სიზუსტით. 5, 15 ან 25 წამის ძიება ამით არ მუშაობს</string>
<string name="seek_duration_title">სწრაფი წინსვლა/-გადახვევა ძიების ხანგრძლივობა</string> <string name="seek_duration_title">სწრაფი წინსვლა/-გადახვევა ძიების ხანგრძლივობა</string>
@@ -100,7 +100,7 @@
<string name="notification_action_shuffle">არევა</string> <string name="notification_action_shuffle">არევა</string>
<string name="notification_action_buffering">Ბუფერიზაცია</string> <string name="notification_action_buffering">Ბუფერიზაცია</string>
<string name="play_audio">აუდიო</string> <string name="play_audio">აუდიო</string>
<string name="night_theme_title">ღამის თემა</string> <string name="night_theme_title">მუქი თემა</string>
<string name="light_theme_title">ღია</string> <string name="light_theme_title">ღია</string>
<string name="dark_theme_title">მუქი</string> <string name="dark_theme_title">მუქი</string>
<string name="black_theme_title">შავი</string> <string name="black_theme_title">შავი</string>
@@ -654,7 +654,7 @@
<string name="downloads_storage_ask_title">იკითხეთ, სად უნდა ჩამოტვირთოთ</string> <string name="downloads_storage_ask_title">იკითხეთ, სად უნდა ჩამოტვირთოთ</string>
<string name="downloads_storage_ask_summary">თქვენ მოგეთხოვებათ სად შეინახოთ თითოეული ჩამოტვირთვა. <string name="downloads_storage_ask_summary">თქვენ მოგეთხოვებათ სად შეინახოთ თითოეული ჩამოტვირთვა.
\n ჩართეთ სისტემის საქაღალდის ამომრჩევი (SAF), თუ გსურთ ჩამოტვირთოთ გარე SD ბარათზე</string> \n ჩართეთ სისტემის საქაღალდის ამომრჩევი (SAF), თუ გსურთ ჩამოტვირთოთ გარე SD ბარათზე</string>
<string name="remove_watched_popup_warning">ვიდეოები, რომლებიც უყურეთ დასაკრავ სიაში დამატებამდე და მის შემდეგ, წაიშლება. \n დარწმუნებული ხართ? ამის გაუქმება შეუძლებელია!</string> <string name="remove_watched_popup_warning">ვიდეოები, რომლებიც უყურეთ დასაკრავ სიაში დამატებამდე და მის შემდეგ, წაიშლება. \n დარწმუნებული ხართ?</string>
<string name="app_license">NewPipe არის copyleft უფასო პროგრამული უზრუნველყოფა: თქვენ შეგიძლიათ გამოიყენოთ, შეისწავლოთ, გააზიაროთ და გააუმჯობესოთ იგი სურვილისამებრ. კონკრეტულად თქვენ შეგიძლიათ გადაანაწილოთ და/ან შეცვალოთ იგი GNU-ს ზოგადი საჯარო ლიცენზიის პირობებით, როგორც ეს გამოქვეყნებულია თავისუფალი პროგრამული უზრუნველყოფის ფონდის მიერ, ლიცენზიის მე-3 ვერსიით, ან (თქვენი სურვილისამებრ) ნებისმიერი შემდგომი ვერსიით.</string> <string name="app_license">NewPipe არის copyleft უფასო პროგრამული უზრუნველყოფა: თქვენ შეგიძლიათ გამოიყენოთ, შეისწავლოთ, გააზიაროთ და გააუმჯობესოთ იგი სურვილისამებრ. კონკრეტულად თქვენ შეგიძლიათ გადაანაწილოთ და/ან შეცვალოთ იგი GNU-ს ზოგადი საჯარო ლიცენზიის პირობებით, როგორც ეს გამოქვეყნებულია თავისუფალი პროგრამული უზრუნველყოფის ფონდის მიერ, ლიცენზიის მე-3 ვერსიით, ან (თქვენი სურვილისამებრ) ნებისმიერი შემდგომი ვერსიით.</string>
<string name="auto">ავტო</string> <string name="auto">ავტო</string>
<string name="blank_page_summary">ცარიელი გვერდი</string> <string name="blank_page_summary">ცარიელი გვერდი</string>
@@ -790,4 +790,33 @@
<string name="youtube_player_http_403">დაკვრის დროს სერვერიდან მიღებული HTTP შეცდომა 403, სავარაუდოდ, გამოწვეულია IP აკრძალვით ან სტრიმინგის URL-ის დებფუსკაციის პრობლემებით.</string> <string name="youtube_player_http_403">დაკვრის დროს სერვერიდან მიღებული HTTP შეცდომა 403, სავარაუდოდ, გამოწვეულია IP აკრძალვით ან სტრიმინგის URL-ის დებფუსკაციის პრობლემებით.</string>
<string name="sign_in_confirm_not_bot_error">%1$s-მა უარი თქვა მონაცემების მიწოდებაზე და ითხოვა შესვლა იმის დასადასტურებლად, რომ მომთხოვნი რობოტი არ არის.\n\nშესაძლოა, თქვენი IP მისამართი დროებით აიკრძალა %1$s-ის მიერ, შეგიძლიათ დაელოდოთ ცოტა ხანს ან გადახვიდეთ სხვა IP მისამართზე (მაგალითად, VPN-ის ჩართვით/გამორთვით, ან WiFi-დან მობილურ მონაცემებზე გადართვით).</string> <string name="sign_in_confirm_not_bot_error">%1$s-მა უარი თქვა მონაცემების მიწოდებაზე და ითხოვა შესვლა იმის დასადასტურებლად, რომ მომთხოვნი რობოტი არ არის.\n\nშესაძლოა, თქვენი IP მისამართი დროებით აიკრძალა %1$s-ის მიერ, შეგიძლიათ დაელოდოთ ცოტა ხანს ან გადახვიდეთ სხვა IP მისამართზე (მაგალითად, VPN-ის ჩართვით/გამორთვით, ან WiFi-დან მობილურ მონაცემებზე გადართვით).</string>
<string name="unsupported_content_in_country">ეს კონტენტი ამჟამად არჩეული კონტენტის ქვეყნისთვის მიუწვდომელია.\n\nშეცვალეთ თქვენი არჩევანი „პარამეტრები &gt; კონტენტი &gt; ნაგულისხმევი კონტენტის ქვეყანა“-დან.</string> <string name="unsupported_content_in_country">ეს კონტენტი ამჟამად არჩეული კონტენტის ქვეყნისთვის მიუწვდომელია.\n\nშეცვალეთ თქვენი არჩევანი „პარამეტრები &gt; კონტენტი &gt; ნაგულისხმევი კონტენტის ქვეყანა“-დან.</string>
<string name="audio_track_name">%1$s %2$s</string>
<string name="audio_track_type_original">ორიგინალი</string>
<string name="audio_track_type_dubbed">გახმოვანებული</string>
<string name="audio_track_type_descriptive">აღწერითი</string>
<string name="audio_track_type_secondary">მეორადი</string>
<string name="channel_tab_videos">ვიდეოები</string>
<string name="channel_tab_tracks">ტრეკები</string>
<string name="channel_tab_shorts">მოკლე ვიდეოები</string>
<string name="channel_tab_livestreams">ლაივი</string>
<string name="channel_tab_channels">არხები</string>
<string name="channel_tab_playlists">დასაკრავი სიები</string>
<string name="channel_tab_albums">ალბომები</string>
<string name="channel_tab_likes">მოწონებები</string>
<string name="channel_tab_about">შესახებ</string>
<string name="show_channel_tabs">არხის ჩანართები</string>
<string name="show_channel_tabs_summary">რომელი ჩანართებია ნაჩვენები არხის გვერდებზე</string>
<string name="open_play_queue">დაკვრის რიგის გახსნა</string>
<string name="toggle_fullscreen">სრულეკრანიან რეჟიმზე გადართვა</string>
<plurals name="replies">
<item quantity="one">%s პასუხი</item>
<item quantity="other">%s პასუხები</item>
</plurals>
<string name="show_more">მეტის ჩვენება</string>
<string name="show_less">ნაკლების ჩვენება</string>
<string name="import_settings_vulnerable_format">იმპორტირებული ექსპორტის პარამეტრები იყენებს დაუცველ ფორმატს, რომელიც მოძველებულია NewPipe 0.27.0 ვერსიიდან. დარწმუნდით, რომ იმპორტირებული ექსპორტი სანდო წყაროდან არის და მომავალში უპირატესობა მიანიჭეთ მხოლოდ NewPipe 0.27.0 ან უფრო ახალი ვერსიიდან მიღებული ექსპორტირებული პარამეტრების გამოყენებას. ამ დაუცველ ფორმატში პარამეტრების იმპორტის მხარდაჭერა მალე მთლიანად გაუქმდება და შემდეგ NewPipe-ის ძველი ვერსიები ვეღარ შეძლებენ ექსპორტირებული პარამეტრების იმპორტირებას ახალი ვერსიებიდან.</string>
<string name="migration_info_6_7_title">SoundCloud-ის ტოპ 50 გვერდი წაიშალა</string>
<string name="migration_info_6_7_message">SoundCloud-მა შეწყვიტა ორიგინალი ტოპ 50 ჩარტების გამოშვება. შესაბამისი ჩანართი წაიშალა თქვენი მთავარი გვერდიდან.</string>
<string name="migration_info_7_8_title">YouTube-ის კომბინირებული ტრენდული გვერდი წაშლილია</string>
<string name="migration_info_7_8_message">YouTube-მა 2025 წლის 21 ივლისიდან შეწყვიტა კომბინირებული ტრენდული გვერდის არსებობა. NewPipe-მა ნაგულისხმევი ტრენდული გვერდი ტრენდული პირდაპირი ტრანსლაციებით ჩაანაცვლა.\n\nასევე შეგიძლიათ აირჩიოთ სხვადასხვა ტრენდული გვერდები „პარამეტრები &gt; მასალა &gt; მთავარი გვერდის შინაარსი“-ში.</string>
</resources> </resources>

View File

@@ -223,4 +223,12 @@
<string name="metadata_tags">Tibzimin</string> <string name="metadata_tags">Tibzimin</string>
<string name="blank_page_summary">Asebter d ilem</string> <string name="blank_page_summary">Asebter d ilem</string>
<string name="settings_category_exoplayer_title">Iɣewwaṛen n ExoPlayer</string> <string name="settings_category_exoplayer_title">Iɣewwaṛen n ExoPlayer</string>
<plurals name="days">
<item quantity="one">%d n wass</item>
<item quantity="other">%d n wussan</item>
</plurals>
<plurals name="videos">
<item quantity="one">%s n tvidyut</item>
<item quantity="other">%s n tvidyutin</item>
</plurals>
</resources> </resources>

View File

@@ -831,6 +831,23 @@
<string name="player_http_403">재생 중 서버에서 HTTP 403 오류를 수신했으며, 스트리밍 URL이 만료되었거나 IP 차단으로 인해 발생했을 수 있습니다</string> <string name="player_http_403">재생 중 서버에서 HTTP 403 오류를 수신했으며, 스트리밍 URL이 만료되었거나 IP 차단으로 인해 발생했을 수 있습니다</string>
<string name="player_http_invalid_status">재생 중 서버에서 HTTP %1$s 오류를 수신했습니다</string> <string name="player_http_invalid_status">재생 중 서버에서 HTTP %1$s 오류를 수신했습니다</string>
<string name="youtube_player_http_403">재생 중 서버에서 HTTP 403 오류를 수신했으며, 스트리밍 URL 역난독화 문제나 IP 차단 때문일 수 있습니다</string> <string name="youtube_player_http_403">재생 중 서버에서 HTTP 403 오류를 수신했으며, 스트리밍 URL 역난독화 문제나 IP 차단 때문일 수 있습니다</string>
<string name="sign_in_confirm_not_bot_error">%1$s에서 데이터 제공을 거부하고, 요청자가 봇이 아닌지 확인하기 위해 로그인을 요청하고 있습니다.\n\n아마 IP가 %1$s에서 임시 차단되었을 것이며, 잠시 기다리거나 다른 IP로 전환할 수 있습니다 (예를 들자면 VPN을 켜/끄거나, WiFi를 모바일 데이터로 바꾸세요).</string> <string name="sign_in_confirm_not_bot_error">%1$s에서 데이터 제공을 거부하고, 요청자가 봇이 아닌지 확인하기 위해 로그인을 요청하고 있습니다.\n\n아마 IP가 %1$s에서 임시 차단되었을 것이며, 잠시 기다리거나 다른 IP로 전환할 수 있습니다 (예를 들 VPN을 켜/끄거나, WiFi를 모바일 데이터로 바꿔 보세요).\n\n자세한 정보는 <a href="%2$s">여기 FAQ</a>를 확인하세요.</string>
<string name="unsupported_content_in_country">이 콘텐츠는 현재 선택한 콘텐츠 지역에서 이용할 수 없습니다.\n\n\"설정 &gt; 콘텐츠 &gt; 기본 콘텐츠 국가\"에서 지역을 바꾸세요.</string> <string name="unsupported_content_in_country">이 콘텐츠는 현재 선택한 콘텐츠 지역에서 이용할 수 없습니다.\n\n\"설정 &gt; 콘텐츠 &gt; 기본 콘텐츠 국가\"에서 지역을 바꾸세요.</string>
<string name="kao_dialog_warning">2025년 8월, Google은 2026년 9월부터 인증된 기기에 앱을 설치하려면 Play 스토어 외 앱을 포함한 모든 Android 앱에 대해 개발자 인증을 받아야 한다고 발표했습니다. NewPipe 개발자는 이 요구 사항에 동의하지 않으므로, 이 이후 NewPipe는 더 이상 인증된 Android 기기에서 동작하지 않을 것입니다.</string>
<string name="kao_dialog_more_info">자세히</string>
<string name="kao_solution">해결책</string>
<plurals name="export_subscriptions">
<item quantity="other">구독 %d건 내보내는 중…</item>
</plurals>
<plurals name="load_subscriptions">
<item quantity="other">구독 %d건 불러오는 중…</item>
</plurals>
<plurals name="import_subscriptions">
<item quantity="other">구독 %d건 가져오는 중…</item>
</plurals>
<string name="import_subscriptions_title">구독 가져오기</string>
<string name="export_subscriptions_title">구독 내보내기</string>
<string name="import_subscriptions_summary">이전에 내보낸 .json에서 구독을 가져옵니다</string>
<string name="export_subscriptions_summary">구독 현황을 .json 파일로 내보냅니다</string>
<string name="import_from_previous_export">이전 내보내기에서 가져오기</string>
</resources> </resources>

View File

@@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

View File

@@ -2,8 +2,8 @@
<resources> <resources>
<string name="caption_none">Nav Subtitri</string> <string name="caption_none">Nav Subtitri</string>
<string name="playlist_thumbnail_change_success">Atskaņošanas saraksta attēls nomainīts.</string> <string name="playlist_thumbnail_change_success">Atskaņošanas saraksta attēls nomainīts.</string>
<string name="playlist_creation_success">Atskaņošanas saraksts radīts</string> <string name="playlist_creation_success">Atskaņošanas saraksts izveidots</string>
<string name="delete_playlist_prompt">Dzēst atskaņošanas sarakstu\?</string> <string name="delete_playlist_prompt">Vai tiešām vēlaties dzēst šo atskaņošanas sarakstu?</string>
<string name="set_as_playlist_thumbnail">Iestatīt, kā atskaņošanas saraksta attēlu</string> <string name="set_as_playlist_thumbnail">Iestatīt, kā atskaņošanas saraksta attēlu</string>
<string name="add_to_playlist">Pievienot atskaņošanas sarakstam</string> <string name="add_to_playlist">Pievienot atskaņošanas sarakstam</string>
<string name="name">Nosaukums</string> <string name="name">Nosaukums</string>
@@ -29,10 +29,10 @@
<string name="new_and_hot">Jauns un populārs</string> <string name="new_and_hot">Jauns un populārs</string>
<string name="top_50">Top 50</string> <string name="top_50">Top 50</string>
<string name="error_unable_to_load_comments">Nevarēja ielādēt komentārus</string> <string name="error_unable_to_load_comments">Nevarēja ielādēt komentārus</string>
<string name="import_settings">Vai jūs vēlaties ievietot arī iestatījumus?</string> <string name="import_settings">Vai vēlaties ievietot arī iestatījumus?</string>
<string name="override_current_data">Šis pārrakstīt jūsu tagadējo uzstādījumu.</string> <string name="override_current_data">Pašreizējie dati tiks aizstāti.</string>
<string name="could_not_import_all_files">Uzmanību: Ne visas datnes varēja ievietot.</string> <string name="could_not_import_all_files">Uzmanību: Ne visas datnes varēja ievietot.</string>
<string name="no_valid_zip_file">Nav derīgs ZIP fails</string> <string name="no_valid_zip_file">Nederīga ZIP datne</string>
<string name="import_complete_toast">Ievietošana pabeigta</string> <string name="import_complete_toast">Ievietošana pabeigta</string>
<string name="export_complete_toast">Eksportēts</string> <string name="export_complete_toast">Eksportēts</string>
<string name="select_a_kiosk">Atlasiet kiosku</string> <string name="select_a_kiosk">Atlasiet kiosku</string>
@@ -47,16 +47,15 @@
<string name="main_page_content_summary">Kādas cilnes rādīt galvenajā lapā</string> <string name="main_page_content_summary">Kādas cilnes rādīt galvenajā lapā</string>
<string name="main_page_content">Galvenā lapa</string> <string name="main_page_content">Galvenā lapa</string>
<string name="title_most_played">Visvairāk Atskaņotais</string> <string name="title_most_played">Visvairāk Atskaņotais</string>
<string name="title_last_played">Pēdējais Atskaņotais</string> <string name="title_last_played">Pēdējais atskaņotais</string>
<string name="delete_item_search_history">Vai jūs vēlaties izdzēst šo lietu no meklēšanas vēstures\?</string> <string name="delete_item_search_history">Vai tiešām vēlaties izdzēst šo vaicājumu no meklēšanas vēstures?</string>
<string name="action_history">Vēsture</string> <string name="action_history">Vēsture</string>
<string name="title_activity_history">Vēsture</string> <string name="title_activity_history">Vēsture</string>
<string name="read_full_license">Izlasīt licenci</string> <string name="read_full_license">Izlasīt licenci</string>
<string name="app_license">Newpipe ir bezmaksas programmatūra: jūs varat izmantot, izpētīt, dalīties un uzlabot to jebkurā brīdī. Tieši jūs varat kopīgot un/ vai modificēt to saskaņā ar GNU Vispārējās Publiskās Licences noteikumiem, ko publicējusi Brīvās Programmatūras Fonds, vai nu 3. licences versija, vai (pēc jūsu izvēles) jebkura vēlāka versija.</string> <string name="app_license">Newpipe ir bezmaksas programmatūra: jūs varat izmantot, izpētīt, dalīties un uzlabot to jebkurā brīdī. Tieši jūs varat kopīgot un/ vai modificēt to saskaņā ar GNU Vispārējās Publiskās Licences noteikumiem, ko publicējusi Brīvās Programmatūras Fonds, vai nu 3. licences versija, vai (pēc jūsu izvēles) jebkura vēlāka versija.</string>
<string name="app_license_title">NewPipe Licence</string> <string name="app_license_title">NewPipe Licence</string>
<string name="read_privacy_policy">Izslasīt privātuma politiku</string> <string name="read_privacy_policy">Izslasīt privātuma politiku</string>
<string name="privacy_policy_encouragement">NewPipe projekts uztver jūsu privātumu ļoti nopietni . Tāpēc lietotne nesavāc datus bez jūsu piekrišanas. <string name="privacy_policy_encouragement">Datu aizsardzība ir ļoti svarīga NewPipe projektam. Tāpēc lietotne neapkopo datus bez jūsu piekrišanas.\nNewPipe konfidencialitātes politika sīki izskaidro, kādi dati tiek nosūtīti un uzglabāti, kad nosūtiet avārijas ziņojumu.</string>
\nNewPipe privātuma politika sīki izskaidro, kādi dati tiek nosūtīti un uzglabāti, nosūtot kļūdas ziņojumu.</string>
<string name="privacy_policy_title">NewPipe Privātuna Politika</string> <string name="privacy_policy_title">NewPipe Privātuna Politika</string>
<string name="website_encouragement">Apmeklēt NewPipe mājaslapu, lai iegūtu vairāk informācijas un ziņu.</string> <string name="website_encouragement">Apmeklēt NewPipe mājaslapu, lai iegūtu vairāk informācijas un ziņu.</string>
<string name="website_title">Mājaslapa</string> <string name="website_title">Mājaslapa</string>
@@ -69,7 +68,7 @@
<string name="app_description">Libre, viegla atskaņošana uz Android.</string> <string name="app_description">Libre, viegla atskaņošana uz Android.</string>
<string name="tab_licenses">Licences</string> <string name="tab_licenses">Licences</string>
<string name="tab_about">Par un BUJ</string> <string name="tab_about">Par un BUJ</string>
<string name="title_licenses">Trešo pušu Licences</string> <string name="title_licenses">Trešo pušu licences</string>
<string name="title_activity_about">Par NewPipe</string> <string name="title_activity_about">Par NewPipe</string>
<string name="charset_most_special_characters">Lielākā daļa īpašo rakstzīmju</string> <string name="charset_most_special_characters">Lielākā daļa īpašo rakstzīmju</string>
<string name="charset_letters_and_digits">Burti un cipari</string> <string name="charset_letters_and_digits">Burti un cipari</string>
@@ -81,7 +80,7 @@
<string name="recaptcha_request_toast">reCAPTCHA izaicinājums dots</string> <string name="recaptcha_request_toast">reCAPTCHA izaicinājums dots</string>
<string name="subtitle_activity_recaptcha">Nospiediet \"Pabeigts\", kad to atrisinat</string> <string name="subtitle_activity_recaptcha">Nospiediet \"Pabeigts\", kad to atrisinat</string>
<string name="title_activity_recaptcha">reCAPTCHA izaicinājums</string> <string name="title_activity_recaptcha">reCAPTCHA izaicinājums</string>
<string name="one_item_deleted">1 lieta izdzēsta.</string> <string name="one_item_deleted">1 vienums dzēsts.</string>
<string name="msg_popup_permission">Šī atļauja ir nepieciešama, lai <string name="msg_popup_permission">Šī atļauja ir nepieciešama, lai
\natvērtu popup režīmā</string> \natvērtu popup režīmā</string>
<string name="no_available_dir">Lūdzu nosakiet lejupielādes mapi iestatījumos vēlāk</string> <string name="no_available_dir">Lūdzu nosakiet lejupielādes mapi iestatījumos vēlāk</string>
@@ -92,13 +91,13 @@
<string name="msg_running">NewPipe lejupielādē</string> <string name="msg_running">NewPipe lejupielādē</string>
<string name="msg_error">Kļūda</string> <string name="msg_error">Kļūda</string>
<string name="msg_threads">Procesi</string> <string name="msg_threads">Procesi</string>
<string name="msg_name">Faila nosaukums</string> <string name="msg_name">Datnes nosaukums</string>
<string name="ok">Labi</string> <string name="ok">Labi</string>
<string name="rename">Pārsaukt</string> <string name="rename">Pārsaukt</string>
<string name="dismiss">Noraidīt</string> <string name="dismiss">Noraidīt</string>
<string name="checksum">Kontrolsumma</string> <string name="checksum">Kontrolsumma</string>
<string name="delete">Izdzēst</string> <string name="delete">Dzēst</string>
<string name="create">Radīt</string> <string name="create">Izveidot / Saglabāt</string>
<string name="pause">Pauzēt</string> <string name="pause">Pauzēt</string>
<string name="start">Sākt</string> <string name="start">Sākt</string>
<string name="no_comments">Nav komentāru</string> <string name="no_comments">Nav komentāru</string>
@@ -154,10 +153,10 @@
<string name="info_labels">Kas:\nRequest:\nContent Valoda:\nContent Valsts:\nApp Valoda:\nService:\nGMT Laiks:\nPackage:\nVersion:\nOS versija:</string> <string name="info_labels">Kas:\nRequest:\nContent Valoda:\nContent Valsts:\nApp Valoda:\nService:\nGMT Laiks:\nPackage:\nVersion:\nOS versija:</string>
<string name="hash_channel_description">Paziņojumi video apstrādes progresam</string> <string name="hash_channel_description">Paziņojumi video apstrādes progresam</string>
<string name="hash_channel_name">Video haša paziņojums</string> <string name="hash_channel_name">Video haša paziņojums</string>
<string name="popup_remember_size_pos_summary">Atcerēties pēdējo uznirstošā loga izmēru un pozīciju</string> <string name="popup_remember_size_pos_summary">Atceras pēdējo uznirstošā loga izmēru un pozīciju</string>
<string name="popup_remember_size_pos_title">Atcerēties uznirstošā loga īpašības</string> <string name="popup_remember_size_pos_title">Atcerēties uznirstošā loga īpašības</string>
<string name="default_popup_resolution_title">Uznirstošā loga noklusējuma izšķirtspēja</string> <string name="default_popup_resolution_title">Noklusējuma uznirstošā loga izšķirtspēja</string>
<string name="controls_popup_title">Uznirstošs logs</string> <string name="controls_popup_title">Skatīt uznirstošā logā</string>
<string name="open_in_popup_mode">Atvērt uznirstošā logā</string> <string name="open_in_popup_mode">Atvērt uznirstošā logā</string>
<string name="what_happened_headline">Kas notika:</string> <string name="what_happened_headline">Kas notika:</string>
<string name="what_device_headline">Informācija:</string> <string name="what_device_headline">Informācija:</string>
@@ -169,16 +168,16 @@
<string name="error_report_button_text">Ziņojiet pa e-pastu</string> <string name="error_report_button_text">Ziņojiet pa e-pastu</string>
<string name="sorry_string">Piedotiet, tam nevajadzēja notikt.</string> <string name="sorry_string">Piedotiet, tam nevajadzēja notikt.</string>
<string name="permission_display_over_apps">Dot atļauju rādīt pāri citām aplikācijām</string> <string name="permission_display_over_apps">Dot atļauju rādīt pāri citām aplikācijām</string>
<string name="restore_defaults_confirmation">Vai jūs vēlaties atjaunot noklusējumus\?</string> <string name="restore_defaults_confirmation">Vai tiešām vēlaties atjaunot noklusējuma vērtības?</string>
<string name="restore_defaults">Atjaunot noklusējumus</string> <string name="restore_defaults">Atjaunot noklusējuma vērtības</string>
<string name="saved_tabs_invalid_json">Nevarēja nolasīt saglabātās cilnes, tādēļ izmanto noklusējuma</string> <string name="saved_tabs_invalid_json">Nevarēja nolasīt saglabātās cilnes, tādēļ izmanto noklusējuma</string>
<string name="no_streams_available_download">Neviens video nav pieejams lejupielādei</string> <string name="no_streams_available_download">Neviens video nav pieejams lejupielādei</string>
<string name="error_occurred_detail">Notika kļūda: %1$s</string> <string name="error_occurred_detail">Notika kļūda: %1$s</string>
<string name="file_name_empty_error">Faila nosaukums nevar būt tukšs</string> <string name="file_name_empty_error">Datnes nosaukums nevar būt tukšs</string>
<string name="invalid_file">Fails neeksistē, vai atļauja to lasīt vai rakstīt, nav dota</string> <string name="invalid_file">Datne neeksistē vai nav dota atļauja to lasīt vai rakstīt</string>
<string name="invalid_source">Tāds fails/saturs neeksistē</string> <string name="invalid_source">Tāda datne/saturs neeksistē</string>
<string name="invalid_directory">Tāda mape neeksistē</string> <string name="invalid_directory">Tāda mape neeksistē</string>
<string name="missing_file">Fails pārvietots vai izdzēsts</string> <string name="missing_file">Datne pārvietota vai dzēsta</string>
<string name="audio_streams_empty">Netika atrasts audio</string> <string name="audio_streams_empty">Netika atrasts audio</string>
<string name="video_streams_empty">Netika atrasti video</string> <string name="video_streams_empty">Netika atrasti video</string>
<string name="external_player_unsupported_link_type">Ārējie atskaņotāj neatbalsta šāda tipa saites</string> <string name="external_player_unsupported_link_type">Ārējie atskaņotāj neatbalsta šāda tipa saites</string>
@@ -191,26 +190,26 @@
<string name="parsing_error">Nevarēja apstrādāt mājaslapu</string> <string name="parsing_error">Nevarēja apstrādāt mājaslapu</string>
<string name="could_not_load_thumbnails">Nevarēja ielādēt visus video attēlus</string> <string name="could_not_load_thumbnails">Nevarēja ielādēt visus video attēlus</string>
<string name="network_error">Tīkla kļūda</string> <string name="network_error">Tīkla kļūda</string>
<string name="download_to_sdcard_error_message">Lejupielādēt uz SD karti nav iespējams. Atiestatīt lejupielāžu mapes lokāciju\?</string> <string name="download_to_sdcard_error_message">Lejupielāde ārējā SD kartē nav iespējama. Vai tiešām vēlaties atiestatīt lejupielāžu mapi?</string>
<string name="download_to_sdcard_error_title">Ārējā krātuve nepieejama</string> <string name="download_to_sdcard_error_title">Ārējā krātuve nepieejama</string>
<string name="general_error">Kļūda</string> <string name="general_error">Kļūda</string>
<string name="search_history_deleted">Meklēšanas vēsture izdzēsta</string> <string name="search_history_deleted">Meklēšanas vēsture dzēsta</string>
<string name="delete_search_history_alert">Izdzēsy visu meklēšanas vēsturi\?</string> <string name="delete_search_history_alert">Vai tiešām vēlaties izdzēst visu meklēšanas vēsturi?</string>
<string name="clear_search_history_summary">Izdzēš meklēto vārdu vēsturi</string> <string name="clear_search_history_summary">Izdzēš visus meklēšanas vaicājumus</string>
<string name="clear_search_history_title">Izdzēst skatīšanās vēsturi</string> <string name="clear_search_history_title">Notīrīt meklēšanas vēsturi</string>
<string name="watch_history_states_deleted">Atskaņošanas pozīcikas izdzēstas</string> <string name="watch_history_states_deleted">Atskaņošanas pozīcijas dzēstas</string>
<string name="delete_playback_states_alert">Izdzēst visas atskaņošanas pozīcijas\?</string> <string name="delete_playback_states_alert">Vai tiešām vēlaties dzēst visas atskaņošanas pozīcijas?</string>
<string name="clear_playback_states_summary">Izdzēš visas atskaņošanas pozīcijas</string> <string name="clear_playback_states_summary">Izdzēš visas atskaņošanas pozīcijas</string>
<string name="clear_playback_states_title">Izdzēst atskaņošanas pozīcijas</string> <string name="clear_playback_states_title">Notīrīt atskaņošanas pozīcijas</string>
<string name="watch_history_deleted">Skatīšanās vēsture izdzēsta</string> <string name="watch_history_deleted">Skatīšanās vēsture dzēsta</string>
<string name="delete_view_history_alert">Izdzēst visu skatīšanās vēsturi\?</string> <string name="delete_view_history_alert">Vai tiešām vēlaties dzēst visu skatīšanās vēsturi?</string>
<string name="clear_views_history_summary">Izdzēš atskaņoto videoklipu un atskaņošanas pozīciju vēsturi</string> <string name="clear_views_history_summary">Izdzēš atskaņoto video / audio un atskaņošanas pozīciju vēsturi</string>
<string name="clear_views_history_title">Notīrīt skatīšanās vēsturi</string> <string name="clear_views_history_title">Notīrīt skatīšanās vēsturi</string>
<string name="clear_cookie_summary">Notīrīt sīkfailus , kurus NewPipe saglabā, kad jūs atrisinat reCAPTCHA</string> <string name="clear_cookie_summary">Izdzēš sīkdatnes, kuras NewPipe uzglabā, kad jūs atrisiniet reCAPTCHA</string>
<string name="export_data_summary">Eksportēt vēsturi, abonementus, atskaņošanas sarakstus un iestatījumus</string> <string name="export_data_summary">Eksportēt vēsturi, abonementus, atskaņošanas sarakstus un iestatījumus</string>
<string name="import_data_summary">Aizstās jūsu pašreizējo vēsturi, abonementus, atskaņošanas sarakstus un (pēc izvēles) iestatījumus</string> <string name="import_data_summary">Aizstās jūsu pašreizējo vēsturi, abonementus, atskaņošanas sarakstus un (pēc izvēles) iestatījumus</string>
<string name="recaptcha_cookies_cleared">reCAPTCHA sīkfaili tika izdzēsti</string> <string name="recaptcha_cookies_cleared">reCAPTCHA sīkdatnes dzēstas</string>
<string name="clear_cookie_title">Izdzēst reCAPTCHA sīkfailus</string> <string name="clear_cookie_title">Notīrīt reCAPTCHA sīkdatnes</string>
<string name="export_data_title">Eksportēt datubāzi</string> <string name="export_data_title">Eksportēt datubāzi</string>
<string name="import_data_title">Ievietot datubāzi</string> <string name="import_data_title">Ievietot datubāzi</string>
<string name="switch_to_main">Pārslēgt uz Galveno</string> <string name="switch_to_main">Pārslēgt uz Galveno</string>
@@ -218,14 +217,14 @@
<string name="switch_to_background">Pārslēgt uz Fonu</string> <string name="switch_to_background">Pārslēgt uz Fonu</string>
<string name="unknown_content">[Nezināms]</string> <string name="unknown_content">[Nezināms]</string>
<string name="app_update_notification_channel_description">Paziņojumi par jaunām NewPipe versijām</string> <string name="app_update_notification_channel_description">Paziņojumi par jaunām NewPipe versijām</string>
<string name="app_update_notification_channel_name">Aplikācijas atjauninājuma paziņojums</string> <string name="app_update_notification_channel_name">Lietotnes atjauninājuma paziņojums</string>
<string name="notification_channel_description">Paziņojumi priekš NewPipe atskaņotāja</string> <string name="notification_channel_description">Paziņojumi priekš NewPipe atskaņotāja</string>
<string name="notification_channel_name">NewPipe paziņojums</string> <string name="notification_channel_name">NewPipe paziņojums</string>
<string name="file">Fails</string> <string name="file">Datne</string>
<string name="just_once">Tikai Vienreiz</string> <string name="just_once">Tikai Vienreiz</string>
<string name="always">Vienmēr</string> <string name="always">Vienmēr</string>
<string name="play_all">Atskaņot Visu</string> <string name="play_all">Atskaņot Visu</string>
<string name="file_deleted">Fails izdzēsts</string> <string name="file_deleted">Datne dzēsta</string>
<string name="undo">Atsaukt</string> <string name="undo">Atsaukt</string>
<string name="best_resolution">Labākā izšķirtspēja</string> <string name="best_resolution">Labākā izšķirtspēja</string>
<string name="clear">Notīrīt</string> <string name="clear">Notīrīt</string>
@@ -281,17 +280,7 @@
<string name="content_not_supported">NewPipe šo saturu vēl neatbalsta. <string name="content_not_supported">NewPipe šo saturu vēl neatbalsta.
\n \n
\nCerams, ka to atbalstīs nākamajā versijā.</string> \nCerams, ka to atbalstīs nākamajā versijā.</string>
<string name="feed_use_dedicated_fetch_method_help_text">Vai jūs domājat, ka plūsmas atjaunināšana ir pārāk lēna\? Ja tā, mēģiniet iespējot ātro atjaunināšanu (to var mainīt iestatījumos vai nospiežot pogu zemāk). <string name="feed_use_dedicated_fetch_method_help_text">Vai jūs domājat, ka plūsmas atjaunināšana ir pārāk lēna? Ja tā, mēģiniet iespējot ātro atjaunināšanu (to var mainīt iestatījumos vai nospiežot pogu zemāk). \n \nNewPipe piedāvā divas plūsmas atjaunināšanas stratēģijas: \n• Notiek visa abonēšanas kanāla iegūšana, kas ir lēna, bet pabeigta. \n• izmantojot īpašu servisu, kas ir ātrs, bet parasti nav pilnīgs. \n \nAtšķirība starp abiem ir tā, ka ātrajā parasti trūkst informācijas, piemēram, video ilgums vai veids (nevar atšķirt tiešraides video no parastajiem), un tas var atgriezt mazāk vienumu. \n \nYouTube ir pakalpojuma piemērs, kas piedāvā šo ātro metodi ar savu RSS plūsmu. \n \nTātad izvēle sakrīt ar vēlamo: ātrums vai precīza informācija.</string>
\n
\nNewPipe piedāvā divas plūsmas atjaunināšanas stratēģijas:
\n• Notiek visa abonēšanas kanāla iegūšana, kas ir lēna, bet pabeigta.
\n• izmantojot īpašu servisu, kas ir ātrs, bet parasti nav pilnīgs.
\n
\nAtšķirība starp abiem ir tā, ka ātrajā parasti trūkst informācijas, piemēram, video ilgums vai veids (nevar atšķirt tiešraides video no parastajiem), un tas var atgriezt mazāk vienumu.
\n
\nYouTube ir pakalpojuma piemērs, kas piedāvā šo ātro metodi ar savu RSS plūsmu.
\n
\nTātad izvēle sakrīt ar vēlamo: ātrums vai precīza informācija.</string>
<string name="feed_use_dedicated_fetch_method_disable_button">Izslēgt ātro režīmu</string> <string name="feed_use_dedicated_fetch_method_disable_button">Izslēgt ātro režīmu</string>
<string name="feed_use_dedicated_fetch_method_enable_button">Ieslēgt ātro režīmu</string> <string name="feed_use_dedicated_fetch_method_enable_button">Ieslēgt ātro režīmu</string>
<string name="feed_use_dedicated_fetch_method_summary">Pieejams dažos pakalpojumos, tas parasti ir daudz ātrāk, taču var atgriezt ierobežotu daudzumu informācijas un bieži arī nepilnīgu informāciju (piemēram, nav video ilguma, vienuma veida, nav tiešraides statusa)</string> <string name="feed_use_dedicated_fetch_method_summary">Pieejams dažos pakalpojumos, tas parasti ir daudz ātrāk, taču var atgriezt ierobežotu daudzumu informācijas un bieži arī nepilnīgu informāciju (piemēram, nav video ilguma, vienuma veida, nav tiešraides statusa)</string>
@@ -314,7 +303,7 @@
<string name="feed_processing_message">Notiek plūsmas apstrāde …</string> <string name="feed_processing_message">Notiek plūsmas apstrāde …</string>
<string name="feed_notification_loading">Notiek plūsmas ielāde…</string> <string name="feed_notification_loading">Notiek plūsmas ielāde…</string>
<string name="feed_subscription_not_loaded_count">Nav ielādēts: %d</string> <string name="feed_subscription_not_loaded_count">Nav ielādēts: %d</string>
<string name="feed_oldest_subscription_update">Plūsma pēdējoreiz atjaunināta: %s</string> <string name="feed_oldest_subscription_update">Atjaunināta: %s</string>
<string name="feed_groups_header_title">Abonementu grupas</string> <string name="feed_groups_header_title">Abonementu grupas</string>
<string name="fragment_feed_title">Kas jauns</string> <string name="fragment_feed_title">Kas jauns</string>
<plurals name="days"> <plurals name="days">
@@ -337,10 +326,10 @@
<item quantity="one">%d sekundi</item> <item quantity="one">%d sekundi</item>
<item quantity="other">%d sekundes</item> <item quantity="other">%d sekundes</item>
</plurals> </plurals>
<string name="new_seek_duration_toast">ExoPlayer ierobežojumu dēļ meklēšanas ilgums tika iestatīts uz %d sekundēm</string> <string name="new_seek_duration_toast">ExoPlayer ierobežojumu dēļ šanas solis tika iestatīts uz %d sekundēm</string>
<string name="remove_watched_popup_partially_watched_streams">Jā, un daļēji skatītos video</string> <string name="remove_watched_popup_partially_watched_streams">Jā, un daļēji skatītos</string>
<string name="remove_watched_popup_warning">Tiešraides, kas pirms tam skatītas un pēc tam pievienotas atskaņošanas sarakstam, tiks noņemtas. \nVai tiešām turpināt?</string> <string name="remove_watched_popup_warning">Tiešraides, kas iepriekš noskatītas un pēc tam pievienotas atskaņošanas sarakstam, tiks noņemtas. \nVai tiešām turpināt?</string>
<string name="remove_watched_popup_title">Vai tiešām noņemt skatītās tiešraides?</string> <string name="remove_watched_popup_title">Vai tiešām vēlaties noņemt skatītās tiešraides?</string>
<string name="remove_watched">Noņemt skatīto</string> <string name="remove_watched">Noņemt skatīto</string>
<string name="systems_language">System default</string> <string name="systems_language">System default</string>
<string name="app_language_title">Lietotnes valoda</string> <string name="app_language_title">Lietotnes valoda</string>
@@ -360,17 +349,17 @@
<string name="max_retry_desc">Maksimālais mēģinājumu skaits pirms lejupielādes atcelšanas</string> <string name="max_retry_desc">Maksimālais mēģinājumu skaits pirms lejupielādes atcelšanas</string>
<string name="max_retry_msg">Maksimālais atkārtoto mēģinājumu skaits</string> <string name="max_retry_msg">Maksimālais atkārtoto mēģinājumu skaits</string>
<string name="stop">Stop</string> <string name="stop">Stop</string>
<string name="delete_downloaded_files">Dzēst lejupielādētos failus</string> <string name="delete_downloaded_files">Dzēst lejupielādētās datnes</string>
<string name="confirm_prompt">Vai vēlaties notīrīt lejupielāžu vēsturi vai izdzēst visus lejupielādētos failus\?</string> <string name="confirm_prompt">Vai tiešām vēlaties dzēst lejupielāžu vēsturi un visas lejupielādētās datnes?</string>
<string name="clear_download_history">Notīrīt lejupielāžu vēsturi</string> <string name="clear_download_history">Notīrīt lejupielāžu vēsturi</string>
<string name="error_download_resource_gone">Nevar atgūt šo lejupielādi</string> <string name="error_download_resource_gone">Nevar atgūt šo lejupielādi</string>
<string name="error_timeout">Savienojums pārtraukts</string> <string name="error_timeout">Savienojums pārtraukts</string>
<string name="error_progress_lost">Progress zaudēts, jo fails tika izdzēsts</string> <string name="error_progress_lost">Progress zaudēts, jo datne tika dzēsta</string>
<string name="error_insufficient_storage_left">Ierīcē nav vietas</string> <string name="error_insufficient_storage_left">Ierīcē nav vietas</string>
<string name="error_postprocessing_stopped">Strādājot ar failu, NewPipe tika aizvērts</string> <string name="error_postprocessing_stopped">Strādājot ar failu, NewPipe tika aizvērts</string>
<string name="error_postprocessing_failed">Pēcapstrāde neizdevās</string> <string name="error_postprocessing_failed">Pēcapstrāde neizdevās</string>
<string name="error_http_not_found">Nav atrasts</string> <string name="error_http_not_found">Nav atrasts</string>
<string name="error_http_unsupported_range">Serveris nepieņem vairāku procesu lejupielādes, mēģiniet vēlreiz ar @ string / msg_threads = 1</string> <string name="error_http_unsupported_range">Serveris nepieņem daudzpavedienu lejupielādes, mēģiniet vēlreiz ar @string/msg_threads = 1</string>
<string name="error_http_no_content">Serveris nesūta datus</string> <string name="error_http_no_content">Serveris nesūta datus</string>
<string name="error_connect_host">Nevar izveidot savienojumu ar serveri</string> <string name="error_connect_host">Nevar izveidot savienojumu ar serveri</string>
<string name="error_unknown_host">Nevarēja atrast serveri</string> <string name="error_unknown_host">Nevarēja atrast serveri</string>
@@ -380,9 +369,9 @@
<string name="show_error">Rādīt kļūdu</string> <string name="show_error">Rādīt kļūdu</string>
<string name="download_already_pending">Ir gaidāma lejupielāde ar šo nosaukumu</string> <string name="download_already_pending">Ir gaidāma lejupielāde ar šo nosaukumu</string>
<string name="download_already_running">Notiek lejupielāde ar šo nosaukumu</string> <string name="download_already_running">Notiek lejupielāde ar šo nosaukumu</string>
<string name="overwrite_failed">nevar pārrakstīt failu</string> <string name="overwrite_failed">nevar pārrakstīt datni</string>
<string name="overwrite_finished_warning">Lejupielādēts fails ar šo nosaukumu jau pastāv</string> <string name="overwrite_finished_warning">Lejupielādētā datne ar šādu nosaukumu jau pastāv</string>
<string name="overwrite_unrelated_warning">Fails ar šo nosaukumu jau pastāv</string> <string name="overwrite_unrelated_warning">Datne ar šādu nosaukumu jau pastāv</string>
<string name="overwrite">Pārrakstīt</string> <string name="overwrite">Pārrakstīt</string>
<string name="generate_unique_name">Ģenerēt unikālu nosaukumu</string> <string name="generate_unique_name">Ģenerēt unikālu nosaukumu</string>
<string name="permission_denied">Darbību noraidīja sistēma</string> <string name="permission_denied">Darbību noraidīja sistēma</string>
@@ -394,11 +383,9 @@
<string name="minimize_on_exit_summary">Darbība, pārslēdzoties uz citu lietotni no galvenā video atskaņotāja — %s</string> <string name="minimize_on_exit_summary">Darbība, pārslēdzoties uz citu lietotni no galvenā video atskaņotāja — %s</string>
<string name="minimize_on_exit_title">Minimizēt, pārslēdzot aplikāciju</string> <string name="minimize_on_exit_title">Minimizēt, pārslēdzot aplikāciju</string>
<string name="playback_step">Solis</string> <string name="playback_step">Solis</string>
<string name="skip_silence_checkbox">Klusuma laikā patīt uz priekšu</string> <string name="skip_silence_checkbox">Klusuma brīžos patīt uz priekšu</string>
<string name="unhook_checkbox">Atvienot (var izraisīt traucējumus)</string> <string name="unhook_checkbox">Atvienot (var izraisīt traucējumus)</string>
<string name="import_network_expensive_warning">Paturiet prātā, ka šī darbība var pieprasīt lielu datu daudzumu <string name="import_network_expensive_warning">Paturiet prātā, ka šī darbība var pieprasīt lielu datu daudzumu\n\nVai vēlaties turpināt?</string>
\n
\nVai vēlaties turpināt\?</string>
<string name="drawer_close">Aizvērt Atvilkni</string> <string name="drawer_close">Aizvērt Atvilkni</string>
<string name="drawer_open">Atvērt Atvilkni</string> <string name="drawer_open">Atvērt Atvilkni</string>
<string name="most_liked">Vispopulārākais</string> <string name="most_liked">Vispopulārākais</string>
@@ -431,7 +418,7 @@
<string name="paused">Pausēts</string> <string name="paused">Pausēts</string>
<string name="missions_header_pending">Gaida</string> <string name="missions_header_pending">Gaida</string>
<string name="missions_header_finished">Pabeigts</string> <string name="missions_header_finished">Pabeigts</string>
<string name="app_update_available_notification_title">Ir pieejams Newpipe atjauninājums!</string> <string name="app_update_available_notification_title">Pieejama jauna NewPipe versija!</string>
<string name="auto">Automātiski</string> <string name="auto">Automātiski</string>
<string name="grid">Tīkls</string> <string name="grid">Tīkls</string>
<string name="list">Saraksts</string> <string name="list">Saraksts</string>
@@ -446,8 +433,7 @@
<string name="limit_data_usage_none_description">Nav ierobežojuma</string> <string name="limit_data_usage_none_description">Nav ierobežojuma</string>
<string name="decline">Nepiekrist</string> <string name="decline">Nepiekrist</string>
<string name="accept">Piekrist</string> <string name="accept">Piekrist</string>
<string name="start_accept_privacy_policy">Lai ievērotu Eiropas Vispārējās datu aizsardzības regulu (GDPR), mēs pievēršam jūsu uzmanību NewPipe privātuma politikai. Lūdzu, rūpīgi izlasiet to. <string name="start_accept_privacy_policy">Lai ievērotu Eiropas Vispārīgo datu aizsardzības regulu (GDPR), mēs vēršam jūsu uzmanību NewPipe konfidencialitātes politikai. Lūdzu, rūpīgi izlasiet to.\nJums tā ir jāpieņem, lai nosūtītu mums kļūdas ziņojumu.</string>
\nJums ir ta jāpieņem, lai nosūtītu mums kļūdas ziņojumu.</string>
<string name="playback_reset">Atiestatīt</string> <string name="playback_reset">Atiestatīt</string>
<string name="playback_pitch">Tonis</string> <string name="playback_pitch">Tonis</string>
<string name="playback_tempo">Temps</string> <string name="playback_tempo">Temps</string>
@@ -464,46 +450,46 @@
<string name="show_original_time_ago_title">Rādīt oriģinālo laiku uz lietām</string> <string name="show_original_time_ago_title">Rādīt oriģinālo laiku uz lietām</string>
<string name="show_memory_leaks">Rādīt atmiņas noplūdes</string> <string name="show_memory_leaks">Rādīt atmiņas noplūdes</string>
<string name="caption_setting_title">Subtitri</string> <string name="caption_setting_title">Subtitri</string>
<string name="caption_auto_generated">Automātiski radīti</string> <string name="caption_auto_generated">Automātiski izveidots</string>
<string name="resize_zoom">Pietuvināt</string> <string name="resize_zoom">Pietuvināt</string>
<string name="resize_fill">Piepildīt</string> <string name="resize_fill">Piepildīt</string>
<string name="resize_fit">Pielāgot</string> <string name="resize_fit">Pielāgot</string>
<string name="content_language_title">Noklusējuma satura valoda</string> <string name="content_language_title">Noklusējuma satura valoda</string>
<string name="default_content_country_title">Noklusējuma satura valsts</string> <string name="default_content_country_title">Noklusējuma satura valsts</string>
<string name="unsupported_url_dialog_message">Nevarēja atpazīt saites URL. Atvērt ar citu aplikāciju\?</string> <string name="unsupported_url_dialog_message">Nevarēja atpazīt saites URL. Vai atvērt citā lietotnē?</string>
<string name="unsupported_url">Neatbalstīts saites URL</string> <string name="unsupported_url">Neatbalstīts saites URL</string>
<string name="show_hold_to_append_summary">Rādīt padomu, kad nospiežat fona vai popup pogu pie video \"Informācija:\"</string> <string name="show_hold_to_append_summary">Rādīt padomu, kad nospiežat fona vai popup pogu pie video \"Informācija:\"</string>
<string name="show_hold_to_append_title">Rādīt \"Nospiediet, lai pievienotu\" padomu</string> <string name="show_hold_to_append_title">Rādīt \"Nospiediet, lai pievienotu\" padomu</string>
<string name="autoplay_title">Automātiski atskaņot</string> <string name="autoplay_title">Automātiski atskaņot</string>
<string name="download_dialog_title">Lejupielādēt</string> <string name="download_dialog_title">Lejupielādēt</string>
<string name="resume_on_audio_focus_gain_summary">Turpināt atskaņošanu pēc pārtraukumiem (piemēram, telefona zvana)</string> <string name="resume_on_audio_focus_gain_summary">Turpina atskaņot video pēc pārtraukumiem (piemēram, telefona zvana)</string>
<string name="resume_on_audio_focus_gain_title">Turpināt atskaņošanu</string> <string name="resume_on_audio_focus_gain_title">Turpināt atskaņošanu</string>
<string name="enable_watch_history_summary">Uzglabāt skatīto video vēsturi</string> <string name="enable_watch_history_summary">Uzglabā skatīto video vēsturi</string>
<string name="settings_category_clear_data_title">Dzēst datus</string> <string name="settings_category_clear_data_title">Notīrīt datus</string>
<string name="enable_playback_state_lists_summary">Rādīt atskaņošanas pozīcijas indikatoru sarakstos</string> <string name="enable_playback_state_lists_summary">Rāda atskaņošanas pozīcijas indikatoru sarakstos</string>
<string name="enable_playback_state_lists_title">Atskaņošanas pozīcija sarakstos</string> <string name="enable_playback_state_lists_title">Atskaņošanas pozīcija sarakstos</string>
<string name="enable_playback_resume_summary">Saglabāt pēdējo atskaņošanas pozīciju</string> <string name="enable_playback_resume_summary">Saglabāt pēdējo atskaņošanas pozīciju</string>
<string name="enable_playback_resume_title">Atsākt atskaņošanu</string> <string name="enable_playback_resume_title">Atsākt atskaņošanu</string>
<string name="enable_watch_history_title">Skatīšanās vēsture</string> <string name="enable_watch_history_title">Skatīšanās vēsture</string>
<string name="enable_search_history_summary">Glabāt meklēšanas vēsturi lokāli (ierīces krātuvē)</string> <string name="enable_search_history_summary">Glabāt meklēšanas vēsturi lokāli (ierīces krātuvē)</string>
<string name="enable_search_history_title">Meklēšanas vēsture</string> <string name="enable_search_history_title">Meklēšanas vēsture</string>
<string name="show_search_suggestions_summary">Izvēlieties, kādus ieteikumus rādīt, rakstot meklēšanas joslā</string> <string name="show_search_suggestions_summary">Atlasīt, kādus ieteikumus rādīt, ievadot vaicājumu meklēšanas joslā</string>
<string name="show_search_suggestions_title">Meklēšanas ieteikumi</string> <string name="show_search_suggestions_title">Meklēšanas ieteikumi</string>
<string name="auto_queue_toggle">Automātiski atskaņot</string> <string name="auto_queue_toggle">Automātiski pievienot</string>
<string name="auto_queue_summary">Turpināt atskaņot videoklipus, automātiski pievienojot līdzīgus videoklipus</string> <string name="auto_queue_summary">Pievieno līdzīgus video atskaņošanas rindai, kad atskaņo pēdējo video, ja vien nav iespējota atkārtotā, malt uz riņķi, atskaņošana</string>
<string name="auto_queue_title">Automātiski atskaņot nāko videoklipu</string> <string name="auto_queue_title">Automātiski pievienot nākamo video</string>
<string name="metadata_cache_wipe_complete_notice">Kešatmiņas metadati notīrīti</string> <string name="metadata_cache_wipe_complete_notice">Metadatu kešatmiņa notīrīta</string>
<string name="metadata_cache_wipe_summary">Izdzēš visus kešatmiņā glabātos vietnes datus</string> <string name="metadata_cache_wipe_summary">Izdzēš visus kešatmiņā glabātos vietnes datus</string>
<string name="metadata_cache_wipe_title">Notīrīt kešatmiņas metadatus</string> <string name="metadata_cache_wipe_title">Notīrīt kešatmiņā saglabātos metadatus</string>
<string name="thumbnail_cache_wipe_complete_notice">Attēlu kešatmiņa notīrīta</string> <string name="thumbnail_cache_wipe_complete_notice">Attēlu kešatmiņa notīrīta</string>
<string name="show_meta_info_summary">Izslēdziet, lai paslēptu papildus informācijas laukus par video autoru, video saturu vai meklēšanas vaicājuma rezultātu</string> <string name="show_meta_info_summary">Izslēdziet, ja nevēlaties redzēt papildus informācijas laukus - video autoru, video saturu vai meklēšanas vaicājuma rezultātu</string>
<string name="show_meta_info_title">Rādīt papildus informāciju</string> <string name="show_meta_info_title">Rādīt papildus informāciju</string>
<string name="show_description_summary">Izslēdziet, ja nevēlaties redzēt video aprakstu un papildus informāciju</string> <string name="show_description_summary">Izslēdziet, ja nevēlaties redzēt video aprakstu un papildus informāciju</string>
<string name="show_description_title">Rādīt video aprakstu</string> <string name="show_description_title">Rādīt video aprakstu</string>
<string name="show_next_and_similar_title">Rādīt \'Nākos\' un \'Līdzīgos\' videoklipus</string> <string name="show_next_and_similar_title">Rādīt \'Nākamos\' un \'Līdzīgos\' video</string>
<string name="show_comments_summary">Izslēdziet, lai paslēptu komentārus</string> <string name="show_comments_summary">Izslēdziet, ja vēlaties paslēpt komentārus</string>
<string name="show_comments_title">Rādīt komentārus</string> <string name="show_comments_title">Rādīt komentārus</string>
<string name="clear_queue_confirmation_description">Tagadējā atskaņošanas rinda tiks aizvietota</string> <string name="clear_queue_confirmation_description">Pašreizējā atskaņošanas rinda tiks aizstāta/pārrakstīta</string>
<string name="clear_queue_confirmation_summary">Mainot vienu atskaņotāju uz citu, jūsu atskaņošanas rinda var tikt aizstāta/pārrakstīta</string> <string name="clear_queue_confirmation_summary">Mainot vienu atskaņotāju uz citu, jūsu atskaņošanas rinda var tikt aizstāta/pārrakstīta</string>
<string name="clear_queue_confirmation_title">Prasīt apstiprinājumu, pirms notīrīt atskaņošanas rindu</string> <string name="clear_queue_confirmation_title">Prasīt apstiprinājumu, pirms notīrīt atskaņošanas rindu</string>
<string name="seek_duration_title">Ātrās uz priekšu/atpakaļ tīšanas solis</string> <string name="seek_duration_title">Ātrās uz priekšu/atpakaļ tīšanas solis</string>
@@ -516,61 +502,61 @@
<string name="default_video_format_title">Noklusējuma video formāts</string> <string name="default_video_format_title">Noklusējuma video formāts</string>
<string name="default_audio_format_title">Noklusējuma audio formāts</string> <string name="default_audio_format_title">Noklusējuma audio formāts</string>
<string name="play_audio">Audio</string> <string name="play_audio">Audio</string>
<string name="notification_colorize_summary">Ļaut Android pielāgot paziņojuma krāsu atbilstoši galvenajai krāsai video attēlā (ņemiet vērā, ka tas nav pieejams visās ierīcēs)</string> <string name="notification_colorize_summary">Ļauj Android pielāgot paziņojuma krāsu atbilstoši galvenajai krāsai video attēlā (ņemiet vērā, ka tas nav pieejams visās ierīcēs)</string>
<string name="share">Kopīgot</string> <string name="share">Kopīgot</string>
<string name="open_with">Atvērt ar</string> <string name="open_with">Atvērt ar</string>
<string name="open_in_browser">Atvērt pārlūkā</string> <string name="open_in_browser">Atvērt pārlūkā</string>
<string name="cancel">Atcelt</string> <string name="cancel">Atcelt</string>
<string name="install">Uzstādīt</string> <string name="install">Uzstādīt</string>
<string name="no_player_found_toast">Netika atrasts video atskaņotājs (jūs variet uzstādīt VLC, lai to atskaņotu).</string> <string name="no_player_found_toast">Netika atrasts video atskaņotājs (jūs variet uzstādīt VLC, lai to atskaņotu).</string>
<string name="no_player_found">Netika atrasts video atskaņotājs. Uzstādīt VLC?</string> <string name="no_player_found">Netika atrasts video atskaņotājs. Vai uzstādīt VLC?</string>
<string name="upload_date_text">Publicēts %1$s</string> <string name="upload_date_text">Publicēts %1$s</string>
<string name="main_bg_subtitle">Nospiediet uz meklēšanas ikonas, lai sāktu.</string> <string name="main_bg_subtitle">Nospiediet uz meklēšanas ikonas, lai atrastu vēlamo saturu.</string>
<string name="notification_colorize_title">Pielāgot paziņojumu krāsu</string> <string name="notification_colorize_title">Pielāgot paziņojumu krāsu</string>
<string name="notification_action_nothing">Nekas</string> <string name="notification_action_nothing">Neko</string>
<string name="notification_action_buffering">Ielādējas</string> <string name="notification_action_buffering">Ielādējas</string>
<string name="notification_action_shuffle">Sajaukt</string> <string name="notification_action_shuffle">Sajaukt</string>
<string name="notification_action_repeat">Atkārtot</string> <string name="notification_action_repeat">Atkārtot</string>
<string name="notification_actions_at_most_three">Jūs varat izvēlēties ne vairāk kā 3 darbības, kuras rādīs kompaktajā paziņojumā!</string> <string name="notification_actions_at_most_three">Jūs variet atlasīt ne vairāk kā 3 darbības, ko rādīt kompaktajā paziņojumā!</string>
<string name="notification_actions_summary">Rediģējiet katru paziņojuma darbību, pieskaroties tai. Izvēlieties trīs darbības, kuras rādīs kompaktā paziņojumā, izmantojot rūtiņas labajā pusē.</string> <string name="notification_actions_summary">Rediģējiet katru zemāk redzamo paziņojuma darbību, pieskaroties tai. Atķeksējiet izvēles rūtiņas labajā pusē, lai atlasītu līdz pat trīm darbībām, kuras rādīt kompaktajā paziņojumā.</string>
<string name="notification_action_4_title">Piektā darbības poga</string> <string name="notification_action_4_title">Piektā darbības poga</string>
<string name="notification_action_3_title">Ceturtā darbības poga</string> <string name="notification_action_3_title">Ceturtā darbības poga</string>
<string name="notification_action_2_title">Trešā darbības poga</string> <string name="notification_action_2_title">Trešā darbības poga</string>
<string name="notification_action_1_title">Otrā darbības poga</string> <string name="notification_action_1_title">Otrā darbības poga</string>
<string name="notification_action_0_title">Pirmā darbības poga</string> <string name="notification_action_0_title">Pirmā darbības poga</string>
<string name="notification_scale_to_square_image_summary">Apgriezt video attēlu, kuru rāda paziņojumā, no 16:9 uz 1:1 proporciju (iespējams, attēls būs izstiepts)</string> <string name="notification_scale_to_square_image_summary">Apgriež paziņojumā redzamo video sīkattēlu no 16:9 uz 1:1 malu attiecību (iespējams, attēls būs izstiepts)</string>
<string name="notification_scale_to_square_image_title">Apgriezt video attēlu uz 1:1 proporciju</string> <string name="notification_scale_to_square_image_title">Apgriezt video sīkattēlu uz 1:1 malu attiecību</string>
<string name="show_play_with_kodi_summary">Rādīt opciju atskaņot video ar Kodi mediju centru</string> <string name="show_play_with_kodi_summary">Rādīt opciju atskaņot video Kodi mediju centrā</string>
<string name="show_play_with_kodi_title">Rādīt \"Atskaņot ar Kodi\" opciju</string> <string name="show_play_with_kodi_title">Rādīt \"Atskaņot Kodi\" opciju</string>
<string name="kore_not_found">Uzstādīt trūkstošo Kore lietotni?</string> <string name="kore_not_found">Uzstādīt trūkstošo Kore, tālvadības pults, lietotni?</string>
<string name="play_with_kodi_title">Atskaņot ar Kodi</string> <string name="play_with_kodi_title">Atskaņot Kodi</string>
<string name="show_higher_resolutions_summary">Tikai dažas ierīcas var atskaņot 2K/4K videoklipus</string> <string name="show_higher_resolutions_summary">Ne visas ierīcas var atskaņot 2K/4K izšķirtspējas video</string>
<string name="show_higher_resolutions_title">Rādīt augstākas izšķirtspējas</string> <string name="show_higher_resolutions_title">Rādīt augstākas izšķirtspējas</string>
<string name="default_resolution_title">Noklusējuma izšķirtspēja</string> <string name="default_resolution_title">Noklusējuma izšķirtspēja</string>
<string name="download_path_audio_dialog_title">Izvēlieties lejupielādes mapi priekš audio failiem</string> <string name="download_path_audio_dialog_title">Atlasīt lejupielādes mapi, kur glabāt audio datnes</string>
<string name="download_path_audio_summary">Lejupielādētie audio faili tiek glabāti šeit</string> <string name="download_path_audio_summary">Lejupielādētās audio datnes tiek glabātas šeit</string>
<string name="download_path_audio_title">Audio lejupielādes mape</string> <string name="download_path_audio_title">Audio lejupielādes mape</string>
<string name="download_path_dialog_title">Izvēlaties lejupielādes mapi priekš video failiem</string> <string name="download_path_dialog_title">Atlasīt lejupielādes mapi, kur glabāt video datnes</string>
<string name="download_path_summary">Lejupielādētās video datnes tiek glabātas šeit</string> <string name="download_path_summary">Lejupielādētās video datnes tiek glabātas šeit</string>
<string name="download_path_title">Video lejupielādes mape</string> <string name="download_path_title">Video lejupielādes mape</string>
<string name="controls_add_to_playlist_title">Pievienot</string> <string name="controls_add_to_playlist_title">Pievienot</string>
<string name="controls_background_title">Klausīties fonā</string> <string name="controls_background_title">Klausīt fonā</string>
<string name="tab_choose">Atlasiet cilni</string> <string name="tab_choose">Atlasiet cilni</string>
<string name="tab_bookmarks">Saglabātie saraksti</string> <string name="tab_bookmarks">Saglabātie saraksti</string>
<string name="tab_subscriptions">Abonementi</string> <string name="tab_subscriptions">Abonementi</string>
<string name="show_info">Rādīt informāciju</string> <string name="show_info">Rādīt informāciju</string>
<string name="subscription_update_failed">Abonementu nevarēja atjaunināt</string> <string name="subscription_update_failed">Abonementu nevarēja atjaunināt</string>
<string name="subscription_change_failed">Nevarēja mainīt abonementu</string> <string name="subscription_change_failed">Abonementu nevarēja mainīt</string>
<string name="channel_unsubscribed">Atcelts kanāla abonements</string> <string name="channel_unsubscribed">Atcelts kanāla abonements</string>
<string name="unsubscribe">Atcelt abonementu</string> <string name="unsubscribe">Atcelt abonementu</string>
<string name="subscribed_button_title">Abonēts</string> <string name="subscribed_button_title">Abonēts</string>
<string name="subscribe_button_title">Abonēt</string> <string name="subscribe_button_title">Abonēt</string>
<string name="use_external_audio_player_title">Izmantot ārējo audio atskaņotāju</string> <string name="use_external_audio_player_title">Izmantot ārējo audio atskaņotāju</string>
<string name="use_external_video_player_summary">Noņem skaņu dažās izšķirtspējās</string> <string name="use_external_video_player_summary">Dažās izšķirtspējās nav pieejami skaņas celiņi</string>
<string name="use_external_video_player_title">Izmantot ārējo video atskaņotāju</string> <string name="use_external_video_player_title">Izmantot ārējo video atskaņotāju</string>
<string name="share_dialog_title">Kopīgot ar</string> <string name="share_dialog_title">Kopīgot ar</string>
<string name="search_showing_result_for">Tiek rādīti %s rezultāti</string> <string name="search_showing_result_for">Tiek rādīti %s vaicājuma rezultāti</string>
<string name="did_you_mean">Vai jūs domājāt \"%1$s\"\?</string> <string name="did_you_mean">Varbūt jūs gribējāt meklēt \"%1$s\"?</string>
<string name="settings">Iestatījumi</string> <string name="settings">Iestatījumi</string>
<string name="search">Meklēt</string> <string name="search">Meklēt</string>
<string name="controls_download_desc">Lejupielādēt video datni</string> <string name="controls_download_desc">Lejupielādēt video datni</string>
@@ -600,7 +586,7 @@
<string name="metadata_language">Valoda</string> <string name="metadata_language">Valoda</string>
<string name="metadata_age_limit">Vecuma ierobežojums</string> <string name="metadata_age_limit">Vecuma ierobežojums</string>
<string name="metadata_licence">License</string> <string name="metadata_licence">License</string>
<string name="metadata_tags">Tagi</string> <string name="metadata_tags">Birkas</string>
<string name="metadata_category">Kategorija</string> <string name="metadata_category">Kategorija</string>
<string name="downloads_storage_ask_summary_no_saf_notice">Jums tiks jautāts, kur saglabāt katru lejupielādi</string> <string name="downloads_storage_ask_summary_no_saf_notice">Jums tiks jautāts, kur saglabāt katru lejupielādi</string>
<string name="dont_show">Nerādīt</string> <string name="dont_show">Nerādīt</string>
@@ -613,18 +599,18 @@
<string name="disable_media_tunneling_title">Izslēgt multivides tuneļošanu</string> <string name="disable_media_tunneling_title">Izslēgt multivides tuneļošanu</string>
<string name="disable_media_tunneling_summary">Izslēdziet multivides tuneļošanu, ja jums video atskaņošanas laikā parādās melns ekrāns vai aizķeršanās.</string> <string name="disable_media_tunneling_summary">Izslēdziet multivides tuneļošanu, ja jums video atskaņošanas laikā parādās melns ekrāns vai aizķeršanās.</string>
<string name="description_select_enable">Ieslēgt teksta atlasīšanu video aprakstā</string> <string name="description_select_enable">Ieslēgt teksta atlasīšanu video aprakstā</string>
<string name="no_dir_yet">Lejupielādes mape vēl nav iestatīta, izvēlieties noklusējuma lejupielādes mapi</string> <string name="no_dir_yet">Lejupielādes mape vēl nav iestatīta, atlasiet noklusējuma lejupielādes mapi tagad</string>
<string name="main_page_content_swipe_remove">Pavelciet atlasīto elementu pa kreisi vai labi, lai to aizvāktu</string> <string name="main_page_content_swipe_remove">Pavelciet atlasīto elementu pa kreisi vai labi, lai to aizvāktu</string>
<string name="local_search_suggestions">Lokālie meklēšanas ieteikumi</string> <string name="local_search_suggestions">Lokālos meklēšanas ieteikumus</string>
<string name="high_quality_larger">Augstas kvalitātes (lielāks)</string> <string name="high_quality_larger">Augstas kvalitātes (lielāks)</string>
<string name="check_for_updates">Pārbaudīt atjauninājumus</string> <string name="check_for_updates">Pārbaudīt atjauninājumus</string>
<string name="manual_update_description">Pašrocīgi pārbaudīt jaunas versijas pieejamību</string> <string name="manual_update_description">Pašrocīgi veikt jaunas versijas pārbaudi</string>
<string name="seekbar_preview_thumbnail_title">Video atskaņošanas joslas sīktēla priekšskatījums</string> <string name="seekbar_preview_thumbnail_title">Video atskaņošanas joslas sīktēla priekšskatījums</string>
<string name="checking_updates_toast">Pārbauda, vai ir atjauninājumi</string> <string name="checking_updates_toast">Notiek atjauninājumu pārbaude</string>
<string name="downloads_storage_use_saf_summary_api_29">Sākot ar Android 10, tikai“Krātuves Piekļuves Sistēma” ir atbalstīta</string> <string name="downloads_storage_use_saf_summary_api_29">Sākot ar Android 10, tikai“Krātuves Piekļuves Sistēma” ir atbalstīta</string>
<string name="feed_load_error_account_info">Nevarēja ielādēt straumi priekš \'%s\'.</string> <string name="feed_load_error_account_info">Nevarēja ielādēt straumi priekš \'%s\'.</string>
<string name="feed_load_error">Kļūda lādējot plūsmu</string> <string name="feed_load_error">Kļūda lādējot plūsmu</string>
<string name="feed_load_error_terminated">Autora konts tika slēgts.\nNewPipe turpmāk vairs nevarēs ielādēt šī kanāla plūsmas saturu.\nVai tiešām atteikties no šī kanāla abonēšanas?</string> <string name="feed_load_error_terminated">Autora konts tika slēgts.\nNewPipe turpmāk vairs nevarēs ielādēt šī kanāla saturu.\nVai tiešām vēlaties atteikties no šī kanāla abonēšanas?</string>
<string name="feed_load_error_fast_unknown">Ātrās straumes režīms nesniedz vairāk informācijas par šo.</string> <string name="feed_load_error_fast_unknown">Ātrās straumes režīms nesniedz vairāk informācijas par šo.</string>
<string name="description_select_disable">Izslēgt teksta atlasīšanu video aprakstā</string> <string name="description_select_disable">Izslēgt teksta atlasīšanu video aprakstā</string>
<string name="metadata_privacy_internal">Iekšeji</string> <string name="metadata_privacy_internal">Iekšeji</string>
@@ -635,20 +621,20 @@
<string name="metadata_privacy">Privātums</string> <string name="metadata_privacy">Privātums</string>
<string name="metadata_privacy_unlisted">Sarakstā neiekļauts</string> <string name="metadata_privacy_unlisted">Sarakstā neiekļauts</string>
<string name="metadata_host">Uzņēmums</string> <string name="metadata_host">Uzņēmums</string>
<string name="remote_search_suggestions">Servera meklēšanas ieteikumi</string> <string name="remote_search_suggestions">Servera meklēšanas ieteikumus</string>
<string name="mark_as_watched">Atzīmēt kā noskatītu</string> <string name="mark_as_watched">Atzīmēt kā noskatītu</string>
<string name="processing_may_take_a_moment">Apstrādā... Var aizņemt kādu laiku</string> <string name="processing_may_take_a_moment">Apstrādā... Var aizņemt kādu laiku</string>
<plurals name="deleted_downloads_toast"> <plurals name="deleted_downloads_toast">
<item quantity="zero">Izdzēsa %1$s lejupielāžu</item> <item quantity="zero">Dzēstas %1$s lejupielādes</item>
<item quantity="one">Izdzēsa %1$s lejupielādi</item> <item quantity="one">Dzēsta %1$s lejupielāde</item>
<item quantity="other">Izdzēsa %1$s lejupielādes</item> <item quantity="other">Dzēstas %1$s lejupielādes</item>
</plurals> </plurals>
<plurals name="download_finished_notification"> <plurals name="download_finished_notification">
<item quantity="zero">%s lejupielādes pabeigtas</item> <item quantity="zero">%s lejupielādes pabeigtas</item>
<item quantity="one">%s lejupielāde pabeigta</item> <item quantity="one">%s lejupielāde pabeigta</item>
<item quantity="other">%s lejupielādes pabeigtas</item> <item quantity="other">%s lejupielādes pabeigtas</item>
</plurals> </plurals>
<string name="description_select_note">Tagad varat atlasīt tekstu video aprakstā.</string> <string name="description_select_note">Tagad variet atlasīt tekstu video aprakstā.</string>
<string name="notifications">Paziņojumi</string> <string name="notifications">Paziņojumi</string>
<string name="crash_the_player">Avarēt atskaņotāju</string> <string name="crash_the_player">Avarēt atskaņotāju</string>
<string name="settings_category_player_notification_summary">Pielāgojiet pašlaik atskaņotās plūsmas paziņojumu</string> <string name="settings_category_player_notification_summary">Pielāgojiet pašlaik atskaņotās plūsmas paziņojumu</string>
@@ -660,13 +646,13 @@
<item quantity="one">%s jauna tiešraide</item> <item quantity="one">%s jauna tiešraide</item>
<item quantity="other">%s jaunas tiešraides</item> <item quantity="other">%s jaunas tiešraides</item>
</plurals> </plurals>
<string name="streams_notification_channel_description">Paziņojumi par jaunām tiešraidēm abonementos</string> <string name="streams_notification_channel_description">\@string/enable_streams_notifications_summary</string>
<string name="faq_title">Bieži uzdotie jautājumi</string> <string name="faq_title">Bieži uzdotie jautājumi</string>
<string name="error_report_channel_description">Paziņojumi, lai ziņotu par kļūdām</string> <string name="error_report_channel_description">Paziņojumi, lai ziņotu par kļūdām</string>
<string name="error_report_channel_name">Kļūdas ziņojuma paziņojums</string> <string name="error_report_channel_name">Kļūdas ziņojuma paziņojums</string>
<string name="progressive_load_interval_title">Atskaņošanas ielādes intervāla lielums</string> <string name="progressive_load_interval_title">Atskaņošanas ielādes intervāla lielums</string>
<string name="error_report_notification_title">NewPipe radās kļūdu, pieskarieties, lai ziņotu</string> <string name="error_report_notification_title">NewPipe radās kļūdu, pieskarieties, lai ziņotu</string>
<string name="left_gesture_control_title">Kreisā žesta darbība</string> <string name="left_gesture_control_title">Kreisās puses žesta darbība</string>
<string name="msg_failed_to_copy">Neizdevās kopēt starpliktuvē</string> <string name="msg_failed_to_copy">Neizdevās kopēt starpliktuvē</string>
<string name="unset_playlist_thumbnail">Noņemt pastāvīgo sīktēlu</string> <string name="unset_playlist_thumbnail">Noņemt pastāvīgo sīktēlu</string>
<string name="check_new_streams">Pārbaudīt, vai nav jaunas tiešraides</string> <string name="check_new_streams">Pārbaudīt, vai nav jaunas tiešraides</string>
@@ -677,21 +663,21 @@
<string name="leak_canary_not_available">LeakCanary nav pieejams</string> <string name="leak_canary_not_available">LeakCanary nav pieejams</string>
<string name="create_error_notification">Izveidot kļūdas paziņojumu</string> <string name="create_error_notification">Izveidot kļūdas paziņojumu</string>
<string name="any_network">Jebkurš tīkls</string> <string name="any_network">Jebkurš tīkls</string>
<string name="app_update_unavailable_toast">Jums ir jaunākā NewPipe versija</string> <string name="app_update_unavailable_toast">Jūs jau izmantojiet jaunāko NewPipe versiju</string>
<string name="ignore_hardware_media_buttons_summary">Noderīgi, piemēram, lietojot austiņas ar bojātām pogām</string> <string name="ignore_hardware_media_buttons_summary">Noder, piemēram, kad lietojiet austiņas ar bojātām pogām</string>
<string name="prefer_descriptive_audio_summary">Atskaņos skaņu celiņu ar audio aprakstiem vājredzīgajiem, ja tāds ir pieejams</string> <string name="prefer_descriptive_audio_summary">Atskaņos skaņas celiņu ar audio aprakstiem vājredzīgajiem, ja tāds ir pieejams</string>
<string name="ignore_hardware_media_buttons_title">Ignorēt ierīces multimēdiju pogas</string> <string name="ignore_hardware_media_buttons_title">Ignorēt pieslēgtās ierīces multimēdiju pogas</string>
<string name="delete_downloaded_files_confirm">Izdzēst visus lejupielādētos failus\?</string> <string name="delete_downloaded_files_confirm">Vai tiešām vēlaties dzēst visas lejupielādētās datnes?</string>
<string name="feed_new_items">Jaunumi kanālā</string> <string name="feed_new_items">Jaunumi kanālā</string>
<string name="prefer_original_audio_title">Dot priekšroku oriģinālajai skaņai</string> <string name="prefer_original_audio_title">Dot priekšroku oriģinālajai skaņai</string>
<string name="prefer_original_audio_summary">Atskaņos oriģinālo skaņu celiņu neatkarīgi no valodas</string> <string name="prefer_original_audio_summary">Atskaņos oriģinālo skaņas celiņu neatkarīgi no iestatītās valodas</string>
<string name="prefer_descriptive_audio_title">Dot priekšroku skaņu celiņam ar audio aprakstu</string> <string name="prefer_descriptive_audio_title">Dot priekšroku skaņu celiņam ar audio aprakstu</string>
<string name="left_gesture_control_summary">Izvēlēties žestu kreisajai atskaņotāja ekrāna pusei</string> <string name="left_gesture_control_summary">Atlasiet žestu atskaņotāja ekrāna kreisajai pusei</string>
<string name="right_gesture_control_summary">Izvēlēties žestu labajai atskaņotāja ekrāna pusei</string> <string name="right_gesture_control_summary">Atlasiet žestu atskaņotāja ekrāna labajai pusei</string>
<string name="right_gesture_control_title">Labējā žesta darbība</string> <string name="right_gesture_control_title">Labās puses žesta darbība</string>
<string name="brightness">Spilgtums</string> <string name="brightness">Regulēt spilgtumu</string>
<string name="volume">Skaļums</string> <string name="volume">Regulēt skaļumu</string>
<string name="none">Nekā</string> <string name="none">Darīt neko</string>
<string name="import_subscriptions_hint">Abonementus var ievietot vai izgūt, izmantojot 3-punktoto izvēlni augšējā labajā ekrāna stūrī</string> <string name="import_subscriptions_hint">Abonementus var ievietot vai izgūt, izmantojot 3-punktoto izvēlni augšējā labajā ekrāna stūrī</string>
<string name="faq_description">Ja Jums rodas problēmas ar lietotni, noteikti apskatiet šīs atbildes bieži uzdotiem jautājumiem!</string> <string name="faq_description">Ja Jums rodas problēmas ar lietotni, noteikti apskatiet šīs atbildes bieži uzdotiem jautājumiem!</string>
<string name="faq">Skatīt tīkla vietnē</string> <string name="faq">Skatīt tīkla vietnē</string>
@@ -701,18 +687,18 @@
<string name="playlist_add_stream_success_duplicate">Dublikāts pievienots %d reizi(-es)</string> <string name="playlist_add_stream_success_duplicate">Dublikāts pievienots %d reizi(-es)</string>
<string name="show_crash_the_player_title">Rādīt \"avarēt atskaņotāju\"</string> <string name="show_crash_the_player_title">Rādīt \"avarēt atskaņotāju\"</string>
<string name="card">Karte</string> <string name="card">Karte</string>
<string name="app_update_available_notification_text">Spiediet, lai lejupielādētu %s</string> <string name="app_update_available_notification_text">Nospiediet, lai lejupielādētu %s</string>
<string name="remove_duplicates_title">Dzēst dublikātus\?</string> <string name="remove_duplicates_title">Vai tiešām vēlaties dzēst dublikātus?</string>
<string name="remove_duplicates_message">Vai vēlaties dzēst visus tiešraižu dublikātus šajā sarakstā\?</string> <string name="remove_duplicates_message">Vai tiešām vēlaties noņemt visus dublētos vienumus šajā atskaņošanas sarakstā?</string>
<string name="feed_show_hide_streams">Rādīt/slēpt tiešraides</string> <string name="feed_show_hide_streams">Rādīt/slēpt tiešraides</string>
<string name="fast_mode">Ātrais režīms</string> <string name="fast_mode">Ātrais režīms</string>
<string name="enable_streams_notifications_summary">Paziņot par jaunām tiešraidēm no abonementiem</string> <string name="enable_streams_notifications_summary">Informē, ja pieejami jauni video / audio abonementos</string>
<string name="percent">Procenti</string> <string name="percent">Procenti</string>
<string name="semitone">Pustonis</string> <string name="semitone">Pustonis</string>
<string name="enable_streams_notifications_title">Paziņojumi par jaunām tiešraidēm</string> <string name="enable_streams_notifications_title">Paziņot par jauniem video / audio</string>
<string name="streams_notifications_interval_title">Pārbaužu biežums</string> <string name="streams_notifications_interval_title">Pārbaužu biežums</string>
<string name="main_tabs_position_summary">Galvenās cilnes atlasītāja pārvietošana uz apakšu</string> <string name="main_tabs_position_summary">Galvenās cilnes atlasītāja pārvietošana uz apakšu</string>
<string name="notification_actions_summary_android13">Rediģējiet katru turpmāk norādīto paziņojuma darbību, pieskaroties tai. Pirmās trīs darbības (atskaņošana/pauze, iepriekšējais un nākamais) ir iestatītas sistēmā, un tās nevar pielāgot.</string> <string name="notification_actions_summary_android13">Rediģējiet katru zemāk redzamo paziņojuma darbību, pieskaroties tai. Pirmās trīs darbības (atskaņot/pauze, iepriekšējais un nākamais) ir sistēmas iestatītas, un tās nevar pielāgot.</string>
<string name="progressive_load_interval_summary">Mainīt progresīvā satura ielādes intervāla lielumu (pašlaik %s). Mazāka vērtība var paātrināt to sākotnējo ielādi</string> <string name="progressive_load_interval_summary">Mainīt progresīvā satura ielādes intervāla lielumu (pašlaik %s). Mazāka vērtība var paātrināt to sākotnējo ielādi</string>
<string name="yes"></string> <string name="yes"></string>
<string name="no"></string> <string name="no"></string>
@@ -726,16 +712,14 @@
<string name="channel_tab_about">Par</string> <string name="channel_tab_about">Par</string>
<string name="metadata_thumbnails">Sīkattēli</string> <string name="metadata_thumbnails">Sīkattēli</string>
<string name="sort">Kārtot</string> <string name="sort">Kārtot</string>
<string name="auto_update_check_description">NewPipe var pati automātiski pārbaudīt jaunas versijas pieejamību laiku pa laikam un informēt jūs, kad tā ir pieejama.\nVai jūs tiešām gribiet ieslēgt šo funkciju?</string> <string name="auto_update_check_description">NewPipe pati var veikt jaunas versijas pārbaudi laiku pa laikam un informēt jūs, kad tā ir pieejama.\nVai tiešām vēlaties ieslēgt šo funkciju?</string>
<string name="no_appropriate_file_manager_message">Netika atrasts atbilstošs failu pārvaldnieks šai darbībai. <string name="no_appropriate_file_manager_message">Netika atrasts atbilstošs failu pārvaldnieks šai darbībai.
\nLūdzu instalējiet failu pārvaldnieku vai pamēģiniet atspējot \'%s\' lejuplādēšanas iestatījumos</string> \nLūdzu instalējiet failu pārvaldnieku vai pamēģiniet atspējot \'%s\' lejuplādēšanas iestatījumos</string>
<string name="audio_track_type_original">oriģinālais</string> <string name="audio_track_type_original">oriģinālais</string>
<string name="streams_notifications_network_title">Nepieciešams tīkla savienojums</string> <string name="streams_notifications_network_title">Nepieciešams tīkla savienojums</string>
<string name="reset_settings_summary">Atiestatīt visus iestatījumus uz to sākotnējām vērtībām</string> <string name="reset_settings_summary">Atiestata visus iestatījumus uz to sākotnējām vērtībām</string>
<string name="reset_settings_title">Atiestatīt iestatījumus</string> <string name="reset_settings_title">Atiestatīt iestatījumus</string>
<string name="reset_all_settings">Visu iestatījumu atiestatošana atmetīs visus jūsu izvēlētos iestatījumus un restartēs aplikāciju. <string name="reset_all_settings">Atiestatot iestatījumus, visi jūsu iestatītie iestatījumi tiks atmesti uz to noklusētajām vērtībām un lietotne palaista pa jaunu.\n\nVai tiešām vēlaties turpināt?</string>
\n
\nVai jūs esat droši, ka vēlaties turpināt?</string>
<string name="night_theme_available">Šī opcija ir pieejama tikai, ja %s ir izvēlēts kā motīvs</string> <string name="night_theme_available">Šī opcija ir pieejama tikai, ja %s ir izvēlēts kā motīvs</string>
<string name="detail_pinned_comment_view_description">Piespraustais komentārs</string> <string name="detail_pinned_comment_view_description">Piespraustais komentārs</string>
<string name="notifications_disabled">Paziņojumi ir atspējoti</string> <string name="notifications_disabled">Paziņojumi ir atspējoti</string>
@@ -760,7 +744,7 @@
<string name="show_error_snackbar">Rādīt kļūdas paziņojumu</string> <string name="show_error_snackbar">Rādīt kļūdas paziņojumu</string>
<string name="feed_fetch_channel_tabs">Piegādāt kanālu cilnes</string> <string name="feed_fetch_channel_tabs">Piegādāt kanālu cilnes</string>
<string name="feed_fetch_channel_tabs_summary">Cilnes, kuras piegādāt, atjaunojot jauninājumus. Šai opcijai nav nekādas iedarbības, ja kanāls tiek atjaunots ātrajā režīmā.</string> <string name="feed_fetch_channel_tabs_summary">Cilnes, kuras piegādāt, atjaunojot jauninājumus. Šai opcijai nav nekādas iedarbības, ja kanāls tiek atjaunots ātrajā režīmā.</string>
<string name="disable_media_tunneling_automatic_info">Multivides tuneļošana tika atspēkota pēc noklusējuma tādēļ, ka ir zināms, ka jūsu ierīces modelis to neatbalsta.</string> <string name="disable_media_tunneling_automatic_info">Multivides tunešana tika atspējota pēc noklusējuma tādēļ, ka ir zināms, ka jūsu ierīces modelis to neatbalsta.</string>
<string name="select_quality_external_players">Izvēlēties kvalitāti ārējiem atskaņotājiem</string> <string name="select_quality_external_players">Izvēlēties kvalitāti ārējiem atskaņotājiem</string>
<string name="settings_category_exoplayer_title">ExoPlayer iestatījumi</string> <string name="settings_category_exoplayer_title">ExoPlayer iestatījumi</string>
<string name="show_channel_tabs">Kanālu cilnes</string> <string name="show_channel_tabs">Kanālu cilnes</string>
@@ -771,8 +755,8 @@
<string name="metadata_subchannel_avatars">Apakškanālu avatāri</string> <string name="metadata_subchannel_avatars">Apakškanālu avatāri</string>
<string name="metadata_uploader_avatars">Augšuplādētāju avatāri</string> <string name="metadata_uploader_avatars">Augšuplādētāju avatāri</string>
<string name="duration">Ilgums</string> <string name="duration">Ilgums</string>
<string name="rewind">Attīt</string> <string name="rewind">Attīt - tīt atpakaļ</string>
<string name="forward">Patīt</string> <string name="forward">Tīt uz priekšu</string>
<string name="image_quality_summary">Izvēlēties attēlu kvalitāti un vai vispār ielādēt attēlus, lai samazinātu datu un atmiņas lietojumu. Izmaiņas iztīra iekšējās atmiņas un diska attēlu kešatmiņu — %s</string> <string name="image_quality_summary">Izvēlēties attēlu kvalitāti un vai vispār ielādēt attēlus, lai samazinātu datu un atmiņas lietojumu. Izmaiņas iztīra iekšējās atmiņas un diska attēlu kešatmiņu — %s</string>
<plurals name="replies"> <plurals name="replies">
<item quantity="zero">%s atbildes</item> <item quantity="zero">%s atbildes</item>
@@ -836,4 +820,17 @@
<string name="select_a_feed_group">Atlasiet abonementu grupu</string> <string name="select_a_feed_group">Atlasiet abonementu grupu</string>
<string name="migration_info_7_8_title">YouTube likvidēja apvienoto pašlaik populārs</string> <string name="migration_info_7_8_title">YouTube likvidēja apvienoto pašlaik populārs</string>
<string name="permission_display_over_apps_permission_name">“Ļaut rādīt virs citām lietotnēm”</string> <string name="permission_display_over_apps_permission_name">“Ļaut rādīt virs citām lietotnēm”</string>
<string name="search_with_service_name">Meklēt %1$s</string>
<string name="search_with_service_name_and_filter">Meklēt %1$s (%2$s)</string>
<string name="migration_info_6_7_title">SoundCloud Top 50 lapa likvidēta</string>
<string name="no_feed_group_created_yet">Vēl nav izveidota neviena abonementu grupa</string>
<string name="account_terminated_service_provides_reason">Konts slēgts\n\n%1$s norāda, ka iemesls kādēļ: %2$s</string>
<string name="player_http_403">Atskaņošanas laikā no servera saņemta HTTP 403 kļūda, ko, iespējams, izraisīja straumēšanas URL derīguma beigu termiņš vai IP aizliegums</string>
<string name="player_http_invalid_status">Atskaņošanas laikā no servera saņemta HTTP %1$s kļūda</string>
<string name="youtube_player_http_403">Atskaņošanas laikā no servera saņemta HTTP 403 kļūda, ko, iespējams, izraisīja IP aizliegums vai straumēšanas URL atšifrēšanas (deobfuskācijas) problēmas</string>
<string name="kao_dialog_warning">2025. gada augustā Google paziņoja, ka, sākot ar 2026. gada septembri, lai uzstādītu lietotnes, būs nepieciešama izstrādātāja verifikācija visām Android lietotnēm sertificētajās ierīcēs, tostarp arī tām, kuras uzstādītas ārpus Play veikala. Tā kā NewPipe izstrādātāji nepiekrīt un negrib pieņemt šo prasību, pēc šī datuma NewPipe vairs nedarbosies sertificētajās Android ierīcēs.</string>
<string name="kao_dialog_more_info">Detalizētāka informācija</string>
<string name="kao_solution">Risinājums</string>
<string name="migration_info_6_7_message">SoundCloud likvidēja oriģinālos Top 50 topus. Atbilstošā cilne noņemta no jūsu galvenās lapas.</string>
<string name="permission_display_over_apps_message">Lai varētu izmantot uznirstošo atskaņotāju, lūdzu, atlasiet %1$s šajā Android iestatījumu izvēlnē un iespējojiet %2$s.</string>
</resources> </resources>

View File

@@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

View File

@@ -847,4 +847,9 @@
<string name="youtube_player_http_403">HTTP-fout 403 ontvangen van de server tijdens het afspelen, waarschijnlijk veroorzaakt door een ip-blokkade of problemen met de deobfuscatie van de streaming-url</string> <string name="youtube_player_http_403">HTTP-fout 403 ontvangen van de server tijdens het afspelen, waarschijnlijk veroorzaakt door een ip-blokkade of problemen met de deobfuscatie van de streaming-url</string>
<string name="sign_in_confirm_not_bot_error">%1$s weigerde gegevens te verstrekken en vroeg om een login om te bevestigen dat de aanvrager geen bot is.\n\nUw ip-adres is mogelijk tijdelijk geblokkeerd door %1$s. U kunt even wachten of overschakelen naar een ander ip-adres (bijvoorbeeld door een vpn in of uit te schakelen, of door over te schakelen van wifi naar mobiele data).</string> <string name="sign_in_confirm_not_bot_error">%1$s weigerde gegevens te verstrekken en vroeg om een login om te bevestigen dat de aanvrager geen bot is.\n\nUw ip-adres is mogelijk tijdelijk geblokkeerd door %1$s. U kunt even wachten of overschakelen naar een ander ip-adres (bijvoorbeeld door een vpn in of uit te schakelen, of door over te schakelen van wifi naar mobiele data).</string>
<string name="unsupported_content_in_country">Deze inhoud is niet beschikbaar voor het momenteel geselecteerde inhouds­land.\n\nWijzig uw selectie via Instellingen &gt; Inhoud &gt; Standaard­land voor inhoud.</string> <string name="unsupported_content_in_country">Deze inhoud is niet beschikbaar voor het momenteel geselecteerde inhouds­land.\n\nWijzig uw selectie via Instellingen &gt; Inhoud &gt; Standaard­land voor inhoud.</string>
<string name="kao_dialog_more_info">Details</string>
<string name="kao_solution">Oplossing</string>
<string name="import_subscriptions_title">Abonnementen importeren</string>
<string name="export_subscriptions_title">Abonnementen exporteren</string>
<string name="import_from_previous_export">Importeren vanuit vorige export</string>
</resources> </resources>

View File

@@ -24,7 +24,7 @@
<string name="subscription_change_failed">ਸਬਸਕ੍ਰਿਪਸ਼ਨ ਨੂੰ ਬਦਲਿਆ ਨਹੀਂ ਜਾ ਸਕਿਆ</string> <string name="subscription_change_failed">ਸਬਸਕ੍ਰਿਪਸ਼ਨ ਨੂੰ ਬਦਲਿਆ ਨਹੀਂ ਜਾ ਸਕਿਆ</string>
<string name="show_info">ਜਾਣਕਾਰੀ ਵਿਖਾਓ</string> <string name="show_info">ਜਾਣਕਾਰੀ ਵਿਖਾਓ</string>
<string name="subscription_update_failed">ਸਬਸਕ੍ਰਿਪਸ਼ਨ ਅਪਡੇਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ</string> <string name="subscription_update_failed">ਸਬਸਕ੍ਰਿਪਸ਼ਨ ਅਪਡੇਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ</string>
<string name="tab_subscriptions">ਸਬਸਕ੍ਰਿਪਸ਼ਨਾਂ</string> <string name="tab_subscriptions">ਸਬਸਕ੍ਰਿਪਸ਼ਨਜ਼</string>
<string name="tab_bookmarks">ਬੁੱਕਮਾਰਕ ਕੀਤੀਆਂ ਪਲੇਲਿਸਟਾਂ</string> <string name="tab_bookmarks">ਬੁੱਕਮਾਰਕ ਕੀਤੀਆਂ ਪਲੇਲਿਸਟਾਂ</string>
<string name="fragment_feed_title">ਨਵਾਂ ਕੀ ਹੈ</string> <string name="fragment_feed_title">ਨਵਾਂ ਕੀ ਹੈ</string>
<string name="controls_background_title">ਬੈਕਗ੍ਰਾਊਂਡ</string> <string name="controls_background_title">ਬੈਕਗ੍ਰਾਊਂਡ</string>
@@ -104,10 +104,10 @@
<string name="switch_to_background">ਬੈਕਗ੍ਰਾਊਂਡ ਮੋਡ ਵਿੱਚ ਚਲਾਓ</string> <string name="switch_to_background">ਬੈਕਗ੍ਰਾਊਂਡ ਮੋਡ ਵਿੱਚ ਚਲਾਓ</string>
<string name="switch_to_popup">ਪੌਪ-ਅਪ ਮੋਡ ਵਿੱਚ ਚਲਾਓ</string> <string name="switch_to_popup">ਪੌਪ-ਅਪ ਮੋਡ ਵਿੱਚ ਚਲਾਓ</string>
<string name="switch_to_main">ਮੇਨ ਤੇ ਚਲਾਓ</string> <string name="switch_to_main">ਮੇਨ ਤੇ ਚਲਾਓ</string>
<string name="import_data_title">ਡਾਟਾਬੇਸ ਆਯਾਤ ਕਰੋ</string> <string name="import_data_title">ਡਾਟਾਬੇਸ ਇੰਪੋਰਟ ਕਰੋ</string>
<string name="export_data_title">ਡਾਟਾਬੇਸ ਨਿਰਯਾਤ ਕਰੋ</string> <string name="export_data_title">ਡਾਟਾਬੇਸ ਐਕਸਪੋਰਟ ਕਰੋ</string>
<string name="import_data_summary">ਤੁਹਾਡੇ ਮੌਜੂਦਾ ਇਤਿਹਾਸ, ਸਬਸਕ੍ਰਿਪਸ਼ਨਾਂ, ਪਲੇਲਿਸਟਾਂ ਅਤੇ (ਚੋਣਵੇਂ ਤੌਰ \'ਤੇ) ਸੈਟਿੰਗਾਂ ਨੂੰ ਨਵੀਆਂ ਨਾਲ ਬਦਲ ਦਿੰਦਾ ਹੈ</string> <string name="import_data_summary">ਤੁਹਾਡੇ ਮੌਜੂਦਾ ਇਤਿਹਾਸ, ਸਬਸਕ੍ਰਿਪਸ਼ਨਾਂ, ਪਲੇਲਿਸਟਾਂ ਅਤੇ (ਚੋਣਵੇਂ ਤੌਰ \'ਤੇ) ਸੈਟਿੰਗਾਂ ਨੂੰ ਨਵੀਆਂ ਨਾਲ ਬਦਲ ਦਿੰਦਾ ਹੈ</string>
<string name="export_data_summary">ਇਤਿਹਾਸ, ਸਬਸਕ੍ਰਿਪਸ਼ਨਾਂ, ਪਲੇਲਿਸਟਾਂ ਅਤੇ ਸੈਟਿੰਗਾਂ ਨਿਰਯਾਤ ਕਰੋ</string> <string name="export_data_summary">ਇਤਿਹਾਸ, ਸਬਸਕ੍ਰਿਪਸ਼ਨਾਂ, ਪਲੇਲਿਸਟਾਂ ਅਤੇ ਸੈਟਿੰਗਾਂ ਐਕਸਪੋਰਟ ਕਰੋ</string>
<string name="clear_views_history_title">ਵੇਖੇ ਗਏ ਵੀਡੀਓਜ਼ ਦੀ ਸੂਚੀ ਮਿਟਾਓ</string> <string name="clear_views_history_title">ਵੇਖੇ ਗਏ ਵੀਡੀਓਜ਼ ਦੀ ਸੂਚੀ ਮਿਟਾਓ</string>
<string name="clear_views_history_summary">ਚਲਾਈਆਂ ਗਈਆਂ ਸਟ੍ਰੀਮਾਂ ਦੇ ਇਤਿਹਾਸ ਅਤੇ ਪਲੇ-ਸਥਿਤੀਆਂ ਨੂੰ ਮਿਟਾਉਂਦਾ ਹੈ</string> <string name="clear_views_history_summary">ਚਲਾਈਆਂ ਗਈਆਂ ਸਟ੍ਰੀਮਾਂ ਦੇ ਇਤਿਹਾਸ ਅਤੇ ਪਲੇ-ਸਥਿਤੀਆਂ ਨੂੰ ਮਿਟਾਉਂਦਾ ਹੈ</string>
<string name="delete_view_history_alert">ਕੀ ਵੇਖੇ ਗਏ ਵੀਡੀਓਜ਼ ਦਾ ਇਤਿਹਾਸ ਮਿਟਾ ਦਿੱਤਾ ਜਾਵੇ\?</string> <string name="delete_view_history_alert">ਕੀ ਵੇਖੇ ਗਏ ਵੀਡੀਓਜ਼ ਦਾ ਇਤਿਹਾਸ ਮਿਟਾ ਦਿੱਤਾ ਜਾਵੇ\?</string>
@@ -273,7 +273,7 @@
<string name="export_to">ਤੇ ਐਕਸਪੋਰਟ ਕਰੋ</string> <string name="export_to">ਤੇ ਐਕਸਪੋਰਟ ਕਰੋ</string>
<string name="import_ongoing">ਇੰਪੋਰਟ ਹੋ ਰਿਹਾ ਹੈ…</string> <string name="import_ongoing">ਇੰਪੋਰਟ ਹੋ ਰਿਹਾ ਹੈ…</string>
<string name="export_ongoing">ਐਕਸਪੋਰਟ ਹੋ ਰਿਹਾ ਹੈ…</string> <string name="export_ongoing">ਐਕਸਪੋਰਟ ਹੋ ਰਿਹਾ ਹੈ…</string>
<string name="import_file_title">ਇੰਪੋਰਟ ਫਾਈਲ</string> <string name="import_file_title">ਫ਼ਾਈਲ ਇੰਪੋਰਟ ਕਰੋ</string>
<string name="previous_export">ਪਿੱਛਲਾ ਐਕਸਪੋਰਟ</string> <string name="previous_export">ਪਿੱਛਲਾ ਐਕਸਪੋਰਟ</string>
<string name="subscriptions_import_unsuccessful">ਸਬਸਕ੍ਰਿਪਸ਼ਨਾਂ ਇੰਪੋਰਟ ਨਹੀਂ ਹੋ ਸਕੀਆਂ</string> <string name="subscriptions_import_unsuccessful">ਸਬਸਕ੍ਰਿਪਸ਼ਨਾਂ ਇੰਪੋਰਟ ਨਹੀਂ ਹੋ ਸਕੀਆਂ</string>
<string name="subscriptions_export_unsuccessful">ਸਬਸਕ੍ਰਿਪਸ਼ਨਾਂ ਐਕਸਪੋਰਟ ਨਹੀਂ ਹੋ ਸਕੀਆਂ</string> <string name="subscriptions_export_unsuccessful">ਸਬਸਕ੍ਰਿਪਸ਼ਨਾਂ ਐਕਸਪੋਰਟ ਨਹੀਂ ਹੋ ਸਕੀਆਂ</string>
@@ -430,7 +430,7 @@
<string name="description_select_disable">ਵੇਰਵੇ \'ਚੋਂ ਲਿਖਤ ਚੁਣਨਾ ਬੰਦ ਕਰੋ</string> <string name="description_select_disable">ਵੇਰਵੇ \'ਚੋਂ ਲਿਖਤ ਚੁਣਨਾ ਬੰਦ ਕਰੋ</string>
<string name="description_select_enable">ਵੇਰਵੇ \'ਚੋਂ ਲਿਖਤ ਚੁਣਨਾ ਚਾਲੂ ਕਰੋ</string> <string name="description_select_enable">ਵੇਰਵੇ \'ਚੋਂ ਲਿਖਤ ਚੁਣਨਾ ਚਾਲੂ ਕਰੋ</string>
<string name="description_select_note">ਤੁਸੀਂ ਹੁਣ ਵੇਰਵੇ \'ਚੋਂ ਲਿਖਤ ਨੂੰ ਚੁਣ ਸਕਦੇ ਹੋ। ਨੋਟ ਕਰੋ ਕਿ ਪੰਨਾ ਜਗ-ਬੁੱਝ ਸਕਦਾ ਹੈ ਅਤੇ ਚੋਣ ਮੋਡ ਵਿੱਚ ਹੋਣ ਵੇਲੇ ਲਿੰਕ ਕਲਿੱਕ ਕਰਨ ਯੋਗ ਨਹੀਂ ਹੋ ਸਕਦੇ ਹਨ।</string> <string name="description_select_note">ਤੁਸੀਂ ਹੁਣ ਵੇਰਵੇ \'ਚੋਂ ਲਿਖਤ ਨੂੰ ਚੁਣ ਸਕਦੇ ਹੋ। ਨੋਟ ਕਰੋ ਕਿ ਪੰਨਾ ਜਗ-ਬੁੱਝ ਸਕਦਾ ਹੈ ਅਤੇ ਚੋਣ ਮੋਡ ਵਿੱਚ ਹੋਣ ਵੇਲੇ ਲਿੰਕ ਕਲਿੱਕ ਕਰਨ ਯੋਗ ਨਹੀਂ ਹੋ ਸਕਦੇ ਹਨ।</string>
<string name="download_has_started">ਡਾਊਨਲੋਡ ਸ਼ੁਰੂ ਹੋ ਗਿਐ</string> <string name="download_has_started">ਡਾਊਨਲੋਡ ਸ਼ੁਰੂ ਹੋਇਆ</string>
<string name="select_night_theme_toast">ਤੁਸੀਂ ਆਪਣੀ ਪਸੰਦੀਦਾ ਰਾਤ ਦੀ ਥੀਮ ਹੇਠਾਂ ਚੁਣ ਸਕਦੇ ਹੋ</string> <string name="select_night_theme_toast">ਤੁਸੀਂ ਆਪਣੀ ਪਸੰਦੀਦਾ ਰਾਤ ਦੀ ਥੀਮ ਹੇਠਾਂ ਚੁਣ ਸਕਦੇ ਹੋ</string>
<string name="night_theme_summary">ਆਪਣੀ ਪਸੰਦੀਦਾ ਰਾਤ ਦੀ ਥੀਮ ਚੁਣੋ — %s</string> <string name="night_theme_summary">ਆਪਣੀ ਪਸੰਦੀਦਾ ਰਾਤ ਦੀ ਥੀਮ ਚੁਣੋ — %s</string>
<string name="auto_device_theme_title">ਆਟੋਮੈਟਿਕ (ਡਿਵਾਈਸ ਥੀਮ)</string> <string name="auto_device_theme_title">ਆਟੋਮੈਟਿਕ (ਡਿਵਾਈਸ ਥੀਮ)</string>
@@ -494,8 +494,8 @@
<item quantity="other">%d ਸਕਿੰਟ</item> <item quantity="other">%d ਸਕਿੰਟ</item>
</plurals> </plurals>
<string name="remove_watched_popup_partially_watched_streams">ਹਾਂ, ਅਤੇ ਅੱਧ-ਪਚੱਧੀਆਂ ਵੇਖੀਆਂ ਹੋਈਆਂ ਵੀ</string> <string name="remove_watched_popup_partially_watched_streams">ਹਾਂ, ਅਤੇ ਅੱਧ-ਪਚੱਧੀਆਂ ਵੇਖੀਆਂ ਹੋਈਆਂ ਵੀ</string>
<string name="remove_watched_popup_warning">ਪਲੇਲਿਸਟ ਵਿੱਚ ਸ਼ਾਮਿਲ ਪਹਿਲਾਂ ਤੇ ਬਾਅਦ ਵਿੱਚ ਵੇਖੇ ਜਾ ਚੁੱਕੇ ਵੀਡੀਓ ਹਟਾ ਦਿੱਤ ਜਾਣਗੇ। \nਕੀ ਵਾਕਿਆ ਹੀ ਤੁਸੀਂ ਇਹਨਾਂ ਨੂੰ ਹਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ? ਇਸ ਕਾਰਵਾਈ ਨੂੰ ਵਾਪਸ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਣਾ!</string> <string name="remove_watched_popup_warning">ਪਲੇਲਿਸਟ ਵਿੱਚ ਸ਼ਾਮਿਲ ਪਹਿਲਾਂ ਤੇ ਬਾਅਦ ਵਿੱਚ ਵੇਖੀਆਂ ਸਟ੍ਰੀਮਾਂ ਨੂੰ ਹਟਾ ਦਿੱਤ ਜਾਵੇਗਾ।\nਕੀ ਤੁਸੀਂ ਯਕੀਨਨ ਇਹ ਚਾਹੁੰਦੇ ਹੋ?</string>
<string name="remove_watched_popup_title">ਵੇਖੇ ਹੋਏ ਵੀਡੀਓ ਹਟਾ ਦੇਈਏ?</string> <string name="remove_watched_popup_title">ਕੀ ਵੇਖੀਆਂ ਸਟ੍ਰੀਮਾਂ ਨੂੰ ਹਟਾਉਣਾ ਹੈ?</string>
<string name="remove_watched">ਵੇਖੇ ਹੋਏ ਨੂੰ ਹਟਾਓ</string> <string name="remove_watched">ਵੇਖੇ ਹੋਏ ਨੂੰ ਹਟਾਓ</string>
<string name="systems_language">ਸਿਸਟਮ ਡਿਫ਼ਾਲਟ</string> <string name="systems_language">ਸਿਸਟਮ ਡਿਫ਼ਾਲਟ</string>
<string name="app_language_title">ਐਪ ਦੀ ਭਾਸ਼ਾ</string> <string name="app_language_title">ਐਪ ਦੀ ਭਾਸ਼ਾ</string>
@@ -651,8 +651,7 @@
<item quantity="other">%1$s ਡਾਊਨਲੋਡ ਹਟਾਏ</item> <item quantity="other">%1$s ਡਾਊਨਲੋਡ ਹਟਾਏ</item>
</plurals> </plurals>
<string name="detail_sub_channel_thumbnail_view_description">ਚੈਨਲ ਦਾ ਅਵਤਾਰ ਥੰਮਨੇਲ</string> <string name="detail_sub_channel_thumbnail_view_description">ਚੈਨਲ ਦਾ ਅਵਤਾਰ ਥੰਮਨੇਲ</string>
<string name="no_appropriate_file_manager_message_android_10">ਇਸ ਕਾਰਜ ਲਈ ਕੋਈ ਢੁਕਵਾਂ ਫਾਈਲ ਮੈਨੇਜਰ ਨਹੀਂ ਮਿਲਿਆ। <string name="no_appropriate_file_manager_message_android_10">ਇਸ ਕਾਰਜ ਲਈ ਕੋਈ ਢੁਕਵਾਂ ਫਾਈਲ ਮੈਨੇਜਰ ਨਹੀਂ ਮਿਲਿਆ।\nਕ੍ਰਿਪਾ ਕਰਕੇ ਸਟੋਰੇਜ ਐਕਸਿਸ ਫਰੇਮਵਰਕ SAF ਅਨੁਕੂਲ ਫਾਈਲ ਮੈਨੇਜਰ ਸਥਾਪਤ ਕਰੋ</string>
\nਕ੍ਰਿਪਾ ਕਰਕੇ ਸਟੋਰੇਜ ਐਕਸਿਸ ਫਰੇਮਵਰਕ SAF ਅਨੁਕੂਲ ਫਾਈਲ ਮੈਨੇਜਰ ਇੰਨਸਟਾਲ ਕਰੋ</string>
<string name="tablet_mode_title">ਟੈਬਲੇਟ ਮੋਡ</string> <string name="tablet_mode_title">ਟੈਬਲੇਟ ਮੋਡ</string>
<string name="notifications_disabled">ਨੋਟੀਫਿਕੇਸ਼ਨ ਬੰਦ ਕੀਤੇ ਹੋਏ ਹਨ</string> <string name="notifications_disabled">ਨੋਟੀਫਿਕੇਸ਼ਨ ਬੰਦ ਕੀਤੇ ਹੋਏ ਹਨ</string>
<string name="toggle_all">ਸਭ ਨੂੰ ਟੌਗਲ ਕਰੋ</string> <string name="toggle_all">ਸਭ ਨੂੰ ਟੌਗਲ ਕਰੋ</string>
@@ -684,7 +683,7 @@
\n \n
\nਤੁਹਾਡੀ ਚੋਣ ਇਸ ਗੱਲ ਤੇ ਮੁਨੱਸਰ ਕਰਦੀ ਹੈ ਕਿ ਤੁਸੀਂ ਗਤੀ ਤੇ ਸਟੀਕਤਾ ਵਿੱਚੋਂ ਕਿਸ ਨੂੰ ਪ੍ਰਾਥਮਿਕਤਾ ਦਿੰਦੇ ਹੋ।</string> \nਤੁਹਾਡੀ ਚੋਣ ਇਸ ਗੱਲ ਤੇ ਮੁਨੱਸਰ ਕਰਦੀ ਹੈ ਕਿ ਤੁਸੀਂ ਗਤੀ ਤੇ ਸਟੀਕਤਾ ਵਿੱਚੋਂ ਕਿਸ ਨੂੰ ਪ੍ਰਾਥਮਿਕਤਾ ਦਿੰਦੇ ਹੋ।</string>
<string name="fast_mode">ਤੇਜ ਮੋਡ</string> <string name="fast_mode">ਤੇਜ ਮੋਡ</string>
<string name="import_subscriptions_hint">3-ਡੌਟ ਮੀਨੂ ਤੋਂ ਸਬਸਕ੍ਰਿਪਸ਼ਨਾਂ ਨੂੰ ਆਯਾਤ ਜਾਂ ਨਿਰਯਾਤ ਕਰੋ</string> <string name="import_subscriptions_hint">3-ਡੌਟ ਮੀਨੂ ਤੋਂ ਸਬਸਕ੍ਰਿਪਸ਼ਨਾਂ ਨੂੰ ਇੰਪੋਰਟ ਜਾਂ ਐਕਸਪੋਰਟ ਕਰੋ</string>
<string name="app_update_unavailable_toast">ਤੁਸੀਂ ਨਿਊਪਾਈਪ ਦਾ ਨਵੀਨਤਮ ਸੰਸਕਰਣ ਚਲਾ ਰਹੇ ਹੋ</string> <string name="app_update_unavailable_toast">ਤੁਸੀਂ ਨਿਊਪਾਈਪ ਦਾ ਨਵੀਨਤਮ ਸੰਸਕਰਣ ਚਲਾ ਰਹੇ ਹੋ</string>
<string name="app_update_available_notification_text">%s ਨੂੰ ਡਾਊਨਲੋਡ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ</string> <string name="app_update_available_notification_text">%s ਨੂੰ ਡਾਊਨਲੋਡ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ</string>
<string name="night_theme_available">ਇਹ ਵਿਕਲਪ ਤਾਂ ਹੀ ਉਪਲਬਧ ਹੁੰਦਾ ਹੈ ਜੇਕਰ %s ਨੂੰ ਥੀਮ ਲਈ ਚੁਣਿਆ ਜਾਂਦਾ ਹੈ</string> <string name="night_theme_available">ਇਹ ਵਿਕਲਪ ਤਾਂ ਹੀ ਉਪਲਬਧ ਹੁੰਦਾ ਹੈ ਜੇਕਰ %s ਨੂੰ ਥੀਮ ਲਈ ਚੁਣਿਆ ਜਾਂਦਾ ਹੈ</string>
@@ -827,6 +826,26 @@
<string name="player_http_403">ਪਲੇਅ ਕਰਦੇ ਸਮੇਂ ਸਰਵਰ ਤੋਂ HTTP error 403 ਪ੍ਰਾਪਤ ਹੋਇਆ, ਜੋ ਸ਼ਾਇਦ ਸਟ੍ਰੀਮਿੰਗ URL ਦੀ ਮਿਆਦ ਪੁੱਗਣ ਜਾਂ IP ਦੀ ਪਾਬੰਦੀ ਕਾਰਨ ਹੋਈ ਹੈ</string> <string name="player_http_403">ਪਲੇਅ ਕਰਦੇ ਸਮੇਂ ਸਰਵਰ ਤੋਂ HTTP error 403 ਪ੍ਰਾਪਤ ਹੋਇਆ, ਜੋ ਸ਼ਾਇਦ ਸਟ੍ਰੀਮਿੰਗ URL ਦੀ ਮਿਆਦ ਪੁੱਗਣ ਜਾਂ IP ਦੀ ਪਾਬੰਦੀ ਕਾਰਨ ਹੋਈ ਹੈ</string>
<string name="player_http_invalid_status">ਚਲਾਉਣ ਦੌਰਾਨ ਸਰਵਰ ਤੋਂ HTTP error %1$s ਪ੍ਰਾਪਤ ਹੋਇਆ</string> <string name="player_http_invalid_status">ਚਲਾਉਣ ਦੌਰਾਨ ਸਰਵਰ ਤੋਂ HTTP error %1$s ਪ੍ਰਾਪਤ ਹੋਇਆ</string>
<string name="youtube_player_http_403">ਪਲੇਅ ਕਰਦੇ ਸਮੇਂ ਸਰਵਰ ਤੋਂ HTTP error 403 ਪ੍ਰਾਪਤ ਹੋਇਆ, ਜੋ ਸ਼ਾਇਦ IP ਬੈਨ ਜਾਂ ਸਟ੍ਰੀਮਿੰਗ URL ਡੀਔਬਫਸਕੇਸ਼ਨ ਸਮੱਸਿਆਵਾਂ ਕਾਰਨ ਹੋਈ ਹੈ</string> <string name="youtube_player_http_403">ਪਲੇਅ ਕਰਦੇ ਸਮੇਂ ਸਰਵਰ ਤੋਂ HTTP error 403 ਪ੍ਰਾਪਤ ਹੋਇਆ, ਜੋ ਸ਼ਾਇਦ IP ਬੈਨ ਜਾਂ ਸਟ੍ਰੀਮਿੰਗ URL ਡੀਔਬਫਸਕੇਸ਼ਨ ਸਮੱਸਿਆਵਾਂ ਕਾਰਨ ਹੋਈ ਹੈ</string>
<string name="sign_in_confirm_not_bot_error">%1$s ਨੇ ਡੇਟਾ ਪ੍ਰਦਾਨ ਕਰਨ ਤੋਂ ਇਨਕਾਰ ਕਰ ਦਿੱਤਾ, ਅਤੇ ਇਹ ਪੁਸ਼ਟੀ ਕਰਨ ਲਈ ਲੌਗਇਨ ਕਰਨ ਲਈ ਕਿਹਾ ਕਿ ਬੇਨਤੀਕਰਤਾ ਬੋਟ ਨਹੀਂ ਹੈ।\n\nਹੋ ਸਕਦਾ ਹੈ ਕਿ %1$s ਨੇ ਤੁਹਾਡੇ IP ਨੂੰ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਪਾਬੰਦੀ ਲਗਾਈ ਹੋਵੇ, ਤੁਸੀਂ ਕੁਝ ਸਮਾਂ ਉਡੀਕ ਕਰ ਸਕਦੇ ਹੋ ਜਾਂ ਕਿਸੇ ਵੱਖਰੇ IP \'ਤੇ ਸਵਿੱਚ ਕਰ ਸਕਦੇ ਹੋ (ਉਦਾਹਰਣ ਵਜੋਂ VPN ਨੂੰ ਚਾਲੂ/ਬੰਦ ਕਰਕੇ, ਜਾਂ WiFi ਤੋਂ ਮੋਬਾਈਲ ਡੇਟਾ \'ਤੇ ਸਵਿੱਚ ਕਰਕੇ)।</string> <string name="sign_in_confirm_not_bot_error">%1$s ਨੇ ਡੇਟਾ ਪ੍ਰਦਾਨ ਕਰਨ ਤੋਂ ਇਨਕਾਰ ਕਰ ਦਿੱਤਾ, ਅਤੇ ਇਹ ਪੁਸ਼ਟੀ ਕਰਨ ਲਈ ਲੌਗਇਨ ਕਰਨ ਲਈ ਕਿਹਾ ਕਿ ਬੇਨਤੀਕਰਤਾ ਬੋਟ ਨਹੀਂ ਹੈ।\n\nਹੋ ਸਕਦਾ ਹੈ ਕਿ %1$s ਨੇ ਤੁਹਾਡੇ IP ਨੂੰ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਪਾਬੰਦੀ ਲਗਾਈ ਹੋਵੇ, ਤੁਸੀਂ ਕੁਝ ਸਮਾਂ ਉਡੀਕ ਕਰ ਸਕਦੇ ਹੋ ਜਾਂ ਕਿਸੇ ਵੱਖਰੇ IP \'ਤੇ ਸਵਿੱਚ ਕਰ ਸਕਦੇ ਹੋ (ਉਦਾਹਰਣ ਵਜੋਂ VPN ਨੂੰ ਚਾਲੂ/ਬੰਦ ਕਰਕੇ, ਜਾਂ WiFi ਤੋਂ ਮੋਬਾਈਲ ਡੇਟਾ \'ਤੇ ਸਵਿੱਚ ਕਰਕੇ)।\n\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ ਕਿਰਪਾ ਕਰਕੇ <a href="%2$s">ਇਹ FAQ ਐਂਟਰੀ</a> ਵੇਖੋ।</string>
<string name="unsupported_content_in_country">ਇਹ ਸਮੱਗਰੀ ਵਰਤਮਾਨ ਵਿੱਚ ਚੁਣੇ ਗਏ ਦੇਸ਼ ਦੀ ਸਮੱਗਰੀ ਲਈ ਉਪਲੱਬਧ ਨਹੀਂ ਹੈ।\n\n\"ਸੈਟਿੰਗਾਂ &gt; ਸਮੱਗਰੀ &gt; ਡਿਫ਼ਾਲਟ ਸਮੱਗਰੀ ਦੇਸ਼\" ਤੋਂ ਆਪਣੀ ਚੋਣ ਬਦਲੋ।</string> <string name="unsupported_content_in_country">ਇਹ ਸਮੱਗਰੀ ਵਰਤਮਾਨ ਵਿੱਚ ਚੁਣੇ ਗਏ ਦੇਸ਼ ਦੀ ਸਮੱਗਰੀ ਲਈ ਉਪਲੱਬਧ ਨਹੀਂ ਹੈ।\n\n\"ਸੈਟਿੰਗਾਂ &gt; ਸਮੱਗਰੀ &gt; ਡਿਫ਼ਾਲਟ ਸਮੱਗਰੀ ਦੇਸ਼\" ਤੋਂ ਆਪਣੀ ਚੋਣ ਬਦਲੋ।</string>
<string name="kao_dialog_warning">ਅਗਸਤ 2025 ਵਿੱਚ, ਗੂਗਲ ਨੇ ਐਲਾਨ ਕੀਤਾ ਕਿ ਸਤੰਬਰ 2026 ਤੋਂ, ਐਪਸ ਨੂੰ ਸਥਾਪਿਤ ਕਰਨ ਲਈ ਪ੍ਰਮਾਣਿਤ ਡਿਵਾਈਸਾਂ \'ਤੇ ਸਾਰੇ ਐਂਡਰਾਇਡ ਐਪਸ ਲਈ ਡਿਵੈਲਪਰ ਤਸਦੀਕ ਦੀ ਲੋੜ ਹੋਵੇਗੀ, ਜਿਸ ਵਿੱਚ ਪਲੇ ਸਟੋਰ ਤੋਂ ਬਾਹਰ ਸਥਾਪਤ ਕੀਤੇ ਐਪਸ ਵੀ ਸ਼ਾਮਲ ਹਨ। ਕਿਉਂਕਿ ਨਿਊਪਾਈਪ ਦੇ ਡਿਵੈਲਪਰ ਇਸ ਲੋੜ ਨਾਲ ਸਹਿਮਤ ਨਹੀਂ ਹਨ, ਇਸ ਲਈ ਨਿਊਪਾਈਪ ਉਸ ਸਮੇਂ ਤੋਂ ਬਾਅਦ ਪ੍ਰਮਾਣਿਤ ਐਂਡਰਾਇਡ ਡਿਵਾਈਸਾਂ \'ਤੇ ਕੰਮ ਨਹੀਂ ਕਰੇਗੀ।</string>
<string name="kao_dialog_more_info">ਵੇਰਵੇ</string>
<string name="kao_solution">ਹੱਲ</string>
<plurals name="export_subscriptions">
<item quantity="one">%d ਸਬਸਕ੍ਰਿਪਸ਼ਨ ਐਕਸਪੋਰਟ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ…</item>
<item quantity="other">%d ਸਬਸਕ੍ਰਿਪਸ਼ਨਾਂ ਐਕਸਪੋਰਟ ਕੀਤੀਆਂ ਜਾ ਰਹੀਆਂ ਹਨ…</item>
</plurals>
<plurals name="load_subscriptions">
<item quantity="one">%d ਸਬਸਕ੍ਰਿਪਸ਼ਨ ਲੋਡ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ…</item>
<item quantity="other">%d ਸਬਸਕ੍ਰਿਪਸ਼ਨਾਂ ਲੋਡ ਕੀਤੀਆਂ ਜਾ ਰਹੀਆਂ ਹਨ…</item>
</plurals>
<plurals name="import_subscriptions">
<item quantity="one">%d ਸਬਸਕ੍ਰਿਪਸ਼ਨ ਇੰਪੋਰਟ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ…</item>
<item quantity="other">%d ਸਬਸਕ੍ਰਿਪਸ਼ਨਾਂ ਇੰਪੋਰਟ ਕੀਤੀਆਂ ਜਾ ਰਹੀਆਂ ਹਨ…</item>
</plurals>
<string name="import_subscriptions_title">ਸਬਸਕ੍ਰਿਪਸ਼ਨਾਂ ਇੰਪੋਰਟ ਕਰੋ</string>
<string name="export_subscriptions_title">ਸਬਸਕ੍ਰਿਪਸ਼ਨਾਂ ਐਕਸਪੋਰਟ ਕਰੋ</string>
<string name="import_subscriptions_summary">ਪਹਿਲਾਂ ਕੀਤੇ .json ਐਕਸਪੋਰਟ ਤੋਂ ਸਬਸਕ੍ਰਿਪਸ਼ਨਾਂ ਨੂੰ ਇੰਪੋਰਟ ਕਰੋ</string>
<string name="export_subscriptions_summary">ਆਪਣੀਆਂ ਸਬਸਕ੍ਰਿਪਸ਼ਨਾਂ ਨੂੰ .json ਫਾਈਲ ਵਿੱਚ ਐਕਸਪੋਰਟ ਕਰੋ</string>
<string name="import_from_previous_export">ਪਹਿਲਾਂ ਕੀਤੇ ਐਕਸਪੋਰਟ ਤੋਂ ਇੰਪੋਰਟ ਕਰੋ</string>
</resources> </resources>

View File

@@ -868,6 +868,32 @@
<string name="player_http_403">Podczas odtwarzania otrzymano od serwera błąd HTTP 403, prawdopodobnie spowodowany wygaśnięciem adresu URL strumienia lub blokadą adresu IP.</string> <string name="player_http_403">Podczas odtwarzania otrzymano od serwera błąd HTTP 403, prawdopodobnie spowodowany wygaśnięciem adresu URL strumienia lub blokadą adresu IP.</string>
<string name="player_http_invalid_status">Podczas odtwarzania otrzymano od serwera błąd HTTP %1$s.</string> <string name="player_http_invalid_status">Podczas odtwarzania otrzymano od serwera błąd HTTP %1$s.</string>
<string name="youtube_player_http_403">Podczas odtwarzania otrzymano od serwera błąd HTTP 403, prawdopodobnie spowodowany blokadą adresu IP lub problemami z odszyfrowaniem adresu URL strumienia.</string> <string name="youtube_player_http_403">Podczas odtwarzania otrzymano od serwera błąd HTTP 403, prawdopodobnie spowodowany blokadą adresu IP lub problemami z odszyfrowaniem adresu URL strumienia.</string>
<string name="sign_in_confirm_not_bot_error">%1$s odmówił dostarczenia danych, prosząc o zalogowanie się w celu potwierdzenia, że nie jest się botem.\n\nTwoje IP mogło zostać tymczasowo zablokowane przez %1$s. Możesz chwilę poczekać lub zmienić adres IP (na przykład włączając/wyłączając VPN lub przełączając się z sieci Wi-Fi na dane komórkowe).</string> <string name="sign_in_confirm_not_bot_error">%1$s odmówił dostarczenia danych, prosząc o zalogowanie się w celu potwierdzenia, że nie jest się botem.\n\nTwoje IP mogło zostać tymczasowo zablokowane przez %1$s. Możesz chwilę poczekać lub zmienić adres IP (na przykład włączając/wyłączając VPN lub przełączając się z sieci Wi-Fi na dane komórkowe).\n\nZobacz <a href="%2$s">ten wpis w FAQ</a>, aby uzyskać więcej informacji.</string>
<string name="unsupported_content_in_country">Ta treść nie jest dostępna dla aktualnie wybranego kraju treści.\n\nZmień swój wybór w „Ustawienia &gt; Zawartość &gt; Domyślny kraj treści”.</string> <string name="unsupported_content_in_country">Ta treść nie jest dostępna dla aktualnie wybranego kraju treści.\n\nZmień swój wybór w „Ustawienia &gt; Zawartość &gt; Domyślny kraj treści”.</string>
<string name="kao_dialog_warning">W sierpniu 2025 r. Google ogłosił, że od września 2026 r. instalowanie aplikacji będzie wymagać weryfikacji ich twórców w przypadku wszystkich aplikacji na Androida na certyfikowanych urządzeniach, w tym tych zainstalowanych poza sklepem Google Play. Ponieważ programiści NewPipe nie zgadzają się z tym wymogiem, NewPipie nie będzie już działać na certyfikowanych urządzeniach z Androidem po tym czasie.</string>
<string name="kao_dialog_more_info">Szczegóły</string>
<string name="kao_solution">Rozwiązanie</string>
<plurals name="export_subscriptions">
<item quantity="one">Eksportowanie %d subskrypcji…</item>
<item quantity="few">Eksportowanie %d subskrypcji…</item>
<item quantity="many">Eksportowanie %d subskrypcji…</item>
<item quantity="other">Eksportowanie %d subskrypcji…</item>
</plurals>
<plurals name="load_subscriptions">
<item quantity="one">Ładowanie %d subskrypcji…</item>
<item quantity="few">Ładowanie %d subskrypcji…</item>
<item quantity="many">Ładowanie %d subskrypcji…</item>
<item quantity="other">Ładowanie %d subskrypcji…</item>
</plurals>
<plurals name="import_subscriptions">
<item quantity="one">Importowanie %d subskrypcji…</item>
<item quantity="few">Importowanie %d subskrypcji…</item>
<item quantity="many">Importowanie %d subskrypcji…</item>
<item quantity="other">Importowanie %d subskrypcji…</item>
</plurals>
<string name="import_subscriptions_title">Importuj subskrypcje</string>
<string name="export_subscriptions_title">Eksportuj subskrypcje</string>
<string name="import_subscriptions_summary">Zaimportuj subskrypcje z poprzedniego eksportu do .json</string>
<string name="export_subscriptions_summary">Wyeksportuj swoje subskrypcje do pliku .json</string>
<string name="import_from_previous_export">Importuj z poprzedniego eksportu</string>
</resources> </resources>

View File

@@ -859,6 +859,29 @@
<string name="player_http_403">Erro HTTP 403 recebido do servidor durante a reprodução, provavelmente causado por URL de streaming expirado ou IP banido</string> <string name="player_http_403">Erro HTTP 403 recebido do servidor durante a reprodução, provavelmente causado por URL de streaming expirado ou IP banido</string>
<string name="player_http_invalid_status">Erro HTTP %1$s recebido do servidor durante reprodução</string> <string name="player_http_invalid_status">Erro HTTP %1$s recebido do servidor durante reprodução</string>
<string name="youtube_player_http_403">Erro HTTP 403 recebido do servidor durante a reprodução, provavelmente causado por um banimento de IP ou problemas de desofuscação de URL de streaming</string> <string name="youtube_player_http_403">Erro HTTP 403 recebido do servidor durante a reprodução, provavelmente causado por um banimento de IP ou problemas de desofuscação de URL de streaming</string>
<string name="sign_in_confirm_not_bot_error">%1$s se recusou a fornecer dados, solicitando um login para confirmar que o solicitante não é um bot.\n\nSeu IP pode ter sido temporariamente banido por %1$s. Você pode esperar um pouco ou mudar para um IP diferente (por exemplo, ativando/desativando uma VPN ou alternando de Wi-Fi para dados móveis).</string> <string name="sign_in_confirm_not_bot_error">%1$s se recusou a fornecer dados, solicitando um login para confirmar que o solicitante não é um bot.\n\nSeu IP pode ter sido temporariamente banido por %1$s. Você pode esperar um pouco ou mudar para um IP diferente (por exemplo, ativando/desativando uma VPN ou alternando de Wi-Fi para dados móveis).\n\nConfira <a href="%2$s">este artigo do FAQ</a> para mais informações.</string>
<string name="unsupported_content_in_country">Este conteúdo não está disponível para o país selecionado atualmente.\n\nAltere sua seleção acessando “Configurações &gt; Conteúdo &gt; País padrão do conteúdo”.</string> <string name="unsupported_content_in_country">Este conteúdo não está disponível para o país selecionado atualmente.\n\nAltere sua seleção acessando “Configurações &gt; Conteúdo &gt; País padrão do conteúdo”.</string>
<string name="kao_dialog_warning">Em agosto de 2025, o Google anunciou que, a partir de setembro de 2026, a instalação de aplicativos exigirá a verificação do desenvolvedor para todos os aplicativos Android em dispositivos certificados, incluindo aqueles instalados fora da Play Store. Como os desenvolvedores do NewPipe não concordam com esse requisito, o NewPipe não funcionará mais em dispositivos Android certificados após essa data.</string>
<string name="kao_dialog_more_info">Detalhes</string>
<string name="kao_solution">Solução</string>
<plurals name="export_subscriptions">
<item quantity="one">Exportando %d inscrição…</item>
<item quantity="many">Exportando %d inscrições…</item>
<item quantity="other">Exportando %d inscrições…</item>
</plurals>
<plurals name="load_subscriptions">
<item quantity="one">Carregando %d inscrição…</item>
<item quantity="many">Carregando %d inscrições…</item>
<item quantity="other">Carregando %d inscrições…</item>
</plurals>
<plurals name="import_subscriptions">
<item quantity="one">Importando %d inscrição…</item>
<item quantity="many">Importando %d inscrições…</item>
<item quantity="other">Importando %d inscrições…</item>
</plurals>
<string name="import_subscriptions_title">Importar inscrições</string>
<string name="export_subscriptions_title">Exportar inscrições</string>
<string name="import_subscriptions_summary">Importar inscrições do arquivo .json exportado anterior</string>
<string name="export_subscriptions_summary">Exportar inscrições para arquivo .json</string>
<string name="import_from_previous_export">Importar da exportação anterior</string>
</resources> </resources>

View File

@@ -144,7 +144,7 @@
<string name="delete_downloaded_files">Eliminar ficheiros descarregados</string> <string name="delete_downloaded_files">Eliminar ficheiros descarregados</string>
<string name="app_language_title">Idioma da aplicação</string> <string name="app_language_title">Idioma da aplicação</string>
<string name="users">Utilizadores</string> <string name="users">Utilizadores</string>
<string name="remove_watched_popup_warning">Os vídeos que tenham sido vistos antes e depois de serem adicionados à lista de reprodução serão removidos. \nTem a certeza? Esta ação não pode ser revertida!</string> <string name="remove_watched_popup_warning">Os vídeos que tenham sido vistos antes e após serem adicionados à lista de reprodução serão removidos. \nTem a certeza?</string>
<plurals name="watching"> <plurals name="watching">
<item quantity="one">%s a ver</item> <item quantity="one">%s a ver</item>
<item quantity="many">%s a ver</item> <item quantity="many">%s a ver</item>
@@ -857,8 +857,11 @@
<string name="entry_deleted">Entrada apagada</string> <string name="entry_deleted">Entrada apagada</string>
<string name="account_terminated_service_provides_reason">Conta terminada\n\n%1$s fornece esta razão: %2$s</string> <string name="account_terminated_service_provides_reason">Conta terminada\n\n%1$s fornece esta razão: %2$s</string>
<string name="player_http_invalid_status">Erro HTTP %1$s recebido do servidor ao reproduzir</string> <string name="player_http_invalid_status">Erro HTTP %1$s recebido do servidor ao reproduzir</string>
<string name="sign_in_confirm_not_bot_error">%1$s recusou fornecer dados, pedindo por um login para confirmar que o solicitante não é um bot.\n\nO seu IP pode ter sido temporariamente banido por %1$s, pode esperar algum tempo ou mudar para um IP diferente (por exemplo, a ligar / desligar uma VPN, ou a alternar de Wi-Fi para dados móveis).</string> <string name="sign_in_confirm_not_bot_error">%1$s recusou fornecer dados, pedindo por um login para confirmar que o solicitante não é um bot.\n\nO seu IP pode ter sido temporariamente banido por %1$s, você pode esperar algum tempo ou mudar para um IP diferente (por exemplo, a ligar/desligar uma VPN, ou a alternar de Wi-Fi para dados móveis).\n\nConfira <a href="%2$s">este artigo do FAQ</a> para mais informações.</string>
<string name="unsupported_content_in_country">Este conteúdo não está disponível para o país de conteúdo atualmente selecionado.\n\nAltere a sua seleção de \"Configurações &gt; Conteúdo &gt; País predefinido de conteúdo\".</string> <string name="unsupported_content_in_country">Este conteúdo não está disponível para o país de conteúdo atualmente selecionado.\n\nAltere a sua seleção de \"Configurações &gt; Conteúdo &gt; País predefinido de conteúdo\".</string>
<string name="player_http_403">Erro HTTP 403 recebido do servidor durante a reprodução, provavelmente causado pela URL de streaming expirado ou IP banido</string> <string name="player_http_403">Erro HTTP 403 recebido do servidor durante a reprodução, provavelmente causado pela URL de streaming expirado ou IP banido</string>
<string name="youtube_player_http_403">Erro HTTP 403 recebido do servidor durante a reprodução, provavelmente causado por um bloqueio de IP ou problemas de desofuscação da URL de streaming</string> <string name="youtube_player_http_403">Erro HTTP 403 recebido do servidor durante a reprodução, provavelmente causado por um bloqueio de IP ou problemas de desofuscação da URL de streaming</string>
<string name="kao_dialog_warning">Em agosto de 2025, o Google anunciou que, a partir de setembro de 2026, a instalação de apps exigirá a verificação do programador para todas as apps Android em dispositivos certificados, incluindo aqueles instalados fora da Play Store. Como os programadores do NewPipe não concordam com este requisito, o NewPipe já não funcionará em dispositivos Android certificados após essa data.</string>
<string name="kao_dialog_more_info">Pormenores</string>
<string name="kao_solution">Solução</string>
</resources> </resources>

View File

@@ -517,7 +517,7 @@
<string name="restricted_video">Este vídeo está restringido a adultos. <string name="restricted_video">Este vídeo está restringido a adultos.
\n \n
\nPara o poder ver, tem que ativar \"%1$s\" nas definições.</string> \nPara o poder ver, tem que ativar \"%1$s\" nas definições.</string>
<string name="remove_watched_popup_warning">Os vídeos que tenham sido vistos antes e depois de serem adicionados à lista de reprodução serão removidos. \nTem a certeza? Esta ação não pode ser revertida!</string> <string name="remove_watched_popup_warning">Os vídeos que tenham sido vistos antes e após serem adicionados à lista de reprodução serão removidos. \nTem a certeza?</string>
<string name="remove_watched_popup_partially_watched_streams">Sim e também os vídeos parcialmente vistos</string> <string name="remove_watched_popup_partially_watched_streams">Sim e também os vídeos parcialmente vistos</string>
<string name="remove_watched_popup_title">Remover transmissões vistas?</string> <string name="remove_watched_popup_title">Remover transmissões vistas?</string>
<string name="remove_watched">Remover visualizados</string> <string name="remove_watched">Remover visualizados</string>
@@ -857,8 +857,11 @@
<string name="entry_deleted">Entrada apagada</string> <string name="entry_deleted">Entrada apagada</string>
<string name="account_terminated_service_provides_reason">Conta terminada\n\n%1$s fornece esta razão: %2$s</string> <string name="account_terminated_service_provides_reason">Conta terminada\n\n%1$s fornece esta razão: %2$s</string>
<string name="player_http_invalid_status">Erro HTTP %1$s recebido do servidor ao reproduzir</string> <string name="player_http_invalid_status">Erro HTTP %1$s recebido do servidor ao reproduzir</string>
<string name="sign_in_confirm_not_bot_error">%1$s recusou fornecer dados, pedindo por um login para confirmar que o solicitante não é um bot.\n\nO seu IP pode ter sido temporariamente banido por %1$s, pode esperar algum tempo ou mudar para um IP diferente (por exemplo, a ligar / desligar uma VPN, ou a alternar de Wi-Fi para dados móveis).</string> <string name="sign_in_confirm_not_bot_error">%1$s recusou fornecer dados, pedindo por um login para confirmar que o solicitante não é um bot.\n\nO seu IP pode ter sido temporariamente banido por %1$s, você pode esperar algum tempo ou mudar para um IP diferente (por exemplo, a ligar/desligar uma VPN, ou a alternar de Wi-Fi para dados móveis).\n\nConfira <a href="%2$s">este artigo do FAQ</a> para mais informações.</string>
<string name="unsupported_content_in_country">Este conteúdo não está disponível para o país de conteúdo atualmente selecionado.\n\nAltere a sua seleção de \"Configurações &gt; Conteúdo &gt; País predefinido de conteúdo\".</string> <string name="unsupported_content_in_country">Este conteúdo não está disponível para o país de conteúdo atualmente selecionado.\n\nAltere a sua seleção de \"Configurações &gt; Conteúdo &gt; País predefinido de conteúdo\".</string>
<string name="player_http_403">Erro HTTP 403 recebido do servidor durante a reprodução, provavelmente causado pela URL de streaming expirado ou IP banido</string> <string name="player_http_403">Erro HTTP 403 recebido do servidor durante a reprodução, provavelmente causado pela URL de streaming expirado ou IP banido</string>
<string name="youtube_player_http_403">Erro HTTP 403 recebido do servidor durante a reprodução, provavelmente causado por um bloqueio de IP ou problemas de desofuscação da URL de streaming</string> <string name="youtube_player_http_403">Erro HTTP 403 recebido do servidor durante a reprodução, provavelmente causado por um bloqueio de IP ou problemas de desofuscação da URL de streaming</string>
<string name="kao_dialog_warning">Em agosto de 2025, o Google anunciou que, a partir de setembro de 2026, a instalação de apps exigirá a verificação do programador para todas as apps Android em dispositivos certificados, incluindo aqueles instalados fora da Play Store. Como os programadores do NewPipe não concordam com este requisito, o NewPipe já não funcionará em dispositivos Android certificados após essa data.</string>
<string name="kao_dialog_more_info">Detalhes</string>
<string name="kao_solution">Solução</string>
</resources> </resources>

View File

@@ -1,3 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
</resources>

View File

@@ -633,7 +633,7 @@
<string name="feed_load_error">Ошибка загрузки подписки</string> <string name="feed_load_error">Ошибка загрузки подписки</string>
<string name="open_website_license">Открыть веб-сайт</string> <string name="open_website_license">Открыть веб-сайт</string>
<string name="account_terminated">Аккаунт отключён</string> <string name="account_terminated">Аккаунт отключён</string>
<string name="downloads_storage_use_saf_summary_api_29">Начиная с Android 10 поддерживается только «Storage Access Framework»</string> <string name="downloads_storage_use_saf_summary_api_29">Начиная с Android 10, поддерживается только \"Storage Access Framework\"</string>
<string name="downloads_storage_ask_summary_no_saf_notice">Спрашивать, куда сохранять каждую загрузку</string> <string name="downloads_storage_ask_summary_no_saf_notice">Спрашивать, куда сохранять каждую загрузку</string>
<string name="no_dir_yet">Папка для загрузки ещё не выбрана, укажите папку для загрузки сейчас</string> <string name="no_dir_yet">Папка для загрузки ещё не выбрана, укажите папку для загрузки сейчас</string>
<string name="off">Отключить</string> <string name="off">Отключить</string>
@@ -866,4 +866,7 @@
<string name="youtube_player_http_403">Во время воспроизведения получена ошибка HTTP 403 от сервера, вероятно, вызванная блокировкой IP-адреса или проблемами деобфускации URL-адреса потоковой передачи</string> <string name="youtube_player_http_403">Во время воспроизведения получена ошибка HTTP 403 от сервера, вероятно, вызванная блокировкой IP-адреса или проблемами деобфускации URL-адреса потоковой передачи</string>
<string name="sign_in_confirm_not_bot_error">%1$s отказался предоставить данные, запросив логин для подтверждения, что запросчик не бот.\n\nВозможно, ваш IP-адрес временно заблокирован %1$s. Вы можете подождать некоторое время или переключиться на другой IP-адрес (например, включив/выключив VPN или переключившись с Wi-Fi на мобильный интернет).</string> <string name="sign_in_confirm_not_bot_error">%1$s отказался предоставить данные, запросив логин для подтверждения, что запросчик не бот.\n\nВозможно, ваш IP-адрес временно заблокирован %1$s. Вы можете подождать некоторое время или переключиться на другой IP-адрес (например, включив/выключив VPN или переключившись с Wi-Fi на мобильный интернет).</string>
<string name="unsupported_content_in_country">Этот контент недоступен для выбранной страны контента.\n\nИзмените свой выбор в разделе «Настройки &gt; Контент &gt; Страна контента по умолчанию».</string> <string name="unsupported_content_in_country">Этот контент недоступен для выбранной страны контента.\n\nИзмените свой выбор в разделе «Настройки &gt; Контент &gt; Страна контента по умолчанию».</string>
<string name="kao_dialog_warning">В августе 2025 года, Google анонсировала, что с сентября 2026 года, установка приложений потребует верификации разработчика для всех Android приложений на сертифицированных устройствах, включая те, которые были установлены не через Play Store. Поскольку разработчики NewPipe не согласны с этим требованием, NewPipe перестанет работать на сертифицированных Android устройствах после этой даты.</string>
<string name="kao_dialog_more_info">Подробнее</string>
<string name="kao_solution">Решение</string>
</resources> </resources>

View File

@@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

View File

@@ -860,6 +860,32 @@
<string name="player_http_403">Počas prehrávania bola zo servera prijatá chyba HTTP 403, pravdepodobne spôsobená vypršaním platnosti streamingovej adresy URL alebo zákazom IP adresy</string> <string name="player_http_403">Počas prehrávania bola zo servera prijatá chyba HTTP 403, pravdepodobne spôsobená vypršaním platnosti streamingovej adresy URL alebo zákazom IP adresy</string>
<string name="player_http_invalid_status">Chyba HTTP %1$s prijatá zo servera počas prehrávania</string> <string name="player_http_invalid_status">Chyba HTTP %1$s prijatá zo servera počas prehrávania</string>
<string name="youtube_player_http_403">Chyba HTTP 403 prijatá zo servera počas prehrávania, pravdepodobne spôsobená zákazom IP adresy alebo problémami s deobfuskáciou streamingovej URL adresy</string> <string name="youtube_player_http_403">Chyba HTTP 403 prijatá zo servera počas prehrávania, pravdepodobne spôsobená zákazom IP adresy alebo problémami s deobfuskáciou streamingovej URL adresy</string>
<string name="sign_in_confirm_not_bot_error">%1$s odmietol poskytnúť údaje, žiada o prihlásenie na potvrdenie, že žiadateľ nie je bot.\n\nVaša IP adresa mohla byť dočasne zakázaná %1$s, môžete nejaký čas počkať alebo prejsť na inú IP adresu (napríklad zapnutím/vypnutím VPN alebo prepnutím z WiFi na mobilné dáta).</string> <string name="sign_in_confirm_not_bot_error">%1$s odmietol poskytnúť údaje, žiada o prihlásenie na potvrdenie, že žiadateľ nie je bot.\n\nVaša IP adresa mohla byť dočasne zakázaná %1$s, môžete nejaký čas počkať alebo prejsť na inú IP adresu (napríklad zapnutím/vypnutím VPN alebo prepnutím z WiFi na mobilné dáta).\n\nPozrite si <a href="%2$s">túto časť FAQ</a> pre viac informácií.</string>
<string name="unsupported_content_in_country">Tento obsah nie je dostupný pre aktuálne zvolenú krajinu obsahu.\n\nZmeňte výber v ponuke \"Nastavenia &gt; Obsah &gt; Predvolená krajina obsahu\".</string> <string name="unsupported_content_in_country">Tento obsah nie je dostupný pre aktuálne zvolenú krajinu obsahu.\n\nZmeňte výber v ponuke \"Nastavenia &gt; Obsah &gt; Predvolená krajina obsahu\".</string>
<string name="kao_dialog_warning">V auguste 2025 spoločnosť Google oznámila, že od septembra 2026 bude inštalácia aplikácií vyžadovať overenie vývojára pre všetky aplikácie Android na certifikovaných zariadeniach, vrátane tých, ktoré sú inštalované mimo obchodu Play Store. Keďže vývojári NewPipe s touto požiadavkou nesúhlasia, NewPipe po tomto termíne nebude na certifikovaných zariadeniach Android fungovať.</string>
<string name="kao_dialog_more_info">Podrobnosti</string>
<string name="kao_solution">Riešenie</string>
<plurals name="export_subscriptions">
<item quantity="one">Exportovanie %d odberu…</item>
<item quantity="few">Exportovanie %d odberov…</item>
<item quantity="many">Exportovanie %d odberov…</item>
<item quantity="other">Exportovanie %d odberov…</item>
</plurals>
<plurals name="load_subscriptions">
<item quantity="one">Načítanie %d odberu…</item>
<item quantity="few">Načítanie %d odberov…</item>
<item quantity="many">Načítanie %d odberov…</item>
<item quantity="other">Načítanie %d odberov…</item>
</plurals>
<plurals name="import_subscriptions">
<item quantity="one">Importovanie %d odberu…</item>
<item quantity="few">Importovanie %d odberov…</item>
<item quantity="many">Importovanie %d odberov…</item>
<item quantity="other">Importovanie %d odberov…</item>
</plurals>
<string name="import_subscriptions_title">Importovať odbery</string>
<string name="export_subscriptions_title">Exportovať odbery</string>
<string name="import_subscriptions_summary">Import odberov z predchádzajúceho exportu .json</string>
<string name="export_subscriptions_summary">Export vašich odberov do súboru .json</string>
<string name="import_from_previous_export">Importovať z predchádzajúceho exportu</string>
</resources> </resources>

View File

@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="use_inexact_seek_title">Dhaafinta dagdaga ah</string> <string name="use_inexact_seek_title">Isticmaal Dhaafinta dagdaga ah</string>
<string name="popup_remember_size_pos_summary">Xusuusnow meeshii iyo cabirkii udambeeyay ee daaqada</string> <string name="popup_remember_size_pos_summary">Xusuusnow meeshii iyo cabirkii udambeeyay ee daaqada</string>
<string name="popup_remember_size_pos_title">Xusuusnow fadhiga daaqada</string> <string name="popup_remember_size_pos_title">Xusuusnow fadhiga daaqada</string>
<string name="dark_theme_title">Madow</string> <string name="dark_theme_title">Mugdi</string>
<string name="theme_title">Nashqada</string> <string name="theme_title">Nashqada</string>
<string name="default_video_format_title">Nooca muuqaalka</string> <string name="default_video_format_title">Nooca muuqaalka</string>
<string name="default_audio_format_title">Nooca dhagaysiga</string> <string name="default_audio_format_title">Nooca Maqaalka</string>
<string name="notification_colorize_summary">Androidka hakuu baddalo midabka ogaysiiska galka waxa daaran asagoo kusalaynaya midabka galka shayga daaran (aalladahoo dhan looma wada heli karo nidaamkan)</string> <string name="notification_colorize_summary">Androidka hakuu baddalo midabka ogaysiiska galka waxa daaran asagoo kusalaynaya midabka galka shayga daaran (aalladahoo dhan looma wada heli karo nidaamkan)</string>
<string name="notification_colorize_title">Midabbee ogaysiiska</string> <string name="notification_colorize_title">Midabbee ogaysiiska</string>
<string name="notification_action_buffering">Soo Kicinaya</string> <string name="notification_action_buffering">Soo Kicinaya</string>
@@ -14,25 +14,25 @@
<string name="notification_action_repeat">Ku celi</string> <string name="notification_action_repeat">Ku celi</string>
<string name="notification_actions_at_most_three">Ugu badnaan waxad dooran kartaa sadex shay iney ka muuqdaan ogaysiiska yar!</string> <string name="notification_actions_at_most_three">Ugu badnaan waxad dooran kartaa sadex shay iney ka muuqdaan ogaysiiska yar!</string>
<string name="notification_actions_summary">Wax ka baddal hawsha ogaysiiska adigoo dushooda ku dhufanaya. Dooro ilaa sadex kamida si ay uga muuqdaan ogaysiiska yar adigoo saxaya santuuqa dhanka midig kaga yaala</string> <string name="notification_actions_summary">Wax ka baddal hawsha ogaysiiska adigoo dushooda ku dhufanaya. Dooro ilaa sadex kamida si ay uga muuqdaan ogaysiiska yar adigoo saxaya santuuqa dhanka midig kaga yaala</string>
<string name="notification_action_4_title">Batoonka hawsha shanaad</string> <string name="notification_action_4_title">Batoonka shanaad</string>
<string name="notification_action_3_title">Batoonka hawsha afraad</string> <string name="notification_action_3_title">Batoonka afraad</string>
<string name="notification_action_2_title">Batoonka hawsha sadexaad</string> <string name="notification_action_2_title">Batoonka saddexaad</string>
<string name="notification_action_1_title">Batoonka hawsha labaad</string> <string name="notification_action_1_title">Batoonka labaad</string>
<string name="notification_action_0_title">Batoonka hawsha koowaad</string> <string name="notification_action_0_title">Batoonka koowaad</string>
<string name="notification_scale_to_square_image_summary">La ekaysii galka muuqaalka xaga ogaysiisyada ka muuqda cabirka 1:1 ayadoo laga soo baddalayo 16:9</string> <string name="notification_scale_to_square_image_summary">La ekaysii galka muuqaalka xaga ogaysiisyada ka muuqda cabirka 1:1 ayadoo laga soo baddalayo 16:9</string>
<string name="notification_scale_to_square_image_title">Galka la ekaysii cabirka 1:1</string> <string name="notification_scale_to_square_image_title">Galka la ekaysii cabirka 1:1</string>
<string name="show_play_with_kodi_summary">Soo bandhig istikhyaar ah in muuqaalka lagu furo xarunta madadaalada Kodi</string> <string name="show_play_with_kodi_summary">Soo bandhig istikhyaar ah in muuqaalka lagu furo Kodi</string>
<string name="show_play_with_kodi_title">Soodhig istikhyaarka \"Ku fur Kodi\"</string> <string name="show_play_with_kodi_title">Soodhig istikhyaarka \"Ku fur Kodi\"</string>
<string name="kore_not_found">Kushub appka maqan ee Kore\?</string> <string name="kore_not_found">Soo deji appka maqan ee Kore?</string>
<string name="play_with_kodi_title">Ku fur Kodi</string> <string name="play_with_kodi_title">Ku fur Kodi</string>
<string name="show_higher_resolutions_summary">Aalladaha qaar kaliya ayaa furi kara muuqaalada 2K/4K ga ah</string> <string name="show_higher_resolutions_summary">Aalladaha qaar kaliya ayaa furi kara muuqaalada 2K/4K ga ah</string>
<string name="show_higher_resolutions_title">Tus tayooyinka kasii sareeeya</string> <string name="show_higher_resolutions_title">Tus tayooyinka sare</string>
<string name="default_popup_resolution_title">Tayada muuqaalka daaqada</string> <string name="default_popup_resolution_title">Tayada muuqaalka daaqada</string>
<string name="default_resolution_title">Tayada muuqaalka</string> <string name="default_resolution_title">Tayada muuqaalka</string>
<string name="download_path_audio_dialog_title">Dooro khaanada dhagaysiga lasoo dajiyo</string> <string name="download_path_audio_dialog_title">Dooro Khaanada soo dejinta ee faylasha maqalka ah</string>
<string name="download_path_dialog_title">Dooro khaanada muuqaalada lasoo dajiyo</string> <string name="download_path_dialog_title">Dooro khaanada Muuqaallada lagu soo dejinayo</string>
<string name="download_path_audio_summary">Dhagaysiyada lasoo dajiyay halkan ayaa lagu kaydiyaa</string> <string name="download_path_audio_summary">Dhagaysiyada lasoo dajiyay halkan ayaa lagu kaydiyey</string>
<string name="download_path_summary">Muuqaalada lasoo dajiyo halkan ayaa lagu kaydiyaa</string> <string name="download_path_summary">Muuqaalada lasoo dajiyo halkan ayaa lagu kaydiyey</string>
<string name="download_path_audio_title">Khaanada dajinta dhagaysiga</string> <string name="download_path_audio_title">Khaanada dajinta dhagaysiga</string>
<string name="download_path_title">Khaanada dajinta muuqaalada</string> <string name="download_path_title">Khaanada dajinta muuqaalada</string>
<string name="controls_add_to_playlist_title">Ku Dar</string> <string name="controls_add_to_playlist_title">Ku Dar</string>
@@ -41,17 +41,17 @@
<string name="tab_choose">Dooro Daaqada</string> <string name="tab_choose">Dooro Daaqada</string>
<string name="tab_bookmarks">La calaamadsaday</string> <string name="tab_bookmarks">La calaamadsaday</string>
<string name="tab_subscriptions">Rukunka</string> <string name="tab_subscriptions">Rukunka</string>
<string name="show_info">Faahfaahinta</string> <string name="show_info">Tus Faahfaahinta</string>
<string name="subscription_update_failed">Lama cusbooneysiin karo rukunka</string> <string name="subscription_update_failed">Lama cusbooneysiin karo rukunka</string>
<string name="subscription_change_failed">Lama baddali karo rukunka</string> <string name="subscription_change_failed">Lama baddali karo rukunka</string>
<string name="channel_unsubscribed">Kanaalka waad iskajoojisay</string> <string name="channel_unsubscribed">Kanaalka waad iskajoojisay</string>
<string name="unsubscribe">Iskajooji Rukunka</string> <string name="unsubscribe">Iskajooji Rukunka</string>
<string name="subscribed_button_title">Rukuntay</string> <string name="subscribed_button_title">Rukuntay</string>
<string name="subscribe_button_title">Rukumo</string> <string name="subscribe_button_title">Rukumo</string>
<string name="use_external_audio_player_title">Isticmaal dhagaysi daare dibada ah</string> <string name="use_external_audio_player_title">Isticmaal dhagaysi Daare dibada ah</string>
<string name="use_external_video_player_summary">Codka ayuu ka saaraa tayada muuqaalada qaar</string> <string name="use_external_video_player_summary">Codka ayuu ka saaraa tayada muuqaalada qaar</string>
<string name="use_external_video_player_title">Isticmaal muuqaal daare dibada ah</string> <string name="use_external_video_player_title">Isticmaal muuqaal daare dibada ah</string>
<string name="share_dialog_title">La wadaag</string> <string name="share_dialog_title">Ku La wadaag</string>
<string name="search_showing_result_for">Kutusaya natiijooyinka: %s</string> <string name="search_showing_result_for">Kutusaya natiijooyinka: %s</string>
<string name="did_you_mean">Ma waxaad ka waday \"%1$s\"\?</string> <string name="did_you_mean">Ma waxaad ka waday \"%1$s\"\?</string>
<string name="settings">Fadhiga</string> <string name="settings">Fadhiga</string>
@@ -64,7 +64,7 @@
<string name="no_player_found_toast">Wax fura lama helin shaygan. (waxaad Ku shuban kartaa VLC si aad u furto).</string> <string name="no_player_found_toast">Wax fura lama helin shaygan. (waxaad Ku shuban kartaa VLC si aad u furto).</string>
<string name="no_player_found">Wax fura lama helin shaygan. Ku shubo VLC\?</string> <string name="no_player_found">Wax fura lama helin shaygan. Ku shubo VLC\?</string>
<string name="upload_date_text">Lasoo galiyay: %1$s</string> <string name="upload_date_text">Lasoo galiyay: %1$s</string>
<string name="main_bg_subtitle">Ku dhufo waynaysada 🔍 si aad wax uraadiso.</string> <string name="main_bg_subtitle">Ku dhufo raadinta si aad wax uraadiso.</string>
<string name="overwrite_unrelated_warning">Shay magacan leh ayaa horay ujiray</string> <string name="overwrite_unrelated_warning">Shay magacan leh ayaa horay ujiray</string>
<string name="overwrite">Ku badal</string> <string name="overwrite">Ku badal</string>
<string name="generate_unique_name">Usamee magac gaar ah</string> <string name="generate_unique_name">Usamee magac gaar ah</string>
@@ -262,7 +262,7 @@
<string name="error_report_open_github_notice">Fadlan hubi in arin cilladdan ka hadlaya horay loo wariyay. Marka wax horay u jiray la wariyo markale, wakhti ayaad naga qaadaysaa wakhtigaas oo aan cilada ku sixi la hayn.</string> <string name="error_report_open_github_notice">Fadlan hubi in arin cilladdan ka hadlaya horay loo wariyay. Marka wax horay u jiray la wariyo markale, wakhti ayaad naga qaadaysaa wakhtigaas oo aan cilada ku sixi la hayn.</string>
<string name="error_report_open_issue_button_text">Ku wari xaga GitHub-ka</string> <string name="error_report_open_issue_button_text">Ku wari xaga GitHub-ka</string>
<string name="copy_for_github">Koobiyee warka oo diyaarsan</string> <string name="copy_for_github">Koobiyee warka oo diyaarsan</string>
<string name="error_report_button_text">Khaladkan email ahaan ku warceli</string> <string name="error_report_button_text">Khaladkan email ahaan uga war bixi</string>
<string name="sorry_string">Waan ka xunahay, sidaa inay dhacdo ma ahayn.</string> <string name="sorry_string">Waan ka xunahay, sidaa inay dhacdo ma ahayn.</string>
<string name="permission_display_over_apps">U ogolow appka inuu dul fuulo applicationada kale</string> <string name="permission_display_over_apps">U ogolow appka inuu dul fuulo applicationada kale</string>
<string name="restore_defaults_confirmation">Ma rabtaa inaad sidii hore kuceliso\?</string> <string name="restore_defaults_confirmation">Ma rabtaa inaad sidii hore kuceliso\?</string>
@@ -400,11 +400,11 @@
<string name="show_comments_title">Tus faallooyinka</string> <string name="show_comments_title">Tus faallooyinka</string>
<string name="clear_queue_confirmation_description">Hormada daareha hadda wax shidaya waa la baddali doonaa</string> <string name="clear_queue_confirmation_description">Hormada daareha hadda wax shidaya waa la baddali doonaa</string>
<string name="clear_queue_confirmation_summary">Kala baddalka daareha waxay badali kartaa hormada sidaas darteed waydii in la xaqiijiyo intaan hormada la tirtirin</string> <string name="clear_queue_confirmation_summary">Kala baddalka daareha waxay badali kartaa hormada sidaas darteed waydii in la xaqiijiyo intaan hormada la tirtirin</string>
<string name="clear_queue_confirmation_title">Xaqiijinta tirtirka hormada</string> <string name="clear_queue_confirmation_title">Weydii xaqiijin ka hor intaadan tirtirin saf-ka</string>
<string name="seek_duration_title">Wakhtiga horay udhaafinta/dibucelinta</string> <string name="seek_duration_title">Wakhtiga horay udhaafinta/dibucelinta</string>
<string name="black_theme_title">Mugdi</string> <string name="black_theme_title">Madow</string>
<string name="light_theme_title">Caddaan</string> <string name="light_theme_title">Iftiin</string>
<string name="play_audio">Dhagaysi</string> <string name="play_audio">Maqal</string>
<string name="notification_action_nothing">Waxba</string> <string name="notification_action_nothing">Waxba</string>
<string name="search">Raadi</string> <string name="search">Raadi</string>
<string name="download">Daji</string> <string name="download">Daji</string>
@@ -491,7 +491,7 @@
</plurals> </plurals>
<string name="new_seek_duration_toast">Ayadooy ugu wacantahay xayiraad xaga ExoPlayer-ka ah xadka dhaaf-dhaafinta waa %d ilbiriqsi</string> <string name="new_seek_duration_toast">Ayadooy ugu wacantahay xayiraad xaga ExoPlayer-ka ah xadka dhaaf-dhaafinta waa %d ilbiriqsi</string>
<string name="remove_watched_popup_partially_watched_streams">Haa, sidoo kale ku dar muuqaalada qayb laga daawaday</string> <string name="remove_watched_popup_partially_watched_streams">Haa, sidoo kale ku dar muuqaalada qayb laga daawaday</string>
<string name="remove_watched_popup_warning">Muuqaalada la daawaday kahor iyo kadib markii xulka lagu daray waa la saari doonaa. \nMa hubtaa? Arrinkan dib looma soocelin karo!</string> <string name="remove_watched_popup_warning">Muuqaalada la daawaday kahor iyo kadib markii xulka lagu daray waa la saari doonaa. \nMa hubtaa?</string>
<string name="remove_watched_popup_title">Saar muuqaalada la daawaday?</string> <string name="remove_watched_popup_title">Saar muuqaalada la daawaday?</string>
<string name="remove_watched">Saar kuwa la daawaday</string> <string name="remove_watched">Saar kuwa la daawaday</string>
<string name="systems_language">Aaladu saytahay</string> <string name="systems_language">Aaladu saytahay</string>
@@ -520,7 +520,7 @@
<string name="error_postprocessing_failed">Habayntii way guuldareystay</string> <string name="error_postprocessing_failed">Habayntii way guuldareystay</string>
<string name="error_http_not_found">Lama helin</string> <string name="error_http_not_found">Lama helin</string>
<string name="error_http_unsupported_range">Martigaliyuhu ma aqbalo dajinta qaybaha badan leh, iskula day @string/msg_threads = 1</string> <string name="error_http_unsupported_range">Martigaliyuhu ma aqbalo dajinta qaybaha badan leh, iskula day @string/msg_threads = 1</string>
<string name="error_connect_host">Kuma xidhi karo martigaliyaha</string> <string name="error_connect_host">Kuma xidhmi karo server-ka</string>
<string name="error_unknown_host">Lama heli karo martigaliyaha</string> <string name="error_unknown_host">Lama heli karo martigaliyaha</string>
<string name="error_ssl_exception">Lama samayn karo iskuxidh amni ah</string> <string name="error_ssl_exception">Lama samayn karo iskuxidh amni ah</string>
<string name="error_path_creation">khaanadii la rabay lama samayn karo</string> <string name="error_path_creation">khaanadii la rabay lama samayn karo</string>
@@ -630,7 +630,7 @@
<string name="remote_search_suggestions">Soojeedinada raadinta banaanka</string> <string name="remote_search_suggestions">Soojeedinada raadinta banaanka</string>
<string name="local_search_suggestions">Soojeedinada raadinta gudaha</string> <string name="local_search_suggestions">Soojeedinada raadinta gudaha</string>
<string name="progressive_load_interval_title">Cabirka soodaarida udhexeeya</string> <string name="progressive_load_interval_title">Cabirka soodaarida udhexeeya</string>
<string name="crash_the_player">Jabi Daareha</string> <string name="crash_the_player">Jabi Daaraha</string>
<string name="yes">Haa</string> <string name="yes">Haa</string>
<string name="no">Maya</string> <string name="no">Maya</string>
<string name="search_with_service_name">Raadi %1$s</string> <string name="search_with_service_name">Raadi %1$s</string>

View File

@@ -847,4 +847,7 @@
<string name="youtube_player_http_403">HTTP-fel 403 mottogs från servern under spelning, troligen orsakat av en IP-avstängning eller problem med deobfuskering av streaming-URL:er</string> <string name="youtube_player_http_403">HTTP-fel 403 mottogs från servern under spelning, troligen orsakat av en IP-avstängning eller problem med deobfuskering av streaming-URL:er</string>
<string name="sign_in_confirm_not_bot_error">%1$s vägrade att tillhandahålla data och bad om en inloggning för att bekräfta att den som begärde detta inte är en bot.\n\nDin IP-adress kan ha blivit tillfälligt avstängd av %1$s. Du kan vänta en stund eller byta till en annan IP-adress (till exempel genom att slå på/av ett VPN eller genom att byta från WiFi till mobildata).</string> <string name="sign_in_confirm_not_bot_error">%1$s vägrade att tillhandahålla data och bad om en inloggning för att bekräfta att den som begärde detta inte är en bot.\n\nDin IP-adress kan ha blivit tillfälligt avstängd av %1$s. Du kan vänta en stund eller byta till en annan IP-adress (till exempel genom att slå på/av ett VPN eller genom att byta från WiFi till mobildata).</string>
<string name="unsupported_content_in_country">Detta innehåll är inte tillgängligt för det valda innehållslandet.\n\nÄndra ditt val från \"Inställningar &gt; Innehåll &gt; Standardinnehållsland\".</string> <string name="unsupported_content_in_country">Detta innehåll är inte tillgängligt för det valda innehållslandet.\n\nÄndra ditt val från \"Inställningar &gt; Innehåll &gt; Standardinnehållsland\".</string>
<string name="kao_dialog_warning">Google har meddelat att från och med 2026/2027 kommer alla appar på certifierade Android-enheter att kräva att utvecklarna lämnar sina personliga identitetsuppgifter direkt till Google. Eftersom utvecklarna av denna app inte accepterar detta krav kommer appen inte längre att fungera på certifierade Android-enheter efter den tiden.</string>
<string name="kao_dialog_more_info">Detaljer</string>
<string name="kao_solution">Lösning</string>
</resources> </resources>

View File

@@ -845,6 +845,26 @@
<string name="player_http_403">Oynatırken sunucudan HTTP 403 hatası alındı, akış URLsi bitmiş ya da IP engellenmiş olabilir</string> <string name="player_http_403">Oynatırken sunucudan HTTP 403 hatası alındı, akış URLsi bitmiş ya da IP engellenmiş olabilir</string>
<string name="player_http_invalid_status">Oynatırken sunucudan HTTP %1$s hatası alındı</string> <string name="player_http_invalid_status">Oynatırken sunucudan HTTP %1$s hatası alındı</string>
<string name="youtube_player_http_403">Oynatırken sunucudan HTTP 403 hatası alındı, IP engeli ya da akış URLsi çözme sorunları olabilir</string> <string name="youtube_player_http_403">Oynatırken sunucudan HTTP 403 hatası alındı, IP engeli ya da akış URLsi çözme sorunları olabilir</string>
<string name="sign_in_confirm_not_bot_error">%1$s veri sağlamayı geri çevirdi, istekçinin robot olmadığını doğrulaması için oturum açmasını istiyor.\n\n%1$s, IP adresinizi geçici olarak engellemiş olabilir, bir süre bekleyebilir ya da başka IP\'ye geçebilirsiniz (örneğin VPN\'i açıp/kapatarak ya da WiFi\'den mobil veriye geçerek).</string> <string name="sign_in_confirm_not_bot_error">%1$s veri sağlamıyor, istekçinin robot olmadığını doğrulaması için oturum açmasını istiyor.\n\n%1$s, IP adresinizi geçici olarak engellemiş olabilir, bir süre bekleyebilir ya da başka IP\'ye geçebilirsiniz (örneğin VPN\'i açıp/kapatarak ya da WiFi\'den mobil veriye geçerek).\n\nDaha çok bilgi için <a href="%2$s">bu SSS girdisine</a> bakın.</string>
<string name="unsupported_content_in_country">Bu içerik şu anda seçili içerik ülkesinde kullanılamıyor.\n\nSeçiminizi \"Ayarlar &gt; İçerik &gt; Öntanımlı içerik ülkesi\"nden değiştirin.</string> <string name="unsupported_content_in_country">Bu içerik şu anda seçili içerik ülkesinde kullanılamıyor.\n\nSeçiminizi \"Ayarlar &gt; İçerik &gt; Öntanımlı içerik ülkesi\"nden değiştirin.</string>
<string name="kao_dialog_warning">Google, Eylül 2026\'dan sonra sertifikalı Android aygıtlarda Play Store dışından kurulmuşlarla birlikte tüm uygulamaların, geliştiricilerin kişisel kimlik bilgilerini doğrudan Googlea göndermesini gerektireceğini duyurdu. NewPipe geliştiricileri bu zorunluluğu kabul etmediğinden, NewPipe bu tarihten sonra sertifikalı Android aygıtlarda çalışmayacaktır.</string>
<string name="kao_dialog_more_info">Ayrıntılar</string>
<string name="kao_solution">Çözüm</string>
<plurals name="export_subscriptions">
<item quantity="one">%d abonelik dışa aktarılıyor…</item>
<item quantity="other">%d abonelik dışa aktarılıyor…</item>
</plurals>
<plurals name="load_subscriptions">
<item quantity="one">%d abonelik yükleniyor…</item>
<item quantity="other">%d abonelik yükleniyor…</item>
</plurals>
<plurals name="import_subscriptions">
<item quantity="one">%d abonelik içeri aktarılıyor…</item>
<item quantity="other">%d abonelik içeri aktarılıyor…</item>
</plurals>
<string name="import_subscriptions_title">Abonelikleri içeri aktar</string>
<string name="export_subscriptions_title">Abonelikleri dışarı aktar</string>
<string name="import_subscriptions_summary">Abonelikleri önceki dışarı aktarmadaki .json dosyası ile içeri aktar</string>
<string name="export_subscriptions_summary">Aboneliklerini bir .json dosyasında dışarı aktar</string>
<string name="import_from_previous_export">Önceki dışarı aktarmadan içe aktar</string>
</resources> </resources>

View File

@@ -491,7 +491,7 @@
<string name="feed_use_dedicated_fetch_method_disable_button">Звичайний режим</string> <string name="feed_use_dedicated_fetch_method_disable_button">Звичайний режим</string>
<string name="feed_use_dedicated_fetch_method_enable_button">Швидкий режим</string> <string name="feed_use_dedicated_fetch_method_enable_button">Швидкий режим</string>
<string name="feed_use_dedicated_fetch_method_summary">Доступно для деяких служб, швидке, але може повертати не весь вміст каналу і часто неповну інформацію (тривалість, тип елемента, статус трансляції)</string> <string name="feed_use_dedicated_fetch_method_summary">Доступно для деяких служб, швидке, але може повертати не весь вміст каналу і часто неповну інформацію (тривалість, тип елемента, статус трансляції)</string>
<string name="feed_use_dedicated_fetch_method_title">Оновлення з RSS, коли воно є</string> <string name="feed_use_dedicated_fetch_method_title">Отримувати з виділеної стрічки, коли доступно</string>
<string name="feed_update_threshold_option_always_update">Оновлювати постійно</string> <string name="feed_update_threshold_option_always_update">Оновлювати постійно</string>
<string name="feed_update_threshold_summary">Період актуальності підписок після поновлення — %s</string> <string name="feed_update_threshold_summary">Період актуальності підписок після поновлення — %s</string>
<string name="feed_update_threshold_title">Поріг оновлення підписок</string> <string name="feed_update_threshold_title">Поріг оновлення підписок</string>
@@ -510,8 +510,8 @@
<string name="feed_oldest_subscription_update">Останнє оновлення: %s</string> <string name="feed_oldest_subscription_update">Останнє оновлення: %s</string>
<string name="new_seek_duration_toast">Через обмеження ExoPlayer точність перемотування становить %d секунд</string> <string name="new_seek_duration_toast">Через обмеження ExoPlayer точність перемотування становить %d секунд</string>
<string name="remove_watched_popup_partially_watched_streams">Так, а також частково переглянуті відео</string> <string name="remove_watched_popup_partially_watched_streams">Так, а також частково переглянуті відео</string>
<string name="remove_watched_popup_warning">Відео, які Ви переглядали до та після додавання в добірку, вилучатимуться. \nВи впевнені? Це незворотна дія!</string> <string name="remove_watched_popup_warning">Потоки, які були переглянуті до та після додавання в добірку, будуть видалені. \nВи впевнені?</string>
<string name="remove_watched_popup_title">Видалити переглянуті відео?</string> <string name="remove_watched_popup_title">Видалити переглянуті потоки?</string>
<string name="remove_watched">Видалити переглянуті</string> <string name="remove_watched">Видалити переглянуті</string>
<string name="playlist_no_uploader">Створено автоматично (автора не знайдено)</string> <string name="playlist_no_uploader">Створено автоматично (автора не знайдено)</string>
<string name="infinite_videos">∞ вiдео</string> <string name="infinite_videos">∞ вiдео</string>
@@ -604,7 +604,7 @@
<string name="notification_scale_to_square_image_summary">Обрізати мініатюру відео показувану в сповіщенні з пропорцій 16: 9 до 1:1</string> <string name="notification_scale_to_square_image_summary">Обрізати мініатюру відео показувану в сповіщенні з пропорцій 16: 9 до 1:1</string>
<string name="disable_media_tunneling_summary">Вимкнення тунелювання медіаданих за наявності чорного екрана або гальмування під час відтворення відео.</string> <string name="disable_media_tunneling_summary">Вимкнення тунелювання медіаданих за наявності чорного екрана або гальмування під час відтворення відео.</string>
<string name="disable_media_tunneling_title">Вимкнути тунелювання медіа</string> <string name="disable_media_tunneling_title">Вимкнути тунелювання медіа</string>
<string name="downloads_storage_use_saf_summary_api_29">«Фреймворк доступу до сховища» (SAF) підтримується лише починаючи з Android 10</string> <string name="downloads_storage_use_saf_summary_api_29">Починаючи з Android 10, підтримується тільки \"Storage Access Framework\"</string>
<string name="downloads_storage_ask_summary_no_saf_notice">Вас питатиме, куди зберігати кожне завантаження</string> <string name="downloads_storage_ask_summary_no_saf_notice">Вас питатиме, куди зберігати кожне завантаження</string>
<string name="no_dir_yet">Не вказано теки завантаження, оберіть типову теку завантаження зараз</string> <string name="no_dir_yet">Не вказано теки завантаження, оберіть типову теку завантаження зараз</string>
<string name="open_website_license">Відкрити вебсайт</string> <string name="open_website_license">Відкрити вебсайт</string>
@@ -866,4 +866,7 @@
<string name="youtube_player_http_403">Під час відтворення від сервера отримано помилку HTTP 403, ймовірно, через заборону IP-адреси або проблеми з деобфускацією URL-адреси потокової передачі</string> <string name="youtube_player_http_403">Під час відтворення від сервера отримано помилку HTTP 403, ймовірно, через заборону IP-адреси або проблеми з деобфускацією URL-адреси потокової передачі</string>
<string name="sign_in_confirm_not_bot_error">%1$s відмовився надати дані, запитуючи логін для підтвердження того, що запитувач не є ботом.\n\nВаша IP-адреса могла бути тимчасово заблокована %1$s. Ви можете почекати деякий час або перейти на іншу IP-адресу (наприклад, увімкнувши/вимкнувши VPN або переключившись з Wi-Fi на мобільні дані).</string> <string name="sign_in_confirm_not_bot_error">%1$s відмовився надати дані, запитуючи логін для підтвердження того, що запитувач не є ботом.\n\nВаша IP-адреса могла бути тимчасово заблокована %1$s. Ви можете почекати деякий час або перейти на іншу IP-адресу (наприклад, увімкнувши/вимкнувши VPN або переключившись з Wi-Fi на мобільні дані).</string>
<string name="unsupported_content_in_country">Цей контент недоступний для вибраної країни контенту.\n\nЗмініть свій вибір у розділі \"Налаштування &gt; Контент &gt; Країна контенту за замовчуванням\".</string> <string name="unsupported_content_in_country">Цей контент недоступний для вибраної країни контенту.\n\nЗмініть свій вибір у розділі \"Налаштування &gt; Контент &gt; Країна контенту за замовчуванням\".</string>
<string name="kao_dialog_warning">У серпні 2025 року, Google анонсувала, що з вересня 2026 року, для встановлення застосунків буде потрібна верифікація розробника для всіх Android застосунків на сертифікованих пристроях, включаючи ті, що були встановлені не через Play Store. Оскільки розробники NewPipe не згодні з цією вимогою, NewPipe перестане працювати на сертифікованих Android пристроях після цієї дати.</string>
<string name="kao_dialog_more_info">Детальніше</string>
<string name="kao_solution">Вирішення</string>
</resources> </resources>

View File

@@ -62,7 +62,7 @@
<string name="general_error">Lỗi</string> <string name="general_error">Lỗi</string>
<string name="network_error">Lỗi kết nối mạng</string> <string name="network_error">Lỗi kết nối mạng</string>
<string name="could_not_load_thumbnails">Không thể tải tất cả hình thu nhỏ</string> <string name="could_not_load_thumbnails">Không thể tải tất cả hình thu nhỏ</string>
<string name="parsing_error">Không thể phân tích cú pháp trang web vì trang này đã ngừng hoạt động vào 21/07/2025.</string> <string name="parsing_error">Không thể phân tích cú pháp web.</string>
<string name="content_not_available">Nội dung không khả dụng</string> <string name="content_not_available">Nội dung không khả dụng</string>
<string name="could_not_setup_download_menu">Không thể thiết lập menu tải về</string> <string name="could_not_setup_download_menu">Không thể thiết lập menu tải về</string>
<string name="app_ui_crash">Ứng dụng/Giao diện người dùng bị lỗi</string> <string name="app_ui_crash">Ứng dụng/Giao diện người dùng bị lỗi</string>
@@ -821,8 +821,8 @@
<string name="trending_movies">Phim và chương trình đang thịnh hành</string> <string name="trending_movies">Phim và chương trình đang thịnh hành</string>
<string name="trending_music">Âm nhạc đang thịnh hành</string> <string name="trending_music">Âm nhạc đang thịnh hành</string>
<string name="player_http_403">Đã xảy ra lỗi HTTP 403 trong khi phát, có thể do URL phát sóng đã hết hạn hoặc bị ban IP</string> <string name="player_http_403">Đã xảy ra lỗi HTTP 403 trong khi phát, có thể do URL phát sóng đã hết hạn hoặc bị ban IP</string>
<string name="sign_in_confirm_not_bot_error">%1$s đã từ chối cung cấp dữ liệu, cần phải đăng nhập để xác nhận yêu cầu viên ko phải là bot.\n\nIP này có vẻ đã bị ban tạm thời bởi %1$s, bạn có thể đợi một lúc hoặc chuyển sang IP khác (ví dụ như việc tắt / bật lại VPN, hoặc là chuyển mạng từ WIFI sang 4G/5G).</string> <string name="sign_in_confirm_not_bot_error">%1$s đã từ chối cung cấp dữ liệu, cần phải đăng nhập để xác nhận requester của NewPipe ko phải là bot.\n\nIP này có vẻ đã bị ban tạm thời bởi %1$s, bạn có thể đợi một lúc hoặc chuyển sang IP khác (ví dụ như việc tắt / bật lại VPN, hoặc là chuyển mạng từ WIFI sang 4G/5G).\n\nXem qua <a href="%2$s">phần FAQ này</a> đẻ biết thêm chi tiết</string>
<string name="unsupported_content_in_country">Nội dung này không được hỗ trợ tại quốc gia mà bạn chọn.\n\nHãy đổi quốc gia trong phần \"Cài đặt &gt; Nội dung &gt; Nội dung quốc gia mặc định\".</string> <string name="unsupported_content_in_country">Nội dung này không được hỗ trợ tại quốc gia mà bạn chọn.\n\nHãy đổi quốc gia trong phần \"Cài đặt &gt; Nội dung &gt; Quốc gia nội dung mặc định\".</string>
<string name="permission_display_over_apps_message">Để sử dụng tính năng phát video nổi, hãy chọn %1$s trong Cài đặt Android và bật tính năng %2$s.</string> <string name="permission_display_over_apps_message">Để sử dụng tính năng phát video nổi, hãy chọn %1$s trong Cài đặt Android và bật tính năng %2$s.</string>
<string name="youtube_player_http_403">Đã xảy ra lỗi HTTP 403 trong khi phát, có thể IP này đã bị ban hoặc vấn đề phát URL deobfuscation</string> <string name="youtube_player_http_403">Đã xảy ra lỗi HTTP 403 trong khi phát, có thể IP này đã bị ban hoặc vấn đề phát URL deobfuscation</string>
<string name="permission_display_over_apps_permission_name">\"Cho phép hiển thị trên ứng dụng khác\"</string> <string name="permission_display_over_apps_permission_name">\"Cho phép hiển thị trên ứng dụng khác\"</string>
@@ -831,4 +831,7 @@
<string name="account_terminated_service_provides_reason">Tài khoản bị vô hiệu hóa. \n\n%1$s cung cấp lý do này: %2$s</string> <string name="account_terminated_service_provides_reason">Tài khoản bị vô hiệu hóa. \n\n%1$s cung cấp lý do này: %2$s</string>
<string name="entry_deleted">Entry đã xóa</string> <string name="entry_deleted">Entry đã xóa</string>
<string name="player_http_invalid_status">Đã xảy ra lỗi HTTP %1$s trong khi phát</string> <string name="player_http_invalid_status">Đã xảy ra lỗi HTTP %1$s trong khi phát</string>
<string name="kao_dialog_warning">Từ tháng 8 năm 2025, Google đã thông báo rằng kể từ tháng 9 năm 2026, việc cài app sẽ yêu cầu các nhà phát triển phải xác minh trên những thiết bị đã chứng nhận, kể cả đối với các ứng dụng ngoài Play Store. Vì các nhà phát triển của NewPipe không đồng ý với điều kiện này, nên có lẽ NewPipe sẽ không còn hoạt động trên các máy Android được chứng nhận sau thời điểm ấy.</string>
<string name="kao_dialog_more_info">Chi tiết</string>
<string name="kao_solution">Giải pháp</string>
</resources> </resources>

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="open_in_browser">im brüscher öffn</string>
<string name="yes">passd scho</string>
<string name="ok">passd scho</string>
<string name="cancel">stoarnieren</string>
<string name="install">iser</string>
<string name="no">net</string>
<string name="share">tealn</string>
</resources>

View File

@@ -831,6 +831,23 @@
<string name="player_http_403">播放时从服务器收到 HTTP 403 错误,可能因串流 URL 过期或 IP 封锁导致</string> <string name="player_http_403">播放时从服务器收到 HTTP 403 错误,可能因串流 URL 过期或 IP 封锁导致</string>
<string name="player_http_invalid_status">播放时从服务器收到 HTTP %1$s 错误</string> <string name="player_http_invalid_status">播放时从服务器收到 HTTP %1$s 错误</string>
<string name="youtube_player_http_403">播放时从服务器收到 HTTP 403 错误,可能因 IP 封锁或串流 URL 解密问题导致</string> <string name="youtube_player_http_403">播放时从服务器收到 HTTP 403 错误,可能因 IP 封锁或串流 URL 解密问题导致</string>
<string name="sign_in_confirm_not_bot_error">%1$s 拒绝提供数据, 要求登录确认请求方不是机器人。\n\n你的 IP 可能已经暂时被 %1$s 封禁,你可以等待一段时间或切换到不同 IP (比如开/关 VPN, 或者从 WiFi 连接切换到移动数据)。</string> <string name="sign_in_confirm_not_bot_error">%1$s 拒绝提供数据, 要求登录确认请求方不是机器人。\n\n你的 IP 可能已经暂时被 %1$s 封禁,你可以等待一段时间或切换到不同 IP (比如开/关 VPN, 或者从 WiFi 连接切换到移动数据)。\n\n请见 <a href="%2$s">此 FAQ条目</a> 获取更多信息。</string>
<string name="unsupported_content_in_country">此内容对当前选中的内容地区不可用。\n\n要更改选择请前往 “设置 &gt; 内容 &gt; 默认内容地区”。</string> <string name="unsupported_content_in_country">此内容对当前选中的内容地区不可用。\n\n要更改选择请前往 “设置 &gt; 内容 &gt; 默认内容地区”。</string>
<string name="kao_dialog_warning">2025 年 8 月Google 宣布自 2026 年 9 月起,在已认证设备上安装所有安卓应用都需要开发者验证身份,包括在 Play 商店之外安装的应用。由于 NewPipe 开发者反对此要求NewPipe 在此时间点后不会再在已认证设备上工作。</string>
<string name="kao_dialog_more_info">详情</string>
<string name="kao_solution">解决方案</string>
<plurals name="export_subscriptions">
<item quantity="other">正在导出 %d 个订阅…</item>
</plurals>
<plurals name="load_subscriptions">
<item quantity="other">正在加载 %d 个订阅…</item>
</plurals>
<plurals name="import_subscriptions">
<item quantity="other">正在导入 %d 个订阅…</item>
</plurals>
<string name="import_subscriptions_title">导入订阅</string>
<string name="export_subscriptions_title">导出订阅</string>
<string name="import_subscriptions_summary">从之前的 .json 导出文件导入订阅</string>
<string name="export_subscriptions_summary">导出订阅到 .json 文件</string>
<string name="import_from_previous_export">从之前的导出文件导入</string>
</resources> </resources>

View File

@@ -343,7 +343,7 @@
<string name="generate_unique_name">生成獨特的名稱</string> <string name="generate_unique_name">生成獨特的名稱</string>
<string name="overwrite">覆寫</string> <string name="overwrite">覆寫</string>
<string name="overwrite_finished_warning">有已下載的同名檔案</string> <string name="overwrite_finished_warning">有已下載的同名檔案</string>
<string name="download_already_running">已有進行的下載與此同名</string> <string name="download_already_running">已有正在進行的下載與此同名</string>
<string name="show_error">顯示錯誤</string> <string name="show_error">顯示錯誤</string>
<string name="error_file_creation">無法建立檔案</string> <string name="error_file_creation">無法建立檔案</string>
<string name="error_path_creation">無法建立目的地資料夾</string> <string name="error_path_creation">無法建立目的地資料夾</string>
@@ -377,7 +377,7 @@
<string name="missing_file">檔案已被移動或刪除</string> <string name="missing_file">檔案已被移動或刪除</string>
<string name="overwrite_unrelated_warning">同名的檔案已存在</string> <string name="overwrite_unrelated_warning">同名的檔案已存在</string>
<string name="overwrite_failed">無法覆寫檔案</string> <string name="overwrite_failed">無法覆寫檔案</string>
<string name="download_already_pending">已有擱置的下載與此同名</string> <string name="download_already_pending">已有正在擱置的下載與此同名</string>
<string name="error_postprocessing_stopped">NewPipe 在處理檔案時被關閉</string> <string name="error_postprocessing_stopped">NewPipe 在處理檔案時被關閉</string>
<string name="error_insufficient_storage_left">裝置上沒有剩餘的空間</string> <string name="error_insufficient_storage_left">裝置上沒有剩餘的空間</string>
<string name="error_progress_lost">進度遺失,因為檔案已被刪除</string> <string name="error_progress_lost">進度遺失,因為檔案已被刪除</string>
@@ -811,6 +811,23 @@
<string name="player_http_403">播放時收到來自伺服器的 HTTP 錯誤 403可能因串流網址過期或 IP 封鎖所致</string> <string name="player_http_403">播放時收到來自伺服器的 HTTP 錯誤 403可能因串流網址過期或 IP 封鎖所致</string>
<string name="player_http_invalid_status">播放時收到來自伺服器的 HTTP 錯誤 %1$s</string> <string name="player_http_invalid_status">播放時收到來自伺服器的 HTTP 錯誤 %1$s</string>
<string name="youtube_player_http_403">播放時收到來自伺服器的 HTTP 錯誤 403可能因 IP 封鎖或串流網址去混淆化問題所致</string> <string name="youtube_player_http_403">播放時收到來自伺服器的 HTTP 錯誤 403可能因 IP 封鎖或串流網址去混淆化問題所致</string>
<string name="sign_in_confirm_not_bot_error">%1$s 拒絕提供資料,要求登入以確認請求者並非機器人。\n\n您的 IP 位址可能已被 %1$s 暫時封鎖,您可稍候片刻或切換至其他 IP 位址(例如開啟/關閉 VPN或從 Wi-Fi 切換至行動數據)。</string> <string name="sign_in_confirm_not_bot_error">%1$s 拒絕提供資料,要求登入以確認請求者並非機器人。\n\n您的 IP 位址可能已被 %1$s 暫時封鎖,您可稍候片刻或切換至其他 IP 位址(例如開啟/關閉 VPN或從 Wi-Fi 切換至行動數據)。\n\n更多資訊請參見<a href="%2$s">此 FAQ 條目</a></string>
<string name="unsupported_content_in_country">此內容目前無法於您所選的國家/地區提供。\n\n請至「設定」→「內容」→「預設內容國家」變更您的選擇。</string> <string name="unsupported_content_in_country">此內容目前無法於您所選的國家/地區提供。\n\n請至「設定」→「內容」→「預設內容國家」變更您的選擇。</string>
<string name="kao_dialog_warning">2025年8月Google 宣佈自2026年9月起所有經認證裝置上的 Android 應用程式(包含不是透過 Play 商店安裝的應用程式)皆須通過開發者驗證方可安裝。由於 NewPipe 開發團隊不接受此項要求,該應用程式屆時將無法在經認證的 Android 裝置上運作。</string>
<string name="kao_dialog_more_info">詳細資訊</string>
<string name="kao_solution">解決方案</string>
<plurals name="export_subscriptions">
<item quantity="other">正在匯出 %d 個訂閱…</item>
</plurals>
<plurals name="load_subscriptions">
<item quantity="other">正在載入 %d 個訂閱…</item>
</plurals>
<plurals name="import_subscriptions">
<item quantity="other">正在匯入 %d 個訂閱…</item>
</plurals>
<string name="import_subscriptions_title">匯入訂閱</string>
<string name="export_subscriptions_title">匯出訂閱</string>
<string name="export_subscriptions_summary">匯出您的訂閱至 .json 檔案</string>
<string name="import_subscriptions_summary">從先前匯出的 .json 匯入訂閱</string>
<string name="import_from_previous_export">從先前的匯出檔案匯入</string>
</resources> </resources>

View File

@@ -10,6 +10,8 @@
<string name="saved_tabs_key">saved_tabs_key</string> <string name="saved_tabs_key">saved_tabs_key</string>
<!-- Key values --> <!-- Key values -->
<string name="kao_last_checked_key">kao_last_checked</string>
<string name="download_path_video_key">download_path</string> <string name="download_path_video_key">download_path</string>
<string name="download_path_audio_key">download_path_audio</string> <string name="download_path_audio_key">download_path_audio</string>
@@ -411,6 +413,8 @@
<string name="import_export_data_path">import_export_data_path</string> <string name="import_export_data_path">import_export_data_path</string>
<string name="import_data">import_data</string> <string name="import_data">import_data</string>
<string name="export_data">export_data</string> <string name="export_data">export_data</string>
<string name="import_subscriptions_key">import_subscriptions_key</string>
<string name="export_subscriptions_key">export_subscriptions_key</string>
<string name="clear_cookie_key">clear_cookie</string> <string name="clear_cookie_key">clear_cookie</string>
@@ -1211,7 +1215,6 @@
<item>fi</item> <item>fi</item>
<item>fil</item> <item>fil</item>
<item>fr</item> <item>fr</item>
<item>frc</item>
<item>gl</item> <item>gl</item>
<item>gu</item> <item>gu</item>
<item>he</item> <item>he</item>
@@ -1312,7 +1315,6 @@
<item>Suomen kieli</item> <item>Suomen kieli</item>
<item>Wikang Filipino</item> <item>Wikang Filipino</item>
<item>Français</item> <item>Français</item>
<item>Français (Louisiana)</item>
<item>Galego</item> <item>Galego</item>
<item>ગુજરાતી</item> <item>ગુજરાતી</item>
<item>עברית</item> <item>עברית</item>

View File

@@ -501,6 +501,18 @@
<string name="show_error_snackbar">Show an error snackbar</string> <string name="show_error_snackbar">Show an error snackbar</string>
<string name="create_error_notification">Create an error notification</string> <string name="create_error_notification">Create an error notification</string>
<!-- Subscriptions import/export --> <!-- Subscriptions import/export -->
<plurals name="export_subscriptions">
<item quantity="one">Exporting %d subscription…</item>
<item quantity="other">Exporting %d subscriptions…</item>
</plurals>
<plurals name="load_subscriptions">
<item quantity="one">Loading %d subscription…</item>
<item quantity="other">Loading %d subscriptions…</item>
</plurals>
<plurals name="import_subscriptions">
<item quantity="one">Importing %d subscription…</item>
<item quantity="other">Importing %d subscriptions…</item>
</plurals>
<string name="import_title">Import</string> <string name="import_title">Import</string>
<string name="import_from">Import from</string> <string name="import_from">Import from</string>
<string name="export_to">Export to</string> <string name="export_to">Export to</string>
@@ -508,6 +520,11 @@
<string name="export_ongoing">Exporting…</string> <string name="export_ongoing">Exporting…</string>
<string name="import_file_title">Import file</string> <string name="import_file_title">Import file</string>
<string name="previous_export">Previous export</string> <string name="previous_export">Previous export</string>
<string name="import_subscriptions_title">Import subscriptions"</string>
<string name="export_subscriptions_title">Export subscriptions</string>
<string name="import_subscriptions_summary">Import subscriptions from a previous .json export"</string>
<string name="export_subscriptions_summary">Export your subscriptions to a .json file</string>
<string name="import_from_previous_export">Import from previous export</string>
<string name="subscriptions_import_unsuccessful">Could not import subscriptions</string> <string name="subscriptions_import_unsuccessful">Could not import subscriptions</string>
<string name="subscriptions_export_unsuccessful">Could not export subscriptions</string> <string name="subscriptions_export_unsuccessful">Could not export subscriptions</string>
<string name="import_youtube_instructions">Import YouTube subscriptions from Google takeout: <string name="import_youtube_instructions">Import YouTube subscriptions from Google takeout:
@@ -878,6 +895,9 @@
<string name="player_http_403">HTTP error 403 received from server while playing, likely caused by streaming URL expiration or an IP ban</string> <string name="player_http_403">HTTP error 403 received from server while playing, likely caused by streaming URL expiration or an IP ban</string>
<string name="player_http_invalid_status">HTTP error %1$s received from server while playing</string> <string name="player_http_invalid_status">HTTP error %1$s received from server while playing</string>
<string name="youtube_player_http_403">HTTP error 403 received from server while playing, likely caused by an IP ban or streaming URL deobfuscation issues</string> <string name="youtube_player_http_403">HTTP error 403 received from server while playing, likely caused by an IP ban or streaming URL deobfuscation issues</string>
<string name="sign_in_confirm_not_bot_error">%1$s refused to provide data, asking for a login to confirm the requester is not a bot.\n\nYour IP might have been temporarily banned by %1$s, you can wait some time or switch to a different IP (for example by turning on/off a VPN, or by switching from WiFi to mobile data).</string> <string name="sign_in_confirm_not_bot_error">%1$s refused to provide data, asking for a login to confirm the requester is not a bot.\n\nYour IP might have been temporarily banned by %1$s, you can wait some time or switch to a different IP (for example by turning on/off a VPN, or by switching from WiFi to mobile data).\n\nPlease see <a href="%2$s">this FAQ entry</a> for more information.</string>
<string name="unsupported_content_in_country">This content is not available for the currently selected content country.\n\nChange your selection from \"Settings > Content > Default content country\".</string> <string name="unsupported_content_in_country">This content is not available for the currently selected content country.\n\nChange your selection from \"Settings > Content > Default content country\".</string>
<string name="kao_dialog_warning">In August 2025, Google announced that as of September 2026, installing apps will require developer verification for all Android apps on certified devices, including those installed outside of the Play Store. Since the developers of NewPipe do not agree to this requirement, NewPipe will no longer work on certified Android devices after that time.</string>
<string name="kao_dialog_more_info">Details</string>
<string name="kao_solution">Solution</string>
</resources> </resources>

View File

@@ -22,4 +22,18 @@
android:summary="@string/reset_settings_summary" android:summary="@string/reset_settings_summary"
app:singleLineTitle="false" app:singleLineTitle="false"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<Preference
android:key="@string/export_subscriptions_key"
android:title="@string/export_subscriptions_title"
android:summary="@string/export_subscriptions_summary"
app:singleLineTitle="false"
app:iconSpaceReserved="false" />
<Preference
android:key="@string/import_subscriptions_key"
android:title="@string/import_subscriptions_title"
android:summary="@string/import_subscriptions_summary"
app:singleLineTitle="false"
app:iconSpaceReserved="false" />
</PreferenceScreen> </PreferenceScreen>

View File

@@ -5,11 +5,11 @@ import static org.junit.Assert.fail;
import org.junit.Test; import org.junit.Test;
import org.schabi.newpipe.extractor.subscription.SubscriptionExtractor; import org.schabi.newpipe.extractor.subscription.SubscriptionExtractor;
import org.schabi.newpipe.extractor.subscription.SubscriptionItem; import org.schabi.newpipe.local.subscription.workers.ImportExportJsonHelper;
import org.schabi.newpipe.local.subscription.workers.SubscriptionItem;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@@ -23,26 +23,22 @@ public class ImportExportJsonHelperTest {
final String emptySource = final String emptySource =
"{\"app_version\":\"0.11.6\",\"app_version_int\": 47,\"subscriptions\":[]}"; "{\"app_version\":\"0.11.6\",\"app_version_int\": 47,\"subscriptions\":[]}";
final List<SubscriptionItem> items = ImportExportJsonHelper.readFrom( final var items = ImportExportJsonHelper.readFrom(
new ByteArrayInputStream(emptySource.getBytes(StandardCharsets.UTF_8)), null); new ByteArrayInputStream(emptySource.getBytes(StandardCharsets.UTF_8)));
assertTrue(items.isEmpty()); assertTrue(items.isEmpty());
} }
@Test @Test
public void testInvalidSource() { public void testInvalidSource() {
final List<String> invalidList = Arrays.asList( final var invalidList = Arrays.asList("{}", "", null, "gibberish");
"{}",
"",
null,
"gibberish");
for (final String invalidContent : invalidList) { for (final String invalidContent : invalidList) {
try { try {
if (invalidContent != null) { if (invalidContent != null) {
final byte[] bytes = invalidContent.getBytes(StandardCharsets.UTF_8); final byte[] bytes = invalidContent.getBytes(StandardCharsets.UTF_8);
ImportExportJsonHelper.readFrom((new ByteArrayInputStream(bytes)), null); ImportExportJsonHelper.readFrom(new ByteArrayInputStream(bytes));
} else { } else {
ImportExportJsonHelper.readFrom(null, null); ImportExportJsonHelper.readFrom(null);
} }
fail("didn't throw exception"); fail("didn't throw exception");
@@ -58,38 +54,24 @@ public class ImportExportJsonHelperTest {
@Test @Test
public void ultimateTest() throws Exception { public void ultimateTest() throws Exception {
// Read from file // Read from file
final List<SubscriptionItem> itemsFromFile = readFromFile(); final var itemsFromFile = readFromFile();
// Test writing to an output // Test writing to an output
final String jsonOut = testWriteTo(itemsFromFile); final String jsonOut = testWriteTo(itemsFromFile);
// Read again // Read again
final List<SubscriptionItem> itemsSecondRead = readFromWriteTo(jsonOut); final var itemsSecondRead = readFromWriteTo(jsonOut);
// Check if both lists have the exact same items // Check if both lists have the exact same items
if (itemsFromFile.size() != itemsSecondRead.size()) { if (!itemsFromFile.equals(itemsSecondRead)) {
fail("The list of items were different from each other"); fail("The list of items were different from each other");
} }
for (int i = 0; i < itemsFromFile.size(); i++) {
final SubscriptionItem item1 = itemsFromFile.get(i);
final SubscriptionItem item2 = itemsSecondRead.get(i);
final boolean equals = item1.getServiceId() == item2.getServiceId()
&& item1.getUrl().equals(item2.getUrl())
&& item1.getName().equals(item2.getName());
if (!equals) {
fail("The list of items were different from each other");
}
}
} }
private List<SubscriptionItem> readFromFile() throws Exception { private List<SubscriptionItem> readFromFile() throws Exception {
final InputStream inputStream = getClass().getClassLoader().getResourceAsStream( final var inputStream = getClass().getClassLoader()
"import_export_test.json"); .getResourceAsStream("import_export_test.json");
final List<SubscriptionItem> itemsFromFile = ImportExportJsonHelper.readFrom( final var itemsFromFile = ImportExportJsonHelper.readFrom(inputStream);
inputStream, null);
if (itemsFromFile.isEmpty()) { if (itemsFromFile.isEmpty()) {
fail("ImportExportJsonHelper.readFrom(input) returned a null or empty list"); fail("ImportExportJsonHelper.readFrom(input) returned a null or empty list");
@@ -98,10 +80,10 @@ public class ImportExportJsonHelperTest {
return itemsFromFile; return itemsFromFile;
} }
private String testWriteTo(final List<SubscriptionItem> itemsFromFile) throws Exception { private String testWriteTo(final List<SubscriptionItem> itemsFromFile) {
final ByteArrayOutputStream out = new ByteArrayOutputStream(); final var out = new ByteArrayOutputStream();
ImportExportJsonHelper.writeTo(itemsFromFile, out, null); ImportExportJsonHelper.writeTo(itemsFromFile, out);
final String jsonOut = out.toString("UTF-8"); final String jsonOut = out.toString(StandardCharsets.UTF_8);
if (jsonOut.isEmpty()) { if (jsonOut.isEmpty()) {
fail("JSON returned by writeTo was empty"); fail("JSON returned by writeTo was empty");
@@ -111,10 +93,8 @@ public class ImportExportJsonHelperTest {
} }
private List<SubscriptionItem> readFromWriteTo(final String jsonOut) throws Exception { private List<SubscriptionItem> readFromWriteTo(final String jsonOut) throws Exception {
final ByteArrayInputStream inputStream = new ByteArrayInputStream( final var inputStream = new ByteArrayInputStream(jsonOut.getBytes(StandardCharsets.UTF_8));
jsonOut.getBytes(StandardCharsets.UTF_8)); final var secondReadItems = ImportExportJsonHelper.readFrom(inputStream);
final List<SubscriptionItem> secondReadItems = ImportExportJsonHelper.readFrom(
inputStream, null);
if (secondReadItems.isEmpty()) { if (secondReadItems.isEmpty()) {
fail("second call to readFrom returned an empty list"); fail("second call to readFrom returned an empty list");

View File

@@ -3,7 +3,9 @@ package org.schabi.newpipe.settings
import android.content.SharedPreferences import android.content.SharedPreferences
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
import java.nio.file.Files import kotlin.io.path.createTempFile
import kotlin.io.path.exists
import kotlin.io.path.fileSize
import org.junit.Assert import org.junit.Assert
import org.junit.Test import org.junit.Test
import org.mockito.Mockito import org.mockito.Mockito
@@ -47,10 +49,10 @@ class ImportAllCombinationsTest {
BackupFileLocator::class.java, BackupFileLocator::class.java,
Mockito.withSettings().stubOnly() Mockito.withSettings().stubOnly()
) )
val db = File.createTempFile("newpipe_", "") val db = createTempFile("newpipe_", "")
val dbJournal = File.createTempFile("newpipe_", "") val dbJournal = createTempFile("newpipe_", "")
val dbWal = File.createTempFile("newpipe_", "") val dbWal = createTempFile("newpipe_", "")
val dbShm = File.createTempFile("newpipe_", "") val dbShm = createTempFile("newpipe_", "")
Mockito.`when`(fileLocator.db).thenReturn(db) Mockito.`when`(fileLocator.db).thenReturn(db)
Mockito.`when`(fileLocator.dbJournal).thenReturn(dbJournal) Mockito.`when`(fileLocator.dbJournal).thenReturn(dbJournal)
Mockito.`when`(fileLocator.dbShm).thenReturn(dbShm) Mockito.`when`(fileLocator.dbShm).thenReturn(dbShm)
@@ -62,7 +64,7 @@ class ImportAllCombinationsTest {
Assert.assertFalse(dbJournal.exists()) Assert.assertFalse(dbJournal.exists())
Assert.assertFalse(dbWal.exists()) Assert.assertFalse(dbWal.exists())
Assert.assertFalse(dbShm.exists()) Assert.assertFalse(dbShm.exists())
Assert.assertTrue("database file size is zero", Files.size(db.toPath()) > 0) Assert.assertTrue("database file size is zero", db.fileSize() > 0)
} }
} else { } else {
runTest { runTest {
@@ -70,7 +72,7 @@ class ImportAllCombinationsTest {
Assert.assertTrue(dbJournal.exists()) Assert.assertTrue(dbJournal.exists())
Assert.assertTrue(dbWal.exists()) Assert.assertTrue(dbWal.exists())
Assert.assertTrue(dbShm.exists()) Assert.assertTrue(dbShm.exists())
Assert.assertEquals(0, Files.size(db.toPath())) Assert.assertEquals(0, db.fileSize())
} }
} }

View File

@@ -4,8 +4,15 @@ import android.content.SharedPreferences
import com.grack.nanojson.JsonParser import com.grack.nanojson.JsonParser
import java.io.File import java.io.File
import java.io.ObjectInputStream import java.io.ObjectInputStream
import java.nio.file.Files import java.nio.file.Paths
import java.util.zip.ZipFile import java.util.zip.ZipFile
import kotlin.io.path.createTempDirectory
import kotlin.io.path.createTempFile
import kotlin.io.path.deleteIfExists
import kotlin.io.path.div
import kotlin.io.path.exists
import kotlin.io.path.fileSize
import kotlin.io.path.inputStream
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse import org.junit.Assert.assertFalse
import org.junit.Assert.assertThrows import org.junit.Assert.assertThrows
@@ -46,7 +53,7 @@ class ImportExportManagerTest {
@Test @Test
fun `The settings must be exported successfully in the correct format`() { fun `The settings must be exported successfully in the correct format`() {
val db = File(classloader.getResource("settings/newpipe.db")!!.file) val db = Paths.get(classloader.getResource("settings/newpipe.db")!!.toURI())
`when`(fileLocator.db).thenReturn(db) `when`(fileLocator.db).thenReturn(db)
val expectedPreferences = mapOf("such pref" to "much wow") val expectedPreferences = mapOf("such pref" to "much wow")
@@ -81,29 +88,29 @@ class ImportExportManagerTest {
@Test @Test
fun `Ensuring db directory existence must work`() { fun `Ensuring db directory existence must work`() {
val dir = Files.createTempDirectory("newpipe_").toFile() val path = createTempDirectory("newpipe_") / BackupFileLocator.FILE_NAME_DB
Assume.assumeTrue(dir.delete()) Assume.assumeTrue(path.parent.deleteIfExists())
`when`(fileLocator.dbDir).thenReturn(dir) `when`(fileLocator.db).thenReturn(path)
ImportExportManager(fileLocator).ensureDbDirectoryExists() ImportExportManager(fileLocator).ensureDbDirectoryExists()
assertTrue(dir.exists()) assertTrue(path.parent.exists())
} }
@Test @Test
fun `Ensuring db directory existence must work when the directory already exists`() { fun `Ensuring db directory existence must work when the directory already exists`() {
val dir = Files.createTempDirectory("newpipe_").toFile() val path = createTempDirectory("newpipe_") / BackupFileLocator.FILE_NAME_DB
`when`(fileLocator.dbDir).thenReturn(dir) `when`(fileLocator.db).thenReturn(path)
ImportExportManager(fileLocator).ensureDbDirectoryExists() ImportExportManager(fileLocator).ensureDbDirectoryExists()
assertTrue(dir.exists()) assertTrue(path.parent.exists())
} }
@Test @Test
fun `The database must be extracted from the zip file`() { fun `The database must be extracted from the zip file`() {
val db = File.createTempFile("newpipe_", "") val db = createTempFile("newpipe_", "")
val dbJournal = File.createTempFile("newpipe_", "") val dbJournal = createTempFile("newpipe_", "")
val dbWal = File.createTempFile("newpipe_", "") val dbWal = createTempFile("newpipe_", "")
val dbShm = File.createTempFile("newpipe_", "") val dbShm = createTempFile("newpipe_", "")
`when`(fileLocator.db).thenReturn(db) `when`(fileLocator.db).thenReturn(db)
`when`(fileLocator.dbJournal).thenReturn(dbJournal) `when`(fileLocator.dbJournal).thenReturn(dbJournal)
`when`(fileLocator.dbShm).thenReturn(dbShm) `when`(fileLocator.dbShm).thenReturn(dbShm)
@@ -117,15 +124,15 @@ class ImportExportManagerTest {
assertFalse(dbJournal.exists()) assertFalse(dbJournal.exists())
assertFalse(dbWal.exists()) assertFalse(dbWal.exists())
assertFalse(dbShm.exists()) assertFalse(dbShm.exists())
assertTrue("database file size is zero", Files.size(db.toPath()) > 0) assertTrue("database file size is zero", db.fileSize() > 0)
} }
@Test @Test
fun `Extracting the database from an empty zip must not work`() { fun `Extracting the database from an empty zip must not work`() {
val db = File.createTempFile("newpipe_", "") val db = createTempFile("newpipe_", "")
val dbJournal = File.createTempFile("newpipe_", "") val dbJournal = createTempFile("newpipe_", "")
val dbWal = File.createTempFile("newpipe_", "") val dbWal = createTempFile("newpipe_", "")
val dbShm = File.createTempFile("newpipe_", "") val dbShm = createTempFile("newpipe_", "")
`when`(fileLocator.db).thenReturn(db) `when`(fileLocator.db).thenReturn(db)
val emptyZip = File(classloader.getResource("settings/nodb_noser_nojson.zip")?.file!!) val emptyZip = File(classloader.getResource("settings/nodb_noser_nojson.zip")?.file!!)
@@ -136,7 +143,7 @@ class ImportExportManagerTest {
assertTrue(dbJournal.exists()) assertTrue(dbJournal.exists())
assertTrue(dbWal.exists()) assertTrue(dbWal.exists())
assertTrue(dbShm.exists()) assertTrue(dbShm.exists())
assertEquals(0, Files.size(db.toPath())) assertEquals(0, db.fileSize())
} }
@Test @Test

View File

@@ -9,5 +9,6 @@ plugins {
alias(libs.plugins.jetbrains.kotlin.kapt) apply false alias(libs.plugins.jetbrains.kotlin.kapt) apply false
alias(libs.plugins.google.ksp) apply false alias(libs.plugins.google.ksp) apply false
alias(libs.plugins.jetbrains.kotlin.parcelize) apply false alias(libs.plugins.jetbrains.kotlin.parcelize) apply false
alias(libs.plugins.jetbrains.kotlinx.serialization) apply false
alias(libs.plugins.sonarqube) apply false alias(libs.plugins.sonarqube) apply false
} }

View File

@@ -1 +0,0 @@
اندرویددا یوتیوب اوچون بیر اؤزگور و یونگول قاپاخ.

View File

@@ -1 +1,11 @@
Opraveno nepřehrávání jakéhokoli streamu ve službě YouTube Oprava chyby „Obsah není k dispozici“: videa z YouTube lze nyní opět přehrávat!
Další opravy chyb z verze 0.28.1:
• Přetahování položek playlistu pouze na sousední pozice
• Blikání názvu/komentářů mezi aktuálním a předchozím videem
• Nefunkční možnost „Spustit hlavní přehrávač na celou obrazovku“
Další vylepšení:
• [YouTube] Opětovné povolení přetáčení živých přenosů až o 4 hodiny zpět
• Nepřetáčení živého videa při přehrávání na pozadí
• Nové uživatelské rozhraní pro „Odebrat zhlédnuté“

View File

@@ -0,0 +1,14 @@
Důležité
Přidány informace a výzva k akci v rámci kampaně Keep Android Open: https://www.keepandroidopen.org/
Vylepšeno
[Feed] Změna pořadí aktualizace starších odběrů
Zrušeno kupení stránek s komentáři
Nepředávání události kliknutí podkladovým zobrazením při kliknutí na stránku s podrobnostmi o videu
Opraveno
Rozložení záhlaví odpovědí na komentáře bez avataru
Několik oprav rozhraní souvisejících s přehrávačem
[SoundCloud] Oprava streamů s dlouhými ID
a další opravy a vylepšení!

View File

@@ -0,0 +1,14 @@
Wichtig
Informationen zur Kampagne „Keep Android Open“: https://keepandroidopen.org/de/
Verbessert
[Feed] Die Reihenfolge, in der veraltete Abos aktualisiert werden
Kommentarseiten nicht stapeln
Beim Klicken auf die Videodetailseite keine Klickereignisse an darunterliegende Ansichten weiterleiten
Behoben
Layout der Kommentarantworten ohne Profilbild
Mehrere Player-bezogene Korrekturen der Bedienoberfläche
[SoundCloud] Streams mit langen IDs
und weitere Korrekturen und Verbesserungen!

View File

@@ -7,6 +7,6 @@ Verbessert
• [Bandcamp] Anzeige zusätzlicher Informationen im Radio-Kiosk • [Bandcamp] Anzeige zusätzlicher Informationen im Radio-Kiosk
Behoben Behoben
• [YouTube] Behebung gelegentlicher HTTP-403-Fehler am Anfang oder in der Mitte von Videos • [YouTube] Gelegentliche HTTP-403-Fehler am Anfang oder in der Mitte von Videos
• [YouTube] Extrahieren von Avataren und Banner aus mehr Kanal-Header-Typen • [YouTube] Extrahieren von Profilbildern und Banner aus mehr Kanal-Header-Typen
• [Bandcamp] Verschiedene Fehler behoben und HTTPS wird stets verwendet • [Bandcamp] Verschiedene Fehler behoben und HTTPS wird immer verwendet

View File

@@ -0,0 +1,14 @@
Important
Information on and call for action for the Keep Android Open campaign added: https://www.keepandroidopen.org/
Improved
[Feed] Shuffle the order outdated subscriptions are updated in
Do not stack comment pages
Do not pass click events to underlying views when clicking on video detail page
Fixed
Comment replies header layout without avatar image
Multiple player-related UI fixes
[SoundCloud] Fix streams with long IDs
and more fixes and improvements!

View File

@@ -0,0 +1,15 @@
Important
Informations et appel à l'action pour la campagne Keep Android Open ajoutés : https://www.keepandroidopen.org/
Améliorations
[Flux] Ordre de mise à jour des abonnements obsolètes aléatoire
Pages de commentaires non empilées
Événements de clic désactivés sur la page de détails d'une vidéo
Corrections
Affichage de l'en-tête des réponses aux commentaires sans image d'avatar
Corrections d'interface utilisateur pour plusieurs lecteurs
[SoundCloud] Correction des flux avec des identifiants longs
Et bien d'autres corrections et améliorations!

View File

@@ -1 +1,10 @@
फिक्स्ड YouTube कोई स्ट्रीम नहीं चला रहा है इस हॉटफ़िक्स रिलीज़ से "Content not available" एरर ठीक हो गया है: अब YouTube वीडियो फिर से चलाए जा सकते हैं!
इससे 0.28.1 में आई कुछ और गड़बड़ियाँ भी ठीक हो गई हैं:
• प्लेलिस्ट आइटम को खींचकर सिर्फ़ आस-पास की जगहों पर ही ले जा पाना
• मौजूदा और पिछले वीडियो के बीच टाइटल/कमेंट्स का बार-बार बदलना
• "Start main player in fullscreen" ऑप्शन का काम न करना
दूसरे सुधार:
• [YouTube] लाइवस्ट्रीम को 4 घंटे तक पीछे ले जाने की सुविधा फिर से चालू
• बैकग्राउंड में चलते समय लाइवस्ट्रीम वीडियो लोड न करना

View File

@@ -0,0 +1,4 @@
∙ स्ट्रीम को पिछली प्लेबैक स्थिति से फिर से शुरू करने की समस्या ठीक की गई
∙ [YouTube] ज़्यादा चैनल URL फ़ॉर्मैट के लिए सपोर्ट जोड़ा गया
∙ [YouTube] ज़्यादा वीडियो मेटा-इन्फ़ो फ़ॉर्मैट के लिए सपोर्ट जोड़ा गया
∙ अनुवाद अपडेट किए गए

View File

@@ -0,0 +1,14 @@
ज़रूरी
'Keep Android Open' कैंपेन के बारे में जानकारी और कार्रवाई के लिए अपील जोड़ी गई: https://www.keepandroidopen.org/
बेहतर
[फ़ीड] पुरानी सब्सक्रिप्शन के अपडेट होने का क्रम बदला गया
कमेंट पेज एक के ऊपर एक न दिखें
वीडियो डिटेल पेज पर क्लिक करने पर, क्लिक इवेंट नीचे के व्यूज़ तक न पहुँचें
ठीक किया गया
कमेंट रिप्लाई हेडर लेआउट में अवतार इमेज न दिखना
प्लेयर से जुड़े कई UI सुधार
[SoundCloud] लंबी ID वाले स्ट्रीम को ठीक किया गया
और भी कई सुधार और बेहतर बदलाव!

View File

@@ -0,0 +1,16 @@
# Peningkatan
Pertahankan pemutar saat ini ketika mengklik stempel waktu
Cobalah untuk memulihkan misi pengunduhan yang tertunda jika memungkinkan
Tambahkan opsi untuk menghapus unduhan tanpa ikut menghapus berkas
Izin Overlay: menampilkan dialog penjelasan untuk Android > R
Mendukung tautan on.soundcloud saat membuka
Banyak perbaikan dan optimasi kecil.
# Telah diperbaiki
Memperbaiki format penghitungan pendek untuk versi Android di bawah 7
Memperbaiki notifikasi berhantu
Memperbaiki berkas SRT
Memperbaiki banyak sekali kerusakan
# Pengembangan
Modernisasi kode internal

Some files were not shown because too many files have changed in this diff Show More