From 2339f51ad4707367a98c844840dd4f5f7295675f Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Fri, 14 Feb 2025 21:14:42 -0300 Subject: [PATCH 001/143] [#11930] Share as YouTube temporary playlist Initial commit. --- .../local/playlist/LocalPlaylistFragment.java | 100 +++++++++++++----- .../local/playlist/PlayListShareMode.java | 8 ++ .../playlist/LocalPlaylistFragmentTest.java | 55 ++++++++++ 3 files changed, 138 insertions(+), 25 deletions(-) create mode 100644 app/src/main/java/org/schabi/newpipe/local/playlist/PlayListShareMode.java create mode 100644 app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java index c87d9cccc..3e99b01c4 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java @@ -2,6 +2,9 @@ package org.schabi.newpipe.local.playlist; import static org.schabi.newpipe.error.ErrorUtil.showUiErrorSnackbar; import static org.schabi.newpipe.ktx.ViewUtils.animate; +import static org.schabi.newpipe.local.playlist.PlayListShareMode.JUST_URLS; +import static org.schabi.newpipe.local.playlist.PlayListShareMode.WITH_TITLES; +import static org.schabi.newpipe.local.playlist.PlayListShareMode.YOUTUBE_TEMP_PLAYLIST; import static org.schabi.newpipe.util.ThemeHelper.shouldUseGridLayout; import android.content.Context; @@ -64,12 +67,14 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; +import java.util.stream.Stream; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.core.Single; import io.reactivex.rxjava3.disposables.CompositeDisposable; import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.schedulers.Schedulers; +import okhttp3.HttpUrl; public class LocalPlaylistFragment extends BaseLocalListFragment, Void> implements PlaylistControlViewHolder, DebounceSavable { @@ -385,34 +390,76 @@ public class LocalPlaylistFragment extends BaseLocalListFragment Single.just(playlist.stream() - .map(PlaylistStreamEntry::getStreamEntity) - .map(streamEntity -> { - if (shouldSharePlaylistDetails) { - return context.getString(R.string.video_details_list_item, - streamEntity.getTitle(), streamEntity.getUrl()); - } else { - return streamEntity.getUrl(); - } - }) - .collect(Collectors.joining("\n")))) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(urlsText -> ShareUtils.shareText( - context, name, shouldSharePlaylistDetails - ? context.getString(R.string.share_playlist_content_details, - name, urlsText) : urlsText), - throwable -> showUiErrorSnackbar(this, "Sharing playlist", throwable))); + .flatMapSingle(playlist -> Single.just(export( shareMode + , playlist.stream().map(PlaylistStreamEntry::getStreamEntity) + , context + ) + )) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( urlsText -> ShareUtils.shareText( context + , name + , shareMode == JUST_URLS ? urlsText + : context.getString(R.string.share_playlist_content_details, name, urlsText)) + , throwable -> showUiErrorSnackbar(this, "Sharing playlist", throwable)) + ); + } + + static String export(PlayListShareMode shareMode, Stream entityStream, Context context) { + + return switch(shareMode) { + + case WITH_TITLES -> exportWithTitles(entityStream, context); + case JUST_URLS -> exportJustUrls(entityStream); + case YOUTUBE_TEMP_PLAYLIST -> exportAsYoutubeTempPlaylist(entityStream); + }; + } + + static String exportWithTitles(Stream entityStream, Context context) { + + return entityStream + .map(entity -> context.getString(R.string.video_details_list_item, entity.getTitle(), entity.getUrl())) + .collect(Collectors.joining("\n")); + } + + static String exportJustUrls(Stream entityStream) { + + return entityStream + .map(StreamEntity::getUrl) + .collect(Collectors.joining("\n")); + } + + static String exportAsYoutubeTempPlaylist(Stream entityStream) { + + String videoIDs = entityStream + .map(entity -> getYouTubeId(entity.getUrl())) + .collect(Collectors.joining(",")); + + return "http://www.youtube.com/watch_videos?video_ids=" + videoIDs; + } + + /** + * Gets the video id from a YouTube URL + */ + static String getYouTubeId(String url) { + + HttpUrl httpUrl = HttpUrl.parse(url); + + return httpUrl == null ? null + : httpUrl.queryParameter("v") + ; } public void removeWatchedStreams(final boolean removePartiallyWatched) { @@ -875,10 +922,13 @@ public class LocalPlaylistFragment extends BaseLocalListFragment - sharePlaylist(/* shouldSharePlaylistDetails= */ true) + sharePlaylist(WITH_TITLES) + ) + .setNeutralButton("Share as YouTube temporary playlist", (dialog, which) -> // TODO R.string.share_playlist_as_YouTube_temporary_playlist + sharePlaylist(YOUTUBE_TEMP_PLAYLIST) ) .setNegativeButton(R.string.share_playlist_with_list, (dialog, which) -> - sharePlaylist(/* shouldSharePlaylistDetails= */ false) + sharePlaylist(JUST_URLS) ) .show(); } diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/PlayListShareMode.java b/app/src/main/java/org/schabi/newpipe/local/playlist/PlayListShareMode.java new file mode 100644 index 000000000..3de1effc9 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/PlayListShareMode.java @@ -0,0 +1,8 @@ +package org.schabi.newpipe.local.playlist; + +public enum PlayListShareMode { + + JUST_URLS + ,WITH_TITLES + ,YOUTUBE_TEMP_PLAYLIST +} diff --git a/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java b/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java new file mode 100644 index 000000000..41e1f6091 --- /dev/null +++ b/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java @@ -0,0 +1,55 @@ +package org.schabi.newpipe.local.playlist; + +import static org.schabi.newpipe.local.playlist.PlayListShareMode.YOUTUBE_TEMP_PLAYLIST; + +import androidx.annotation.NonNull; + +import org.junit.Assert; +import org.junit.Test; +import org.schabi.newpipe.database.stream.model.StreamEntity; +import org.schabi.newpipe.extractor.stream.StreamType; + +import java.util.List; +import java.util.stream.Stream; + +public class LocalPlaylistFragmentTest { + + @Test + public void youTubeTempPlaylist() { + + Stream entityStream = List.of( + + "https://www.youtube.com/watch?v=1" + ,"https://www.youtube.com/watch?v=2" + ,"https://www.youtube.com/watch?v=3" + ) + .stream() + .map(LocalPlaylistFragmentTest::newStreamEntity) + ; + + String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, entityStream, null); + + Assert.assertEquals("http://www.youtube.com/watch_videos?video_ids=1,2,3", url); + } + + @NonNull + static StreamEntity newStreamEntity(String url) { + + return new StreamEntity( + + 0 + , 1 + , url + , "Title" + , StreamType.VIDEO_STREAM + , 100 + , "Uploader" + , null + , null + , null + , null + , null + , null + ); + } +} From 430b4eb916765fd5cdbf3398e2d15f636865785a Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Sat, 15 Feb 2025 13:08:00 +0100 Subject: [PATCH 002/143] Translated using Weblate (Persian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 92.7% (686 of 740 strings) Translated using Weblate (Swedish) Currently translated at 100.0% (84 of 84 strings) Translated using Weblate (Turkish) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Georgian) Currently translated at 83.3% (70 of 84 strings) Translated using Weblate (Estonian) Currently translated at 16.6% (14 of 84 strings) Translated using Weblate (Estonian) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Mainfränkisch) Currently translated at 1.0% (8 of 740 strings) Translated using Weblate (Bavarian) Currently translated at 3.9% (29 of 740 strings) Translated using Weblate (German) Currently translated at 100.0% (84 of 84 strings) Added translation using Weblate (Mainfränkisch) Translated using Weblate (Thai) Currently translated at 36.6% (271 of 740 strings) Translated using Weblate (Armenian) Currently translated at 28.2% (209 of 740 strings) Translated using Weblate (Georgian) Currently translated at 85.7% (72 of 84 strings) Translated using Weblate (Thai) Currently translated at 34.3% (254 of 740 strings) Translated using Weblate (Gujarati) Currently translated at 11.3% (84 of 740 strings) Translated using Weblate (Hungarian) Currently translated at 100.0% (84 of 84 strings) Translated using Weblate (Slovak) Currently translated at 100.0% (84 of 84 strings) Translated using Weblate (Nepali) Currently translated at 1.1% (1 of 84 strings) Translated using Weblate (Slovak) Currently translated at 100.0% (84 of 84 strings) Translated using Weblate (French) Currently translated at 100.0% (84 of 84 strings) Translated using Weblate (Portuguese) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Gujarati) Currently translated at 11.0% (82 of 740 strings) Translated using Weblate (Arabic) Currently translated at 100.0% (740 of 740 strings) Co-authored-by: Alex25820 Co-authored-by: Bruno Fragoso Co-authored-by: Davit Mayilyan Co-authored-by: Emin Tufan Çetin Co-authored-by: Garfield2150 Co-authored-by: Ghost of Sparta Co-authored-by: Goudarz Jafari Co-authored-by: Hosted Weblate Co-authored-by: Kchenik Poudel Co-authored-by: Kuko Co-authored-by: Paul Sibila Co-authored-by: Priit Jõerüüt Co-authored-by: Rex_sa Co-authored-by: Temuri Doghonadze Co-authored-by: freddyLovesUs Co-authored-by: રાજ ભાતેલીઆ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/de/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/et/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/fr/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/hu/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ka/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ne/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/sk/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/sv/ Translation: NewPipe/Metadata --- app/src/main/res/values-ar/strings.xml | 2 +- app/src/main/res/values-bar/strings.xml | 4 +- app/src/main/res/values-et/strings.xml | 55 +++++------- app/src/main/res/values-fa/strings.xml | 2 + app/src/main/res/values-gu/strings.xml | 12 +-- app/src/main/res/values-hy/strings.xml | 8 +- app/src/main/res/values-pt/strings.xml | 4 +- app/src/main/res/values-th/strings.xml | 86 ++++++++++++++----- app/src/main/res/values-tr/strings.xml | 6 +- app/src/main/res/values-vmf/strings.xml | 10 +++ .../metadata/android/de/changelogs/1003.txt | 10 ++- .../metadata/android/et/changelogs/1003.txt | 10 ++- .../metadata/android/et/changelogs/998.txt | 4 + .../metadata/android/et/changelogs/999.txt | 12 +++ .../metadata/android/et/full_description.txt | 2 +- .../metadata/android/et/short_description.txt | 2 +- .../metadata/android/fr/changelogs/1002.txt | 5 +- .../metadata/android/fr/changelogs/1003.txt | 7 +- .../metadata/android/hu/changelogs/1002.txt | 4 +- .../metadata/android/hu/changelogs/1003.txt | 10 ++- .../metadata/android/ka/changelogs/1002.txt | 1 - .../metadata/android/ka/changelogs/1003.txt | 1 - .../metadata/android/ka/changelogs/65.txt | 26 ------ .../metadata/android/ka/changelogs/68.txt | 31 ------- .../metadata/android/ka/changelogs/69.txt | 19 ---- .../metadata/android/ne/short_description.txt | 1 + .../metadata/android/sk/changelogs/1000.txt | 2 +- .../metadata/android/sk/changelogs/1002.txt | 5 +- .../metadata/android/sk/full_description.txt | 2 +- .../metadata/android/sk/short_description.txt | 2 +- .../metadata/android/sv/changelogs/1003.txt | 10 ++- 31 files changed, 179 insertions(+), 176 deletions(-) create mode 100644 app/src/main/res/values-vmf/strings.xml create mode 100644 fastlane/metadata/android/et/changelogs/998.txt create mode 100644 fastlane/metadata/android/et/changelogs/999.txt delete mode 100644 fastlane/metadata/android/ka/changelogs/1002.txt delete mode 100644 fastlane/metadata/android/ka/changelogs/1003.txt delete mode 100644 fastlane/metadata/android/ka/changelogs/65.txt delete mode 100644 fastlane/metadata/android/ka/changelogs/68.txt delete mode 100644 fastlane/metadata/android/ka/changelogs/69.txt create mode 100644 fastlane/metadata/android/ne/short_description.txt diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 5946b6b16..3b70c9d8c 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -18,7 +18,7 @@ اختر مجلد التنزيل لملفات الفيديو يتم تخزين ملفات الفيديو التي تم تنزيلها هنا مجلد تحميل الفيديو - ثبت + ثبيت تطبيق Kore غير موجود. هل تريد تثبيته؟ فاتح خطأ في الشبكة diff --git a/app/src/main/res/values-bar/strings.xml b/app/src/main/res/values-bar/strings.xml index 1949e1efa..63ae52c9a 100644 --- a/app/src/main/res/values-bar/strings.xml +++ b/app/src/main/res/values-bar/strings.xml @@ -26,4 +26,6 @@ Duad bei manchen Auflösungen d\'Tonspur weggad Im Pop-up Modus aufmacha Drug auf\'d Lubn zum ofanga. - \ No newline at end of file + Bassd scho + naa + diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index a002c9a0d..cb1034b14 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -99,8 +99,8 @@ Alati Üks kord Fail - NewPipe teavitus - Teavitused NewPipe pleierile + NewPipe\'i teavitus + NewPipe\'i meediaesitaja teavitused [Tundmatu] Lülita taustale Lülita hüpikpleierile @@ -183,7 +183,7 @@ Failinimi Lõimed Viga - NewPipe allalaadimine + NewPipe\'i on allalaadimisel Üksikasjade nägemiseks toksa Palun oota… Kopeeriti lõikepuhvrisse @@ -197,18 +197,18 @@ Asendustähemärk Tähed ja numbrid Erimärgid - NewPipe rakendusest + Rakenduse teave: NewPipe Kolmanda osapoole litsentsid Rakenduse teave ja KKK Litsentsid Panusta Vaata GitHubis Anneta - Veebileht - Enama info saamiseks külasta NewPipe veebilehte. - NewPipe privaatsuspoliitika + Veebisait + Täiendava info ja uudiste lugemiseks külasta NewPipe\'i veebisaiti. + NewPipe\'i privaatsuspoliitika Loe privaatsuspoliitikat - NewPipe litsents + NewPipe\'i litsents Loe litsentsi Ajalugu Ajalugu @@ -303,11 +303,10 @@ © %1$s %2$s %3$s alla Vaba ja lihtne voogesitus Androidis. Kui sul on ideid kujunduse muutmisest, koodi puhastamisest või suurtest koodi muudatustest - abi on alati teretulnud. Mida rohkem tehtud, seda paremaks läheb! - NewPipe arendajad on vabatahtlikud, kes kulutavad oma vaba aega, toomaks sulle parimat kasutamise kogemust. On aeg anda tagasi aidates arendajaid ja muuta NewPipe veel paremaks, nautides ise tassi kohvi. + NewPipe\'i arendajad on vabatahtlikud, kes kulutavad oma vaba aega, toomaks sulle parimat kasutuskogemust. On aeg anda tagasi aidates arendajaid ja muuta NewPipe veel paremaks, nautides ise tassi kohvi. Anneta - NewPipe võtab privaatsust väga tõsiselt. Seetõttu ei kogu rakendus ilma nõusolekuta mingeid andmeid. -\nNewPipe privaatsuspoliitika selgitab üksikasjalikult, milliseid andmeid saadetakse ja kogutakse veateate saatmisel. - NewPipe vaba avatud koodiga tarkvara. Seada võid kasutada, uurida, jagada ja parandada nii, nagu õigemaks pead. Täpsemalt - seda võid levitada ja/või muuta vastavalt Vaba Tarkvara Sihtasutuse avaldatud GNU Üldise Avaliku Litsentsi v.3 (või sinu valikul hilisema versiooni) tingimustele. + NewPipe võtab privaatsust väga tõsiselt. Seetõttu ei kogu rakendus ilma nõusolekuta mingeid andmeid. \nNewPipe\'i privaatsuspoliitika selgitab üksikasjalikult, milliseid andmeid saadetakse ja kogutakse veateate saatmisel. + NewPipe on vaba ja avatud lähtekoodiga tarkvara. Seada võid kasutada, uurida, jagada ja parandada nii, nagu õigemaks pead. Täpsemalt - seda võid levitada ja/või muuta vastavalt Vaba Tarkvara Sihtasutuse avaldatud GNU Üldise Avaliku Litsentsi v.3 (või sinu valikul hilisema versiooni) tingimustele. Teavita elutsüklist väljas vigadest Impordi SoundCloudi profiil trükkides URL või oma ID: \n @@ -321,8 +320,7 @@ Keri helitu koht edasi Samm Lähtesta - Selleks, et täita Euroopa Üldist Andmekaitse Määrust (GDPR), juhime tähelepanu NewPipe\'i privaatsuspoliitikale. Palun lugege seda hoolikalt. -\nMeile veateate saatmiseks pead sellega nõustuma. + Selleks, et täita Euroopa Üldist Andmekaitse Määrust (GDPR), juhime tähelepanu NewPipe\'i privaatsuspoliitikale. Palun loe seda hoolikalt. \nMeile veateate saatmiseks pead sellega nõustuma. Minimeeri, kui kasutad teisi rakendusi Tegevus lülitusel peamiselt videopleierilt teisele rakendusele — %s Pole @@ -335,7 +333,7 @@ Sündmused Fail kustutati Rakenduse värskenduse teavitus - Teavitus NewPipe uuetest versioonidest + Teavitus NewPipe\'i uuetest versioonidest Väline andmekandja pole saadaval Allalaadimine välisele SD-kaardile ei ole võimalik. Kas lähtestada allalaadimiste kataloogi asukoht\? Tõrge salvestatud vahekaaride lugemisel; kasutatakse vaikeväärtusi @@ -350,7 +348,7 @@ Nimekiri Võrgustik Auto - NewPipe värskendus on saadaval! + NewPipe\'i värskendus on saadaval! Lõpetatud Ootel peatatud @@ -556,7 +554,7 @@ Luba korraga vaid üks allalaadimine Piira allalaadimiste järjekorda Faili kustutamisega läks ka tööjärg kautsi - Faili töötlemisel NewPipe lõpetas töö + NewPipe lõpetas faili töötlemisel töö Lülita meedia tunneldamine välja juhul, kui esitamisel tekib must ekraan või pildi kuvamine on katkendlik. Lülita meedia tunneldamine välja Vaheta teenust, hetkel on kasutusel: @@ -609,9 +607,7 @@ Luba kiire režiim Hangi võimalusel spetsiaalsest voost Kiirvoo režiim ei paku selle kohta täiendavat teavet. - Autori konto on lõpetatud. -\nTulevikus ei saa NewPipe seda voogu laadida. -\nKas soovid tühistada selle kanali tellimuse\? + Autori konto on suletud. \nTulevikus ei saa NewPipe seda meediavoogu laadida. \nKas soovid tühistada selle kanali tellimuse? Voo \'%s\' laadimine nurjus. Via voo laadimisel Värskenda alati @@ -622,17 +618,7 @@ Android 10st alates on toetatud ainult salvestusjuurdepääsu raamistik \'Storage Access Framework\' Sinult küsitakse iga kord, kuhu alla laadimine salvestada Südamlik autor - Kas sinu meelest on voo laadimine aeglane\? Sel juhul proovi lubada kiire laadimine (seda saad muuta seadetes või vajutades allolevat nuppu). -\n -\nNewPipe pakub kahte voo laadimise strateegiat: -\n• Tellitud kanali täielik, kuid aeglane hankimine. -\n• Teenuse spetsiaalse lõpp-punkti kasutamine, mis on kiire, kuid tavaliselt mittetäielik. -\n -\nErinevus nende kahe vahel seisneb selles, et kiirel puudub tavaliselt teave, näiteks üksuse pikkus või tüüp (ei saa eristada reaalajas videoid tavalistest) ja see võib tagastada vähem üksusi. -\n -\nYouTube on näide teenusest, mis pakub seda kiirmeetodit oma RSS-vooga. -\n -\nNii et valik taandub sellele, mida eelistad: kiirus või täpne teave. + Kas sinu meelest on voo laadimine aeglane? Sel juhul proovi lubada kiire laadimine (seda saad muuta seadetes või vajutades allolevat nuppu). \n \nNewPipe pakub kahte voo laadimise strateegiat: \n• Tellitud kanali täielik, kuid aeglane hankimine. \n• Teenuse spetsiaalse otspunkti kasutamine, mis on kiire, kuid tavaliselt mittetäielik. \n \nErinevus nende kahe vahel seisneb selles, et kiirel puudub tavaliselt teave, näiteks üksuse pikkus või tüüp (ei saa eristada reaalajas videoid tavalistest) ja see võib tagastada vähem üksusi. \n \nYouTube on näide teenusest, mis pakub seda kiirmeetodit oma RSS-vooga. \n \nNii et valik taandub sellele, mida eelistad: kiirus või täpne teave. Märgi vaadatuks Näita piltide kohal Picasso värvides riba, mis märgib pildi allikat: punane tähistab võrku, sinine kohalikku andmekandjat ja roheline kohalikku mälu Näita piltide allikat @@ -658,7 +644,7 @@ Uued andmevoo kirjed Näita „Jooksuta meediamängija kokku“ nupukest\\ Näitab valikut meediamängija kokkujooksutamiseks - NewPipe töös tekkis viga, sellest teavitamiseks toksa + NewPipe\'i töös tekkis viga, sellest teavitamiseks toksa Jooksuta meediamängija kokku Näita veateate akent Teavitus vigadest @@ -814,8 +800,7 @@ Näita vähem Muuda iga teavituse tegevust sellel toksates. Kolm esimest tegevust (esita/peata esitus, eelmine video, järgmine video) on süsteemsed ja neid ei saa muuta. Varundus ja taastamine - NewPipe võib aeg-ajalt automaatselt kontrollida uute versioonide olemasolu ning sind vastavalt teavitada. -\nKas sa soovid sellist võimalust kasuutada? + NewPipe võib aeg-ajalt automaatselt kontrollida uute versioonide olemasolu ning sind vastavalt teavitada. \nKas sa soovid sellist võimalust kasutada? Lähtesta seadistused Lähtesta kõik seadistused nende vaikimisi väärtusteks Seadmes pole enam piisavalt vaba ruumi @@ -824,6 +809,6 @@ \nKas sa soovid jätkata? Jah Ei - Imporditavad andmed kasutavad turvaprobleemidega vormingut, mida alates versioonist 0.27.0 NewPipe enam luua ei suuda. Palun kontrolli, et impordifail on loodud usaldusväärse osapoole poolt ning edaspidi loo ekspordifailid NewPipe versiooniga 0.27.0 või uuemaga. Tugi sellise vana vormingu kasutamisele kaob õige pea ja seejärel NewPipe uuemad ja vanemad versioonid ei saa omavahel andmeid enam vahetada. + Imporditavad andmed kasutavad turvaprobleemidega vormingut, mida alates versioonist 0.27.0 NewPipe enam kasutada ei suuda. Palun kontrolli, et impordifail on loodud usaldusväärse osapoole poolt ning eelista ekspordifaile, mis on loodud NewPipe\'i versiooniga 0.27.0 või uuemaga. Tugi sellise vana vormingu kasutamisele kaob õige pea ja seejärel NewPipe\'i uuemad ja vanemad versioonid ei saa omavahel andmeid enam vahetada. täiendav diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index 4bba29c0e..b5e5de31c 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -764,4 +764,6 @@ مدّت پسروی ؟ + پشتیبان‌گیری و بازیابی + بدون جریان زنده diff --git a/app/src/main/res/values-gu/strings.xml b/app/src/main/res/values-gu/strings.xml index cdeac0b82..637fc9bf8 100644 --- a/app/src/main/res/values-gu/strings.xml +++ b/app/src/main/res/values-gu/strings.xml @@ -23,7 +23,7 @@ પ્રથમ ક્રિયા બટન સૂચનામાં બતાવેલ વિડિઓ થંબનેલને ૧૬:૯ થી ૧:૧ સાપેક્ષ ગુણોત્તરમાં કાપો થંબનેલને ૧:૧ સાપેક્ષ ગુણોત્તરમાં કાપો - કોડી મીડિયા સેન્ટર દ્વારા વિડિઓ ચલાવવાનો વિકલ્પ દર્શાવો + કોડિ મીડિયા સેન્ટર દ્વારા વિડિઓ ચલાવવાનો વિકલ્પ દર્શાવો અનુપસ્થિત Kore અનુપ્રયોગ સ્થાપિત કરીએ? ફક્ત થોડા ઉપકરણો 2K / 4K વિડિઓઝ ચલાવી શકે છે ઉચ્ચ રીઝોલ્યુશન બતાવો @@ -40,7 +40,7 @@ પૃષ્ઠભૂમિ ટેબ પસંદ કરો બુકમાર્ક કરેલ પ્લેલિસ્ટ્સ - સબ્સ્ક્રિપ્શન્સ + લવાજમઓ માહિતી બતાવો સબ્સ્ક્રિપ્શન અપડેટ કરી શકાયું નથી સબ્સ્ક્રિપ્શન બદલી શકાયું નહીં @@ -72,13 +72,15 @@ ઠીક છે હા ના - વલણમાં છે + વલણમાંનાં આપોઆપ કતારબદ્ધતા પ્લેયરને ક્રેશ કરો ઇતિહાસ કોટિથી ચલાવો - કોટિથી ચલાવવાનો વિકલ્પ દેખાટો + કોડિથી ચલાવવાનો વિકલ્પ દેખાડો ડાઉનલોડ કરો આપમેળે ચલાવો નવું શું છે - \ No newline at end of file + ડાઉનલોડ્સ + ડાઉનલોડ્સ + diff --git a/app/src/main/res/values-hy/strings.xml b/app/src/main/res/values-hy/strings.xml index 365bfe9ea..3be44ba73 100644 --- a/app/src/main/res/values-hy/strings.xml +++ b/app/src/main/res/values-hy/strings.xml @@ -1,6 +1,6 @@ - Սեղմեք որոնման կոճակը որ սկսել + Սեղմեք խոշորացույցը որ սկսեք Որոնել Բեռնված Բեռնված @@ -228,7 +228,7 @@ Դասավորել Գամված մեկնաբանություն Հաշիվը կասեցված է - + Ալբոմներ Այո Ոչ @@ -241,4 +241,6 @@ Ալիքներ Ուղիղ Անհայտ - \ No newline at end of file + Նկատի ունե՞ս «%1$s» + Բարձրություն + diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index bd98dc7d8..b5ebcbd2e 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -281,7 +281,7 @@ Limpar histórico de visualizações Continuar (sem repetição) a fila de reprodução anexando um vídeo relacionado Mostrar dica \"Toque longo para colocar na fila\" - Mostrar dica ao premir em segundo plano ou no botão \"Detalhes\" da janela popup + Mostrar dica ao premir em segundo plano ou no botão \"Detalhes\" da janela popup:\\ Canais Listas de reprodução Faixas @@ -528,7 +528,7 @@ Remover visualizados Os textos originais dos serviços serão visíveis nos itens do vídeo Mostrar antiguidade nos itens - Ativar \"Modo restrito\" do YouTube + Ativar \"Modo restrito\\ do YouTube Por %s Criado por %s Miniatura do avatar do canal diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 1816fa212..bcbbca0a4 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -1,6 +1,6 @@ - แตะที่ปุ่ม \"ค้นหา\" เพื่อเริ่มต้น + แตะที่สัญลักษณ์แว่นขยายเพื่อเริ่มต้น เผยแพร่เมื่อ %1$s ไม่พบแอปที่สามารถสตรีมสื่อวีดีโอได้ คุณต้องการติดตั้ง VLC หรือไม่\? ไม่พบแอปที่สามารถสตรีมสื่อวีดีโอได้ (คุณสามารถติดตั้ง VLC เพื่อดูวีดีโอ) @@ -12,33 +12,33 @@ ดาวน์โหลด ดาวน์โหลดไฟล์สตรีม ค้นหา - ตั้งค่า + การตั้งค่า หรือคุณหมายถึง \"%1$s\"\? แชร์ด้วย ใช้เครื่องเล่นวีดิโอภายนอก - ใช้แอปเล่นเสียงภายนอก + ใช้เครื่องเล่นเสียงภายนอก ติดตาม ติดตามแล้ว ยกเลิกการติดตาม ยกเลิกการติดตามช่องแล้ว ไม่สามารถเปลี่ยนสถานะการติดตามได้ - ไม่สามารถอัปเดตการติดตาม + ไม่สามารถอัพเดทการติดตาม แสดงข้อมูล การติดตาม เพลย์ลิสต์ที่เก็บไว้ เลือกแท็บ มีอะไรใหม่ - พื้นหลัง - ป๊อปอัพ + เล่นในพื้นหลัง + พ็อปอัพ เพิ่มไปยัง - เส้นทางการดาวน์โหลดวิดีโอ - เส้นทางในการจัดเก็บวิดีโอที่ดาวน์โหลดมา - เลือกเส้นทางการดาวน์โหลดสำหรับไฟล์วิดีโอ - โฟลเดอร์ที่ดาวน์โหลดเสียง + โฟลเดอร์ดาวน์โหลดของวิดีโอ + ไฟล์วิดีโอที่ดาวน์โหลดไว้จะถูกเก็บที่นี่ + เลือกโฟลเดอร์ดาวน์โหลดสำหรับไฟล์วิดีโอ + โฟลเดอร์ดาวน์โหลดของเสียง ไฟล์เสียงที่ดาวน์โหลดไว้จะถูกเก็บไว้ที่นี่ - เลือกเส้นทางการดาวน์โหลดสำหรับไฟล์เสียง + เลือกโฟลเดอร์ดาวน์โหลดสำหรับไฟล์เสียง ความละเอียดเริ่มต้น - ความละเอียดเริ่มต้นในโหมดป๊อปอัพ + ความละเอียดเริ่มต้นในโหมดพ็อปอัพ แสดงความละเอียดที่สูงขึ้น เฉพาะบางอุปกรณ์ที่รองรับการเล่นวิดีโอ 2K/4K เปิดด้วย Kodi @@ -349,7 +349,7 @@ หยุดชั่วคราวเมื่อเปลี่ยนเป็นข้อมูลมือถือ การดาวน์โหลดที่ไม่สามารถหยุดพักได้จะเริ่มต้นใหม่ ปิด - บางความละเอียดอาจไม่มีเสียง + ลบเสียงสำหรับบางความละเอียดหน้าจอ แคช metadate ถูกลบแล้ว เล่นต่อหลังจากการขัดจังหวะ เล่นต่อ @@ -361,13 +361,55 @@ เปิดด้วย ทำเครื่องหมายว่าดูแล้ว ตกลง - ปุ่มการกระทำที่สี่ - ปุ่มการกระทำแรก - ปุ่มการกระทำที่สาม - ปุ่มการกระทำที่ห้า - แก้ไขการกระทำของการแต่การแจ้งเตือนด้วยการแตะไปที่มัน เลือกสามรายการที่จะแสดงในการแจ้งเตือนในการแจ้งเตือนแบบกระทัดรัดโดยใช้ปุ่มกาเครื่องหมายทางขวา - ครอบตัดตัวอย่างภาพเป็นอัตราส่วน 1:1 - ครอบตัดตัวอย่างภาพที่แสดงในการแจ้งเตือนจากอัตราส่วน 16:9 เป็น 1:1 - ทำเครื่องเล่นพัง - ปุ่มการกระทำรอง + ปุ่มคำสั่งที่สี่ + ปุ่มคำสั่งแรก + ปุ่มคำสั่งที่สาม + ปุ่มคำสั่งที่ห้า + แก้ไขคำสั่งของการแต่การแจ้งเตือนด้วยการแตะไปที่มัน เลือกสามรายการที่จะแสดงในการแจ้งเตือนในการแจ้งเตือนแบบกระทัดรัดโดยใช้ปุ่มกาเครื่องหมายทางขวา + ตัดหน้าปกวิดีโอเป็นอัตราส่วน 1:1 + ตัดหน้าปกวิดีโอที่แสดงในการแจ้งเตือนจากอัตราส่วน 16:9 เป็น 1:1 + เครื่องเล่นวิดีโอแครช + ปุ่มคำสั่งที่สอง + โหมดกลางคืน + เลือกเสียงต้นฉบับโดยไม่คำนึงถึงภาษาที่ใช้ + ปิดเพื่อซ่อนคำอธิบายของวิดีโอและข้อมูลเพิ่มเติมอื่นๆ + ชอบเสียงต้นฉบับมากกว่า + ชอบเสียงแบบบรรยายมากกว่า + คำสั่งสัมผัสฝั่งซ้าย + ไม่มี + ใส่ที่อยู่ URL ของอินสแตนซ์ + มีอินสแตนซ์นี้อยู่แล้ว + สลับ + เปลี่ยนสีการแจ้งเตือน + เปลี่ยนจากเครื่องเล่นหนึ่งไปอีกเครื่องเล่นหนึ่งอาจแทนที่คิวของคุณ + มีประโยชน์อย่างมากเมื่อใส่หูฟังที่ปุ่มกดพัง + เลือกเสียงแบบบรรยายสำหรับผู้มีความบกพร่องทางการมองเห็น ถ้าเกิดมีตัวเลือกนี้ + แนะนำการค้นหาที่อยู่ในท้องที่ + เลือกคำสั่งสัมผัสสำหรับฝั่งซ้ายของหน้าจอเครื่องเล่น + การแจ้งเตือนจากเครื่องเล่น + วนซ้ำ + เร่งความเร็วไปข้างหน้า/ย้อนกลับหาช่วงเวลา + เริ่มเครื่องเล่นหลักแบบเต็มหน้าจอ + อย่าเริ่มวิดีโอในเครื่องเล่นเล็ก แต่เปลี่ยนเป็นเต็มหน้าจอโดยตรง ถ้าการหมุนหน้าจออัตโนมัติล็อคไว้ คุณยังสามารถเข้าถึงเครื่องเล่นเล็กโดยการออกจากโหมดเต็มหน้าจอ + ไม่สามารถระบุที่อยู่ URL ได้ ลองเปิดด้วยแอปอื่น + ถามก่อนการเคลียร์คิว + คิวในเครื่องเล่นที่ใช้งานอยู่จะถูกแทนที่ + แสดงคำอธิบาย + แสดง meta info + ล้าง cached metadata + เข้าคิวอัตโนมัติ + เลือกคำสั่งสัมผัสฝั่งขวาของหน้าจอเครื่องเล่น + คำสั่งสัมผัสฝั่งขวา + ความสว่าง + ระดับเสียง + แนะนำการค้นหาที่อยู่ไกลขึ้น + PeerTube อินสแตนซ์ + เลือก PeerTube อินสแตนซ์โปรดของคุณ + หาอินสแตนซ์ที่คุณชอบอยู่ใน %s + เพิ่มอินสแตนซ์ + ไม่สามารถตรวจสอบอินสแตนซ์ได้ + รับรองเฉพาะที่อยู่ URL แบบ HTTPS + ไม่มี + ไม่ + ใช่/ตกลง diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index a87dac75e..1e29f67a5 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -157,7 +157,7 @@ Geçmiş Bu ögeyi arama geçmişinden silmek istiyor musunuz\? \"Basılı tutarak kuyruğa ekle\" ipucunu göster - Video \"Ayrıntılar:\" sayfasında arka plan veya açılır pencere düğmesine basıldığında ipucu göster + Şurada arka plan ya da açılır pencere düğmesine basıldığında ipucu göster: Video \"Ayrıntılar:\\ Tümünü Oynat [Bilinmeyen] Bu akış oynatılamadı @@ -517,7 +517,7 @@ İzleneni kaldır Akış ögelerinde hizmetlerden alınan özgün metinler görünecektir Ögelerde özgün \'… önce\'yi göster - YouTube\'un \"Kısıtlı Kip\"ini aç + Aç: YouTube \"Kısıtlı Kip\\ %s tarafından %s tarafından oluşturuldu Kanalın avatar küçük resmi @@ -658,7 +658,7 @@ Hata raporlama bildirimi NewPipe hatayla karşılaştı, bildirmek için dokun Hata oluştu, bildirime bakın - \"Oynatıcıyı çöktür\"ü göster + Göster: \"Oynatıcıyı çöktür\\ Hata bildirimi oluştur Hata balonu göster Bu eyleme uygun dosya yönetici yok. diff --git a/app/src/main/res/values-vmf/strings.xml b/app/src/main/res/values-vmf/strings.xml new file mode 100644 index 000000000..b1cb4e774 --- /dev/null +++ b/app/src/main/res/values-vmf/strings.xml @@ -0,0 +1,10 @@ + + + im brüscher öffn + passd scho + passd scho + stoarnieren + iser + net + tealn + diff --git a/fastlane/metadata/android/de/changelogs/1003.txt b/fastlane/metadata/android/de/changelogs/1003.txt index 6c6dc761a..76f798a72 100644 --- a/fastlane/metadata/android/de/changelogs/1003.txt +++ b/fastlane/metadata/android/de/changelogs/1003.txt @@ -1,4 +1,6 @@ -Behoben: YouTube spielt keinen Stream ab. - -Diese Version behebt nur den dringendsten Fehler, der das Laden von YouTube-Videodetails verhindert. -Wir sind uns bewusst, dass es andere Probleme gibt, und wir werden bald eine separate Version erstellen, um sie zu lösen. +Dies ist eine Hotfix-Version, die YouTube-Fehler behebt: +• [Youtube] Behebung, dass keine Videoinformationen geladen werden, Behebung von HTTP 403-Fehlern beim Abspielen von Videos und Wiederherstellung der Wiedergabe einiger altersbeschränkter Videos +• Die Größe der Untertitel wird nicht mehr geändert +• Behebung des doppelten Herunterladens von Informationen beim Öffnen eines Streams +• [Soundcloud] Entfernen von nicht abspielbaren DRM-geschützten Streams +• Aktualisierte Übersetzungen diff --git a/fastlane/metadata/android/et/changelogs/1003.txt b/fastlane/metadata/android/et/changelogs/1003.txt index c4c747f5b..53c967eea 100644 --- a/fastlane/metadata/android/et/changelogs/1003.txt +++ b/fastlane/metadata/android/et/changelogs/1003.txt @@ -1,4 +1,6 @@ -Parandasime vea, kus ühtegi YouTube'i meediavoogu ei õnnestunud esitada. - -See versioon parandab vaid hetkel kõige olulisema vea, kus YouTube'i video andmeid ei õnnestunud laadida. -Me oleme teadlikud ka muudest vigadest ning nendega tegeleme hiljem. +See on kiirparandus, mis teeb korda need YouTube'i vead: +• [YouTube] Parandasime vea, kus ühtegi meediavoogu ei õnnestunud esitada, parandasime HTTP 403-tüüpi vead videote esitamisel ja taastasime mõnede vanusepiirangutega videote esitamise +• Parandasime vea, kus subtiitrite suurus ei muutunud +• Parandasime vea, kus meediavoo avamisel laadisime tema teabe kaks korda alla +• [Soundcloud] eemaldasime mitteesitatavad DRM-kaitsega meediavood +• Uuendasime tõlkeid diff --git a/fastlane/metadata/android/et/changelogs/998.txt b/fastlane/metadata/android/et/changelogs/998.txt new file mode 100644 index 000000000..a1bb7399c --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/998.txt @@ -0,0 +1,4 @@ +Parandasime vea, kus ühtegi YouTube'i meediavoogu ei õnnestunud esitada ja HTTP olekuteade oli 403. + +Juhuslikud HTTP 403 veas esituse keskel pole veel parandatud. +Me oleme teadlikud ka sellest veast ja kiirparandus lisandub niipea, kui võimalik. diff --git a/fastlane/metadata/android/et/changelogs/999.txt b/fastlane/metadata/android/et/changelogs/999.txt new file mode 100644 index 000000000..3f3aa24e5 --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/999.txt @@ -0,0 +1,12 @@ +See kiirparandus teeb korda vea, kus YouTube'i video esituse keskel esitus katkeb HTTP olekuteatega 403. + +Uus +• [SoundCloud] Lisandus on.soundcloud.com võrguaadresside tugi + +Täiendused +• [Bandcamp] Näitame lisateavet raadiokioski vaates + +Parandused +• [YouTube] Parandasime juhuslikud HTTP 403 vead videoesituse keskel +• [YouTube] Tuvastame tunnuspildi ja päisepildi enamatest kanalipäisete tüüpidest +• [Bandcamp] Mitmed veaparandused ja nüüdsest alati kasutame HTTPSi diff --git a/fastlane/metadata/android/et/full_description.txt b/fastlane/metadata/android/et/full_description.txt index 1a8cb9cac..e5192d070 100644 --- a/fastlane/metadata/android/et/full_description.txt +++ b/fastlane/metadata/android/et/full_description.txt @@ -1 +1 @@ -NewPipe ei kasuta Google-i raamistiku teeke ega YouTube APIt. See ainult sõelub veebilehelt vajamineva info. Seega saab rakendust kasutada ka seadmes, millesse ei ole paigaldatud Google teenuseid (Google Services). Lisaks ei ole NewPipe kasutamisel vaja YouTube'i kontot ja ta on FLOSS. +NewPipe ei kasuta Google'i raamistiku teeke ega YouTube'i APIt. Ta ainult sõelub veebilehelt vajamineva info. Seega saab rakendust kasutada ka seadmes, millesse ei ole paigaldatud Google'i teenuseid (Google Services). Lisaks ei ole NewPipe'i kasutamisel vaja YouTube'i kontot ja tegemist on avatud lähtekoodil põhineva tasuta ja vaba tarkvaraga. diff --git a/fastlane/metadata/android/et/short_description.txt b/fastlane/metadata/android/et/short_description.txt index 5d0d820e2..ee606a574 100644 --- a/fastlane/metadata/android/et/short_description.txt +++ b/fastlane/metadata/android/et/short_description.txt @@ -1 +1 @@ -Tasuta ja lihtne rakendus YouTube vaatamiseks. +Tasuta ja lihtne rakendus YouTube'i vaatamiseks. diff --git a/fastlane/metadata/android/fr/changelogs/1002.txt b/fastlane/metadata/android/fr/changelogs/1002.txt index 3ad3bf279..1b6846169 100644 --- a/fastlane/metadata/android/fr/changelogs/1002.txt +++ b/fastlane/metadata/android/fr/changelogs/1002.txt @@ -1 +1,4 @@ -Correction de YouTube qui ne lisait aucun média +Correction d'un problème empêchant YouTube de lire les vidéos en streaming. + +Cette version résout uniquement l'erreur la plus urgente qui empêche le chargement des détails des vidéos YouTube. +Nous sommes conscients qu'il existe d'autres problèmes et nous publierons bientôt une version séparée pour les résoudre. diff --git a/fastlane/metadata/android/fr/changelogs/1003.txt b/fastlane/metadata/android/fr/changelogs/1003.txt index 3ad3bf279..6b969c81a 100644 --- a/fastlane/metadata/android/fr/changelogs/1003.txt +++ b/fastlane/metadata/android/fr/changelogs/1003.txt @@ -1 +1,6 @@ -Correction de YouTube qui ne lisait aucun média +Il s'agit d'une version de correction qui résout les erreurs de YouTube : +• [YouTube] Correction du non-chargement des informations des vidéos, correction des erreurs HTTP 403 lors de la lecture des vidéos et restauration de la lecture de certaines vidéos restreintes par l'âge +• Correction des tailles de sous-titres qui ne changent pas +• Correction du téléchargement des informations deux fois lors de l'ouverture d'un flux +• [Soundcloud] Suppression des flux protégés par DRM non lisibles +• Traductions mises à jour diff --git a/fastlane/metadata/android/hu/changelogs/1002.txt b/fastlane/metadata/android/hu/changelogs/1002.txt index 5eebb2174..87454df24 100644 --- a/fastlane/metadata/android/hu/changelogs/1002.txt +++ b/fastlane/metadata/android/hu/changelogs/1002.txt @@ -1,4 +1,4 @@ -Javítva: a YouTube-ról nem játszik le semmilyen streamet. +Javítva a YouTube-ról nem játszik le semmilyen streamet. -Ez a kiadás csak a legsürgősebb hibát kezeli, ami megakadályozza a YouTube-videó részleteinek betöltését. +Ez a kiadás csak a legsürgősebb hibát kezeli, ami megakadályozza a YouTube videó részleteinek betöltését. Tisztában vagyunk azzal, hogy vannak más problémák is, és hamarosan külön kiadást készítünk ezek megoldására. diff --git a/fastlane/metadata/android/hu/changelogs/1003.txt b/fastlane/metadata/android/hu/changelogs/1003.txt index 5eebb2174..b33f5725b 100644 --- a/fastlane/metadata/android/hu/changelogs/1003.txt +++ b/fastlane/metadata/android/hu/changelogs/1003.txt @@ -1,4 +1,6 @@ -Javítva: a YouTube-ról nem játszik le semmilyen streamet. - -Ez a kiadás csak a legsürgősebb hibát kezeli, ami megakadályozza a YouTube-videó részleteinek betöltését. -Tisztában vagyunk azzal, hogy vannak más problémák is, és hamarosan külön kiadást készítünk ezek megoldására. +Ez egy azonnali kiadás, amely a YouTube hibáit javítja: +• [YouTube] A videóinformációk betöltésének elmaradása, a videók lejátszása közben fellépő HTTP 403 hibák javítása és néhány korhatáros videó lejátszásának visszaállítása +• A feliratméret váltásának javítása +• Az információ kétszeri letöltésének javítása a stream megnyitásakor +• [Soundcloud] A lejátszhatatlan DRM-védett streamek eltávolítása +• Frissített fordítások diff --git a/fastlane/metadata/android/ka/changelogs/1002.txt b/fastlane/metadata/android/ka/changelogs/1002.txt deleted file mode 100644 index d20512f17..000000000 --- a/fastlane/metadata/android/ka/changelogs/1002.txt +++ /dev/null @@ -1 +0,0 @@ -გაასწორა YouTube არ უკრავს არცერთ ნაკადს diff --git a/fastlane/metadata/android/ka/changelogs/1003.txt b/fastlane/metadata/android/ka/changelogs/1003.txt deleted file mode 100644 index d20512f17..000000000 --- a/fastlane/metadata/android/ka/changelogs/1003.txt +++ /dev/null @@ -1 +0,0 @@ -გაასწორა YouTube არ უკრავს არცერთ ნაკადს diff --git a/fastlane/metadata/android/ka/changelogs/65.txt b/fastlane/metadata/android/ka/changelogs/65.txt deleted file mode 100644 index e2ca8059d..000000000 --- a/fastlane/metadata/android/ka/changelogs/65.txt +++ /dev/null @@ -1,26 +0,0 @@ -### გაუმჯობესებები - - - გამორთეთ ბურგერმენუს ხატის ანიმაცია #1486 - - ჩამოტვირთვების წაშლის გაუქმება #1472 - - ჩამოტვირთვის ვარიანტი გაზიარების მენიუში #1498 - - დამატებულია გაზიარების ვარიანტი გრძელი შეხების მენიუში #1454 - - მთავარი მოთამაშის მინიმიზაცია #1354 გასასვლელზე - - ბიბლიოთეკის ვერსიის განახლება და მონაცემთა ბაზის სარეზერვო დაფიქსირება #1510 - - ExoPlayer 2.8.2 განახლება #1392 - - გადამუშავდა დაკვრის სიჩქარის კონტროლის დიალოგი, რათა მხარი დაუჭიროს სხვადასხვა ნაბიჯების ზომას უფრო სწრაფი სიჩქარის ცვლილებისთვის. - - დამატებულია გადართვა სწრაფი წინსვლისთვის დუმილის დროს დაკვრის სიჩქარის კონტროლში. ეს გამოსადეგი უნდა იყოს აუდიო წიგნებისთვის და გარკვეული მუსიკის ჟანრებისთვის და შეუძლია ნამდვილი უწყვეტი გამოცდილების მოტანა (და შეიძლება დაარღვიოს სიმღერა მრავალი დუმილით =\\). - - რეფაქტორირებული მედია წყაროს გარჩევადობა, რათა მეტამონაცემების გადაცემა მედიასთან ერთად შიგადაშიგ პლეერში, ვიდრე ხელით. ახლა ჩვენ გვაქვს მეტამონაცემების ერთი წყარო და პირდაპირ ხელმისაწვდომია დაკვრის დაწყებისას. - - დაფიქსირდა დისტანციური დასაკრავი სიის მეტამონაცემები არ განახლდება, როდესაც ახალი მეტამონაცემები ხელმისაწვდომია დასაკრავი სიის ფრაგმენტის გახსნისას. - - სხვადასხვა ინტერფეისის შესწორებები: #1383, ფონური მოთამაშის შეტყობინებების კონტროლი ახლა ყოველთვის თეთრია, უფრო ადვილია ამომხტარი მოთამაშის გამორთვა ფლანგით - - გამოიყენეთ ახალი ექსტრაქტორი რეფაქტორირებული არქიტექტურით მულტისერვისისთვის - - ### ასწორებს - - - დააფიქსირეთ #1440 გატეხილი ვიდეო ინფორმაციის განლაგება #1491 - - ნახეთ ისტორიის შესწორება #1497 - - #1495, მეტამონაცემების (მინიატურების, სათაურის და ვიდეოების რაოდენობა) განახლებით, როგორც კი მომხმარებელი წვდება დასაკრავ სიას. - - #1475, მონაცემთა ბაზაში ხედის დარეგისტრირებით, როდესაც მომხმარებელი იწყებს ვიდეოს გარე პლეერზე დეტალურ ფრაგმენტზე. - - დააფიქსირეთ ეკრანის დროის ამოწურვა ამომხტარი რეჟიმის შემთხვევაში. #1463 (დასწორებულია #640) - - მთავარი ვიდეო პლეერის დაფიქსირება #1509 - - [#1412] დაფიქსირდა გამეორების რეჟიმი, რომელიც იწვევს მოთამაშის NPE-ს, როდესაც მიიღება ახალი განზრახვა, როდესაც მოთამაშის აქტივობა ფონზეა. - - დაფიქსირებული მინიმიზაცია მოთამაშის ამომხტარ ფანჯარაში არ ანადგურებს მოთამაშეს, როდესაც ამომხტარი ნებართვა არ არის მინიჭებული. diff --git a/fastlane/metadata/android/ka/changelogs/68.txt b/fastlane/metadata/android/ka/changelogs/68.txt deleted file mode 100644 index 1c6967bcb..000000000 --- a/fastlane/metadata/android/ka/changelogs/68.txt +++ /dev/null @@ -1,31 +0,0 @@ -v0.14.1-ის ცვლილებები - - ### გამოსწორდა - - დაფიქსირდა ვიდეო url #1659-ის გაშიფვრა ვერ მოხერხდა - - დაფიქსირდა აღწერილობის ბმული კარგად არ არის ამონაწერი #1657 - - v0.14.0-ის # ცვლილებები - - ### ახალი - - ახალი უჯრის დიზაინი #1461 - - ახალი კონფიგურირებადი წინა გვერდი #1461 - - ### გაუმჯობესებები - - გადამუშავებული ჟესტების კონტროლი #1604 - - ახალი გზა ამომხტარი პლეერის დახურვის #1597 - - ### გამოსწორდა - - შეცდომის გამოსწორება, როდესაც ხელმოწერების რაოდენობა მიუწვდომელია. იხურება #1649. - - აჩვენეთ "აბონენტთა რაოდენობა მიუწვდომელია" ამ შემთხვევებში - - შეასწორეთ NPE, როდესაც YouTube დასაკრავი სია ცარიელია - - სწრაფი შესწორება კიოსკებისთვის SoundCloud-ში - - Refactor და bugfix #1623 - - დააფიქსირეთ ციკლური ძიების შედეგი #1562 - - შეასწორეთ ძიების ზოლი, რომელიც არ არის სტატიკურად განლაგებული - - გაასწორეთ YT Premium ვიდეო არ არის სწორად დაბლოკილი - - დააფიქსირეთ ვიდეოები, რომლებიც ზოგჯერ არ იტვირთება (DASH ანალიზების გამო) - - დააფიქსირეთ ბმულები ვიდეოს აღწერაში - - გაფრთხილების ჩვენება, როდესაც ვინმე ცდილობს გარე sdcard-ზე ჩამოტვირთვას - - დააფიქსირეთ არაფერი ნაჩვენები გამონაკლისის გამომწვევი ანგარიში - - ესკიზი არ არის ნაჩვენები ანდროიდ 8.1-ის ფონურ პლეერში [იხილეთ აქ](https://github.com/TeamNewPipe/NewPipe/issues/943) - - სამაუწყებლო მიმღების რეგისტრაციის დაფიქსირება. იხურება #1641. diff --git a/fastlane/metadata/android/ka/changelogs/69.txt b/fastlane/metadata/android/ka/changelogs/69.txt deleted file mode 100644 index 4bc9f3c03..000000000 --- a/fastlane/metadata/android/ka/changelogs/69.txt +++ /dev/null @@ -1,19 +0,0 @@ -### ახალი - - დიდხანს შეეხეთ წაშლას და გააზიარეთ გამოწერებში #1516 - - ტაბლეტის ინტერფეისი და ბადის სიის განლაგება #1617 - - ### გაუმჯობესებები - - შეინახეთ და გადატვირთეთ ბოლო გამოყენებული ასპექტის თანაფარდობა #1748 - - ჩართეთ ხაზოვანი განლაგება ჩამოტვირთვების აქტივობაში ვიდეოს სრული სახელებით #1771 - - წაშალეთ და გააზიარეთ ხელმოწერები პირდაპირ გამოწერების ჩანართიდან #1516 - - ახლა რიგში დაყენება იწვევს ვიდეოს დაკვრას, თუ დაკვრის რიგი უკვე დასრულდა #1783 - - ცალკე პარამეტრები მოცულობისა და სიკაშკაშის ჟესტებისთვის #1644 - - დაამატეთ მხარდაჭერა ლოკალიზაციის #1792-ისთვის - - ### ასწორებს - - დააფიქსირეთ დროის ანალიზი . ფორმატში, ამიტომ NewPipe შეიძლება გამოყენებულ იქნას ფინეთში - - შეასწორეთ გამოწერების რაოდენობა - - დაამატეთ წინა პლანზე სერვისის ნებართვა API 28+ მოწყობილობებისთვის #1830 - - ### ცნობილი შეცდომები - - დაკვრის მდგომარეობის შენახვა შეუძლებელია Android P-ზე diff --git a/fastlane/metadata/android/ne/short_description.txt b/fastlane/metadata/android/ne/short_description.txt new file mode 100644 index 000000000..383f78457 --- /dev/null +++ b/fastlane/metadata/android/ne/short_description.txt @@ -0,0 +1 @@ +एन्ड्रोइडका लागि निशुल्क, हलुका युट्युब फ्रन्टइन्ड । diff --git a/fastlane/metadata/android/sk/changelogs/1000.txt b/fastlane/metadata/android/sk/changelogs/1000.txt index 36b9aeae1..61cabd89d 100644 --- a/fastlane/metadata/android/sk/changelogs/1000.txt +++ b/fastlane/metadata/android/sk/changelogs/1000.txt @@ -1,4 +1,4 @@ -Vylepšenie +Vylepšené - Umožnené kliknutie na popis playlistu, aby sa zobrazilo viac/menej obsahu - [PeerTube] Automatické spracovanie odkazov inštancie `subscribeto.me` - Spustenie prehrávania iba jednej položky v histórii diff --git a/fastlane/metadata/android/sk/changelogs/1002.txt b/fastlane/metadata/android/sk/changelogs/1002.txt index 2f96b8dc5..789b1caef 100644 --- a/fastlane/metadata/android/sk/changelogs/1002.txt +++ b/fastlane/metadata/android/sk/changelogs/1002.txt @@ -1 +1,4 @@ -Fixed YouTube not playing any stream +Opravené prehrávanie videí. + +Toto vydanie rieši len najpálčivejšiu chybu, ktorá zabraňuje načítať detaily s videom. +Sme si vedomí aj ďalších chýb a čoskoro vydáme ďalšie vydanie, ktoré ich bude riešiť. diff --git a/fastlane/metadata/android/sk/full_description.txt b/fastlane/metadata/android/sk/full_description.txt index abda185e2..9de86c677 100644 --- a/fastlane/metadata/android/sk/full_description.txt +++ b/fastlane/metadata/android/sk/full_description.txt @@ -1 +1 @@ -NewPipe nepoužíva žiadne Google knižnice ani YouTube rozhranie. Analyzuje iba webovú stránku aby získala potrebné informácie. Preto je možné túto aplikáciu používať na zariadeniach bez nainštalovaných služieb Google. Na použitie aplikácie NewPipe tiež nepotrebujete účet na YouTube, je to bezproblémové. +NewPipe nepoužíva žiadne Google framework knižnice, ani YouTube API rozhranie. Len analyzuje web, aby získal potrebné informácie. Preto je možné túto aplikáciu používať na zariadeniach bez nainštalovaných Google služieb. Taktiež nepotrebujete účet na YouTube. Appka je FLOSS. diff --git a/fastlane/metadata/android/sk/short_description.txt b/fastlane/metadata/android/sk/short_description.txt index 1fe84348f..b2351c660 100644 --- a/fastlane/metadata/android/sk/short_description.txt +++ b/fastlane/metadata/android/sk/short_description.txt @@ -1 +1 @@ -Jednoduchý a bezplatný YouTube prehrávač pre Android. +Slobodný a nenáročný YouTube prehrávač pre Android. diff --git a/fastlane/metadata/android/sv/changelogs/1003.txt b/fastlane/metadata/android/sv/changelogs/1003.txt index b25a7e652..3b4532ca0 100644 --- a/fastlane/metadata/android/sv/changelogs/1003.txt +++ b/fastlane/metadata/android/sv/changelogs/1003.txt @@ -1,4 +1,6 @@ -Åtgärdat att YouTube inte spelar någon stream. - -Den här versionen fixar enbart det mest brådskande felet som förhindrar att YouTube-videoinformation laddas. -Vi är medvetna om att det finns andra problem, och vi kommer snart att göra en separat version för att lösa dem. +Detta är en snabbkorrigeringsversion som fixar YouTube-fel: +• [YouTube] Fixat att ingen videoinformation laddades, fixat HTTP 403 när videor spelas och återställde uppspelningen av några åldersbegränsade videor +• Fixade att undertexts storleken inte ändrades +• Fixade att information laddades ner två gånger vid öppning av en ström +• [Soundcloud] Tog bort ospelbara DRM-skyddade strömmar +• Uppdaterade översättningar From b764ad33c44e80371e79f3b64edcb3f819e0adfa Mon Sep 17 00:00:00 2001 From: Stypox Date: Sat, 15 Feb 2025 17:48:13 +0100 Subject: [PATCH 003/143] Drop some assumptions on how PlayerService is started and reused Read the comments in the lines changed to understand more --- .../java/org/schabi/newpipe/ktx/Bundle.kt | 13 ++++++ .../schabi/newpipe/player/PlayerService.java | 46 +++++++++++-------- .../newpipe/player/helper/PlayerHolder.java | 4 +- .../schabi/newpipe/util/NavigationHelper.java | 1 + 4 files changed, 43 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/ktx/Bundle.kt b/app/src/main/java/org/schabi/newpipe/ktx/Bundle.kt index 61721d546..e32376960 100644 --- a/app/src/main/java/org/schabi/newpipe/ktx/Bundle.kt +++ b/app/src/main/java/org/schabi/newpipe/ktx/Bundle.kt @@ -7,3 +7,16 @@ import androidx.core.os.BundleCompat inline fun Bundle.parcelableArrayList(key: String?): ArrayList? { return BundleCompat.getParcelableArrayList(this, key, T::class.java) } + +fun Bundle?.toDebugString(): String { + if (this == null) { + return "null" + } + val string = StringBuilder("Bundle{") + for (key in this.keySet()) { + @Suppress("DEPRECATION") // we want this[key] to return items of any type + string.append(" ").append(key).append(" => ").append(this[key]).append(";") + } + string.append(" }") + return string.toString() +} diff --git a/app/src/main/java/org/schabi/newpipe/player/PlayerService.java b/app/src/main/java/org/schabi/newpipe/player/PlayerService.java index e7abf4320..61eb3f733 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PlayerService.java +++ b/app/src/main/java/org/schabi/newpipe/player/PlayerService.java @@ -28,6 +28,7 @@ import android.os.Binder; import android.os.IBinder; import android.util.Log; +import org.schabi.newpipe.ktx.BundleKt; import org.schabi.newpipe.player.mediasession.MediaSessionPlayerUi; import org.schabi.newpipe.player.notification.NotificationPlayerUi; import org.schabi.newpipe.util.ThemeHelper; @@ -41,6 +42,7 @@ import java.lang.ref.WeakReference; public final class PlayerService extends Service { private static final String TAG = PlayerService.class.getSimpleName(); private static final boolean DEBUG = Player.DEBUG; + public static final String SHOULD_START_FOREGROUND_EXTRA = "should_start_foreground_extra"; private Player player; @@ -59,35 +61,39 @@ public final class PlayerService extends Service { assureCorrectAppLanguage(this); ThemeHelper.setTheme(this); - player = new Player(this); - /* - Create the player notification and start immediately the service in foreground, - otherwise if nothing is played or initializing the player and its components (especially - loading stream metadata) takes a lot of time, the app would crash on Android 8+ as the - service would never be put in the foreground while we said to the system we would do so - */ - player.UIs().get(NotificationPlayerUi.class) - .ifPresent(NotificationPlayerUi::createNotificationAndStartForeground); + // Note: you might be tempted to create the player instance and call startForeground here, + // but be aware that the Android system might start the service just to perform media + // queries. In those cases creating a player instance is a waste of resources, and calling + // startForeground means creating a useless empty notification. In case it's really needed + // the player instance can be created here, but startForeground() should definitely not be + // called here unless the service is actually starting in the foreground, to avoid the + // useless notification. } @Override public int onStartCommand(final Intent intent, final int flags, final int startId) { if (DEBUG) { Log.d(TAG, "onStartCommand() called with: intent = [" + intent + + "], extras = [" + BundleKt.toDebugString(intent.getExtras()) + "], flags = [" + flags + "], startId = [" + startId + "]"); } - /* - Be sure that the player notification is set and the service is started in foreground, - otherwise, the app may crash on Android 8+ as the service would never be put in the - foreground while we said to the system we would do so - The service is always requested to be started in foreground, so always creating a - notification if there is no one already and starting the service in foreground should - not create any issues - If the service is already started in foreground, requesting it to be started shouldn't - do anything - */ - if (player != null) { + // All internal NewPipe intents used to interact with the player, that are sent to the + // PlayerService using startForegroundService(), will have SHOULD_START_FOREGROUND_EXTRA, + // to ensure startForeground() is called (otherwise Android will force-crash the app). + if (intent.getBooleanExtra(SHOULD_START_FOREGROUND_EXTRA, false)) { + if (player == null) { + // make sure the player exists, in case the service was resumed + player = new Player(this); + } + + // Be sure that the player notification is set and the service is started in foreground, + // otherwise, the app may crash on Android 8+ as the service would never be put in the + // foreground while we said to the system we would do so. The service is always + // requested to be started in foreground, so always creating a notification if there is + // no one already and starting the service in foreground should not create any issues. + // If the service is already started in foreground, requesting it to be started + // shouldn't do anything. player.UIs().get(NotificationPlayerUi.class) .ifPresent(NotificationPlayerUi::createNotificationAndStartForeground); } diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java index b55a6547a..11b7379b3 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java @@ -130,7 +130,9 @@ public final class PlayerHolder { // and NullPointerExceptions inside the service because the service will be // bound twice. Prevent it with unbinding first unbind(context); - ContextCompat.startForegroundService(context, new Intent(context, PlayerService.class)); + final Intent intent = new Intent(context, PlayerService.class); + intent.putExtra(PlayerService.SHOULD_START_FOREGROUND_EXTRA, true); + ContextCompat.startForegroundService(context, intent); serviceConnection.doPlayAfterConnect(playAfterConnect); bind(context); } diff --git a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java index e4cb46f94..e1d296297 100644 --- a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java @@ -96,6 +96,7 @@ public final class NavigationHelper { } intent.putExtra(Player.PLAYER_TYPE, PlayerType.MAIN.valueForIntent()); intent.putExtra(Player.RESUME_PLAYBACK, resumePlayback); + intent.putExtra(PlayerService.SHOULD_START_FOREGROUND_EXTRA, true); return intent; } From cfb6e114d6918602c5208e3cc5ae35ffc46b91b9 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 16 Feb 2025 10:31:42 +0100 Subject: [PATCH 004/143] Disable logs about view animations by default --- app/src/main/java/org/schabi/newpipe/ktx/View.kt | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/ktx/View.kt b/app/src/main/java/org/schabi/newpipe/ktx/View.kt index bf0dcb201..b781335e1 100644 --- a/app/src/main/java/org/schabi/newpipe/ktx/View.kt +++ b/app/src/main/java/org/schabi/newpipe/ktx/View.kt @@ -17,8 +17,10 @@ import androidx.core.view.isGone import androidx.core.view.isInvisible import androidx.core.view.isVisible import androidx.interpolator.view.animation.FastOutSlowInInterpolator -import org.schabi.newpipe.MainActivity +// logs in this class are disabled by default since it's usually not useful, +// you can enable them by setting this flag to MainActivity.DEBUG +private const val DEBUG = false private const val TAG = "ViewUtils" /** @@ -38,7 +40,7 @@ fun View.animate( delay: Long = 0, execOnEnd: Runnable? = null ) { - if (MainActivity.DEBUG) { + if (DEBUG) { val id = try { resources.getResourceEntryName(id) } catch (e: Exception) { @@ -51,7 +53,7 @@ fun View.animate( Log.d(TAG, "animate(): $msg") } if (isVisible && enterOrExit) { - if (MainActivity.DEBUG) { + if (DEBUG) { Log.d(TAG, "animate(): view was already visible > view = [$this]") } animate().setListener(null).cancel() @@ -60,7 +62,7 @@ fun View.animate( execOnEnd?.run() return } else if ((isGone || isInvisible) && !enterOrExit) { - if (MainActivity.DEBUG) { + if (DEBUG) { Log.d(TAG, "animate(): view was already gone > view = [$this]") } animate().setListener(null).cancel() @@ -89,7 +91,7 @@ fun View.animate( * @param colorEnd the background color to end with */ fun View.animateBackgroundColor(duration: Long, @ColorInt colorStart: Int, @ColorInt colorEnd: Int) { - if (MainActivity.DEBUG) { + if (DEBUG) { Log.d( TAG, "animateBackgroundColor() called with: view = [$this], duration = [$duration], " + @@ -109,7 +111,7 @@ fun View.animateBackgroundColor(duration: Long, @ColorInt colorStart: Int, @Colo } fun View.animateHeight(duration: Long, targetHeight: Int): ValueAnimator { - if (MainActivity.DEBUG) { + if (DEBUG) { Log.d(TAG, "animateHeight: duration = [$duration], from $height to → $targetHeight in: $this") } val animator = ValueAnimator.ofFloat(height.toFloat(), targetHeight.toFloat()) @@ -127,7 +129,7 @@ fun View.animateHeight(duration: Long, targetHeight: Int): ValueAnimator { } fun View.animateRotation(duration: Long, targetRotation: Int) { - if (MainActivity.DEBUG) { + if (DEBUG) { Log.d(TAG, "animateRotation: duration = [$duration], from $rotation to → $targetRotation in: $this") } animate().setListener(null).cancel() From 5819546ea9083359d389ad2df4c4f2199725762f Mon Sep 17 00:00:00 2001 From: Stypox Date: Sat, 15 Feb 2025 18:26:10 +0100 Subject: [PATCH 005/143] Have PlayerService implement MediaBrowserServiceCompat Co-authored-by: Haggai Eran --- app/src/main/AndroidManifest.xml | 8 +++ .../newpipe/player/PlayQueueActivity.java | 3 ++ .../schabi/newpipe/player/PlayerService.java | 49 +++++++++++++++++-- .../newpipe/player/helper/PlayerHolder.java | 1 + app/src/main/res/xml/automotive_app_desc.xml | 3 ++ 5 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 app/src/main/res/xml/automotive_app_desc.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d11de9f47..e52dded5e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -64,6 +64,9 @@ + + + + + + diff --git a/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java b/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java index 195baecbd..f989a68d0 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java +++ b/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java @@ -183,7 +183,10 @@ public final class PlayQueueActivity extends AppCompatActivity //////////////////////////////////////////////////////////////////////////// private void bind() { + // Note: this code should not really exist, and PlayerHolder should be used instead, but + // it will be rewritten when NewPlayer will replace the current player. final Intent bindIntent = new Intent(this, PlayerService.class); + bindIntent.setAction(PlayerService.BIND_PLAYER_HOLDER_ACTION); final boolean success = bindService(bindIntent, serviceConnection, BIND_AUTO_CREATE); if (!success) { unbindService(serviceConnection); diff --git a/app/src/main/java/org/schabi/newpipe/player/PlayerService.java b/app/src/main/java/org/schabi/newpipe/player/PlayerService.java index 61eb3f733..7b9b76cfb 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PlayerService.java +++ b/app/src/main/java/org/schabi/newpipe/player/PlayerService.java @@ -21,28 +21,36 @@ package org.schabi.newpipe.player; import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage; -import android.app.Service; import android.content.Context; import android.content.Intent; import android.os.Binder; +import android.os.Bundle; import android.os.IBinder; +import android.support.v4.media.MediaBrowserCompat; import android.util.Log; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.media.MediaBrowserServiceCompat; + import org.schabi.newpipe.ktx.BundleKt; import org.schabi.newpipe.player.mediasession.MediaSessionPlayerUi; import org.schabi.newpipe.player.notification.NotificationPlayerUi; import org.schabi.newpipe.util.ThemeHelper; import java.lang.ref.WeakReference; +import java.util.List; /** * One service for all players. */ -public final class PlayerService extends Service { +public final class PlayerService extends MediaBrowserServiceCompat { private static final String TAG = PlayerService.class.getSimpleName(); private static final boolean DEBUG = Player.DEBUG; + public static final String SHOULD_START_FOREGROUND_EXTRA = "should_start_foreground_extra"; + public static final String BIND_PLAYER_HOLDER_ACTION = "bind_player_holder_action"; private Player player; @@ -55,6 +63,8 @@ public final class PlayerService extends Service { @Override public void onCreate() { + super.onCreate(); + if (DEBUG) { Log.d(TAG, "onCreate() called"); } @@ -148,6 +158,7 @@ public final class PlayerService extends Service { if (DEBUG) { Log.d(TAG, "destroy() called"); } + super.onDestroy(); cleanup(); } @@ -170,7 +181,25 @@ public final class PlayerService extends Service { @Override public IBinder onBind(final Intent intent) { - return mBinder; + if (DEBUG) { + Log.d(TAG, "onBind() called with: intent = [" + intent + + "], extras = [" + BundleKt.toDebugString(intent.getExtras()) + "]"); + } + + if (BIND_PLAYER_HOLDER_ACTION.equals(intent.getAction())) { + // Note that this binder might be reused multiple times while the service is alive, even + // after unbind() has been called: https://stackoverflow.com/a/8794930 . + return mBinder; + + } else if (MediaBrowserServiceCompat.SERVICE_INTERFACE.equals(intent.getAction())) { + // MediaBrowserService also uses its own binder, so for actions related to the media + // browser service, pass the onBind to the superclass. + return super.onBind(intent); + + } else { + // This is an unknown request, avoid returning any binder to not leak objects. + return null; + } } public static class LocalBinder extends Binder { @@ -188,4 +217,18 @@ public final class PlayerService extends Service { return playerService.get().player; } } + + @Nullable + @Override + public BrowserRoot onGetRoot(@NonNull final String clientPackageName, + final int clientUid, + @Nullable final Bundle rootHints) { + return null; + } + + @Override + public void onLoadChildren(@NonNull final String parentId, + @NonNull final Result> result) { + + } } diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java index 11b7379b3..30cdd5582 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java @@ -183,6 +183,7 @@ public final class PlayerHolder { } final Intent serviceIntent = new Intent(context, PlayerService.class); + serviceIntent.setAction(PlayerService.BIND_PLAYER_HOLDER_ACTION); bound = context.bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE); if (!bound) { diff --git a/app/src/main/res/xml/automotive_app_desc.xml b/app/src/main/res/xml/automotive_app_desc.xml new file mode 100644 index 000000000..90e6f30ef --- /dev/null +++ b/app/src/main/res/xml/automotive_app_desc.xml @@ -0,0 +1,3 @@ + + + From 7d17468266b62ed9689340d6550efbf2540ac560 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 16 Feb 2025 09:11:35 +0100 Subject: [PATCH 006/143] Instantiate media session and connector in PlayerService This changes significantly how the MediaSessionCompat and MediaSessionConnector objects are used: - now they are tied to the service and not to the player, and so they might be reused with multiple players (which should be allowed) - now they can exist even if there is no player (which is fundamental to be able to answer media browser queries) --- .../org/schabi/newpipe/player/Player.java | 15 ++++++- .../schabi/newpipe/player/PlayerService.java | 21 ++++++++- .../mediasession/MediaSessionPlayerUi.java | 43 ++++++++----------- 3 files changed, 51 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/Player.java b/app/src/main/java/org/schabi/newpipe/player/Player.java index 920435a7e..41705ffb2 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -55,6 +55,7 @@ import android.content.SharedPreferences; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; import android.media.AudioManager; +import android.support.v4.media.session.MediaSessionCompat; import android.util.Log; import android.view.LayoutInflater; @@ -71,6 +72,7 @@ import com.google.android.exoplayer2.PlaybackParameters; import com.google.android.exoplayer2.Player.PositionInfo; import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Tracks; +import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector; import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.text.CueGroup; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; @@ -269,7 +271,16 @@ public final class Player implements PlaybackListener, Listener { //////////////////////////////////////////////////////////////////////////*/ //region Constructor - public Player(@NonNull final PlayerService service) { + /** + * @param service the service this player resides in + * @param mediaSession used to build the {@link MediaSessionPlayerUi}, lives in the service and + * could possibly be reused with multiple player instances + * @param sessionConnector used to build the {@link MediaSessionPlayerUi}, lives in the service + * and could possibly be reused with multiple player instances + */ + public Player(@NonNull final PlayerService service, + @NonNull final MediaSessionCompat mediaSession, + @NonNull final MediaSessionConnector sessionConnector) { this.service = service; context = service; prefs = PreferenceManager.getDefaultSharedPreferences(context); @@ -302,7 +313,7 @@ public final class Player implements PlaybackListener, Listener { // notification ui in the UIs list, since the notification depends on the media session in // PlayerUi#initPlayer(), and UIs.call() guarantees UI order is preserved. UIs = new PlayerUiList( - new MediaSessionPlayerUi(this), + new MediaSessionPlayerUi(this, mediaSession, sessionConnector), new NotificationPlayerUi(this) ); } diff --git a/app/src/main/java/org/schabi/newpipe/player/PlayerService.java b/app/src/main/java/org/schabi/newpipe/player/PlayerService.java index 7b9b76cfb..ee8585c9c 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PlayerService.java +++ b/app/src/main/java/org/schabi/newpipe/player/PlayerService.java @@ -27,12 +27,15 @@ import android.os.Binder; import android.os.Bundle; import android.os.IBinder; import android.support.v4.media.MediaBrowserCompat; +import android.support.v4.media.session.MediaSessionCompat; import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.media.MediaBrowserServiceCompat; +import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector; + import org.schabi.newpipe.ktx.BundleKt; import org.schabi.newpipe.player.mediasession.MediaSessionPlayerUi; import org.schabi.newpipe.player.notification.NotificationPlayerUi; @@ -52,6 +55,12 @@ public final class PlayerService extends MediaBrowserServiceCompat { public static final String SHOULD_START_FOREGROUND_EXTRA = "should_start_foreground_extra"; public static final String BIND_PLAYER_HOLDER_ACTION = "bind_player_holder_action"; + // these are instantiated in onCreate() as per + // https://developer.android.com/training/cars/media#browser_workflow + private MediaSessionCompat mediaSession; + private MediaSessionConnector sessionConnector; + + @Nullable private Player player; private final IBinder mBinder = new PlayerService.LocalBinder(this); @@ -71,6 +80,12 @@ public final class PlayerService extends MediaBrowserServiceCompat { assureCorrectAppLanguage(this); ThemeHelper.setTheme(this); + // see https://developer.android.com/training/cars/media#browser_workflow + mediaSession = new MediaSessionCompat(this, "MediaSessionPlayerServ"); + setSessionToken(mediaSession.getSessionToken()); + sessionConnector = new MediaSessionConnector(mediaSession); + sessionConnector.setMetadataDeduplicationEnabled(true); + // Note: you might be tempted to create the player instance and call startForeground here, // but be aware that the Android system might start the service just to perform media // queries. In those cases creating a player instance is a waste of resources, and calling @@ -94,7 +109,7 @@ public final class PlayerService extends MediaBrowserServiceCompat { if (intent.getBooleanExtra(SHOULD_START_FOREGROUND_EXTRA, false)) { if (player == null) { // make sure the player exists, in case the service was resumed - player = new Player(this); + player = new Player(this, mediaSession, sessionConnector); } // Be sure that the player notification is set and the service is started in foreground, @@ -159,7 +174,11 @@ public final class PlayerService extends MediaBrowserServiceCompat { Log.d(TAG, "destroy() called"); } super.onDestroy(); + cleanup(); + + mediaSession.setActive(false); + mediaSession.release(); } private void cleanup() { diff --git a/app/src/main/java/org/schabi/newpipe/player/mediasession/MediaSessionPlayerUi.java b/app/src/main/java/org/schabi/newpipe/player/mediasession/MediaSessionPlayerUi.java index c673e688c..fe884834b 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediasession/MediaSessionPlayerUi.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediasession/MediaSessionPlayerUi.java @@ -38,10 +38,10 @@ public class MediaSessionPlayerUi extends PlayerUi implements SharedPreferences.OnSharedPreferenceChangeListener { private static final String TAG = "MediaSessUi"; - @Nullable - private MediaSessionCompat mediaSession; - @Nullable - private MediaSessionConnector sessionConnector; + @NonNull + private final MediaSessionCompat mediaSession; + @NonNull + private final MediaSessionConnector sessionConnector; private final String ignoreHardwareMediaButtonsKey; private boolean shouldIgnoreHardwareMediaButtons = false; @@ -50,9 +50,13 @@ public class MediaSessionPlayerUi extends PlayerUi private List prevNotificationActions = List.of(); - public MediaSessionPlayerUi(@NonNull final Player player) { + public MediaSessionPlayerUi(@NonNull final Player player, + @NonNull final MediaSessionCompat mediaSession, + @NonNull final MediaSessionConnector sessionConnector) { super(player); - ignoreHardwareMediaButtonsKey = + this.mediaSession = mediaSession; + this.sessionConnector = sessionConnector; + this.ignoreHardwareMediaButtonsKey = context.getString(R.string.ignore_hardware_media_buttons_key); } @@ -61,10 +65,8 @@ public class MediaSessionPlayerUi extends PlayerUi super.initPlayer(); destroyPlayer(); // release previously used resources - mediaSession = new MediaSessionCompat(context, TAG); mediaSession.setActive(true); - sessionConnector = new MediaSessionConnector(mediaSession); sessionConnector.setQueueNavigator(new PlayQueueNavigator(mediaSession, player)); sessionConnector.setPlayer(getForwardingPlayer()); @@ -89,27 +91,18 @@ public class MediaSessionPlayerUi extends PlayerUi public void destroyPlayer() { super.destroyPlayer(); player.getPrefs().unregisterOnSharedPreferenceChangeListener(this); - if (sessionConnector != null) { - sessionConnector.setMediaButtonEventHandler(null); - sessionConnector.setPlayer(null); - sessionConnector.setQueueNavigator(null); - sessionConnector = null; - } - if (mediaSession != null) { - mediaSession.setActive(false); - mediaSession.release(); - mediaSession = null; - } + sessionConnector.setMediaButtonEventHandler(null); + sessionConnector.setPlayer(null); + sessionConnector.setQueueNavigator(null); + mediaSession.setActive(false); prevNotificationActions = List.of(); } @Override public void onThumbnailLoaded(@Nullable final Bitmap bitmap) { super.onThumbnailLoaded(bitmap); - if (sessionConnector != null) { - // the thumbnail is now loaded: invalidate the metadata to trigger a metadata update - sessionConnector.invalidateMediaSessionMetadata(); - } + // the thumbnail is now loaded: invalidate the metadata to trigger a metadata update + sessionConnector.invalidateMediaSessionMetadata(); } @@ -200,8 +193,8 @@ public class MediaSessionPlayerUi extends PlayerUi return; } - if (sessionConnector == null) { - // sessionConnector will be null after destroyPlayer is called + if (!mediaSession.isActive()) { + // mediaSession will be inactive after destroyPlayer is called return; } From 1e08cc8c8f665712c4cfc3849ad96a892a9f3b29 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 16 Feb 2025 08:39:24 +0100 Subject: [PATCH 007/143] Add MediaBrowserCommon with info item's and pages' IDs Co-authored-by: Haggai Eran --- .../player/mediabrowser/MediaBrowserCommon.kt | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserCommon.kt diff --git a/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserCommon.kt b/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserCommon.kt new file mode 100644 index 000000000..12d69a163 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserCommon.kt @@ -0,0 +1,40 @@ +package org.schabi.newpipe.player.mediabrowser + +import org.schabi.newpipe.BuildConfig +import org.schabi.newpipe.extractor.InfoItem.InfoType +import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException + +internal const val ID_AUTHORITY = BuildConfig.APPLICATION_ID +internal const val ID_ROOT = "//$ID_AUTHORITY" +internal const val ID_BOOKMARKS = "playlists" +internal const val ID_HISTORY = "history" +internal const val ID_INFO_ITEM = "item" + +internal const val ID_LOCAL = "local" +internal const val ID_REMOTE = "remote" +internal const val ID_URL = "url" +internal const val ID_STREAM = "stream" +internal const val ID_PLAYLIST = "playlist" +internal const val ID_CHANNEL = "channel" + +internal fun infoItemTypeToString(type: InfoType): String { + return when (type) { + InfoType.STREAM -> ID_STREAM + InfoType.PLAYLIST -> ID_PLAYLIST + InfoType.CHANNEL -> ID_CHANNEL + else -> throw IllegalStateException("Unexpected value: $type") + } +} + +internal fun infoItemTypeFromString(type: String): InfoType { + return when (type) { + ID_STREAM -> InfoType.STREAM + ID_PLAYLIST -> InfoType.PLAYLIST + ID_CHANNEL -> InfoType.CHANNEL + else -> throw IllegalStateException("Unexpected value: $type") + } +} + +internal fun parseError(mediaId: String): ContentNotAvailableException { + return ContentNotAvailableException("Failed to parse media ID $mediaId") +} From 9bb2c0b48453f94b1c59b41fd3038767c8a59257 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 16 Feb 2025 08:42:15 +0100 Subject: [PATCH 008/143] Add getPlaylist(id) to RemotePlaylistManager Co-authored-by: Haggai Eran --- .../newpipe/database/playlist/dao/PlaylistRemoteDAO.java | 2 +- .../schabi/newpipe/local/playlist/RemotePlaylistManager.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistRemoteDAO.java b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistRemoteDAO.java index 8ab8a2afd..ef77d5ade 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistRemoteDAO.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistRemoteDAO.java @@ -34,7 +34,7 @@ public interface PlaylistRemoteDAO extends BasicDAO { @Query("SELECT * FROM " + REMOTE_PLAYLIST_TABLE + " WHERE " + REMOTE_PLAYLIST_ID + " = :playlistId") - Flowable> getPlaylist(long playlistId); + Flowable getPlaylist(long playlistId); @Query("SELECT * FROM " + REMOTE_PLAYLIST_TABLE + " WHERE " + REMOTE_PLAYLIST_URL + " = :url AND " + REMOTE_PLAYLIST_SERVICE_ID + " = :serviceId") diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/RemotePlaylistManager.java b/app/src/main/java/org/schabi/newpipe/local/playlist/RemotePlaylistManager.java index 4cc51f752..08b203a7e 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/RemotePlaylistManager.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/RemotePlaylistManager.java @@ -26,6 +26,10 @@ public class RemotePlaylistManager { return playlistRemoteTable.getPlaylists().subscribeOn(Schedulers.io()); } + public Flowable getPlaylist(final long playlistId) { + return playlistRemoteTable.getPlaylist(playlistId).subscribeOn(Schedulers.io()); + } + public Flowable> getPlaylist(final PlaylistInfo info) { return playlistRemoteTable.getPlaylist(info.getServiceId(), info.getUrl()) .subscribeOn(Schedulers.io()); From 690b40d0c4b6c27c42e8ac001152a2842d2855f6 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 16 Feb 2025 08:55:51 +0100 Subject: [PATCH 009/143] Allow creating PlayQueue from ListInfo and index --- .../newpipe/player/playqueue/AbstractInfoPlayQueue.java | 6 +++++- .../schabi/newpipe/player/playqueue/PlaylistPlayQueue.java | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/AbstractInfoPlayQueue.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/AbstractInfoPlayQueue.java index 33ec390a5..dbfac5cca 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playqueue/AbstractInfoPlayQueue.java +++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/AbstractInfoPlayQueue.java @@ -28,13 +28,17 @@ abstract class AbstractInfoPlayQueue> private transient Disposable fetchReactor; protected AbstractInfoPlayQueue(final T info) { + this(info, 0); + } + + protected AbstractInfoPlayQueue(final T info, final int index) { this(info.getServiceId(), info.getUrl(), info.getNextPage(), info.getRelatedItems() .stream() .filter(StreamInfoItem.class::isInstance) .map(StreamInfoItem.class::cast) .collect(Collectors.toList()), - 0); + index); } protected AbstractInfoPlayQueue(final int serviceId, diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlaylistPlayQueue.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlaylistPlayQueue.java index 01883d7d9..32316f393 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlaylistPlayQueue.java +++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlaylistPlayQueue.java @@ -16,6 +16,10 @@ public final class PlaylistPlayQueue extends AbstractInfoPlayQueue super(info); } + public PlaylistPlayQueue(final PlaylistInfo info, final int index) { + super(info, index); + } + public PlaylistPlayQueue(final int serviceId, final String url, final Page nextPage, From 5eabcb52b5e7b3d3445a8cd59ff06b975995123f Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 16 Feb 2025 08:56:38 +0100 Subject: [PATCH 010/143] Add getThumbnailUrl() to PlaylistLocalItem interface Co-authored-by: Haggai Eran --- .../newpipe/database/playlist/PlaylistLocalItem.java | 5 +++++ .../newpipe/database/playlist/PlaylistMetadataEntry.java | 8 ++++++++ .../database/playlist/model/PlaylistRemoteEntity.java | 3 +++ 3 files changed, 16 insertions(+) diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistLocalItem.java b/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistLocalItem.java index 072c49e2c..91f4622e9 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistLocalItem.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistLocalItem.java @@ -1,5 +1,7 @@ package org.schabi.newpipe.database.playlist; +import androidx.annotation.Nullable; + import org.schabi.newpipe.database.LocalItem; public interface PlaylistLocalItem extends LocalItem { @@ -10,4 +12,7 @@ public interface PlaylistLocalItem extends LocalItem { long getUid(); void setDisplayIndex(long displayIndex); + + @Nullable + String getThumbnailUrl(); } diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistMetadataEntry.java b/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistMetadataEntry.java index 03a1e1e30..8fbadb020 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistMetadataEntry.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistMetadataEntry.java @@ -9,6 +9,8 @@ import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.PLAYLIST import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.PLAYLIST_THUMBNAIL_STREAM_ID; import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.PLAYLIST_THUMBNAIL_URL; +import androidx.annotation.Nullable; + public class PlaylistMetadataEntry implements PlaylistLocalItem { public static final String PLAYLIST_STREAM_COUNT = "streamCount"; @@ -71,4 +73,10 @@ public class PlaylistMetadataEntry implements PlaylistLocalItem { public void setDisplayIndex(final long displayIndex) { this.displayIndex = displayIndex; } + + @Nullable + @Override + public String getThumbnailUrl() { + return thumbnailUrl; + } } diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java index 60027a057..0b0e3605e 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistRemoteEntity.java @@ -2,6 +2,7 @@ package org.schabi.newpipe.database.playlist.model; import android.text.TextUtils; +import androidx.annotation.Nullable; import androidx.room.ColumnInfo; import androidx.room.Entity; import androidx.room.Ignore; @@ -134,6 +135,8 @@ public class PlaylistRemoteEntity implements PlaylistLocalItem { this.name = name; } + @Nullable + @Override public String getThumbnailUrl() { return thumbnailUrl; } From 6cedd117fe6e1e36054e4389aa0296f4ae6cde18 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 16 Feb 2025 08:57:01 +0100 Subject: [PATCH 011/143] Add StreamHistoryEntry.toStreamInfoItem() Co-authored-by: Haggai Eran --- .../database/history/model/StreamHistoryEntry.kt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/app/src/main/java/org/schabi/newpipe/database/history/model/StreamHistoryEntry.kt b/app/src/main/java/org/schabi/newpipe/database/history/model/StreamHistoryEntry.kt index a93ba1652..27fc429f1 100644 --- a/app/src/main/java/org/schabi/newpipe/database/history/model/StreamHistoryEntry.kt +++ b/app/src/main/java/org/schabi/newpipe/database/history/model/StreamHistoryEntry.kt @@ -3,6 +3,8 @@ package org.schabi.newpipe.database.history.model import androidx.room.ColumnInfo import androidx.room.Embedded import org.schabi.newpipe.database.stream.model.StreamEntity +import org.schabi.newpipe.extractor.stream.StreamInfoItem +import org.schabi.newpipe.util.image.ImageStrategy import java.time.OffsetDateTime data class StreamHistoryEntry( @@ -27,4 +29,17 @@ data class StreamHistoryEntry( return this.streamEntity.uid == other.streamEntity.uid && streamId == other.streamId && accessDate.isEqual(other.accessDate) } + + fun toStreamInfoItem(): StreamInfoItem = + StreamInfoItem( + streamEntity.serviceId, + streamEntity.url, + streamEntity.title, + streamEntity.streamType, + ).apply { + duration = streamEntity.duration + uploaderName = streamEntity.uploader + uploaderUrl = streamEntity.uploaderUrl + thumbnails = ImageStrategy.dbUrlToImageList(streamEntity.thumbnailUrl) + } } From 3fcac10e7ffd49a6f8bab78a4349ef717430ccee Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 16 Feb 2025 09:01:31 +0100 Subject: [PATCH 012/143] Add MediaBrowserPlaybackPreparer This class will receive the media URLs generated by [MediaBrowserImpl] and will start playback of the corresponding streams or playlists. Co-authored-by: Haggai Eran Co-authored-by: Profpatsch --- .../MediaBrowserPlaybackPreparer.kt | 258 ++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100644 app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserPlaybackPreparer.kt diff --git a/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserPlaybackPreparer.kt b/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserPlaybackPreparer.kt new file mode 100644 index 000000000..9d77ae8b9 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserPlaybackPreparer.kt @@ -0,0 +1,258 @@ +package org.schabi.newpipe.player.mediabrowser + +import android.content.Context +import android.net.Uri +import android.os.Bundle +import android.os.ResultReceiver +import android.support.v4.media.session.PlaybackStateCompat +import android.util.Log +import com.google.android.exoplayer2.Player +import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector.PlaybackPreparer +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers +import io.reactivex.rxjava3.core.Single +import io.reactivex.rxjava3.disposables.Disposable +import io.reactivex.rxjava3.schedulers.Schedulers +import org.schabi.newpipe.MainActivity +import org.schabi.newpipe.NewPipeDatabase +import org.schabi.newpipe.R +import org.schabi.newpipe.extractor.InfoItem.InfoType +import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException +import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException +import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler +import org.schabi.newpipe.local.playlist.LocalPlaylistManager +import org.schabi.newpipe.local.playlist.RemotePlaylistManager +import org.schabi.newpipe.player.playqueue.ChannelTabPlayQueue +import org.schabi.newpipe.player.playqueue.PlayQueue +import org.schabi.newpipe.player.playqueue.PlaylistPlayQueue +import org.schabi.newpipe.player.playqueue.SinglePlayQueue +import org.schabi.newpipe.util.ChannelTabHelper +import org.schabi.newpipe.util.ExtractorHelper +import org.schabi.newpipe.util.NavigationHelper +import java.util.function.BiConsumer + +/** + * This class is used to cleanly separate the Service implementation (in + * [org.schabi.newpipe.player.PlayerService]) and the playback preparer implementation (in this + * file). We currently use the playback preparer only in conjunction with the media browser: the + * playback preparer will receive the media URLs generated by [MediaBrowserImpl] and will start + * playback of the corresponding streams or playlists. + * + * @param setMediaSessionError takes an error String and an error code from [PlaybackStateCompat], + * calls `sessionConnector.setCustomErrorMessage(errorString, errorCode)` + * @param clearMediaSessionError calls `sessionConnector.setCustomErrorMessage(null)` + */ +class MediaBrowserPlaybackPreparer( + private val context: Context, + private val setMediaSessionError: BiConsumer, // error string, error code + private val clearMediaSessionError: Runnable, +) : PlaybackPreparer { + private val database = NewPipeDatabase.getInstance(context) + private var disposable: Disposable? = null + + fun dispose() { + disposable?.dispose() + } + + //region Overrides + override fun getSupportedPrepareActions(): Long { + return PlaybackStateCompat.ACTION_PLAY_FROM_MEDIA_ID + } + + override fun onPrepare(playWhenReady: Boolean) { + // TODO handle onPrepare + } + + override fun onPrepareFromMediaId(mediaId: String, playWhenReady: Boolean, extras: Bundle?) { + if (MainActivity.DEBUG) { + Log.d(TAG, "onPrepareFromMediaId($mediaId, $playWhenReady, $extras)") + } + + disposable?.dispose() + disposable = extractPlayQueueFromMediaId(mediaId) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + { playQueue -> + clearMediaSessionError.run() + NavigationHelper.playOnBackgroundPlayer(context, playQueue, playWhenReady) + }, + { throwable -> + Log.e(TAG, "Failed to start playback of media ID [$mediaId]", throwable) + onPrepareError() + } + ) + } + + override fun onPrepareFromSearch(query: String, playWhenReady: Boolean, extras: Bundle?) { + onUnsupportedError() + } + + override fun onPrepareFromUri(uri: Uri, playWhenReady: Boolean, extras: Bundle?) { + onUnsupportedError() + } + + override fun onCommand( + player: Player, + command: String, + extras: Bundle?, + cb: ResultReceiver? + ): Boolean { + return false + } + //endregion + + //region Errors + private fun onUnsupportedError() { + setMediaSessionError.accept( + context.getString(R.string.content_not_supported), + PlaybackStateCompat.ERROR_CODE_NOT_SUPPORTED + ) + } + + private fun onPrepareError() { + setMediaSessionError.accept( + context.getString(R.string.error_snackbar_message), + PlaybackStateCompat.ERROR_CODE_APP_ERROR + ) + } + //endregion + + //region Building play queues from playlists and history + private fun extractLocalPlayQueue(playlistId: Long, index: Int): Single { + return LocalPlaylistManager(database).getPlaylistStreams(playlistId).firstOrError() + .map { items -> SinglePlayQueue(items.map { it.toStreamInfoItem() }, index) } + } + + private fun extractRemotePlayQueue(playlistId: Long, index: Int): Single { + return RemotePlaylistManager(database).getPlaylist(playlistId).firstOrError() + .flatMap { ExtractorHelper.getPlaylistInfo(it.serviceId, it.url, false) } + .flatMap { info -> + info.errors.firstOrNull { it !is ContentNotSupportedException }?.let { + return@flatMap Single.error(it) + } + Single.just(PlaylistPlayQueue(info, index)) + } + } + + private fun extractPlayQueueFromMediaId(mediaId: String): Single { + try { + val mediaIdUri = Uri.parse(mediaId) + val path = ArrayList(mediaIdUri.pathSegments) + if (path.isEmpty()) { + throw parseError(mediaId) + } + + return when (/*val uriType = */path.removeAt(0)) { + ID_BOOKMARKS -> extractPlayQueueFromPlaylistMediaId( + mediaId, + path, + mediaIdUri.getQueryParameter(ID_URL) ?: throw parseError(mediaId) + ) + + ID_HISTORY -> extractPlayQueueFromHistoryMediaId(mediaId, path) + + ID_INFO_ITEM -> extractPlayQueueFromInfoItemMediaId( + mediaId, + path, + mediaIdUri.getQueryParameter(ID_URL) ?: throw parseError(mediaId) + ) + + else -> throw parseError(mediaId) + } + } catch (e: ContentNotAvailableException) { + return Single.error(e) + } + } + + @Throws(ContentNotAvailableException::class) + private fun extractPlayQueueFromPlaylistMediaId( + mediaId: String, + path: MutableList, + url: String, + ): Single { + if (path.isEmpty()) { + throw parseError(mediaId) + } + + when (val playlistType = path.removeAt(0)) { + ID_LOCAL, ID_REMOTE -> { + if (path.size != 2) { + throw parseError(mediaId) + } + val playlistId = path[0].toLong() + val index = path[1].toInt() + return if (playlistType == ID_LOCAL) + extractLocalPlayQueue(playlistId, index) + else + extractRemotePlayQueue(playlistId, index) + } + + ID_URL -> { + if (path.size != 1) { + throw parseError(mediaId) + } + + val serviceId = path[0].toInt() + return ExtractorHelper.getPlaylistInfo(serviceId, url, false) + .map { PlaylistPlayQueue(it) } + } + + else -> throw parseError(mediaId) + } + } + + @Throws(ContentNotAvailableException::class) + private fun extractPlayQueueFromHistoryMediaId( + mediaId: String, + path: List, + ): Single { + if (path.size != 1) { + throw parseError(mediaId) + } + + val streamId = path[0].toLong() + return database.streamHistoryDAO().getHistory() + .firstOrError() + .map { items -> + val infoItems = items + .filter { it.streamId == streamId } + .map { it.toStreamInfoItem() } + SinglePlayQueue(infoItems, 0) + } + } + + @Throws(ContentNotAvailableException::class) + private fun extractPlayQueueFromInfoItemMediaId( + mediaId: String, + path: List, + url: String, + ): Single { + if (path.size != 2) { + throw parseError(mediaId) + } + + val serviceId = path[1].toInt() + return when (/*val infoItemType = */infoItemTypeFromString(path[0])) { + InfoType.STREAM -> ExtractorHelper.getStreamInfo(serviceId, url, false) + .map { SinglePlayQueue(it) } + + InfoType.PLAYLIST -> ExtractorHelper.getPlaylistInfo(serviceId, url, false) + .map { PlaylistPlayQueue(it) } + + InfoType.CHANNEL -> ExtractorHelper.getChannelInfo(serviceId, url, false) + .map { info -> + val playableTab = info.tabs + .firstOrNull { ChannelTabHelper.isStreamsTab(it) } + ?: throw ContentNotAvailableException("No streams tab found") + return@map ChannelTabPlayQueue(serviceId, ListLinkHandler(playableTab)) + } + + else -> throw parseError(mediaId) + } + } + //endregion + + companion object { + private val TAG = MediaBrowserPlaybackPreparer::class.simpleName + } +} From 4c88a193bd68739a3f44a9f6e3a23a71b7c638fa Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 16 Feb 2025 09:03:12 +0100 Subject: [PATCH 013/143] Add MediaBrowserImpl This class implements the media browser service interface as a standalone class for clearer separation of concerns (otherwise everything would need to go in PlayerService, since PlayerService overrides MediaBrowserServiceCompat) Co-authored-by: Haggai Eran Co-authored-by: Profpatsch --- .../player/mediabrowser/MediaBrowserImpl.kt | 413 ++++++++++++++++++ .../main/res/drawable/ic_bookmark_white.xml | 10 + .../main/res/drawable/ic_history_white.xml | 10 + app/src/main/res/values/strings.xml | 1 + 4 files changed, 434 insertions(+) create mode 100644 app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserImpl.kt create mode 100644 app/src/main/res/drawable/ic_bookmark_white.xml create mode 100644 app/src/main/res/drawable/ic_history_white.xml diff --git a/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserImpl.kt b/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserImpl.kt new file mode 100644 index 000000000..2cecd928f --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserImpl.kt @@ -0,0 +1,413 @@ +package org.schabi.newpipe.player.mediabrowser + +import android.content.ContentResolver +import android.content.Context +import android.net.Uri +import android.os.Bundle +import android.support.v4.media.MediaBrowserCompat +import android.support.v4.media.MediaDescriptionCompat +import android.util.Log +import androidx.annotation.DrawableRes +import androidx.media.MediaBrowserServiceCompat +import androidx.media.MediaBrowserServiceCompat.Result +import androidx.media.utils.MediaConstants +import io.reactivex.rxjava3.core.Flowable +import io.reactivex.rxjava3.core.Single +import io.reactivex.rxjava3.core.SingleSource +import io.reactivex.rxjava3.disposables.CompositeDisposable +import io.reactivex.rxjava3.schedulers.Schedulers +import org.schabi.newpipe.MainActivity.DEBUG +import org.schabi.newpipe.NewPipeDatabase +import org.schabi.newpipe.R +import org.schabi.newpipe.database.history.model.StreamHistoryEntry +import org.schabi.newpipe.database.playlist.PlaylistLocalItem +import org.schabi.newpipe.database.playlist.PlaylistStreamEntry +import org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity +import org.schabi.newpipe.extractor.InfoItem +import org.schabi.newpipe.extractor.InfoItem.InfoType +import org.schabi.newpipe.extractor.ListInfo +import org.schabi.newpipe.extractor.channel.ChannelInfoItem +import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException +import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException +import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem +import org.schabi.newpipe.extractor.search.SearchInfo +import org.schabi.newpipe.extractor.stream.StreamInfoItem +import org.schabi.newpipe.local.bookmark.MergedPlaylistManager +import org.schabi.newpipe.local.playlist.LocalPlaylistManager +import org.schabi.newpipe.local.playlist.RemotePlaylistManager +import org.schabi.newpipe.util.ExtractorHelper +import org.schabi.newpipe.util.ServiceHelper +import org.schabi.newpipe.util.image.ImageStrategy +import java.util.function.Consumer + +/** + * This class is used to cleanly separate the Service implementation (in + * [org.schabi.newpipe.player.PlayerService]) and the media browser implementation (in this file). + * + * @param notifyChildrenChanged takes the parent id of the children that changed + */ +class MediaBrowserImpl( + private val context: Context, + notifyChildrenChanged: Consumer, // parentId +) { + private val database = NewPipeDatabase.getInstance(context) + private var disposables = CompositeDisposable() + + init { + // this will listen to changes in the bookmarks until this MediaBrowserImpl is dispose()d + disposables.add( + getMergedPlaylists().subscribe { notifyChildrenChanged.accept(ID_BOOKMARKS) } + ) + } + + //region Cleanup + fun dispose() { + disposables.dispose() + } + //endregion + + //region onGetRoot + fun onGetRoot( + clientPackageName: String, + clientUid: Int, + rootHints: Bundle? + ): MediaBrowserServiceCompat.BrowserRoot { + if (DEBUG) { + Log.d(TAG, "onGetRoot($clientPackageName, $clientUid, $rootHints)") + } + + val extras = Bundle() + extras.putBoolean( + MediaConstants.BROWSER_SERVICE_EXTRAS_KEY_SEARCH_SUPPORTED, true + ) + return MediaBrowserServiceCompat.BrowserRoot(ID_ROOT, extras) + } + //endregion + + //region onLoadChildren + fun onLoadChildren(parentId: String, result: Result>) { + result.detach() // allows sendResult() to happen later + disposables.add( + onLoadChildren(parentId) + .subscribe( + { result.sendResult(it) }, + { throwable -> + // null indicates an error, see the docs of MediaSessionCompat.onSearch() + result.sendResult(null) + Log.e(TAG, "onLoadChildren error for parentId=$parentId: $throwable") + } + ) + ) + } + + private fun onLoadChildren(parentId: String): Single> { + if (DEBUG) { + Log.d(TAG, "onLoadChildren($parentId)") + } + + try { + val parentIdUri = Uri.parse(parentId) + val path = ArrayList(parentIdUri.pathSegments) + + if (path.isEmpty()) { + return Single.just( + listOf( + createRootMediaItem( + ID_BOOKMARKS, + context.resources.getString(R.string.tab_bookmarks_short), + R.drawable.ic_bookmark_white + ), + createRootMediaItem( + ID_HISTORY, + context.resources.getString(R.string.action_history), + R.drawable.ic_history_white + ) + ) + ) + } + + when (/*val uriType = */path.removeAt(0)) { + ID_BOOKMARKS -> { + if (path.isEmpty()) { + return populateBookmarks() + } + if (path.size == 2) { + val localOrRemote = path[0] + val playlistId = path[1].toLong() + if (localOrRemote == ID_LOCAL) { + return populateLocalPlaylist(playlistId) + } else if (localOrRemote == ID_REMOTE) { + return populateRemotePlaylist(playlistId) + } + } + Log.w(TAG, "Unknown playlist URI: $parentId") + throw parseError(parentId) + } + + ID_HISTORY -> return populateHistory() + + else -> throw parseError(parentId) + } + } catch (e: ContentNotAvailableException) { + return Single.error(e) + } + } + + private fun createRootMediaItem( + mediaId: String?, + folderName: String?, + @DrawableRes iconResId: Int + ): MediaBrowserCompat.MediaItem { + val builder = MediaDescriptionCompat.Builder() + builder.setMediaId(mediaId) + builder.setTitle(folderName) + val resources = context.resources + builder.setIconUri( + Uri.Builder() + .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE) + .authority(resources.getResourcePackageName(iconResId)) + .appendPath(resources.getResourceTypeName(iconResId)) + .appendPath(resources.getResourceEntryName(iconResId)) + .build() + ) + + val extras = Bundle() + extras.putString( + MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, + context.getString(R.string.app_name) + ) + builder.setExtras(extras) + return MediaBrowserCompat.MediaItem( + builder.build(), + MediaBrowserCompat.MediaItem.FLAG_BROWSABLE + ) + } + + private fun createPlaylistMediaItem(playlist: PlaylistLocalItem): MediaBrowserCompat.MediaItem { + val builder = MediaDescriptionCompat.Builder() + builder + .setMediaId(createMediaIdForInfoItem(playlist is PlaylistRemoteEntity, playlist.uid)) + .setTitle(playlist.orderingName) + .setIconUri(playlist.thumbnailUrl?.let { Uri.parse(it) }) + + val extras = Bundle() + extras.putString( + MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, + context.resources.getString(R.string.tab_bookmarks), + ) + builder.setExtras(extras) + return MediaBrowserCompat.MediaItem( + builder.build(), + MediaBrowserCompat.MediaItem.FLAG_BROWSABLE, + ) + } + + private fun createInfoItemMediaItem(item: InfoItem): MediaBrowserCompat.MediaItem? { + val builder = MediaDescriptionCompat.Builder() + builder.setMediaId(createMediaIdForInfoItem(item)) + .setTitle(item.name) + + when (item.infoType) { + InfoType.STREAM -> builder.setSubtitle((item as StreamInfoItem).uploaderName) + InfoType.PLAYLIST -> builder.setSubtitle((item as PlaylistInfoItem).uploaderName) + InfoType.CHANNEL -> builder.setSubtitle((item as ChannelInfoItem).description) + else -> return null + } + + ImageStrategy.choosePreferredImage(item.thumbnails)?.let { + builder.setIconUri(Uri.parse(it)) + } + + return MediaBrowserCompat.MediaItem( + builder.build(), + MediaBrowserCompat.MediaItem.FLAG_PLAYABLE + ) + } + + private fun buildMediaId(): Uri.Builder { + return Uri.Builder().authority(ID_AUTHORITY) + } + + private fun buildPlaylistMediaId(playlistType: String?): Uri.Builder { + return buildMediaId() + .appendPath(ID_BOOKMARKS) + .appendPath(playlistType) + } + + private fun buildLocalPlaylistItemMediaId(isRemote: Boolean, playlistId: Long): Uri.Builder { + return buildPlaylistMediaId(if (isRemote) ID_REMOTE else ID_LOCAL) + .appendPath(playlistId.toString()) + } + + private fun buildInfoItemMediaId(item: InfoItem): Uri.Builder { + return buildMediaId() + .appendPath(ID_INFO_ITEM) + .appendPath(infoItemTypeToString(item.infoType)) + .appendPath(item.serviceId.toString()) + .appendQueryParameter(ID_URL, item.url) + } + + private fun createMediaIdForInfoItem(isRemote: Boolean, playlistId: Long): String { + return buildLocalPlaylistItemMediaId(isRemote, playlistId) + .build().toString() + } + + private fun createLocalPlaylistStreamMediaItem( + playlistId: Long, + item: PlaylistStreamEntry, + index: Int, + ): MediaBrowserCompat.MediaItem { + val builder = MediaDescriptionCompat.Builder() + builder.setMediaId(createMediaIdForPlaylistIndex(false, playlistId, index)) + .setTitle(item.streamEntity.title) + .setSubtitle(item.streamEntity.uploader) + .setIconUri(Uri.parse(item.streamEntity.thumbnailUrl)) + + return MediaBrowserCompat.MediaItem( + builder.build(), + MediaBrowserCompat.MediaItem.FLAG_PLAYABLE + ) + } + + private fun createRemotePlaylistStreamMediaItem( + playlistId: Long, + item: StreamInfoItem, + index: Int, + ): MediaBrowserCompat.MediaItem { + val builder = MediaDescriptionCompat.Builder() + builder.setMediaId(createMediaIdForPlaylistIndex(true, playlistId, index)) + .setTitle(item.name) + .setSubtitle(item.uploaderName) + + ImageStrategy.choosePreferredImage(item.thumbnails)?.let { + builder.setIconUri(Uri.parse(it)) + } + + return MediaBrowserCompat.MediaItem( + builder.build(), + MediaBrowserCompat.MediaItem.FLAG_PLAYABLE + ) + } + + private fun createMediaIdForPlaylistIndex( + isRemote: Boolean, + playlistId: Long, + index: Int, + ): String { + return buildLocalPlaylistItemMediaId(isRemote, playlistId) + .appendPath(index.toString()) + .build().toString() + } + + private fun createMediaIdForInfoItem(item: InfoItem): String { + return buildInfoItemMediaId(item).build().toString() + } + + private fun populateHistory(): Single> { + val history = database.streamHistoryDAO().getHistory().firstOrError() + return history.map { items -> + items.map { this.createHistoryMediaItem(it) } + } + } + + private fun createHistoryMediaItem(streamHistoryEntry: StreamHistoryEntry): MediaBrowserCompat.MediaItem { + val builder = MediaDescriptionCompat.Builder() + val mediaId = buildMediaId() + .appendPath(ID_HISTORY) + .appendPath(streamHistoryEntry.streamId.toString()) + .build().toString() + builder.setMediaId(mediaId) + .setTitle(streamHistoryEntry.streamEntity.title) + .setSubtitle(streamHistoryEntry.streamEntity.uploader) + .setIconUri(Uri.parse(streamHistoryEntry.streamEntity.thumbnailUrl)) + + return MediaBrowserCompat.MediaItem( + builder.build(), + MediaBrowserCompat.MediaItem.FLAG_PLAYABLE + ) + } + + private fun getMergedPlaylists(): Flowable> { + return MergedPlaylistManager.getMergedOrderedPlaylists( + LocalPlaylistManager(database), + RemotePlaylistManager(database) + ) + } + + private fun populateBookmarks(): Single> { + val playlists = getMergedPlaylists().firstOrError() + return playlists.map { playlist -> + playlist.map { this.createPlaylistMediaItem(it) } + } + } + + private fun populateLocalPlaylist(playlistId: Long): Single> { + val playlist = LocalPlaylistManager(database).getPlaylistStreams(playlistId).firstOrError() + return playlist.map { items -> + items.mapIndexed { index, item -> + createLocalPlaylistStreamMediaItem(playlistId, item, index) + } + } + } + + private fun populateRemotePlaylist(playlistId: Long): Single> { + return RemotePlaylistManager(database).getPlaylist(playlistId).firstOrError() + .flatMap { ExtractorHelper.getPlaylistInfo(it.serviceId, it.url, false) } + .flatMap { info -> + info.errors.firstOrNull { it !is ContentNotSupportedException }?.let { + return@flatMap Single.error(it) + } + Single.just( + info.relatedItems.mapIndexed { index, item -> + createRemotePlaylistStreamMediaItem(playlistId, item, index) + } + ) + } + } + //endregion + + //region Search + fun onSearch( + query: String, + result: Result> + ) { + result.detach() // allows sendResult() to happen later + disposables.add( + searchMusicBySongTitle(query) + .flatMap { this.mediaItemsFromInfoItemList(it) } + .subscribeOn(Schedulers.io()) + .subscribe( + { result.sendResult(it) }, + { throwable -> + // null indicates an error, see the docs of MediaSessionCompat.onSearch() + result.sendResult(null) + Log.e(TAG, "Search error for query=\"$query\": $throwable") + } + ) + ) + } + + private fun searchMusicBySongTitle(query: String?): Single { + val serviceId = ServiceHelper.getSelectedServiceId(context) + return ExtractorHelper.searchFor(serviceId, query, listOf(), "") + } + + private fun mediaItemsFromInfoItemList( + result: ListInfo + ): SingleSource> { + result.errors.firstOrNull()?.let { return@mediaItemsFromInfoItemList Single.error(it) } + + return try { + Single.just( + result.relatedItems.mapNotNull { item -> this.createInfoItemMediaItem(item) } + ) + } catch (e: Exception) { + Single.error(e) + } + } + //endregion + + companion object { + private val TAG: String = MediaBrowserImpl::class.java.getSimpleName() + } +} diff --git a/app/src/main/res/drawable/ic_bookmark_white.xml b/app/src/main/res/drawable/ic_bookmark_white.xml new file mode 100644 index 000000000..a04ed256e --- /dev/null +++ b/app/src/main/res/drawable/ic_bookmark_white.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_history_white.xml b/app/src/main/res/drawable/ic_history_white.xml new file mode 100644 index 000000000..585285b89 --- /dev/null +++ b/app/src/main/res/drawable/ic_history_white.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2c27e6cbb..529ef0d9d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -33,6 +33,7 @@ Show info Subscriptions Bookmarked Playlists + Playlists Choose Tab Background Popup From 064e1d39c73c07e496e7a3ddb2226eb46f59479e Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 16 Feb 2025 09:14:19 +0100 Subject: [PATCH 014/143] Use the media browser implementation in PlayerService Now the media browser queries are replied to by MediaBrowserImpl Co-authored-by: Haggai Eran --- .../schabi/newpipe/player/PlayerService.java | 42 +++++++++++++++---- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/PlayerService.java b/app/src/main/java/org/schabi/newpipe/player/PlayerService.java index ee8585c9c..cbad4220c 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PlayerService.java +++ b/app/src/main/java/org/schabi/newpipe/player/PlayerService.java @@ -37,6 +37,8 @@ import androidx.media.MediaBrowserServiceCompat; import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector; import org.schabi.newpipe.ktx.BundleKt; +import org.schabi.newpipe.player.mediabrowser.MediaBrowserImpl; +import org.schabi.newpipe.player.mediabrowser.MediaBrowserPlaybackPreparer; import org.schabi.newpipe.player.mediasession.MediaSessionPlayerUi; import org.schabi.newpipe.player.notification.NotificationPlayerUi; import org.schabi.newpipe.util.ThemeHelper; @@ -55,6 +57,12 @@ public final class PlayerService extends MediaBrowserServiceCompat { public static final String SHOULD_START_FOREGROUND_EXTRA = "should_start_foreground_extra"; public static final String BIND_PLAYER_HOLDER_ACTION = "bind_player_holder_action"; + // These objects are used to cleanly separate the Service implementation (in this file) and the + // media browser and playback preparer implementations. At the moment the playback preparer is + // only used in conjunction with the media browser. + private MediaBrowserImpl mediaBrowserImpl; + private MediaBrowserPlaybackPreparer mediaBrowserPlaybackPreparer; + // these are instantiated in onCreate() as per // https://developer.android.com/training/cars/media#browser_workflow private MediaSessionCompat mediaSession; @@ -66,10 +74,7 @@ public final class PlayerService extends MediaBrowserServiceCompat { private final IBinder mBinder = new PlayerService.LocalBinder(this); - /*////////////////////////////////////////////////////////////////////////// - // Service's LifeCycle - //////////////////////////////////////////////////////////////////////////*/ - + //region Service lifecycle @Override public void onCreate() { super.onCreate(); @@ -80,12 +85,21 @@ public final class PlayerService extends MediaBrowserServiceCompat { assureCorrectAppLanguage(this); ThemeHelper.setTheme(this); + mediaBrowserImpl = new MediaBrowserImpl(this, this::notifyChildrenChanged); + // see https://developer.android.com/training/cars/media#browser_workflow mediaSession = new MediaSessionCompat(this, "MediaSessionPlayerServ"); setSessionToken(mediaSession.getSessionToken()); sessionConnector = new MediaSessionConnector(mediaSession); sessionConnector.setMetadataDeduplicationEnabled(true); + mediaBrowserPlaybackPreparer = new MediaBrowserPlaybackPreparer( + this, + sessionConnector::setCustomErrorMessage, + () -> sessionConnector.setCustomErrorMessage(null) + ); + sessionConnector.setPlaybackPreparer(mediaBrowserPlaybackPreparer); + // Note: you might be tempted to create the player instance and call startForeground here, // but be aware that the Android system might start the service just to perform media // queries. In those cases creating a player instance is a waste of resources, and calling @@ -177,8 +191,10 @@ public final class PlayerService extends MediaBrowserServiceCompat { cleanup(); + mediaBrowserPlaybackPreparer.dispose(); mediaSession.setActive(false); mediaSession.release(); + mediaBrowserImpl.dispose(); } private void cleanup() { @@ -197,7 +213,9 @@ public final class PlayerService extends MediaBrowserServiceCompat { protected void attachBaseContext(final Context base) { super.attachBaseContext(AudioServiceLeakFix.preventLeakOf(base)); } + //endregion + //region Bind @Override public IBinder onBind(final Intent intent) { if (DEBUG) { @@ -236,18 +254,28 @@ public final class PlayerService extends MediaBrowserServiceCompat { return playerService.get().player; } } + //endregion - @Nullable + //region Media browser @Override public BrowserRoot onGetRoot(@NonNull final String clientPackageName, final int clientUid, @Nullable final Bundle rootHints) { - return null; + // TODO check if the accessing package has permission to view data + return mediaBrowserImpl.onGetRoot(clientPackageName, clientUid, rootHints); } @Override public void onLoadChildren(@NonNull final String parentId, @NonNull final Result> result) { - + mediaBrowserImpl.onLoadChildren(parentId, result); } + + @Override + public void onSearch(@NonNull final String query, + final Bundle extras, + @NonNull final Result> result) { + mediaBrowserImpl.onSearch(query, result); + } + //endregion } From ec6612dd71163578f4cd45500202ecf7a3f8f0b9 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 16 Feb 2025 09:14:26 +0100 Subject: [PATCH 015/143] Call exoPlayer.prepare() on PlaybackPreparer.onPrepare() If a playbackPreparer is set, then instead of calling `player.prepare()`, the MediaSessionConnector will call `playbackPreparer.onPrepare(true)` instead, as seen below. This commit makes it so that playbackPreparer.onPrepare(true) restores the original behavior of just calling player.prepare(). From MediaSessionConnector -> MediaSessionCompat.Callback implementation: ```java @Override public void onPlay() { if (canDispatchPlaybackAction(PlaybackStateCompat.ACTION_PLAY)) { if (player.getPlaybackState() == Player.STATE_IDLE) { if (playbackPreparer != null) { playbackPreparer.onPrepare(/* playWhenReady= */ true); } else { player.prepare(); } } else if (player.getPlaybackState() == Player.STATE_ENDED) { seekTo(player, player.getCurrentMediaItemIndex(), C.TIME_UNSET); } Assertions.checkNotNull(player).play(); } } ``` --- .../main/java/org/schabi/newpipe/player/Player.java | 13 +++++++++++++ .../org/schabi/newpipe/player/PlayerService.java | 7 ++++++- .../mediabrowser/MediaBrowserPlaybackPreparer.kt | 7 ++++++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/Player.java b/app/src/main/java/org/schabi/newpipe/player/Player.java index 41705ffb2..b86d11e5c 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -1386,6 +1386,19 @@ public final class Player implements PlaybackListener, Listener { public void onCues(@NonNull final CueGroup cueGroup) { UIs.call(playerUi -> playerUi.onCues(cueGroup.cues)); } + + /** + * To be called when the {@code PlaybackPreparer} set in the {@link MediaSessionConnector} + * receives an {@code onPrepare()} call. This function allows restoring the default behavior + * that would happen if there was no playback preparer set, i.e. to just call + * {@code player.prepare()}. You can find the default behavior in `onPlay()` inside the + * {@link MediaSessionConnector} file. + */ + public void onPrepare() { + if (!exoPlayerIsNull()) { + simpleExoPlayer.prepare(); + } + } //endregion diff --git a/app/src/main/java/org/schabi/newpipe/player/PlayerService.java b/app/src/main/java/org/schabi/newpipe/player/PlayerService.java index cbad4220c..fa8dda526 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PlayerService.java +++ b/app/src/main/java/org/schabi/newpipe/player/PlayerService.java @@ -96,7 +96,12 @@ public final class PlayerService extends MediaBrowserServiceCompat { mediaBrowserPlaybackPreparer = new MediaBrowserPlaybackPreparer( this, sessionConnector::setCustomErrorMessage, - () -> sessionConnector.setCustomErrorMessage(null) + () -> sessionConnector.setCustomErrorMessage(null), + (playWhenReady) -> { + if (player != null) { + player.onPrepare(); + } + } ); sessionConnector.setPlaybackPreparer(mediaBrowserPlaybackPreparer); diff --git a/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserPlaybackPreparer.kt b/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserPlaybackPreparer.kt index 9d77ae8b9..d059bbdde 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserPlaybackPreparer.kt +++ b/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserPlaybackPreparer.kt @@ -29,6 +29,7 @@ import org.schabi.newpipe.util.ChannelTabHelper import org.schabi.newpipe.util.ExtractorHelper import org.schabi.newpipe.util.NavigationHelper import java.util.function.BiConsumer +import java.util.function.Consumer /** * This class is used to cleanly separate the Service implementation (in @@ -40,11 +41,15 @@ import java.util.function.BiConsumer * @param setMediaSessionError takes an error String and an error code from [PlaybackStateCompat], * calls `sessionConnector.setCustomErrorMessage(errorString, errorCode)` * @param clearMediaSessionError calls `sessionConnector.setCustomErrorMessage(null)` + * @param onPrepare takes playWhenReady, calls `player.prepare()`; this is needed because + * `MediaSessionConnector`'s `onPlay()` method calls this class' [onPrepare] instead of + * `player.prepare()` if the playback preparer is not null, but we want the original behavior */ class MediaBrowserPlaybackPreparer( private val context: Context, private val setMediaSessionError: BiConsumer, // error string, error code private val clearMediaSessionError: Runnable, + private val onPrepare: Consumer, ) : PlaybackPreparer { private val database = NewPipeDatabase.getInstance(context) private var disposable: Disposable? = null @@ -59,7 +64,7 @@ class MediaBrowserPlaybackPreparer( } override fun onPrepare(playWhenReady: Boolean) { - // TODO handle onPrepare + onPrepare.accept(playWhenReady) } override fun onPrepareFromMediaId(mediaId: String, playWhenReady: Boolean, extras: Bundle?) { From dc62d211f5f468526880f295c030d54c8b2caa24 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 16 Feb 2025 10:29:52 +0100 Subject: [PATCH 016/143] Properly stop PlayerService This commit is a consequence of the commit "Drop some assumptions on how PlayerService is started and reused". Since the assumptions on how the PlayerService is started and reused have changed, we also need to adapt the way it is stopped. This means allowing the service to remain alive even after the player is destroyed, in case the system is still accessing PlayerService e.g. through the media browser interface. The foreground service needs to be stopped and the notification removed in any case. --- .../org/schabi/newpipe/player/Player.java | 4 +-- .../schabi/newpipe/player/PlayerService.java | 33 ++++++++++++++++--- .../newpipe/player/helper/PlayerHolder.java | 8 +++++ .../newpipe/player/ui/PopupPlayerUi.java | 2 +- 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/Player.java b/app/src/main/java/org/schabi/newpipe/player/Player.java index b86d11e5c..040f0dc99 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -657,7 +657,7 @@ public final class Player implements PlaybackListener, Listener { Log.d(TAG, "onPlaybackShutdown() called"); } // destroys the service, which in turn will destroy the player - service.stopService(); + service.destroyPlayerAndStopService(); } public void smoothStopForImmediateReusing() { @@ -729,7 +729,7 @@ public final class Player implements PlaybackListener, Listener { pause(); break; case ACTION_CLOSE: - service.stopService(); + service.destroyPlayerAndStopService(); break; case ACTION_PLAY_PAUSE: playPause(); diff --git a/app/src/main/java/org/schabi/newpipe/player/PlayerService.java b/app/src/main/java/org/schabi/newpipe/player/PlayerService.java index fa8dda526..596cdef36 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PlayerService.java +++ b/app/src/main/java/org/schabi/newpipe/player/PlayerService.java @@ -32,6 +32,7 @@ import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.core.app.ServiceCompat; import androidx.media.MediaBrowserServiceCompat; import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector; @@ -150,7 +151,7 @@ public final class PlayerService extends MediaBrowserServiceCompat { Stop the service in this case, which will be removed from the foreground and its notification cancelled in its destruction */ - stopSelf(); + destroyPlayerAndStopService(); return START_NOT_STICKY; } @@ -197,7 +198,6 @@ public final class PlayerService extends MediaBrowserServiceCompat { cleanup(); mediaBrowserPlaybackPreparer.dispose(); - mediaSession.setActive(false); mediaSession.release(); mediaBrowserImpl.dispose(); } @@ -207,11 +207,36 @@ public final class PlayerService extends MediaBrowserServiceCompat { player.destroy(); player = null; } + + // Should already be handled by MediaSessionPlayerUi, but just to be sure. + mediaSession.setActive(false); + + // Should already be handled by NotificationUtil.cancelNotificationAndStopForeground() in + // NotificationPlayerUi, but let's make sure that the foreground service is stopped. + ServiceCompat.stopForeground(this, ServiceCompat.STOP_FOREGROUND_REMOVE); } - public void stopService() { + /** + * Destroys the player and allows the player instance to be garbage collected. Sets the media + * session to inactive. Stops the foreground service and removes the player notification + * associated with it. Tries to stop the {@link PlayerService} completely, but this step will + * have no effect in case some service connection still uses the service (e.g. the Android Auto + * system accesses the media browser even when no player is running). + */ + public void destroyPlayerAndStopService() { + if (DEBUG) { + Log.d(TAG, "destroyPlayerAndStopService() called"); + } + cleanup(); - stopSelf(); + + // This only really stops the service if there are no other service connections (see docs): + // for example the (Android Auto) media browser binder will block stopService(). + // This is why we also stopForeground() above, to make sure the notification is removed. + // If we were to call stopSelf(), then the service would be surely stopped (regardless of + // other service connections), but this would be a waste of resources since the service + // would be immediately restarted by those same connections to perform the queries. + stopService(new Intent(this, PlayerService.class)); } @Override diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java index 30cdd5582..7263afccd 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java @@ -138,8 +138,16 @@ public final class PlayerHolder { } public void stopService() { + if (DEBUG) { + Log.d(TAG, "stopService() called"); + } + if (playerService != null) { + playerService.destroyPlayerAndStopService(); + } final Context context = getCommonContext(); unbind(context); + // destroyPlayerAndStopService() already runs the next line of code, but run it again just + // to make sure to stop the service even if playerService is null by any chance. context.stopService(new Intent(context, PlayerService.class)); } diff --git a/app/src/main/java/org/schabi/newpipe/player/ui/PopupPlayerUi.java b/app/src/main/java/org/schabi/newpipe/player/ui/PopupPlayerUi.java index 02f7c07b0..6c98ab0fa 100644 --- a/app/src/main/java/org/schabi/newpipe/player/ui/PopupPlayerUi.java +++ b/app/src/main/java/org/schabi/newpipe/player/ui/PopupPlayerUi.java @@ -382,7 +382,7 @@ public final class PopupPlayerUi extends VideoPlayerUi { private void end() { windowManager.removeView(closeOverlayBinding.getRoot()); closeOverlayBinding = null; - player.getService().stopService(); + player.getService().destroyPlayerAndStopService(); } }).start(); } From e5458bcb144363e0ee3b7414695014c5658fc371 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 16 Feb 2025 10:45:02 +0100 Subject: [PATCH 017/143] Properly handle item errors during media browser loading Non-item errors, i.e. critical parsing errors of the page, are still handled properly. --- .../player/mediabrowser/MediaBrowserImpl.kt | 46 +++++++------------ .../MediaBrowserPlaybackPreparer.kt | 10 ++-- 2 files changed, 19 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserImpl.kt b/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserImpl.kt index 2cecd928f..3108da80f 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserImpl.kt +++ b/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserImpl.kt @@ -13,7 +13,6 @@ import androidx.media.MediaBrowserServiceCompat.Result import androidx.media.utils.MediaConstants import io.reactivex.rxjava3.core.Flowable import io.reactivex.rxjava3.core.Single -import io.reactivex.rxjava3.core.SingleSource import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.schedulers.Schedulers import org.schabi.newpipe.MainActivity.DEBUG @@ -25,10 +24,8 @@ import org.schabi.newpipe.database.playlist.PlaylistStreamEntry import org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity import org.schabi.newpipe.extractor.InfoItem import org.schabi.newpipe.extractor.InfoItem.InfoType -import org.schabi.newpipe.extractor.ListInfo import org.schabi.newpipe.extractor.channel.ChannelInfoItem import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException -import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem import org.schabi.newpipe.extractor.search.SearchInfo import org.schabi.newpipe.extractor.stream.StreamInfoItem @@ -86,6 +83,10 @@ class MediaBrowserImpl( //region onLoadChildren fun onLoadChildren(parentId: String, result: Result>) { + if (DEBUG) { + Log.d(TAG, "onLoadChildren($parentId)") + } + result.detach() // allows sendResult() to happen later disposables.add( onLoadChildren(parentId) @@ -101,10 +102,6 @@ class MediaBrowserImpl( } private fun onLoadChildren(parentId: String): Single> { - if (DEBUG) { - Log.d(TAG, "onLoadChildren($parentId)") - } - try { val parentIdUri = Uri.parse(parentId) val path = ArrayList(parentIdUri.pathSegments) @@ -353,15 +350,12 @@ class MediaBrowserImpl( private fun populateRemotePlaylist(playlistId: Long): Single> { return RemotePlaylistManager(database).getPlaylist(playlistId).firstOrError() .flatMap { ExtractorHelper.getPlaylistInfo(it.serviceId, it.url, false) } - .flatMap { info -> - info.errors.firstOrNull { it !is ContentNotSupportedException }?.let { - return@flatMap Single.error(it) + .map { + // ignore it.errors, i.e. ignore errors about specific items, since there would + // be no way to show the error properly in Android Auto anyway + it.relatedItems.mapIndexed { index, item -> + createRemotePlaylistStreamMediaItem(playlistId, item, index) } - Single.just( - info.relatedItems.mapIndexed { index, item -> - createRemotePlaylistStreamMediaItem(playlistId, item, index) - } - ) } } //endregion @@ -371,10 +365,16 @@ class MediaBrowserImpl( query: String, result: Result> ) { + if (DEBUG) { + Log.d(TAG, "onSearch($query)") + } + result.detach() // allows sendResult() to happen later disposables.add( searchMusicBySongTitle(query) - .flatMap { this.mediaItemsFromInfoItemList(it) } + // ignore it.errors, i.e. ignore errors about specific items, since there would + // be no way to show the error properly in Android Auto anyway + .map { it.relatedItems.mapNotNull(this::createInfoItemMediaItem) } .subscribeOn(Schedulers.io()) .subscribe( { result.sendResult(it) }, @@ -391,20 +391,6 @@ class MediaBrowserImpl( val serviceId = ServiceHelper.getSelectedServiceId(context) return ExtractorHelper.searchFor(serviceId, query, listOf(), "") } - - private fun mediaItemsFromInfoItemList( - result: ListInfo - ): SingleSource> { - result.errors.firstOrNull()?.let { return@mediaItemsFromInfoItemList Single.error(it) } - - return try { - Single.just( - result.relatedItems.mapNotNull { item -> this.createInfoItemMediaItem(item) } - ) - } catch (e: Exception) { - Single.error(e) - } - } //endregion companion object { diff --git a/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserPlaybackPreparer.kt b/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserPlaybackPreparer.kt index d059bbdde..ae6a9865a 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserPlaybackPreparer.kt +++ b/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserPlaybackPreparer.kt @@ -17,7 +17,6 @@ import org.schabi.newpipe.NewPipeDatabase import org.schabi.newpipe.R import org.schabi.newpipe.extractor.InfoItem.InfoType import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException -import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler import org.schabi.newpipe.local.playlist.LocalPlaylistManager import org.schabi.newpipe.local.playlist.RemotePlaylistManager @@ -131,12 +130,9 @@ class MediaBrowserPlaybackPreparer( private fun extractRemotePlayQueue(playlistId: Long, index: Int): Single { return RemotePlaylistManager(database).getPlaylist(playlistId).firstOrError() .flatMap { ExtractorHelper.getPlaylistInfo(it.serviceId, it.url, false) } - .flatMap { info -> - info.errors.firstOrNull { it !is ContentNotSupportedException }?.let { - return@flatMap Single.error(it) - } - Single.just(PlaylistPlayQueue(info, index)) - } + // ignore info.errors, i.e. ignore errors about specific items, since there would + // be no way to show the error properly in Android Auto anyway + .map { info -> PlaylistPlayQueue(info, index) } } private fun extractPlayQueueFromMediaId(mediaId: String): Single { From 1d98518bfa56b522c7fb74d2ddbe5ef7506755e4 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 16 Feb 2025 10:49:20 +0100 Subject: [PATCH 018/143] Fix loading remote playlists in media browser --- .../player/mediabrowser/MediaBrowserPlaybackPreparer.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserPlaybackPreparer.kt b/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserPlaybackPreparer.kt index ae6a9865a..f34677a29 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserPlaybackPreparer.kt +++ b/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserPlaybackPreparer.kt @@ -147,7 +147,7 @@ class MediaBrowserPlaybackPreparer( ID_BOOKMARKS -> extractPlayQueueFromPlaylistMediaId( mediaId, path, - mediaIdUri.getQueryParameter(ID_URL) ?: throw parseError(mediaId) + mediaIdUri.getQueryParameter(ID_URL) ) ID_HISTORY -> extractPlayQueueFromHistoryMediaId(mediaId, path) @@ -169,7 +169,7 @@ class MediaBrowserPlaybackPreparer( private fun extractPlayQueueFromPlaylistMediaId( mediaId: String, path: MutableList, - url: String, + url: String?, ): Single { if (path.isEmpty()) { throw parseError(mediaId) @@ -189,7 +189,7 @@ class MediaBrowserPlaybackPreparer( } ID_URL -> { - if (path.size != 1) { + if (path.size != 1 || url == null) { throw parseError(mediaId) } From 6558794d265ba8f20958c1e3e1644bcfce22773f Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 18 Feb 2025 17:36:43 +0100 Subject: [PATCH 019/143] Try to bind to PlayerService when MainActivity starts Fixes mini-player not appearing on app start if the player service is already playing something. The PlayerService (and the player) may be started from an external intent that does not involve the MainActivity (e.g. RouterActivity or Android Auto's media browser interface). This PR tries to bind to the PlayerService as soon as the MainActivity starts, but only does so in a passive way, i.e. if the service is not already running it is not started. Once the connection between PlayerHolder and PlayerService is setup, the ACTION_PLAYER_STARTED broadcast is sent to MainActivity so that it can setup the bottom mini-player. Another important thing this commit does is to check whether the player is open before actually adding the mini-player view, since the PlayerService could be bound even without a running player (e.g. Android Auto's media browser is being used). This is a consequence of commit "Drop some assumptions on how PlayerService is started and reused". --- .../java/org/schabi/newpipe/MainActivity.java | 7 ++++- .../newpipe/player/helper/PlayerHolder.java | 30 +++++++++++++++---- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/MainActivity.java b/app/src/main/java/org/schabi/newpipe/MainActivity.java index 354e06587..bbfc98f61 100644 --- a/app/src/main/java/org/schabi/newpipe/MainActivity.java +++ b/app/src/main/java/org/schabi/newpipe/MainActivity.java @@ -848,7 +848,8 @@ public class MainActivity extends AppCompatActivity { @Override public void onReceive(final Context context, final Intent intent) { if (Objects.equals(intent.getAction(), - VideoDetailFragment.ACTION_PLAYER_STARTED)) { + VideoDetailFragment.ACTION_PLAYER_STARTED) + && PlayerHolder.getInstance().isPlayerOpen()) { openMiniPlayerIfMissing(); // At this point the player is added 100%, we can unregister. Other actions // are useless since the fragment will not be removed after that. @@ -860,6 +861,10 @@ public class MainActivity extends AppCompatActivity { final IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(VideoDetailFragment.ACTION_PLAYER_STARTED); registerReceiver(broadcastReceiver, intentFilter); + + // If the PlayerHolder is not bound yet, but the service is running, try to bind to it. + // Once the connection is established, the ACTION_PLAYER_STARTED will be sent. + PlayerHolder.getInstance().tryBindIfNeeded(this); } } diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java index 7263afccd..b9afaa7c7 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java @@ -22,6 +22,7 @@ import org.schabi.newpipe.player.PlayerType; import org.schabi.newpipe.player.event.PlayerServiceEventListener; import org.schabi.newpipe.player.event.PlayerServiceExtendedEventListener; import org.schabi.newpipe.player.playqueue.PlayQueue; +import org.schabi.newpipe.util.NavigationHelper; public final class PlayerHolder { @@ -121,6 +122,9 @@ public final class PlayerHolder { public void startService(final boolean playAfterConnect, final PlayerServiceExtendedEventListener newListener) { + if (DEBUG) { + Log.d(TAG, "startService() called with playAfterConnect=" + playAfterConnect); + } final Context context = getCommonContext(); setListener(newListener); if (bound) { @@ -182,6 +186,10 @@ public final class PlayerHolder { listener.onServiceConnected(player, playerService, playAfterConnect); } startPlayerListener(); + + // notify the main activity that binding the service has completed, so that it can + // open the bottom mini-player + NavigationHelper.sendPlayerStartedEvent(localBinder.getService()); } } @@ -189,16 +197,28 @@ public final class PlayerHolder { if (DEBUG) { Log.d(TAG, "bind() called"); } - - final Intent serviceIntent = new Intent(context, PlayerService.class); - serviceIntent.setAction(PlayerService.BIND_PLAYER_HOLDER_ACTION); - bound = context.bindService(serviceIntent, serviceConnection, - Context.BIND_AUTO_CREATE); + // BIND_AUTO_CREATE starts the service if it's not already running + bound = bind(context, Context.BIND_AUTO_CREATE); if (!bound) { context.unbindService(serviceConnection); } } + public void tryBindIfNeeded(final Context context) { + if (!bound) { + // flags=0 means the service will not be started if it does not already exist. In this + // case the return value is not useful, as a value of "true" does not really indicate + // that the service is going to be bound. + bind(context, 0); + } + } + + private boolean bind(final Context context, final int flags) { + final Intent serviceIntent = new Intent(context, PlayerService.class); + serviceIntent.setAction(PlayerService.BIND_PLAYER_HOLDER_ACTION); + return context.bindService(serviceIntent, serviceConnection, flags); + } + private void unbind(final Context context) { if (DEBUG) { Log.d(TAG, "unbind() called"); From 126f4b0e30e321646537951b21f67a562ec9d6db Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 18 Feb 2025 18:03:10 +0100 Subject: [PATCH 020/143] Fix crash when closing video detail fragment This bug started appearing because the way to close the player is now unified in PlayerHolder.stopService(), which causes the player to reach back to the video detail fragment with a notification of the shutdown (i.e. onServiceStopped() is called). This is fixed by adding a nullability check on the binding. --- .../fragments/detail/VideoDetailFragment.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java index 40a22103b..fa2360247 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java @@ -1848,13 +1848,16 @@ public final class VideoDetailFragment @Override public void onServiceStopped() { - setOverlayPlayPauseImage(false); - if (currentInfo != null) { - updateOverlayData(currentInfo.getName(), - currentInfo.getUploaderName(), - currentInfo.getThumbnails()); + // the binding could be null at this point, if the app is finishing + if (binding != null) { + setOverlayPlayPauseImage(false); + if (currentInfo != null) { + updateOverlayData(currentInfo.getName(), + currentInfo.getUploaderName(), + currentInfo.getThumbnails()); + } + updateOverlayPlayQueueButtonVisibility(); } - updateOverlayPlayQueueButtonVisibility(); } @Override From a7a7dc53631579ea71baed0f097c0ef8638ae07b Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 18 Feb 2025 19:27:42 +0100 Subject: [PATCH 021/143] Handle player and player service separately This is, again, a consequence of the commit "Drop some assumptions on how PlayerService is started and reused". This commit notified VideoDetailFragment of player starting and stopping independently of the player. Read the comments in the code changes for more information. --- .../fragments/detail/VideoDetailFragment.java | 22 +++-- .../newpipe/player/PlayQueueActivity.java | 2 +- .../schabi/newpipe/player/PlayerService.java | 48 ++++++++++- .../PlayerServiceExtendedEventListener.java | 43 +++++++++- .../newpipe/player/helper/PlayerHolder.java | 85 ++++++++++++------- 5 files changed, 158 insertions(+), 42 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java index fa2360247..083d1fe05 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java @@ -236,11 +236,14 @@ public final class VideoDetailFragment // Service management //////////////////////////////////////////////////////////////////////////*/ @Override - public void onServiceConnected(final Player connectedPlayer, - final PlayerService connectedPlayerService, - final boolean playAfterConnect) { - player = connectedPlayer; + public void onServiceConnected(@NonNull final PlayerService connectedPlayerService) { playerService = connectedPlayerService; + } + + @Override + public void onPlayerConnected(@NonNull final Player connectedPlayer, + final boolean playAfterConnect) { + player = connectedPlayer; // It will do nothing if the player is not in fullscreen mode hideSystemUiIfNeeded(); @@ -272,11 +275,18 @@ public final class VideoDetailFragment updateOverlayPlayQueueButtonVisibility(); } + @Override + public void onPlayerDisconnected() { + player = null; + // the binding could be null at this point, if the app is finishing + if (binding != null) { + restoreDefaultBrightness(); + } + } + @Override public void onServiceDisconnected() { playerService = null; - player = null; - restoreDefaultBrightness(); } diff --git a/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java b/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java index f989a68d0..49aff657a 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java +++ b/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java @@ -224,7 +224,7 @@ public final class PlayQueueActivity extends AppCompatActivity Log.d(TAG, "Player service is connected"); if (service instanceof PlayerService.LocalBinder) { - player = ((PlayerService.LocalBinder) service).getPlayer(); + player = ((PlayerService.LocalBinder) service).getService().getPlayer(); } if (player == null || player.getPlayQueue() == null || player.exoPlayerIsNull()) { diff --git a/app/src/main/java/org/schabi/newpipe/player/PlayerService.java b/app/src/main/java/org/schabi/newpipe/player/PlayerService.java index 596cdef36..af6cf2467 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PlayerService.java +++ b/app/src/main/java/org/schabi/newpipe/player/PlayerService.java @@ -46,6 +46,7 @@ import org.schabi.newpipe.util.ThemeHelper; import java.lang.ref.WeakReference; import java.util.List; +import java.util.function.Consumer; /** @@ -74,6 +75,13 @@ public final class PlayerService extends MediaBrowserServiceCompat { private final IBinder mBinder = new PlayerService.LocalBinder(this); + /** + * The parameter taken by this {@link Consumer} can be null to indicate the player is being + * stopped. + */ + @Nullable + private Consumer onPlayerStartedOrStopped = null; + //region Service lifecycle @Override @@ -127,7 +135,8 @@ public final class PlayerService extends MediaBrowserServiceCompat { // PlayerService using startForegroundService(), will have SHOULD_START_FOREGROUND_EXTRA, // to ensure startForeground() is called (otherwise Android will force-crash the app). if (intent.getBooleanExtra(SHOULD_START_FOREGROUND_EXTRA, false)) { - if (player == null) { + final boolean playerWasNull = (player == null); + if (playerWasNull) { // make sure the player exists, in case the service was resumed player = new Player(this, mediaSession, sessionConnector); } @@ -141,6 +150,13 @@ public final class PlayerService extends MediaBrowserServiceCompat { // shouldn't do anything. player.UIs().get(NotificationPlayerUi.class) .ifPresent(NotificationPlayerUi::createNotificationAndStartForeground); + + if (playerWasNull && onPlayerStartedOrStopped != null) { + // notify that a new player was created (but do it after creating the foreground + // notification just to make sure we don't incur, due to slowness, in + // "Context.startForegroundService() did not then call Service.startForeground()") + onPlayerStartedOrStopped.accept(player); + } } if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction()) @@ -204,6 +220,10 @@ public final class PlayerService extends MediaBrowserServiceCompat { private void cleanup() { if (player != null) { + if (onPlayerStartedOrStopped != null) { + // notify that the player is being destroyed + onPlayerStartedOrStopped.accept(null); + } player.destroy(); player = null; } @@ -279,9 +299,31 @@ public final class PlayerService extends MediaBrowserServiceCompat { public PlayerService getService() { return playerService.get(); } + } - public Player getPlayer() { - return playerService.get().player; + /** + * @return the current active player instance. May be null, since the player service can outlive + * the player e.g. to respond to Android Auto media browser queries. + */ + @Nullable + public Player getPlayer() { + return player; + } + + /** + * Sets the listener that will be called when the player is started or stopped. If a + * {@code null} listener is passed, then the current listener will be unset. The parameter taken + * by the {@link Consumer} can be null to indicate that the player is stopping. + * @param listener the listener to set or unset + */ + public void setPlayerListener(@Nullable final Consumer listener) { + this.onPlayerStartedOrStopped = listener; + if (listener != null) { + if (player == null) { + listener.accept(null); + } else { + listener.accept(player); + } } } //endregion diff --git a/app/src/main/java/org/schabi/newpipe/player/event/PlayerServiceExtendedEventListener.java b/app/src/main/java/org/schabi/newpipe/player/event/PlayerServiceExtendedEventListener.java index 8effe2f0e..549abc952 100644 --- a/app/src/main/java/org/schabi/newpipe/player/event/PlayerServiceExtendedEventListener.java +++ b/app/src/main/java/org/schabi/newpipe/player/event/PlayerServiceExtendedEventListener.java @@ -1,11 +1,48 @@ package org.schabi.newpipe.player.event; +import androidx.annotation.NonNull; + import org.schabi.newpipe.player.PlayerService; import org.schabi.newpipe.player.Player; +/** + * In addition to {@link PlayerServiceEventListener}, provides callbacks for service and player + * connections and disconnections. "Connected" here means that the service (resp. the + * player) is running and is bound to {@link org.schabi.newpipe.player.helper.PlayerHolder}. + * "Disconnected" means that either the service (resp. the player) was stopped completely, or that + * {@link org.schabi.newpipe.player.helper.PlayerHolder} is not bound. + */ public interface PlayerServiceExtendedEventListener extends PlayerServiceEventListener { - void onServiceConnected(Player player, - PlayerService playerService, - boolean playAfterConnect); + /** + * The player service just connected to {@link org.schabi.newpipe.player.helper.PlayerHolder}, + * but the player may not be active at this moment, e.g. in case the service is running to + * respond to Android Auto media browser queries without playing anything. + * {@link #onPlayerConnected(Player, boolean)} will be called right after this function if there + * is a player. + * + * @param playerService the newly connected player service + */ + void onServiceConnected(@NonNull PlayerService playerService); + + /** + * The player service is already connected and the player was just started. + * + * @param player the newly connected or started player + * @param playAfterConnect whether to open the video player in the video details fragment + */ + void onPlayerConnected(@NonNull Player player, boolean playAfterConnect); + + /** + * The player got disconnected, for one of these reasons: the player is getting closed while + * leaving the service open for future media browser queries, the service is stopping + * completely, or {@link org.schabi.newpipe.player.helper.PlayerHolder} is unbinding. + */ + void onPlayerDisconnected(); + + /** + * The service got disconnected from {@link org.schabi.newpipe.player.helper.PlayerHolder}, + * either because {@link org.schabi.newpipe.player.helper.PlayerHolder} is unbinding or because + * the service is stopping completely. + */ void onServiceDisconnected(); } diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java index b9afaa7c7..20a0f3766 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java @@ -24,6 +24,9 @@ import org.schabi.newpipe.player.event.PlayerServiceExtendedEventListener; import org.schabi.newpipe.player.playqueue.PlayQueue; import org.schabi.newpipe.util.NavigationHelper; +import java.util.Optional; +import java.util.function.Consumer; + public final class PlayerHolder { private PlayerHolder() { @@ -45,7 +48,16 @@ public final class PlayerHolder { private final PlayerServiceConnection serviceConnection = new PlayerServiceConnection(); private boolean bound; @Nullable private PlayerService playerService; - @Nullable private Player player; + + private Optional getPlayer() { + return Optional.ofNullable(playerService) + .flatMap(s -> Optional.ofNullable(s.getPlayer())); + } + + private Optional getPlayQueue() { + // player play queue might be null e.g. while player is starting + return getPlayer().flatMap(p -> Optional.ofNullable(p.getPlayQueue())); + } /** * Returns the current {@link PlayerType} of the {@link PlayerService} service, @@ -55,21 +67,15 @@ public final class PlayerHolder { */ @Nullable public PlayerType getType() { - if (player == null) { - return null; - } - return player.getPlayerType(); + return getPlayer().map(Player::getPlayerType).orElse(null); } public boolean isPlaying() { - if (player == null) { - return false; - } - return player.isPlaying(); + return getPlayer().map(Player::isPlaying).orElse(false); } public boolean isPlayerOpen() { - return player != null; + return getPlayer().isPresent(); } /** @@ -78,7 +84,7 @@ public final class PlayerHolder { * @return true only if the player is open and its play queue is ready (i.e. it is not null) */ public boolean isPlayQueueReady() { - return player != null && player.getPlayQueue() != null; + return getPlayQueue().isPresent(); } public boolean isBound() { @@ -86,18 +92,11 @@ public final class PlayerHolder { } public int getQueueSize() { - if (player == null || player.getPlayQueue() == null) { - // player play queue might be null e.g. while player is starting - return 0; - } - return player.getPlayQueue().size(); + return getPlayQueue().map(PlayQueue::size).orElse(0); } public int getQueuePosition() { - if (player == null || player.getPlayQueue() == null) { - return 0; - } - return player.getPlayQueue().getIndex(); + return getPlayQueue().map(PlayQueue::getIndex).orElse(0); } public void setListener(@Nullable final PlayerServiceExtendedEventListener newListener) { @@ -108,9 +107,10 @@ public final class PlayerHolder { } // Force reload data from service - if (player != null) { - listener.onServiceConnected(player, playerService, false); + if (playerService != null) { + listener.onServiceConnected(playerService); startPlayerListener(); + // ^ will call listener.onPlayerConnected() down the line if there is an active player } } @@ -181,11 +181,12 @@ public final class PlayerHolder { final PlayerService.LocalBinder localBinder = (PlayerService.LocalBinder) service; playerService = localBinder.getService(); - player = localBinder.getPlayer(); if (listener != null) { - listener.onServiceConnected(player, playerService, playAfterConnect); + listener.onServiceConnected(playerService); + getPlayer().ifPresent(p -> listener.onPlayerConnected(p, playAfterConnect)); } startPlayerListener(); + // ^ will call listener.onPlayerConnected() down the line if there is an active player // notify the main activity that binding the service has completed, so that it can // open the bottom mini-player @@ -229,25 +230,32 @@ public final class PlayerHolder { bound = false; stopPlayerListener(); playerService = null; - player = null; if (listener != null) { + listener.onPlayerDisconnected(); listener.onServiceDisconnected(); } } } private void startPlayerListener() { - if (player != null) { - player.setFragmentListener(internalListener); + if (playerService != null) { + // setting the player listener will take care of calling relevant callbacks if the + // player in the service is (not) already active, also see playerStateListener below + playerService.setPlayerListener(playerStateListener); } + getPlayer().ifPresent(p -> p.setFragmentListener(internalListener)); } private void stopPlayerListener() { - if (player != null) { - player.removeFragmentListener(internalListener); + if (playerService != null) { + playerService.setPlayerListener(null); } + getPlayer().ifPresent(p -> p.removeFragmentListener(internalListener)); } + /** + * This listener will be held by the players created by {@link PlayerService}. + */ private final PlayerServiceEventListener internalListener = new PlayerServiceEventListener() { @Override @@ -334,4 +342,23 @@ public final class PlayerHolder { unbind(getCommonContext()); } }; + + /** + * This listener will be held by bound {@link PlayerService}s to notify of the player starting + * or stopping. This is necessary since the service outlives the player e.g. to answer Android + * Auto media browser queries. + */ + private final Consumer playerStateListener = (@Nullable final Player player) -> { + if (listener != null) { + if (player == null) { + // player.fragmentListener=null is already done by player.stopActivityBinding(), + // which is called by player.destroy(), which is in turn called by PlayerService + // before setting its player to null + listener.onPlayerDisconnected(); + } else { + listener.onPlayerConnected(player, serviceConnection.playAfterConnect); + player.setFragmentListener(internalListener); + } + } + }; } From 94d4c21cc7ec018d86525c839525d9c2aad6fbca Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Tue, 18 Feb 2025 17:47:22 -0300 Subject: [PATCH 022/143] [#11930] @Test export_justUrls() --- .../playlist/LocalPlaylistFragmentTest.java | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java b/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java index 41e1f6091..12242ad1d 100644 --- a/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java +++ b/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java @@ -1,5 +1,6 @@ package org.schabi.newpipe.local.playlist; +import static org.schabi.newpipe.local.playlist.PlayListShareMode.JUST_URLS; import static org.schabi.newpipe.local.playlist.PlayListShareMode.YOUTUBE_TEMP_PLAYLIST; import androidx.annotation.NonNull; @@ -15,23 +16,45 @@ import java.util.stream.Stream; public class LocalPlaylistFragmentTest { @Test - public void youTubeTempPlaylist() { + public void export_asYouTubeTempPlaylist() { - Stream entityStream = List.of( + Stream entityStream = asStreamEntityStream( "https://www.youtube.com/watch?v=1" ,"https://www.youtube.com/watch?v=2" ,"https://www.youtube.com/watch?v=3" - ) - .stream() - .map(LocalPlaylistFragmentTest::newStreamEntity) - ; + ); String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, entityStream, null); Assert.assertEquals("http://www.youtube.com/watch_videos?video_ids=1,2,3", url); } + @Test + public void export_justUrls() { + + Stream entityStream = asStreamEntityStream( + + "https://www.youtube.com/watch?v=1" + ,"https://www.youtube.com/watch?v=2" + ,"https://www.youtube.com/watch?v=3" + ); + + String exported = LocalPlaylistFragment.export(JUST_URLS, entityStream, null); + + Assert.assertEquals(""" + https://www.youtube.com/watch?v=1 + https://www.youtube.com/watch?v=2 + https://www.youtube.com/watch?v=3""", exported); + } + + @NonNull + private static Stream asStreamEntityStream(String... urls) { + + return Stream.of(urls) + .map(LocalPlaylistFragmentTest::newStreamEntity); + } + @NonNull static StreamEntity newStreamEntity(String url) { From c6b87cd3169056b1feb301d26763918ea0caa2e7 Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Tue, 18 Feb 2025 20:59:13 -0300 Subject: [PATCH 023/143] [#11930] Making CheckStyle happy --- .../local/playlist/LocalPlaylistFragment.java | 69 ++++++++++++------- .../local/playlist/PlayListShareMode.java | 6 +- .../playlist/LocalPlaylistFragmentTest.java | 55 ++++++++------- 3 files changed, 74 insertions(+), 56 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java index 3e99b01c4..354985b85 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java @@ -399,27 +399,39 @@ public class LocalPlaylistFragment extends BaseLocalListFragment Single.just(export( shareMode - , playlist.stream().map(PlaylistStreamEntry::getStreamEntity) - , context - ) - )) + .flatMapSingle(playlist -> Single.just(export( + + shareMode, + playlist.stream().map(PlaylistStreamEntry::getStreamEntity), + context + ))) .observeOn(AndroidSchedulers.mainThread()) - .subscribe( urlsText -> ShareUtils.shareText( context - , name - , shareMode == JUST_URLS ? urlsText - : context.getString(R.string.share_playlist_content_details, name, urlsText)) - , throwable -> showUiErrorSnackbar(this, "Sharing playlist", throwable)) - ); + .subscribe( + urlsText -> { + + final String content = shareMode == JUST_URLS + ? urlsText + : context.getString(R.string.share_playlist_content_details, + name, + urlsText + ); + + ShareUtils.shareText(context, name, content); + }, + throwable -> showUiErrorSnackbar(this, "Sharing playlist", throwable) + ) + ); } - static String export(PlayListShareMode shareMode, Stream entityStream, Context context) { + static String export(final PlayListShareMode shareMode, + final Stream entityStream, + final Context context) { - return switch(shareMode) { + return switch (shareMode) { case WITH_TITLES -> exportWithTitles(entityStream, context); case JUST_URLS -> exportJustUrls(entityStream); @@ -427,23 +439,27 @@ public class LocalPlaylistFragment extends BaseLocalListFragment entityStream, Context context) { + static String exportWithTitles(final Stream entityStream, final Context context) { return entityStream - .map(entity -> context.getString(R.string.video_details_list_item, entity.getTitle(), entity.getUrl())) + .map(entity -> context.getString(R.string.video_details_list_item, + entity.getTitle(), + entity.getUrl() + ) + ) .collect(Collectors.joining("\n")); } - static String exportJustUrls(Stream entityStream) { + static String exportJustUrls(final Stream entityStream) { return entityStream .map(StreamEntity::getUrl) .collect(Collectors.joining("\n")); } - static String exportAsYoutubeTempPlaylist(Stream entityStream) { + static String exportAsYoutubeTempPlaylist(final Stream entityStream) { - String videoIDs = entityStream + final String videoIDs = entityStream .map(entity -> getYouTubeId(entity.getUrl())) .collect(Collectors.joining(",")); @@ -451,15 +467,17 @@ public class LocalPlaylistFragment extends BaseLocalListFragment sharePlaylist(WITH_TITLES) ) - .setNeutralButton("Share as YouTube temporary playlist", (dialog, which) -> // TODO R.string.share_playlist_as_YouTube_temporary_playlist + // TODO R.string.share_playlist_as_YouTube_temporary_playlist + .setNeutralButton("Share as YouTube temporary playlist", (dialog, which) -> sharePlaylist(YOUTUBE_TEMP_PLAYLIST) ) .setNegativeButton(R.string.share_playlist_with_list, (dialog, which) -> diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/PlayListShareMode.java b/app/src/main/java/org/schabi/newpipe/local/playlist/PlayListShareMode.java index 3de1effc9..f0433aba8 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/PlayListShareMode.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/PlayListShareMode.java @@ -2,7 +2,7 @@ package org.schabi.newpipe.local.playlist; public enum PlayListShareMode { - JUST_URLS - ,WITH_TITLES - ,YOUTUBE_TEMP_PLAYLIST + JUST_URLS, + WITH_TITLES, + YOUTUBE_TEMP_PLAYLIST } diff --git a/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java b/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java index 12242ad1d..170193155 100644 --- a/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java +++ b/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java @@ -10,37 +10,36 @@ import org.junit.Test; import org.schabi.newpipe.database.stream.model.StreamEntity; import org.schabi.newpipe.extractor.stream.StreamType; -import java.util.List; import java.util.stream.Stream; public class LocalPlaylistFragmentTest { @Test - public void export_asYouTubeTempPlaylist() { + public void exportAsYouTubeTempPlaylist() { - Stream entityStream = asStreamEntityStream( + final Stream entityStream = asStreamEntityStream( - "https://www.youtube.com/watch?v=1" - ,"https://www.youtube.com/watch?v=2" - ,"https://www.youtube.com/watch?v=3" + "https://www.youtube.com/watch?v=1", + "https://www.youtube.com/watch?v=2", + "https://www.youtube.com/watch?v=3" ); - String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, entityStream, null); + final String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, entityStream, null); Assert.assertEquals("http://www.youtube.com/watch_videos?video_ids=1,2,3", url); } @Test - public void export_justUrls() { + public void exportJustUrls() { - Stream entityStream = asStreamEntityStream( + final Stream entityStream = asStreamEntityStream( - "https://www.youtube.com/watch?v=1" - ,"https://www.youtube.com/watch?v=2" - ,"https://www.youtube.com/watch?v=3" + "https://www.youtube.com/watch?v=1", + "https://www.youtube.com/watch?v=2", + "https://www.youtube.com/watch?v=3" ); - String exported = LocalPlaylistFragment.export(JUST_URLS, entityStream, null); + final String exported = LocalPlaylistFragment.export(JUST_URLS, entityStream, null); Assert.assertEquals(""" https://www.youtube.com/watch?v=1 @@ -49,30 +48,30 @@ public class LocalPlaylistFragmentTest { } @NonNull - private static Stream asStreamEntityStream(String... urls) { + private static Stream asStreamEntityStream(final String... urls) { return Stream.of(urls) .map(LocalPlaylistFragmentTest::newStreamEntity); } @NonNull - static StreamEntity newStreamEntity(String url) { + static StreamEntity newStreamEntity(final String url) { return new StreamEntity( - 0 - , 1 - , url - , "Title" - , StreamType.VIDEO_STREAM - , 100 - , "Uploader" - , null - , null - , null - , null - , null - , null + 0, + 1, + url, + "Title", + StreamType.VIDEO_STREAM, + 100, + "Uploader", + null, + null, + null, + null, + null, + null ); } } From acac50a1d1a66a4bd12e87573478d4532ed7ab50 Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Wed, 19 Feb 2025 16:29:34 -0300 Subject: [PATCH 024/143] [#11930] Non-Youtube URLs should be ignored --- .../schabi/newpipe/local/playlist/LocalPlaylistFragment.java | 2 ++ .../newpipe/local/playlist/LocalPlaylistFragmentTest.java | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java index 354985b85..cb47c2199 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java @@ -65,6 +65,7 @@ import org.schabi.newpipe.util.external_communication.ShareUtils; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -461,6 +462,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment getYouTubeId(entity.getUrl())) + .filter(Objects::nonNull) .collect(Collectors.joining(",")); return "http://www.youtube.com/watch_videos?video_ids=" + videoIDs; diff --git a/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java b/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java index 170193155..fb93a9e86 100644 --- a/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java +++ b/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java @@ -20,7 +20,8 @@ public class LocalPlaylistFragmentTest { final Stream entityStream = asStreamEntityStream( "https://www.youtube.com/watch?v=1", - "https://www.youtube.com/watch?v=2", + "https://soundcloud.com/cautious-clayofficial/cold-war-2", // non-Youtube URLs should be + "https://www.youtube.com/watch?v=2", // ignored "https://www.youtube.com/watch?v=3" ); From b1f995a78c6ed792296d35969afcd118c97584a1 Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Thu, 20 Feb 2025 16:26:03 -0300 Subject: [PATCH 025/143] [#11930] Playlist with more than 50 items --- app/build.gradle | 3 ++ .../local/playlist/LocalPlaylistFragment.java | 14 +++++-- .../playlist/LocalPlaylistFragmentTest.java | 37 +++++++++++++++++++ 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index d03bd64e3..2cdc952af 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -255,6 +255,9 @@ dependencies { // HTTP client implementation "com.squareup.okhttp3:okhttp:4.12.0" + // Apache Commons Collections + implementation group: 'org.apache.commons', name: 'commons-collections4', version: '4.4' + // Media player implementation "com.google.android.exoplayer:exoplayer-core:${exoPlayerVersion}" implementation "com.google.android.exoplayer:exoplayer-dash:${exoPlayerVersion}" diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java index cb47c2199..008dc4a9c 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java @@ -31,6 +31,7 @@ import androidx.viewbinding.ViewBinding; import com.evernote.android.state.State; +import org.apache.commons.collections4.queue.CircularFifoQueue; import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; import org.schabi.newpipe.NewPipeDatabase; @@ -460,10 +461,15 @@ public class LocalPlaylistFragment extends BaseLocalListFragment entityStream) { - final String videoIDs = entityStream - .map(entity -> getYouTubeId(entity.getUrl())) - .filter(Objects::nonNull) - .collect(Collectors.joining(",")); + final CircularFifoQueue last50 = new CircularFifoQueue<>(50); + + entityStream + .map(entity -> getYouTubeId(entity.getUrl())) + .filter(Objects::nonNull) + .forEachOrdered(last50::add); + + final String videoIDs = last50.stream() + .collect(Collectors.joining(",")); return "http://www.youtube.com/watch_videos?video_ids=" + videoIDs; } diff --git a/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java b/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java index fb93a9e86..eca798a24 100644 --- a/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java +++ b/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java @@ -10,6 +10,7 @@ import org.junit.Test; import org.schabi.newpipe.database.stream.model.StreamEntity; import org.schabi.newpipe.extractor.stream.StreamType; +import java.util.List; import java.util.stream.Stream; public class LocalPlaylistFragmentTest { @@ -30,6 +31,42 @@ public class LocalPlaylistFragmentTest { Assert.assertEquals("http://www.youtube.com/watch_videos?video_ids=1,2,3", url); } + @Test + public void exportMoreThan50Items() { + /* + * Playlist has more than 50 items => take the last 50 + * (YouTube limitation) + */ + + final List ids = List.of( + + -1, 0, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50 + ); + + final Stream entityStream = ids.stream() + .map(id -> "https://www.youtube.com/watch?v=" + id) + .map(LocalPlaylistFragmentTest::newStreamEntity); + + final String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, entityStream, null); + + Assert.assertEquals( + + "http://www.youtube.com/watch_videos?video_ids=" + + "1,2,3,4,5,6,7,8,9,10," + + "11,12,13,14,15,16,17,18,19,20," + + "21,22,23,24,25,26,27,28,29,30," + + "31,32,33,34,35,36,37,38,39,40," + + "41,42,43,44,45,46,47,48,49,50", + + url + ); + } + @Test public void exportJustUrls() { From c9ec257a5e3d80f753aa112e8f71d15c287a8eb9 Mon Sep 17 00:00:00 2001 From: Thompson3142 <115718208+Thompson3142@users.noreply.github.com> Date: Fri, 21 Feb 2025 10:38:58 +0100 Subject: [PATCH 026/143] Ugly fix for broken text colors in dark mode (#12035) * Ugly fix for broken text colors in dark mode * Add comment for clarification * Added error prevention * Update app/src/main/java/org/schabi/newpipe/MainActivity.java --------- Co-authored-by: Stypox --- .../main/java/org/schabi/newpipe/MainActivity.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/src/main/java/org/schabi/newpipe/MainActivity.java b/app/src/main/java/org/schabi/newpipe/MainActivity.java index 354e06587..b9592085b 100644 --- a/app/src/main/java/org/schabi/newpipe/MainActivity.java +++ b/app/src/main/java/org/schabi/newpipe/MainActivity.java @@ -38,6 +38,7 @@ import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.webkit.WebView; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.FrameLayout; @@ -140,6 +141,19 @@ public class MainActivity extends AppCompatActivity { ThemeHelper.setDayNightMode(this); ThemeHelper.setTheme(this, ServiceHelper.getSelectedServiceId(this)); + // Fixes text color turning black in dark/black mode: + // https://github.com/TeamNewPipe/NewPipe/issues/12016 + // For further reference see: https://issuetracker.google.com/issues/37124582 + if (DeviceUtils.supportsWebView()) { + try { + new WebView(this); + } catch (final Throwable e) { + if (DEBUG) { + Log.e(TAG, "Failed to create WebView", e); + } + } + } + assureCorrectAppLanguage(this); super.onCreate(savedInstanceState); From 49b71942ad9b7027a54434a6b1d72887ebaf0975 Mon Sep 17 00:00:00 2001 From: Stypox Date: Mon, 24 Feb 2025 14:21:05 +0100 Subject: [PATCH 027/143] Fix style and add comment about null player --- .../main/java/org/schabi/newpipe/player/PlayerService.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/PlayerService.java b/app/src/main/java/org/schabi/newpipe/player/PlayerService.java index af6cf2467..1888bce01 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PlayerService.java +++ b/app/src/main/java/org/schabi/newpipe/player/PlayerService.java @@ -319,11 +319,8 @@ public final class PlayerService extends MediaBrowserServiceCompat { public void setPlayerListener(@Nullable final Consumer listener) { this.onPlayerStartedOrStopped = listener; if (listener != null) { - if (player == null) { - listener.accept(null); - } else { - listener.accept(player); - } + // if there is no player, then `null` will be sent here, to ensure the state is synced + listener.accept(player); } } //endregion From 24bb71a23f0df82866f7525f5def7e638ae6f6cd Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Mon, 24 Feb 2025 19:22:36 -0300 Subject: [PATCH 028/143] [#11930] Making it more efficient: Reverse iteration + limit(50) + reverse --- .../local/playlist/LocalPlaylistFragment.java | 45 ++++++++++++------- .../playlist/LocalPlaylistFragmentTest.java | 38 +++++++++++----- 2 files changed, 55 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java index 008dc4a9c..e8d8573a1 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java @@ -1,5 +1,7 @@ package org.schabi.newpipe.local.playlist; +import static com.google.common.collect.Streams.stream; +import static org.apache.commons.collections4.IterableUtils.reversedIterable; import static org.schabi.newpipe.error.ErrorUtil.showUiErrorSnackbar; import static org.schabi.newpipe.ktx.ViewUtils.animate; import static org.schabi.newpipe.local.playlist.PlayListShareMode.JUST_URLS; @@ -7,6 +9,8 @@ import static org.schabi.newpipe.local.playlist.PlayListShareMode.WITH_TITLES; import static org.schabi.newpipe.local.playlist.PlayListShareMode.YOUTUBE_TEMP_PLAYLIST; import static org.schabi.newpipe.util.ThemeHelper.shouldUseGridLayout; +import static java.util.Collections.reverse; + import android.content.Context; import android.os.Bundle; import android.os.Parcelable; @@ -30,7 +34,9 @@ import androidx.recyclerview.widget.RecyclerView; import androidx.viewbinding.ViewBinding; import com.evernote.android.state.State; +import com.google.common.collect.Streams; +import org.apache.commons.collections4.IterableUtils; import org.apache.commons.collections4.queue.CircularFifoQueue; import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; @@ -408,7 +414,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment Single.just(export( shareMode, - playlist.stream().map(PlaylistStreamEntry::getStreamEntity), + playlist, context ))) .observeOn(AndroidSchedulers.mainThread()) @@ -430,20 +436,21 @@ public class LocalPlaylistFragment extends BaseLocalListFragment entityStream, + final List playlist, final Context context) { return switch (shareMode) { - case WITH_TITLES -> exportWithTitles(entityStream, context); - case JUST_URLS -> exportJustUrls(entityStream); - case YOUTUBE_TEMP_PLAYLIST -> exportAsYoutubeTempPlaylist(entityStream); + case WITH_TITLES -> exportWithTitles(playlist, context); + case JUST_URLS -> exportJustUrls(playlist); + case YOUTUBE_TEMP_PLAYLIST -> exportAsYoutubeTempPlaylist(playlist); }; } - static String exportWithTitles(final Stream entityStream, final Context context) { + static String exportWithTitles(final List playlist, final Context context) { - return entityStream + return playlist.stream() + .map(PlaylistStreamEntry::getStreamEntity) .map(entity -> context.getString(R.string.video_details_list_item, entity.getTitle(), entity.getUrl() @@ -452,26 +459,30 @@ public class LocalPlaylistFragment extends BaseLocalListFragment entityStream) { + static String exportJustUrls(final List playlist) { - return entityStream + return playlist.stream() + .map(PlaylistStreamEntry::getStreamEntity) .map(StreamEntity::getUrl) .collect(Collectors.joining("\n")); } - static String exportAsYoutubeTempPlaylist(final Stream entityStream) { + static String exportAsYoutubeTempPlaylist(final List playlist) { - final CircularFifoQueue last50 = new CircularFifoQueue<>(50); - - entityStream + final List videoIDs = + stream(reversedIterable(playlist)) + .map(PlaylistStreamEntry::getStreamEntity) .map(entity -> getYouTubeId(entity.getUrl())) .filter(Objects::nonNull) - .forEachOrdered(last50::add); + .limit(50) + .collect(Collectors.toList()); - final String videoIDs = last50.stream() - .collect(Collectors.joining(",")); + reverse(videoIDs); - return "http://www.youtube.com/watch_videos?video_ids=" + videoIDs; + final String commaSeparatedVideoIDs = videoIDs.stream() + .collect(Collectors.joining(",")); + + return "http://www.youtube.com/watch_videos?video_ids=" + commaSeparatedVideoIDs; } /** diff --git a/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java b/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java index eca798a24..1d5d4a6a0 100644 --- a/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java +++ b/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java @@ -7,6 +7,7 @@ import androidx.annotation.NonNull; import org.junit.Assert; import org.junit.Test; +import org.schabi.newpipe.database.playlist.PlaylistStreamEntry; import org.schabi.newpipe.database.stream.model.StreamEntity; import org.schabi.newpipe.extractor.stream.StreamType; @@ -18,7 +19,7 @@ public class LocalPlaylistFragmentTest { @Test public void exportAsYouTubeTempPlaylist() { - final Stream entityStream = asStreamEntityStream( + final List playlist = asPlaylist( "https://www.youtube.com/watch?v=1", "https://soundcloud.com/cautious-clayofficial/cold-war-2", // non-Youtube URLs should be @@ -26,7 +27,7 @@ public class LocalPlaylistFragmentTest { "https://www.youtube.com/watch?v=3" ); - final String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, entityStream, null); + final String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, playlist, null); Assert.assertEquals("http://www.youtube.com/watch_videos?video_ids=1,2,3", url); } @@ -48,11 +49,13 @@ public class LocalPlaylistFragmentTest { 41, 42, 43, 44, 45, 46, 47, 48, 49, 50 ); - final Stream entityStream = ids.stream() - .map(id -> "https://www.youtube.com/watch?v=" + id) - .map(LocalPlaylistFragmentTest::newStreamEntity); + final List playlist = asPlaylist( - final String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, entityStream, null); + ids.stream() + .map(id -> "https://www.youtube.com/watch?v=" + id) + ); + + final String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, playlist, null); Assert.assertEquals( @@ -70,14 +73,14 @@ public class LocalPlaylistFragmentTest { @Test public void exportJustUrls() { - final Stream entityStream = asStreamEntityStream( + final List playlist = asPlaylist( "https://www.youtube.com/watch?v=1", "https://www.youtube.com/watch?v=2", "https://www.youtube.com/watch?v=3" ); - final String exported = LocalPlaylistFragment.export(JUST_URLS, entityStream, null); + final String exported = LocalPlaylistFragment.export(JUST_URLS, playlist, null); Assert.assertEquals(""" https://www.youtube.com/watch?v=1 @@ -86,10 +89,23 @@ public class LocalPlaylistFragmentTest { } @NonNull - private static Stream asStreamEntityStream(final String... urls) { + static List asPlaylist(final String... urls) { - return Stream.of(urls) - .map(LocalPlaylistFragmentTest::newStreamEntity); + return asPlaylist(Stream.of(urls)); + } + + @NonNull + static List asPlaylist(final Stream urls) { + + return urls + .map(LocalPlaylistFragmentTest::newPlaylistStreamEntry) + .toList(); + } + + @NonNull + private static PlaylistStreamEntry newPlaylistStreamEntry(final String url) { + + return new PlaylistStreamEntry(newStreamEntity(url), 0, 0, 0); } @NonNull From 76a02d5858d99e72a410431e54ad3a0e055c7285 Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Mon, 24 Feb 2025 20:16:40 -0300 Subject: [PATCH 029/143] [#11930] Extracting to a separate file --- .../local/playlist/ExportPlaylist.java | 90 +++++++++++++++++++ .../local/playlist/LocalPlaylistFragment.java | 75 +--------------- ...gmentTest.java => ExportPlaylistTest.java} | 11 +-- 3 files changed, 97 insertions(+), 79 deletions(-) create mode 100644 app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.java rename app/src/test/java/org/schabi/newpipe/local/playlist/{LocalPlaylistFragmentTest.java => ExportPlaylistTest.java} (89%) diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.java b/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.java new file mode 100644 index 000000000..94002dd5b --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.java @@ -0,0 +1,90 @@ +package org.schabi.newpipe.local.playlist; + +import static com.google.common.collect.Streams.stream; +import static org.apache.commons.collections4.IterableUtils.reversedIterable; +import static java.util.Collections.reverse; + +import android.content.Context; + +import org.schabi.newpipe.R; +import org.schabi.newpipe.database.playlist.PlaylistStreamEntry; +import org.schabi.newpipe.database.stream.model.StreamEntity; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import okhttp3.HttpUrl; + + + +final class ExportPlaylist { + + private ExportPlaylist() { + } + + static String export(final PlayListShareMode shareMode, + final List playlist, + final Context context) { + + return switch (shareMode) { + + case WITH_TITLES -> exportWithTitles(playlist, context); + case JUST_URLS -> exportJustUrls(playlist); + case YOUTUBE_TEMP_PLAYLIST -> exportAsYoutubeTempPlaylist(playlist); + }; + } + + static String exportWithTitles(final List playlist, + final Context context) { + + return playlist.stream() + .map(PlaylistStreamEntry::getStreamEntity) + .map(entity -> context.getString(R.string.video_details_list_item, + entity.getTitle(), + entity.getUrl() + ) + ) + .collect(Collectors.joining("\n")); + } + + static String exportJustUrls(final List playlist) { + + return playlist.stream() + .map(PlaylistStreamEntry::getStreamEntity) + .map(StreamEntity::getUrl) + .collect(Collectors.joining("\n")); + } + + static String exportAsYoutubeTempPlaylist(final List playlist) { + + final List videoIDs = + stream(reversedIterable(playlist)) + .map(PlaylistStreamEntry::getStreamEntity) + .map(entity -> getYouTubeId(entity.getUrl())) + .filter(Objects::nonNull) + .limit(50) + .collect(Collectors.toList()); + + reverse(videoIDs); + + final String commaSeparatedVideoIDs = videoIDs.stream() + .collect(Collectors.joining(",")); + + return "http://www.youtube.com/watch_videos?video_ids=" + commaSeparatedVideoIDs; + } + + /** + * Gets the video id from a YouTube URL. + * + * @param url YouTube URL + * @return the video id + */ + static String getYouTubeId(final String url) { + + final HttpUrl httpUrl = HttpUrl.parse(url); + + return httpUrl == null ? null + : httpUrl.queryParameter("v"); + } +} diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java index e8d8573a1..812d9fb38 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java @@ -1,15 +1,13 @@ package org.schabi.newpipe.local.playlist; -import static com.google.common.collect.Streams.stream; -import static org.apache.commons.collections4.IterableUtils.reversedIterable; import static org.schabi.newpipe.error.ErrorUtil.showUiErrorSnackbar; import static org.schabi.newpipe.ktx.ViewUtils.animate; +import static org.schabi.newpipe.local.playlist.ExportPlaylist.export; import static org.schabi.newpipe.local.playlist.PlayListShareMode.JUST_URLS; import static org.schabi.newpipe.local.playlist.PlayListShareMode.WITH_TITLES; import static org.schabi.newpipe.local.playlist.PlayListShareMode.YOUTUBE_TEMP_PLAYLIST; import static org.schabi.newpipe.util.ThemeHelper.shouldUseGridLayout; -import static java.util.Collections.reverse; import android.content.Context; import android.os.Bundle; @@ -34,10 +32,6 @@ import androidx.recyclerview.widget.RecyclerView; import androidx.viewbinding.ViewBinding; import com.evernote.android.state.State; -import com.google.common.collect.Streams; - -import org.apache.commons.collections4.IterableUtils; -import org.apache.commons.collections4.queue.CircularFifoQueue; import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; import org.schabi.newpipe.NewPipeDatabase; @@ -72,17 +66,14 @@ import org.schabi.newpipe.util.external_communication.ShareUtils; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Objects; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; -import java.util.stream.Stream; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.core.Single; import io.reactivex.rxjava3.disposables.CompositeDisposable; import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.schedulers.Schedulers; -import okhttp3.HttpUrl; public class LocalPlaylistFragment extends BaseLocalListFragment, Void> implements PlaylistControlViewHolder, DebounceSavable { @@ -435,70 +426,6 @@ public class LocalPlaylistFragment extends BaseLocalListFragment playlist, - final Context context) { - - return switch (shareMode) { - - case WITH_TITLES -> exportWithTitles(playlist, context); - case JUST_URLS -> exportJustUrls(playlist); - case YOUTUBE_TEMP_PLAYLIST -> exportAsYoutubeTempPlaylist(playlist); - }; - } - - static String exportWithTitles(final List playlist, final Context context) { - - return playlist.stream() - .map(PlaylistStreamEntry::getStreamEntity) - .map(entity -> context.getString(R.string.video_details_list_item, - entity.getTitle(), - entity.getUrl() - ) - ) - .collect(Collectors.joining("\n")); - } - - static String exportJustUrls(final List playlist) { - - return playlist.stream() - .map(PlaylistStreamEntry::getStreamEntity) - .map(StreamEntity::getUrl) - .collect(Collectors.joining("\n")); - } - - static String exportAsYoutubeTempPlaylist(final List playlist) { - - final List videoIDs = - stream(reversedIterable(playlist)) - .map(PlaylistStreamEntry::getStreamEntity) - .map(entity -> getYouTubeId(entity.getUrl())) - .filter(Objects::nonNull) - .limit(50) - .collect(Collectors.toList()); - - reverse(videoIDs); - - final String commaSeparatedVideoIDs = videoIDs.stream() - .collect(Collectors.joining(",")); - - return "http://www.youtube.com/watch_videos?video_ids=" + commaSeparatedVideoIDs; - } - - /** - * Gets the video id from a YouTube URL. - * - * @param url YouTube URL - * @return the video id - */ - static String getYouTubeId(final String url) { - - final HttpUrl httpUrl = HttpUrl.parse(url); - - return httpUrl == null ? null - : httpUrl.queryParameter("v"); - } - public void removeWatchedStreams(final boolean removePartiallyWatched) { if (isRewritingPlaylist) { return; diff --git a/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java b/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.java similarity index 89% rename from app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java rename to app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.java index 1d5d4a6a0..f90fd78bb 100644 --- a/app/src/test/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragmentTest.java +++ b/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.java @@ -1,5 +1,6 @@ package org.schabi.newpipe.local.playlist; +import static org.schabi.newpipe.local.playlist.ExportPlaylist.export; import static org.schabi.newpipe.local.playlist.PlayListShareMode.JUST_URLS; import static org.schabi.newpipe.local.playlist.PlayListShareMode.YOUTUBE_TEMP_PLAYLIST; @@ -14,7 +15,7 @@ import org.schabi.newpipe.extractor.stream.StreamType; import java.util.List; import java.util.stream.Stream; -public class LocalPlaylistFragmentTest { +public class ExportPlaylistTest { @Test public void exportAsYouTubeTempPlaylist() { @@ -27,7 +28,7 @@ public class LocalPlaylistFragmentTest { "https://www.youtube.com/watch?v=3" ); - final String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, playlist, null); + final String url = export(YOUTUBE_TEMP_PLAYLIST, playlist, null); Assert.assertEquals("http://www.youtube.com/watch_videos?video_ids=1,2,3", url); } @@ -55,7 +56,7 @@ public class LocalPlaylistFragmentTest { .map(id -> "https://www.youtube.com/watch?v=" + id) ); - final String url = LocalPlaylistFragment.export(YOUTUBE_TEMP_PLAYLIST, playlist, null); + final String url = export(YOUTUBE_TEMP_PLAYLIST, playlist, null); Assert.assertEquals( @@ -80,7 +81,7 @@ public class LocalPlaylistFragmentTest { "https://www.youtube.com/watch?v=3" ); - final String exported = LocalPlaylistFragment.export(JUST_URLS, playlist, null); + final String exported = export(JUST_URLS, playlist, null); Assert.assertEquals(""" https://www.youtube.com/watch?v=1 @@ -98,7 +99,7 @@ public class LocalPlaylistFragmentTest { static List asPlaylist(final Stream urls) { return urls - .map(LocalPlaylistFragmentTest::newPlaylistStreamEntry) + .map(ExportPlaylistTest::newPlaylistStreamEntry) .toList(); } From 998d84de6c0f1ea707f9efda1ba1ac3a8bab4229 Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Mon, 24 Feb 2025 20:57:06 -0300 Subject: [PATCH 030/143] [#11930] Converting to Kotlin --- .../local/playlist/ExportPlaylist.java | 90 ------------ .../newpipe/local/playlist/ExportPlaylist.kt | 72 ++++++++++ .../local/playlist/LocalPlaylistFragment.java | 2 +- .../local/playlist/ExportPlaylistTest.java | 132 ------------------ .../local/playlist/ExportPlaylistTest.kt | 110 +++++++++++++++ 5 files changed, 183 insertions(+), 223 deletions(-) delete mode 100644 app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.java create mode 100644 app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt delete mode 100644 app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.java create mode 100644 app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.java b/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.java deleted file mode 100644 index 94002dd5b..000000000 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.schabi.newpipe.local.playlist; - -import static com.google.common.collect.Streams.stream; -import static org.apache.commons.collections4.IterableUtils.reversedIterable; -import static java.util.Collections.reverse; - -import android.content.Context; - -import org.schabi.newpipe.R; -import org.schabi.newpipe.database.playlist.PlaylistStreamEntry; -import org.schabi.newpipe.database.stream.model.StreamEntity; - -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -import okhttp3.HttpUrl; - - - -final class ExportPlaylist { - - private ExportPlaylist() { - } - - static String export(final PlayListShareMode shareMode, - final List playlist, - final Context context) { - - return switch (shareMode) { - - case WITH_TITLES -> exportWithTitles(playlist, context); - case JUST_URLS -> exportJustUrls(playlist); - case YOUTUBE_TEMP_PLAYLIST -> exportAsYoutubeTempPlaylist(playlist); - }; - } - - static String exportWithTitles(final List playlist, - final Context context) { - - return playlist.stream() - .map(PlaylistStreamEntry::getStreamEntity) - .map(entity -> context.getString(R.string.video_details_list_item, - entity.getTitle(), - entity.getUrl() - ) - ) - .collect(Collectors.joining("\n")); - } - - static String exportJustUrls(final List playlist) { - - return playlist.stream() - .map(PlaylistStreamEntry::getStreamEntity) - .map(StreamEntity::getUrl) - .collect(Collectors.joining("\n")); - } - - static String exportAsYoutubeTempPlaylist(final List playlist) { - - final List videoIDs = - stream(reversedIterable(playlist)) - .map(PlaylistStreamEntry::getStreamEntity) - .map(entity -> getYouTubeId(entity.getUrl())) - .filter(Objects::nonNull) - .limit(50) - .collect(Collectors.toList()); - - reverse(videoIDs); - - final String commaSeparatedVideoIDs = videoIDs.stream() - .collect(Collectors.joining(",")); - - return "http://www.youtube.com/watch_videos?video_ids=" + commaSeparatedVideoIDs; - } - - /** - * Gets the video id from a YouTube URL. - * - * @param url YouTube URL - * @return the video id - */ - static String getYouTubeId(final String url) { - - final HttpUrl httpUrl = HttpUrl.parse(url); - - return httpUrl == null ? null - : httpUrl.queryParameter("v"); - } -} diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt b/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt new file mode 100644 index 000000000..953cb7d17 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt @@ -0,0 +1,72 @@ +package org.schabi.newpipe.local.playlist + +import android.content.Context +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull +import org.schabi.newpipe.R +import org.schabi.newpipe.database.playlist.PlaylistStreamEntry +import org.schabi.newpipe.local.playlist.PlayListShareMode.JUST_URLS +import org.schabi.newpipe.local.playlist.PlayListShareMode.WITH_TITLES +import org.schabi.newpipe.local.playlist.PlayListShareMode.YOUTUBE_TEMP_PLAYLIST +import java.util.Objects.nonNull + +fun export( + shareMode: PlayListShareMode, + playlist: List, + context: Context +): String { + return when (shareMode) { + WITH_TITLES -> exportWithTitles(playlist, context) + JUST_URLS -> exportJustUrls(playlist) + YOUTUBE_TEMP_PLAYLIST -> exportAsYoutubeTempPlaylist(playlist) + } +} + +fun exportWithTitles( + playlist: List, + context: Context +): String { + + return playlist.asSequence() + .map { it.streamEntity } + .map { entity -> + context.getString( + R.string.video_details_list_item, + entity.title, + entity.url + ) + } + .joinToString(separator = "\n") +} + +fun exportJustUrls(playlist: List): String { + + return playlist.asSequence() + .map { it.streamEntity.url } + .joinToString(separator = "\n") +} + +fun exportAsYoutubeTempPlaylist(playlist: List): String { + + val videoIDs = playlist.asReversed().asSequence() + .map { it.streamEntity } + .map { getYouTubeId(it.url) } + .filter(::nonNull) + .take(50) + .toList() + .asReversed() + .joinToString(separator = ",") + + return "http://www.youtube.com/watch_videos?video_ids=$videoIDs" +} + +/** + * Gets the video id from a YouTube URL. + * + * @param url YouTube URL + * @return the video id + */ +fun getYouTubeId(url: String): String? { + val httpUrl = url.toHttpUrlOrNull() + + return httpUrl?.queryParameter("v") +} diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java index 812d9fb38..61c12bfd4 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java @@ -2,7 +2,7 @@ package org.schabi.newpipe.local.playlist; import static org.schabi.newpipe.error.ErrorUtil.showUiErrorSnackbar; import static org.schabi.newpipe.ktx.ViewUtils.animate; -import static org.schabi.newpipe.local.playlist.ExportPlaylist.export; +import static org.schabi.newpipe.local.playlist.ExportPlaylistKt.export; import static org.schabi.newpipe.local.playlist.PlayListShareMode.JUST_URLS; import static org.schabi.newpipe.local.playlist.PlayListShareMode.WITH_TITLES; import static org.schabi.newpipe.local.playlist.PlayListShareMode.YOUTUBE_TEMP_PLAYLIST; diff --git a/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.java b/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.java deleted file mode 100644 index f90fd78bb..000000000 --- a/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.java +++ /dev/null @@ -1,132 +0,0 @@ -package org.schabi.newpipe.local.playlist; - -import static org.schabi.newpipe.local.playlist.ExportPlaylist.export; -import static org.schabi.newpipe.local.playlist.PlayListShareMode.JUST_URLS; -import static org.schabi.newpipe.local.playlist.PlayListShareMode.YOUTUBE_TEMP_PLAYLIST; - -import androidx.annotation.NonNull; - -import org.junit.Assert; -import org.junit.Test; -import org.schabi.newpipe.database.playlist.PlaylistStreamEntry; -import org.schabi.newpipe.database.stream.model.StreamEntity; -import org.schabi.newpipe.extractor.stream.StreamType; - -import java.util.List; -import java.util.stream.Stream; - -public class ExportPlaylistTest { - - @Test - public void exportAsYouTubeTempPlaylist() { - - final List playlist = asPlaylist( - - "https://www.youtube.com/watch?v=1", - "https://soundcloud.com/cautious-clayofficial/cold-war-2", // non-Youtube URLs should be - "https://www.youtube.com/watch?v=2", // ignored - "https://www.youtube.com/watch?v=3" - ); - - final String url = export(YOUTUBE_TEMP_PLAYLIST, playlist, null); - - Assert.assertEquals("http://www.youtube.com/watch_videos?video_ids=1,2,3", url); - } - - @Test - public void exportMoreThan50Items() { - /* - * Playlist has more than 50 items => take the last 50 - * (YouTube limitation) - */ - - final List ids = List.of( - - -1, 0, - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50 - ); - - final List playlist = asPlaylist( - - ids.stream() - .map(id -> "https://www.youtube.com/watch?v=" + id) - ); - - final String url = export(YOUTUBE_TEMP_PLAYLIST, playlist, null); - - Assert.assertEquals( - - "http://www.youtube.com/watch_videos?video_ids=" - + "1,2,3,4,5,6,7,8,9,10," - + "11,12,13,14,15,16,17,18,19,20," - + "21,22,23,24,25,26,27,28,29,30," - + "31,32,33,34,35,36,37,38,39,40," - + "41,42,43,44,45,46,47,48,49,50", - - url - ); - } - - @Test - public void exportJustUrls() { - - final List playlist = asPlaylist( - - "https://www.youtube.com/watch?v=1", - "https://www.youtube.com/watch?v=2", - "https://www.youtube.com/watch?v=3" - ); - - final String exported = export(JUST_URLS, playlist, null); - - Assert.assertEquals(""" - https://www.youtube.com/watch?v=1 - https://www.youtube.com/watch?v=2 - https://www.youtube.com/watch?v=3""", exported); - } - - @NonNull - static List asPlaylist(final String... urls) { - - return asPlaylist(Stream.of(urls)); - } - - @NonNull - static List asPlaylist(final Stream urls) { - - return urls - .map(ExportPlaylistTest::newPlaylistStreamEntry) - .toList(); - } - - @NonNull - private static PlaylistStreamEntry newPlaylistStreamEntry(final String url) { - - return new PlaylistStreamEntry(newStreamEntity(url), 0, 0, 0); - } - - @NonNull - static StreamEntity newStreamEntity(final String url) { - - return new StreamEntity( - - 0, - 1, - url, - "Title", - StreamType.VIDEO_STREAM, - 100, - "Uploader", - null, - null, - null, - null, - null, - null - ); - } -} diff --git a/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt b/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt new file mode 100644 index 000000000..42622fe9c --- /dev/null +++ b/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt @@ -0,0 +1,110 @@ +package org.schabi.newpipe.local.playlist + +import android.content.Context +import org.junit.Assert.assertEquals +import org.junit.Test +import org.mockito.Mockito.mock +import org.schabi.newpipe.database.playlist.PlaylistStreamEntry +import org.schabi.newpipe.database.stream.model.StreamEntity +import org.schabi.newpipe.extractor.stream.StreamType +import org.schabi.newpipe.local.playlist.PlayListShareMode.JUST_URLS +import org.schabi.newpipe.local.playlist.PlayListShareMode.YOUTUBE_TEMP_PLAYLIST +import java.util.stream.Stream + +class ExportPlaylistTest { + + @Test + fun exportAsYouTubeTempPlaylist() { + val playlist = asPlaylist( + "https://www.youtube.com/watch?v=1", + "https://soundcloud.com/cautious-clayofficial/cold-war-2", // non-Youtube URLs should be ignored + "https://www.youtube.com/watch?v=2", + "https://www.youtube.com/watch?v=3" + ) + + val url = export(YOUTUBE_TEMP_PLAYLIST, playlist, mock(Context::class.java)) + + assertEquals("http://www.youtube.com/watch_videos?video_ids=1,2,3", url) + } + + @Test + fun exportMoreThan50Items() { + /* + * Playlist has more than 50 items => take the last 50 + * (YouTube limitation) + */ + + val ids = listOf( + -1, 0, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50 + ) + + val playlist = asPlaylist( + ids.stream() + .map { id: Int -> "https://www.youtube.com/watch?v=$id" } + ) + + val url = export(YOUTUBE_TEMP_PLAYLIST, playlist, mock(Context::class.java)) + + assertEquals( + "http://www.youtube.com/watch_videos?video_ids=" + + "1,2,3,4,5,6,7,8,9,10," + + "11,12,13,14,15,16,17,18,19,20," + + "21,22,23,24,25,26,27,28,29,30," + + "31,32,33,34,35,36,37,38,39,40," + + "41,42,43,44,45,46,47,48,49,50", + + url + ) + } + + @Test + fun exportJustUrls() { + val playlist = asPlaylist( + "https://www.youtube.com/watch?v=1", + "https://www.youtube.com/watch?v=2", + "https://www.youtube.com/watch?v=3" + ) + + val exported = export(JUST_URLS, playlist, mock(Context::class.java)) + + assertEquals( + """ + https://www.youtube.com/watch?v=1 + https://www.youtube.com/watch?v=2 + https://www.youtube.com/watch?v=3 + """.trimIndent(), + exported + ) + } +} + +fun asPlaylist(vararg urls: String): List { + return asPlaylist(Stream.of(*urls)) +} + +fun asPlaylist(urls: Stream): List { + return urls + .map { url: String -> newPlaylistStreamEntry(url) } + .toList() +} + +fun newPlaylistStreamEntry(url: String): PlaylistStreamEntry { + return PlaylistStreamEntry(newStreamEntity(url), 0, 0, 0) +} + +fun newStreamEntity(url: String): StreamEntity { + return StreamEntity( + 0, + 1, + url, + "Title", + StreamType.VIDEO_STREAM, + 100, + "Uploader" + ) +} From 3c7b026d7d9afbb90ea41fd99bd093396d0e1e91 Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Tue, 25 Feb 2025 20:23:07 -0300 Subject: [PATCH 031/143] [#11930] Updating javadoc --- .../local/playlist/LocalPlaylistFragment.java | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java index 61c12bfd4..de1aabb9c 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java @@ -388,16 +388,15 @@ public class LocalPlaylistFragment extends BaseLocalListFragment Date: Wed, 26 Feb 2025 21:25:39 -0300 Subject: [PATCH 032/143] [#11930] Removing Apache Commons Collections It's no longer needed after the conversion to Kotlin. --- app/build.gradle | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 2cdc952af..d03bd64e3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -255,9 +255,6 @@ dependencies { // HTTP client implementation "com.squareup.okhttp3:okhttp:4.12.0" - // Apache Commons Collections - implementation group: 'org.apache.commons', name: 'commons-collections4', version: '4.4' - // Media player implementation "com.google.android.exoplayer:exoplayer-core:${exoPlayerVersion}" implementation "com.google.android.exoplayer:exoplayer-dash:${exoPlayerVersion}" From f0c89494dd597a65bfb1d7846c940f0f02e7d085 Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Thu, 27 Feb 2025 09:09:08 +0530 Subject: [PATCH 033/143] Fix stream notification grouping --- .../local/feed/notifications/NotificationHelper.kt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt b/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt index 8ea89368d..646596884 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/notifications/NotificationHelper.kt @@ -88,7 +88,7 @@ class NotificationHelper(val context: Context) { // Show individual stream notifications, set channel icon only if there is actually // one - showStreamNotifications(newStreams, data.serviceId, bitmap) + showStreamNotifications(newStreams, data.serviceId, data.url, bitmap) // Show summary notification manager.notify(data.pseudoId, summaryBuilder.build()) @@ -97,7 +97,7 @@ class NotificationHelper(val context: Context) { override fun onBitmapFailed(e: Exception, errorDrawable: Drawable) { // Show individual stream notifications - showStreamNotifications(newStreams, data.serviceId, null) + showStreamNotifications(newStreams, data.serviceId, data.url, null) // Show summary notification manager.notify(data.pseudoId, summaryBuilder.build()) iconLoadingTargets.remove(this) // allow it to be garbage-collected @@ -118,10 +118,11 @@ class NotificationHelper(val context: Context) { private fun showStreamNotifications( newStreams: List, serviceId: Int, + channelUrl: String, channelIcon: Bitmap? ) { for (stream in newStreams) { - val notification = createStreamNotification(stream, serviceId, channelIcon) + val notification = createStreamNotification(stream, serviceId, channelUrl, channelIcon) manager.notify(stream.url.hashCode(), notification) } } @@ -129,6 +130,7 @@ class NotificationHelper(val context: Context) { private fun createStreamNotification( item: StreamInfoItem, serviceId: Int, + channelUrl: String, channelIcon: Bitmap? ): Notification { return NotificationCompat.Builder( @@ -139,7 +141,7 @@ class NotificationHelper(val context: Context) { .setLargeIcon(channelIcon) .setContentTitle(item.name) .setContentText(item.uploaderName) - .setGroup(item.uploaderUrl) + .setGroup(channelUrl) .setColor(ContextCompat.getColor(context, R.color.ic_launcher_background)) .setColorized(true) .setAutoCancel(true) From d81244e77ce6f311520b4db63ba1984c59290a3c Mon Sep 17 00:00:00 2001 From: tfga Date: Mon, 10 Mar 2025 19:11:20 -0300 Subject: [PATCH 034/143] YT temp playlist URL: http => https Co-authored-by: Stypox --- .../java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt b/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt index 953cb7d17..226d4a8b0 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt @@ -56,7 +56,7 @@ fun exportAsYoutubeTempPlaylist(playlist: List): String { .asReversed() .joinToString(separator = ",") - return "http://www.youtube.com/watch_videos?video_ids=$videoIDs" + return "https://www.youtube.com/watch_videos?video_ids=$videoIDs" } /** From 10110397fd3bf3cd97ce8c037e194428f021a9c8 Mon Sep 17 00:00:00 2001 From: Miles Krell Date: Mon, 10 Mar 2025 22:01:09 -0400 Subject: [PATCH 035/143] Use display name instead of only the language --- app/src/main/java/org/schabi/newpipe/util/Localization.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/util/Localization.java b/app/src/main/java/org/schabi/newpipe/util/Localization.java index 8f8ba596f..6830e390b 100644 --- a/app/src/main/java/org/schabi/newpipe/util/Localization.java +++ b/app/src/main/java/org/schabi/newpipe/util/Localization.java @@ -308,7 +308,7 @@ public final class Localization { *
    *
  • English (original)
  • *
  • English (descriptive)
  • - *
  • Spanish (dubbed)
  • + *
  • Spanish (Spain) (dubbed)
  • *
* * @param context the context used to get the app language @@ -318,7 +318,7 @@ public final class Localization { public static String audioTrackName(@NonNull final Context context, final AudioStream track) { final String name; if (track.getAudioLocale() != null) { - name = track.getAudioLocale().getDisplayLanguage(getAppLocale(context)); + name = track.getAudioLocale().getDisplayName(); } else if (track.getAudioTrackName() != null) { name = track.getAudioTrackName(); } else { From c28478ae53a0380f0f053440c187769dd11219d2 Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Tue, 11 Mar 2025 19:44:04 -0300 Subject: [PATCH 036/143] getYouTubeId(): Changing implementation to use YoutubeStreamLinkHandler (PR review from @Stypox) --- .../newpipe/local/playlist/ExportPlaylist.kt | 14 +++---- .../local/playlist/ExportPlaylistTest.kt | 38 ++++++++----------- 2 files changed, 23 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt b/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt index 226d4a8b0..72540d9d2 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt @@ -1,13 +1,13 @@ package org.schabi.newpipe.local.playlist import android.content.Context -import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import org.schabi.newpipe.R import org.schabi.newpipe.database.playlist.PlaylistStreamEntry +import org.schabi.newpipe.extractor.exceptions.ParsingException +import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeStreamLinkHandlerFactory import org.schabi.newpipe.local.playlist.PlayListShareMode.JUST_URLS import org.schabi.newpipe.local.playlist.PlayListShareMode.WITH_TITLES import org.schabi.newpipe.local.playlist.PlayListShareMode.YOUTUBE_TEMP_PLAYLIST -import java.util.Objects.nonNull fun export( shareMode: PlayListShareMode, @@ -48,9 +48,8 @@ fun exportJustUrls(playlist: List): String { fun exportAsYoutubeTempPlaylist(playlist: List): String { val videoIDs = playlist.asReversed().asSequence() - .map { it.streamEntity } - .map { getYouTubeId(it.url) } - .filter(::nonNull) + .map { it.streamEntity.url } + .mapNotNull(::getYouTubeId) .take(50) .toList() .asReversed() @@ -59,6 +58,8 @@ fun exportAsYoutubeTempPlaylist(playlist: List): String { return "https://www.youtube.com/watch_videos?video_ids=$videoIDs" } +val linkHandler: YoutubeStreamLinkHandlerFactory = YoutubeStreamLinkHandlerFactory.getInstance() + /** * Gets the video id from a YouTube URL. * @@ -66,7 +67,6 @@ fun exportAsYoutubeTempPlaylist(playlist: List): String { * @return the video id */ fun getYouTubeId(url: String): String? { - val httpUrl = url.toHttpUrlOrNull() - return httpUrl?.queryParameter("v") + return try { linkHandler.getId(url) } catch (e: ParsingException) { null } } diff --git a/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt b/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt index 42622fe9c..50db490bd 100644 --- a/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt +++ b/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt @@ -16,15 +16,21 @@ class ExportPlaylistTest { @Test fun exportAsYouTubeTempPlaylist() { val playlist = asPlaylist( - "https://www.youtube.com/watch?v=1", + "https://www.youtube.com/watch?v=10000000000", "https://soundcloud.com/cautious-clayofficial/cold-war-2", // non-Youtube URLs should be ignored - "https://www.youtube.com/watch?v=2", - "https://www.youtube.com/watch?v=3" + "https://www.youtube.com/watch?v=20000000000", + "https://www.youtube.com/watch?v=30000000000" ) val url = export(YOUTUBE_TEMP_PLAYLIST, playlist, mock(Context::class.java)) - assertEquals("http://www.youtube.com/watch_videos?video_ids=1,2,3", url) + assertEquals( + "https://www.youtube.com/watch_videos?video_ids=" + + "10000000000," + + "20000000000," + + "30000000000", + url + ) } @Test @@ -34,30 +40,18 @@ class ExportPlaylistTest { * (YouTube limitation) */ - val ids = listOf( - -1, 0, - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50 - ) - val playlist = asPlaylist( - ids.stream() - .map { id: Int -> "https://www.youtube.com/watch?v=$id" } + (10..70) + .map { id -> "https://www.youtube.com/watch?v=aaaaaaaaa$id" } // YouTube video IDs are 11 characters long + .stream() ) val url = export(YOUTUBE_TEMP_PLAYLIST, playlist, mock(Context::class.java)) - assertEquals( - "http://www.youtube.com/watch_videos?video_ids=" + - "1,2,3,4,5,6,7,8,9,10," + - "11,12,13,14,15,16,17,18,19,20," + - "21,22,23,24,25,26,27,28,29,30," + - "31,32,33,34,35,36,37,38,39,40," + - "41,42,43,44,45,46,47,48,49,50", + val videoIDs = (21..70).map { id -> "aaaaaaaaa$id" }.joinToString(",") + assertEquals( + "https://www.youtube.com/watch_videos?video_ids=$videoIDs", url ) } From f96b8f7b2a68ef0a17de762487e06c29fb315554 Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Tue, 11 Mar 2025 20:19:54 -0300 Subject: [PATCH 037/143] Comment: maximum length of 50 items (PR review from @Stypox) --- .../java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt b/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt index 72540d9d2..cb619c7cc 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt @@ -50,7 +50,7 @@ fun exportAsYoutubeTempPlaylist(playlist: List): String { val videoIDs = playlist.asReversed().asSequence() .map { it.streamEntity.url } .mapNotNull(::getYouTubeId) - .take(50) + .take(50) // YouTube limitation: temp playlists can't have more than 50 items .toList() .asReversed() .joinToString(separator = ",") From 8830e87242367124d2618db9a56376761ffe20e1 Mon Sep 17 00:00:00 2001 From: tfga Date: Tue, 11 Mar 2025 20:35:18 -0300 Subject: [PATCH 038/143] YouTube video IDs are 11 characters long Co-authored-by: Stypox --- .../org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt b/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt index 50db490bd..41577742d 100644 --- a/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt +++ b/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt @@ -59,9 +59,9 @@ class ExportPlaylistTest { @Test fun exportJustUrls() { val playlist = asPlaylist( - "https://www.youtube.com/watch?v=1", - "https://www.youtube.com/watch?v=2", - "https://www.youtube.com/watch?v=3" + "https://www.youtube.com/watch?v=10000000000", + "https://www.youtube.com/watch?v=20000000000", + "https://www.youtube.com/watch?v=30000000000" ) val exported = export(JUST_URLS, playlist, mock(Context::class.java)) From 587df093ea66e413cecdcf5143d2453e1e3a9cbe Mon Sep 17 00:00:00 2001 From: tfga Date: Tue, 11 Mar 2025 20:35:41 -0300 Subject: [PATCH 039/143] YouTube video IDs are 11 characters long Co-authored-by: Stypox --- .../org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt b/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt index 41577742d..d9be2271e 100644 --- a/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt +++ b/app/src/test/java/org/schabi/newpipe/local/playlist/ExportPlaylistTest.kt @@ -68,9 +68,9 @@ class ExportPlaylistTest { assertEquals( """ - https://www.youtube.com/watch?v=1 - https://www.youtube.com/watch?v=2 - https://www.youtube.com/watch?v=3 + https://www.youtube.com/watch?v=10000000000 + https://www.youtube.com/watch?v=20000000000 + https://www.youtube.com/watch?v=30000000000 """.trimIndent(), exported ) From 599d86151a80da945c2f4ebd68c96ab04c2334e6 Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Tue, 11 Mar 2025 21:26:58 -0300 Subject: [PATCH 040/143] Making ktLint happy --- .../java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt b/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt index cb619c7cc..0d4dcbfd0 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/ExportPlaylist.kt @@ -50,7 +50,7 @@ fun exportAsYoutubeTempPlaylist(playlist: List): String { val videoIDs = playlist.asReversed().asSequence() .map { it.streamEntity.url } .mapNotNull(::getYouTubeId) - .take(50) // YouTube limitation: temp playlists can't have more than 50 items + .take(50) // YouTube limitation: temp playlists can't have more than 50 items .toList() .asReversed() .joinToString(separator = ",") From b888dc72cff90e213545d346c45169fee8d73f30 Mon Sep 17 00:00:00 2001 From: Miles Krell Date: Tue, 11 Mar 2025 23:29:23 -0400 Subject: [PATCH 041/143] Support per-app language preferences --- app/build.gradle | 4 ++++ app/src/main/res/resources.properties | 1 + 2 files changed, 5 insertions(+) create mode 100644 app/src/main/res/resources.properties diff --git a/app/build.gradle b/app/build.gradle index d03bd64e3..bbb02e8b3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -97,6 +97,10 @@ android { androidTest.assets.srcDirs += files("$projectDir/schemas".toString()) } + androidResources { + generateLocaleConfig = true + } + buildFeatures { viewBinding true buildConfig true diff --git a/app/src/main/res/resources.properties b/app/src/main/res/resources.properties new file mode 100644 index 000000000..467b3efec --- /dev/null +++ b/app/src/main/res/resources.properties @@ -0,0 +1 @@ +unqualifiedResLocale=en-US From f3b3d5c3e7e546e9885e0fb836674c97b67a4d14 Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Wed, 12 Mar 2025 19:08:09 -0300 Subject: [PATCH 042/143] R.string.share_playlist_as_youtube_temporary_playlist --- .../schabi/newpipe/local/playlist/LocalPlaylistFragment.java | 5 ++--- app/src/main/res/values/strings.xml | 1 + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java index de1aabb9c..0cdc74abb 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java @@ -887,9 +887,8 @@ public class LocalPlaylistFragment extends BaseLocalListFragment sharePlaylist(WITH_TITLES) ) - // TODO R.string.share_playlist_as_YouTube_temporary_playlist - .setNeutralButton("Share as YouTube temporary playlist", (dialog, which) -> - sharePlaylist(YOUTUBE_TEMP_PLAYLIST) + .setNeutralButton(R.string.share_playlist_as_youtube_temporary_playlist, + (dialog, which) -> sharePlaylist(YOUTUBE_TEMP_PLAYLIST) ) .setNegativeButton(R.string.share_playlist_with_list, (dialog, which) -> sharePlaylist(JUST_URLS) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2c27e6cbb..7c9637f31 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -849,6 +849,7 @@ Share playlist with details such as playlist name and video titles or as a simple list of video URLs Share with Titles Share URL list + Share as YouTube temporary playlist - %1$s: %2$s %1$s\n%2$s From eb0568044ae4bdc76061281bc4351877c2cb55af Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Wed, 12 Mar 2025 19:09:31 -0300 Subject: [PATCH 043/143] R.string.share_playlist_as_youtube_temporary_playlist: pt-BR + Minor fixes to related translations --- app/src/main/res/values-pt-rBR/strings.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 9f464a11c..d7942aa99 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -791,8 +791,9 @@ Ao vivo Qualidade da imagem \? - Compartilhar URL - Compartilhar com título + Compartilhar URLs + Compartilhar com títulos + Compartilhar como playlist temporária do YouTube %1$s \n%2$s Alternar orientação da tela From 098f60d59301efebdaa014446091a4fd4970fc71 Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Thu, 13 Mar 2025 18:16:09 -0300 Subject: [PATCH 044/143] Don't add the title when sharing as YouTube temp playlist --- .../newpipe/local/playlist/LocalPlaylistFragment.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java index 0cdc74abb..1d08bef81 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java @@ -411,12 +411,12 @@ public class LocalPlaylistFragment extends BaseLocalListFragment { - final String content = shareMode == JUST_URLS - ? urlsText - : context.getString(R.string.share_playlist_content_details, + final String content = shareMode == WITH_TITLES + ? context.getString(R.string.share_playlist_content_details, name, urlsText - ); + ) + : urlsText; ShareUtils.shareText(context, name, content); }, From be097f26c8bfdec006376c22dfc679cad66b3866 Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Thu, 13 Mar 2025 19:10:26 -0300 Subject: [PATCH 045/143] Deleting the "explanatory text" bellow the title Share playlist with details such as playlist name and video titles or as a simple list of video URLs Share playlist with details such as playlist name and video titles or as a simple list of video URLs
(Discussion: https://github.com/TeamNewPipe/NewPipe/pull/12065#discussion_r1994349485) --- .../org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java | 1 - app/src/main/res/values-ar-rLY/strings.xml | 1 - app/src/main/res/values-ar/strings.xml | 1 - app/src/main/res/values-az/strings.xml | 1 - app/src/main/res/values-be/strings.xml | 1 - app/src/main/res/values-bg/strings.xml | 1 - app/src/main/res/values-cs/strings.xml | 1 - app/src/main/res/values-da/strings.xml | 1 - app/src/main/res/values-de/strings.xml | 1 - app/src/main/res/values-el/strings.xml | 1 - app/src/main/res/values-eo/strings.xml | 1 - app/src/main/res/values-es/strings.xml | 1 - app/src/main/res/values-et/strings.xml | 1 - app/src/main/res/values-eu/strings.xml | 1 - app/src/main/res/values-fi/strings.xml | 1 - app/src/main/res/values-fr/strings.xml | 1 - app/src/main/res/values-gl/strings.xml | 1 - app/src/main/res/values-he/strings.xml | 1 - app/src/main/res/values-hi/strings.xml | 1 - app/src/main/res/values-hr/strings.xml | 1 - app/src/main/res/values-hu/strings.xml | 1 - app/src/main/res/values-in/strings.xml | 1 - app/src/main/res/values-is/strings.xml | 1 - app/src/main/res/values-it/strings.xml | 1 - app/src/main/res/values-ja/strings.xml | 1 - app/src/main/res/values-ko/strings.xml | 1 - app/src/main/res/values-lt/strings.xml | 1 - app/src/main/res/values-lv/strings.xml | 1 - app/src/main/res/values-mk/strings.xml | 1 - app/src/main/res/values-ms/strings.xml | 1 - app/src/main/res/values-nl/strings.xml | 1 - app/src/main/res/values-or/strings.xml | 1 - app/src/main/res/values-pa/strings.xml | 1 - app/src/main/res/values-pl/strings.xml | 1 - app/src/main/res/values-pt-rBR/strings.xml | 1 - app/src/main/res/values-pt-rPT/strings.xml | 1 - app/src/main/res/values-pt/strings.xml | 1 - app/src/main/res/values-ro/strings.xml | 1 - app/src/main/res/values-ru/strings.xml | 1 - app/src/main/res/values-ryu/strings.xml | 1 - app/src/main/res/values-sat/strings.xml | 1 - app/src/main/res/values-sc/strings.xml | 1 - app/src/main/res/values-sk/strings.xml | 1 - app/src/main/res/values-sr/strings.xml | 1 - app/src/main/res/values-sv/strings.xml | 1 - app/src/main/res/values-ta/strings.xml | 1 - app/src/main/res/values-tr/strings.xml | 1 - app/src/main/res/values-uk/strings.xml | 1 - app/src/main/res/values-vi/strings.xml | 1 - app/src/main/res/values-zh-rCN/strings.xml | 1 - app/src/main/res/values-zh-rHK/strings.xml | 1 - app/src/main/res/values-zh-rTW/strings.xml | 1 - app/src/main/res/values/strings.xml | 1 - 53 files changed, 53 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java index 1d08bef81..f40e6672c 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java @@ -882,7 +882,6 @@ public class LocalPlaylistFragment extends BaseLocalListFragment sharePlaylist(WITH_TITLES) diff --git a/app/src/main/res/values-ar-rLY/strings.xml b/app/src/main/res/values-ar-rLY/strings.xml index 26c1c8b47..fa19afe78 100644 --- a/app/src/main/res/values-ar-rLY/strings.xml +++ b/app/src/main/res/values-ar-rLY/strings.xml @@ -856,6 +856,5 @@ %1$s \n%2$s شارِك قائمة التشغيل - شارِك قائمة التشغيل بتفاصيليها مثل اسم قائمة التشغيل وعناوين الفيديو أو كقائمة بسيطة من عناوين تشعّبيّة للفيديوهات - %1$s: %2$s diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 5946b6b16..8df5771d7 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -856,7 +856,6 @@ %1$s \n%2$s مشاركة قائمة التشغيل - شارك تفاصيل قائمة التشغيل مثل اسم قائمة التشغيل وعناوين الفيديو أو كقائمة بسيطة من عناوين URL للفيديو - %1$s: %2$s رد %s diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml index f9be4bf46..7fe5bf335 100644 --- a/app/src/main/res/values-az/strings.xml +++ b/app/src/main/res/values-az/strings.xml @@ -787,7 +787,6 @@ Yüksək keyfiyyət \? Oynatma siyahısın paylaş - Pleylist adı və video başlıqları kimi təfsilatlar və ya video URL-lərin sadə siyahısı olaraq pleylist paylaş Başlıqlarla paylaşın - %1$s: %2$s %1$s diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index b15060e36..132bfc954 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -781,7 +781,6 @@ Пераматаць назад Паўтарыць Атрыманыя ўкладкі пры абнаўленні стужкі. Гэты параметр не прымяняецца, калі канал абнаўляецца ў хуткім рэжыме. - Абагуліць плэйліст, перадаецца назва плэйліста і назвы відэа або просты спіс URL-адрасоў відэа Сярэдняя якасць Загрузнік аватараў Банеры diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index fe0376cda..c91d00327 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -714,7 +714,6 @@ Повторение Превъртане назад Напред - Споделете плейлист с подробности, като име на плейлист и заглавия на видеоклипове или като обикновен списък с URL адреси на видеоклипове Споделяне на списък с URL Изтрии всички позиции на възпроизвеждане? Позициите за възпроизвеждане са изтрити diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index e0c92119e..c9d2e1e94 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -806,7 +806,6 @@ Alba Přetočení zpět Znovu přehrát - Sdílejte playlist s podrobnostmi jako je jeho název a názvy videí, nebo jako jednoduchý seznam adres videí Střední kvalita Bannery Playlisty diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index b7925f3a4..f1afafa5f 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -772,7 +772,6 @@ Indlæs ikke billeder Lav kvalitet Del Playliste - Del playliste med detajler såsom playlistenavn og videotitler eller som en simpel liste over video-URL\'er Del med Titler Del URL-liste diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index d246233e3..a7c3f044d 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -804,7 +804,6 @@ %1$s \n%2$s Wiedergabeliste teilen - Teile die Wiedergabeliste mit Details wie dem Namen der Wiedergabeliste und den Videotiteln oder als einfache Liste von Video-URLs - %1$s: %2$s %s Antwort diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 5d89408df..66c16c0b9 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -804,7 +804,6 @@ %1$s \n%2$s Κοινοποίηση λίστας - Μοιραστείτε τη λίστα αναπαραγωγής με λεπτομέρειες όπως το όνομα της λίστας αναπαραγωγής και τους τίτλους βίντεο ή ως μια απλή λίστα διευθύνσεων URL βίντεο - %1$s: %2$s %s απάντηση diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml index 28bc57358..66e2c4d10 100644 --- a/app/src/main/res/values-eo/strings.xml +++ b/app/src/main/res/values-eo/strings.xml @@ -616,7 +616,6 @@ Neniu filmofluo ludeblas por ekstera ludilo Filmetoj Filmetoj kiuj spektiĝis antaŭ aŭ post sia aldoniĝo al la ludlisto foriĝus.. \nĈu vi certas? Ĉi tio nemalfareblus! - Kunhavigus ludliston inkluzivante informojn kiel la nomoj de listeroj, aŭ kiel simpla listo de ligiloj Restarigi implicitajn agordojn Jes, kaj ankaŭ parte spektitajn filmetojn diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 5cceeff41..8e0de7864 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -818,7 +818,6 @@ %1$s \n%2$s Compartir la lista de reproducción - Compartir las listas de reproducción con los detalles como el nombre de la lista y los títulos de los vídeos o como una simple lista de una dirección URL con los vídeos - %1$s: %2$s %s respuesta diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index a002c9a0d..1758092c2 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -804,7 +804,6 @@ %1$s \n%2$s Jaga esitusloendit - Jaga esitusloendit kas väga detailse teabega palade kohta või lihtsa url\'ide loendina - %1$s: %2$s Näita veel diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index f38181f64..b1c393db7 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -774,7 +774,6 @@ Editatu beheko jakinarazpen ekintza bakoitza gainean sakatuz. Lehen hiru ekintzak (erreproduzitu/pausatu, aurrekoa eta hurrengoa) sistemarengatik ezarrita daude eta ezin dira pertsonalizatu. Atzera egin Irudiaren kalitatea - Partekatu erreprodukzio-zerrenda xehetasunekin, esate baterako, erreprodukzio-zerrendaren izena eta bideo-izenburuak edo bideo-URLen zerrenda soil gisa Aukera gehiago Iraupena Aurrera egin diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 889b51152..3aae66640 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -759,7 +759,6 @@ Kelaa taaksepäin Noudettavat välilehdet syötettä päivitettäessä. Tällä valinnalla ei ole vaikutusta, jos kanava päivitetään käyttämällä nopeaa tilaa. Poistetaanko kaikki ladatut tiedostot levyltä\? - Jaa soittolista, jossa on tietoja, kuten soittolistan nimi ja videon nimi, tai yksinkertainen luettelo videoiden URL-osoitteista Keskilaatu Lataajan avatarit Prosentti diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index a2ab6db1b..9c8a36557 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -817,7 +817,6 @@ Avancer Rembobiner Rejouer - Partager la liste de lecture avec des détails tel que son nom et le titre de ses vidéos ou simplement la liste des URLs des vidéos Avatars du téléverseur Sélectionnez la qualité des images et si les images doivent être chargées, pour réduire l\'utilisation de la mémoire et de données. Les modifications vident à la fois le cache des images en mémoire et sur le disque — %s Lire diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 40482eaea..84bbbb338 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -815,7 +815,6 @@ Encabezados Lapelas a mostrar nas páxinas das canles Escolla da calidade das imaxes e se cargar as imaxes na súa totalidade, para reducir o uso de datos e memoria. Os cambios limpan a caché das imaxes na memoria e no disco - %s - Compartir a lista de reprodución con detalles como o nome da lista e os títulos dos videos ou como unha lista sinxela cos enlaces URL dos videos Compartir lista de URLs A configuración da exportación a ser importada emprega un formato vulnerable que fica obsoleto dende NewPipe 0.27.0. Comprobe que a exportación que está a importar proveña dunha fonte fiable e preferibelmente empregue exportacións de NewPipe 0.27.0 ou posterior. A compatibilidade coa importación deste formato vulnerable será eliminada por completo próximamente e as versión antigas de NewPipe non poderán importar configuracións de exportacións dende novas versións. Pistas diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index 45f1d0b50..def09a450 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -830,7 +830,6 @@ %1$s \n%2$s שיתוף רשימת נגינה - שיתוף רשימת נגינה עם פרטים כגון שם רשימת נגינה וכותרות סרטונים או כרשימה פשוטה של כתובות סרטונים - %1$s: %2$s להציג עוד להציג פחות diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 4a629bbe4..4640629a4 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -804,7 +804,6 @@ %1$s \n%2$s प्लेलिस्ट साझा करें - प्लेलिस्ट को प्लेलिस्ट नाम और वीडियो शीर्षक जैसे विवरण के साथ या वीडियो यूआरएल की एक सरल सूची के रूप में साझा करें - %1$s: %2$s %s जवाब diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 9be48f4fb..582421659 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -800,7 +800,6 @@ Srednja kvaliteta Visoka kvaliteta \? - Dijeli playlistu s detaljima kao što su ime playliste i naslovi videa ili kao jednostavan popis URL-ova videa Dijeli s naslovima Dijeli popis URL-ova – %1$s: %2$s diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 71a35db4c..216e6d733 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -796,7 +796,6 @@ Magas minőségű \? Lejátszási lista megosztása - Lejátszási lista megosztása olyan részletekkel, mint például a lejátszási lista neve és a videó címe, vagy a videó webcímek egyszerű listájaként Megosztás címekkel %1$s \n%2$s diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 3183f3014..5120a20de 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -790,7 +790,6 @@ %1$s \n%2$s Bagikan Daftar Putar - Bagikan daftar putar dengan detail seperti nama daftar putar dan judul video atau sebagai daftar video URL yang sederhana Panji - %1$s: %2$s Sentuh untuk menyunting tindakan notifikasi di bawah. Tiga tindakan pertama (mainkan/jeda, sebelumnya dan selanjutnya) disetel oleh sistem dan tidak bisa dikustomisasi. diff --git a/app/src/main/res/values-is/strings.xml b/app/src/main/res/values-is/strings.xml index edeeec214..148181861 100644 --- a/app/src/main/res/values-is/strings.xml +++ b/app/src/main/res/values-is/strings.xml @@ -792,7 +792,6 @@ Losa varanlega smámynd Breyttu hverri tilkynningu hér fyrir neðan með því að ýta á hana. Fyrstu þrjár aðgerðirnar (spila/bíða, fyrra og næsta) eru skilgreindar af kerfinu og er því ekki hægt að sérsníða. Flipar sem á að sækja við uppfærslu þessa streymis. Þetta hefur engin áhrif ef rás er uppfærð með hraðstreymisham. - Deildu spilunarlista með atriðum eins og heiti spilunarlistans og titlum myndskeiða eða sem einföldum lista yfir slóðir á myndskeið Nota varaeiginleika ExoPlayer-afkóðarans Vegna takmarkana í ExoPlayer-spilaranum var tímalengd hoppa sett á %d sekúndur Margmiðlunargöng (media tunneling) voru gerð óvirk á tækinu þínu þar sem þessi gerð tækja er þekkt fyrir að styðja ekki þennan eiginleika. diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index a6a560fb4..542040d26 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -817,7 +817,6 @@ %1$s \n%2$s Condividi playlist - Condividi la playlist con dettagli come il suo nome e i titoli video o come un semplice elenco di URL video - %1$s: %2$s %s risposta diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index eeac136fc..04e54348d 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -791,7 +791,6 @@ %1$s \n%2$s プレイリストを共有 - プレイリスト名やビデオタイトルなどの詳細を含むプレイリスト、またはビデオURLのみのシンプルなリストとしてプレイリストを共有します - %1$s: %2$s %sの返信 diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 39114997a..283adc7f2 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -776,7 +776,6 @@ 되감기 다시 재생 피드를 업데이트할 때 가져올 탭입니다. 빠른 모드를 사용하여 채널을 업데이트하는 경우 이 옵션은 효과가 없습니다. - 재생목록 이름, 동영상 제목 등의 세부정보 또는 간단한 동영상 URL 목록으로 재생목록을 공유하세요 중간 품질 업로더 아바타 배너 diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index 455f0e8c7..23476bf36 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -825,7 +825,6 @@ Vaizdo įrašai Takeliai Pasirinkite paveikslėlių kokybę ir ar apskritai įkelti paveikslėlius, kad sumažintumėte duomenų ir atminties naudojimą. Pakeitimai išvalo atmintyje ir diske esančių vaizdų talpyklą - %s - Dalintis grojaraščiu su tokia informacija kaip grojaraščio pavadinimas ir vaizdo įrašo pavadinimas arba paprastas vaizdo įrašų nuorodų sąrašas Dalintis su pavadinimais Dalintis grojaraščiu Dalintis nuorodų sąrašu diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml index 0698f89d3..2f528a346 100644 --- a/app/src/main/res/values-lv/strings.xml +++ b/app/src/main/res/values-lv/strings.xml @@ -824,7 +824,6 @@ %1$s %2$s Skaņdarbi Īsie video - Kopīgot atskaņošanas saraksta nosaukumu un to video nosaukumus vai tikai atskaņošanas sarakstā iekļauto video URL saites Kopīgot atskaņošanas sarakstu Kopīgot nosaukumus Importētā eksporta iestatījumi izmanto ievainojamo formātu, kas tika pārtraukts kopš NewPipe 0.27.0 versijas. Pārliecinieties, ka importētie dati ir no uzticama avota, un turpmāk ir vēlams izmantot tikai datus, kas veikti NewPipe 0.27.0 vai jaunākās versijās. Iestatījumu importēšanas atbalsts šajā neaizsargātajā formātā drīzumā tiks pilnībā aizvākts, un tad vecās NewPipe versijas vairs nevarēs importēt iestatījumus, kas veikti jaunajās versijās. diff --git a/app/src/main/res/values-mk/strings.xml b/app/src/main/res/values-mk/strings.xml index 92d265758..ba41b730b 100644 --- a/app/src/main/res/values-mk/strings.xml +++ b/app/src/main/res/values-mk/strings.xml @@ -713,7 +713,6 @@ Инстанцата не може да биде потврдена Изберете го квалитетот на сликите и дали воопшто да се вчитуваат слики, за да го намалите користењето на интернет и меморија. Промените го чистат кешот на сликите (анг. image cache), како и во меморијата, така и на дискот — %s - %1$s: %2$s - Споделете ја плејлистата со подробности (детали), како името на плејлистата и насловите на видеата или како едноставен список од линковите на видеата Ништо Поставките во извезениот фајл кој се увезува користат ранлив формат кој повеќе не е поддржан од NewPipe 0.27.0. Уверете се дека извезениот фајл кој се увезува е од доверлив извор и претпочитајте во иднина да користите само износи добиени од NewPipe 0.27.0 или понова верзија. Поддршката за увезување поставки од овој ранлив формат наскоро ќе биде целосно укината и тогаш старите верзии на NewPipe повеќе нема да можат да увезуваат поставки од износи од новите верзии. Побарај потврда пред чистење на редоследот diff --git a/app/src/main/res/values-ms/strings.xml b/app/src/main/res/values-ms/strings.xml index 9864051d8..bb0527655 100644 --- a/app/src/main/res/values-ms/strings.xml +++ b/app/src/main/res/values-ms/strings.xml @@ -503,7 +503,6 @@ Mutu rendah Mutu sederhana Mutu tinggi - Kongsikan senarai main dengan butiran seperti nama senarai main dan tajuk video atau sebagai senarai ringkas URL video Kongsi dengan Tajuk Kongsi senarai URL Tunjukkan lagi diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index a478ba8c3..33ed4d26d 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -804,7 +804,6 @@ %1$s \n%2$s Afspeellijst delen - Deel afspeellijst met details zoals afspeellijstnaam en videotitels of als een eenvoudige lijst met video-URL\'s - %1$s: %2$s %s reactie diff --git a/app/src/main/res/values-or/strings.xml b/app/src/main/res/values-or/strings.xml index 91c7f1425..cae53566e 100644 --- a/app/src/main/res/values-or/strings.xml +++ b/app/src/main/res/values-or/strings.xml @@ -804,7 +804,6 @@ %1$s \n%2$s ଖେଳ ତାଲିକା ସହଭାଗ କରନ୍ତୁ - ପ୍ଲେ-ଲିଷ୍ଟ ନାମ ଏବଂ ଭିଡିଓ ଶୀର୍ଷକ କିମ୍ବା ଭିଡିଓ URLଗୁଡ଼ିକର ଏକ ସରଳ ତାଲିକା ଭାବରେ ବିବରଣୀ ସହିତ ପ୍ଲେ-ଲିଷ୍ଟ ଅଂଶୀଦାର କରନ୍ତୁ - %1$s: %2$s ଅଧିକ ଦର୍ଶାନ୍ତୁ ଏହା ଉପରେ ଟ୍ୟାପ କରି ନିମ୍ନରେ ଦିଆଯାଇଥିବା ପ୍ରତ୍ୟେକ ବିଜ୍ଞପ୍ତି କାର୍ଯ୍ୟକୁ ସମ୍ପାଦନ କରନ୍ତୁ । ପ୍ରଥମ ତିନୋଟି କାର୍ଯ୍ୟ (ଖେଳ/ବିରତି, ପୂର୍ବବର୍ତ୍ତୀ ଏବଂ ପରବର୍ତ୍ତୀ) ତନ୍ତ୍ର ଦ୍ୱାରା ସେଟ କରାଯାଇଥାଏ ଏବଂ ଏହାକୁ ଇଚ୍ଛାରୂପଣ କରାଯାଇପାରିବ ନାହିଁ । diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml index bfb51a738..0da6cdd09 100644 --- a/app/src/main/res/values-pa/strings.xml +++ b/app/src/main/res/values-pa/strings.xml @@ -804,7 +804,6 @@ %1$s \n%2$s ਪਲੇਲਿਸਟ ਸਾਂਝੀ ਕਰੋ - ਪਲੇਲਿਸਟ ਨੂੰ ਪਲੇਲਿਸਟ ਨਾਮ ਅਤੇ ਵੀਡੀਓ ਸਿਰਲੇਖ ਜਿਹੇ ਵੇਰਵਿਆਂ ਸਮੇਤ ਜਾਂ ਵੀਡੀਓ URL ਦੀ ਇੱਕ ਸਰਲ ਸੂਚੀ ਦੇ ਰੂਪ ਵਿੱਚ ਸਾਂਝਾ ਕਰੋ - %1$s: %2$s %s ਜਵਾਬ diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index b3a43f403..63768acb5 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -825,7 +825,6 @@ %1$s \n%2$s Udostępnij playlistę - Udostępnij playlistę ze szczegółami, takimi jak nazwa playlisty i tytuły wideo, lub jako prostą listę adresów URL wideo. – %1$s: %2$s %s odpowiedź diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index d7942aa99..e0b58da6a 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -809,7 +809,6 @@ Avançar Retroceder Repetir - Compartilhar playlist com detalhes como o nome da playlist e títulos de vídeo ou como uma lista simples dos URL de vídeos Qualidade média Fotos de perfil do autor - %1$s: %2$s diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index 59c77daca..85e951b8e 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -804,7 +804,6 @@ Recuar Repetição Separadores a obter ao atualizar o feed. Esta opção não tem efeito se um canal for atualizado utilizando o modo rápido. - Partilhe a lista de reprodução com detalhes como o nome da lista de reprodução e os títulos dos vídeos ou como uma simples lista de URLs de vídeos Média qualidade Avatar dos publicadores Bandeiras diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index bd98dc7d8..1326e0ca7 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -817,7 +817,6 @@ Canais Vídeo anterior Direto - Partilhe a lista de reprodução com detalhes como o nome da lista de reprodução e os títulos dos vídeos ou como uma simples lista de URLs de vídeos Escolha a qualidade das imagens e se pretende carregar imagens, para reduzir a utilização de dados e de memória. As alterações limpam a cache de imagens na memória e no disco - %s Mostrar mais diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 3cc83967f..fc62b5d1e 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -791,7 +791,6 @@ File ce vor fi preluate când se actualizează fluxul. Această opțiune nu are niciun efect dacă un canal este actualizat folosind modul rapid. Selectați o coloană sonoră cu descrieri pentru persoane cu deficiențe vizuale, dacă este disponibilă Acțiunea gestului din stânga - Distribuiți playlistul cu detalii precum numele playlistului și titlurile videourilor sau ca o simplă listă de URL-uri a videourilor Calitate medie Preferați audioul descriptiv Modificați dimensiunea intervalului de încărcare pentru conținuturi progresive (în prezent %s). O valoare mai mică poate accelera încărcarea lor inițială diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 35fdb8263..71dcdaea4 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -808,7 +808,6 @@ Перемотать назад Повторить Получаемые вкладки при обновлении ленты. Эта функция не применяется, если канал обновляется с помощью быстрого режима. - Поделиться подборкой с подробностями, такими как название подборки и названия видео, или просто списком URL видео Среднее качество Загрузчик аватаров Баннеры diff --git a/app/src/main/res/values-ryu/strings.xml b/app/src/main/res/values-ryu/strings.xml index c0195057a..0396245e1 100644 --- a/app/src/main/res/values-ryu/strings.xml +++ b/app/src/main/res/values-ryu/strings.xml @@ -804,7 +804,6 @@ %1$s \n%2$s プレイリストちゅーゆーいん - プレイリストめいてぃがろービデオタイトルんでーぬしょうさいくくむるプレイリスト、あらんでぃビデオURLぬみぬシンプルやるリストとぅしてぃプレイリストちゅーゆーいんさびーん - %1$s: %2$s %sぬへんしん diff --git a/app/src/main/res/values-sat/strings.xml b/app/src/main/res/values-sat/strings.xml index 751a0cde7..8b44cd5e0 100644 --- a/app/src/main/res/values-sat/strings.xml +++ b/app/src/main/res/values-sat/strings.xml @@ -678,7 +678,6 @@ ᱞᱟᱯᱷᱟᱝ ᱥᱤᱠᱷᱱᱟ. ᱛᱟᱞᱢᱟ ᱥᱤᱠᱷᱱᱟᱹᱛ ᱩᱥᱩᱞ ᱥᱤᱠᱷᱱᱟᱹᱛ - ᱯᱷᱟᱭᱞᱤᱥᱴ ᱧᱩᱛᱩᱢ ᱟᱨ ᱵᱷᱤᱰᱤᱭᱳ ᱧᱩᱛᱩᱢ ᱞᱮᱠᱟᱛᱮ ᱟᱨᱵᱟᱝ ᱵᱷᱤᱰᱤᱭᱳ URL ᱨᱮᱱᱟᱜ ᱢᱤᱫ ᱞᱮᱠᱟᱱ ᱞᱤᱥᱴᱤ ᱞᱮᱠᱟᱛᱮ ᱴᱷᱟᱶ ᱮᱢ ᱢᱮ URL ᱛᱟᱹᱞᱠᱟᱹ ᱥᱟᱯᱲᱟᱣ - %1$s: %2$s ᱱᱚᱴᱤᱯᱷᱤᱠᱮᱥᱚᱱ ᱨᱮ ᱑᱖:᱙ ᱠᱷᱚᱱ ᱑:᱑ ᱟᱥᱯᱮᱠᱴ ᱚᱱᱩᱯᱟᱹᱛ ᱨᱮ ᱵᱷᱤᱰᱤᱭᱳ ᱛᱷᱚᱢᱵᱱᱮᱞ ᱜᱮᱫᱽ ᱢᱮ diff --git a/app/src/main/res/values-sc/strings.xml b/app/src/main/res/values-sc/strings.xml index 9b6fb5863..d92532c31 100644 --- a/app/src/main/res/values-sc/strings.xml +++ b/app/src/main/res/values-sc/strings.xml @@ -788,7 +788,6 @@ Torra in segus Torra a reprodùere Ischedas de recuperare cando agiornas sa fonte. Custa optzione non tenet efetu si unu canale benit agiornadu impreende sa modalidade lestra. - Cumpartzi s\'iscalita cun detàllios che a su nùmene de s\'iscalita e sos tìtulos de sos vìdeos o che a una lista simpre de URL de vìdeos Calidade mesana Avatars de su carrigadore Insignas diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 0677feb95..dee7b1264 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -823,7 +823,6 @@ %s odpovede %s odpovedí - Zdieľajte playlist s podrobnosťami, ako je jeho názov a názvy videí, alebo ako jednoduchý zoznam URL adries videí - %1$s: %2$s %1$s \n%2$s diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index a837451ba..5c8c28a57 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -817,7 +817,6 @@ %1$s \n%2$s Дели плејлисту - Делите плејлисту са детаљима, као што су назив плејлисте и наслови видео снимака или као једноставна листа URL адреса видео снимака -%1$s: %2$s %s одговор diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 740143d0b..c85d17220 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -804,7 +804,6 @@ Uppladdarens visningsbilder Banderoller - %1$s: %2$s - Dela spellistan med detaljer så som spellistans namn och video-titlarna eller som en enkel lista med URL till videorna Välj bildkvalitet och om bilder överhuvudtaget ska laddas för att minska data och minnesanvändningen. Ändringar rensar både i minnet och bildcache på disk – %s Visa mer diff --git a/app/src/main/res/values-ta/strings.xml b/app/src/main/res/values-ta/strings.xml index 958df593e..0056f7416 100644 --- a/app/src/main/res/values-ta/strings.xml +++ b/app/src/main/res/values-ta/strings.xml @@ -470,7 +470,6 @@ முன்னோக்கி பட தகுதி உயர் தகுதி - பிளேலிச்ட் பெயர் மற்றும் வீடியோ தலைப்புகள் போன்ற விவரங்களுடன் அல்லது வீடியோ முகவரி களின் எளிய பட்டியலாக பிளேலிச்ட்டைப் பகிரவும் மேலும் விருப்பங்கள் காலம் முன்னாடி diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index a87dac75e..ccd3b3b62 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -791,7 +791,6 @@ Geri sar Yeniden oynat Besleme güncellenirken alınacak sekmeler. Hızlı kip kullanılırken kanal güncelleniyorsa bu seçeneğin etkisi yoktur. - Oynatma listesini, oynatma listesi adı ve video başlıkları gibi ayrıntılarla ya da video adreslerinin basit listesi olarak paylaş Orta nitelik Yükleyen avatarları Afişler diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 39fdddd67..22d9eb478 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -821,7 +821,6 @@ %1$s \n%2$s Поділитися добіркою - Поділитися добіркою з подробицями, такими як назва добірки та назви відео, або просто списком URL-адрес відео - %1$s: %2$s Показати більше Відредагуйте кожну дію сповіщення, натиснувши на неї. Перші три дії (відтворення/пауза, попередній і наступний) встановлюються системою і не можуть бути змінені. diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 23a0c96dc..22bc03c2c 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -787,7 +787,6 @@ Tua đi Album Tua lại - Chia sẻ danh sách phát với các thông tin chi tiết như tên danh sách phát và tiêu đề video hoặc dưới dạng danh sách URL video đơn giản Chất lượng trung bình - %1$s: %2$s Chọn chất lượng hình ảnh và chọn có tải chất lượng ảnh hay không, để giảm mức sử dụng dữ liệu và bộ nhớ. Thay đổi xoá cache ảnh cho cả trong bộ nhớ lẫn ổ cứng - %s diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 5efb32d4f..e8d19cb8b 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -791,7 +791,6 @@ %1$s \n%2$s 分享播放列表 - 分享详细的播放列表(带名称和视频标题等信息)或只分享视频网址列表 - %1$s: %2$s %s 条回复 diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 0a862a48d..c804c53c0 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -775,7 +775,6 @@ 跳後 重播 更新摘要嘅時候要攞邊啲分頁返嚟。若果頻道用快速模式更新,就橫豎都無相干嘞。 - 分享播放清單要詳細包含播放清單個名同埋入面啲片名,定簡單得啲影片嘅 URL 一般畫質 上載者嘅頭像 橫額 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 30d66f124..030c23f60 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -791,7 +791,6 @@ %1$s \n%2$s 分享播放清單 - 分享包含播放清單名稱與影片標題等詳細資訊的播放清單,或是僅作為簡單的影片網址清單 - %1$s:%2$s %s 個回覆 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7c9637f31..729dae48c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -846,7 +846,6 @@ High quality \? Share Playlist - Share playlist with details such as playlist name and video titles or as a simple list of video URLs Share with Titles Share URL list Share as YouTube temporary playlist From 2ceb70236ef27b070eebbda25cbcca778db2c8e2 Mon Sep 17 00:00:00 2001 From: "Thiago F. G. Albuquerque" Date: Fri, 14 Mar 2025 21:56:42 -0300 Subject: [PATCH 046/143] sharePlaylist(): converting javadoc from Markdown back to "classic javadoc" (request from @Stypox) --- .../local/playlist/LocalPlaylistFragment.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java index f40e6672c..f5562549c 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java @@ -388,15 +388,16 @@ public class LocalPlaylistFragment extends BaseLocalListFragment + *
  • {@code JUST_URLS}: shares the URLs only.
  • + *
  • {@code WITH_TITLES}: each entry in the list is accompanied by its title.
  • + *
  • {@code YOUTUBE_TEMP_PLAYLIST}: shares as a YouTube temporary playlist.
  • + * + * + * @param shareMode The way the playlist should be shared. + */ private void sharePlaylist(final PlayListShareMode shareMode) { final Context context = requireContext(); From d321e57620c4260bc2a776fb04334dca3a5c88f2 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Sat, 15 Mar 2025 00:12:09 +0100 Subject: [PATCH 047/143] Translated using Weblate (Czech) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Swedish) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Catalan) Currently translated at 88.2% (653 of 740 strings) Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 90.4% (76 of 84 strings) Translated using Weblate (Belarusian) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Hindi) Currently translated at 100.0% (84 of 84 strings) Translated using Weblate (Punjabi) Currently translated at 100.0% (84 of 84 strings) Translated using Weblate (Belarusian) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Punjabi) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Hindi) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Portuguese) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Bulgarian) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (German) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (German) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Bulgarian) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Croatian) Currently translated at 99.7% (738 of 740 strings) Translated using Weblate (Russian) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Indonesian) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Belarusian) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Belarusian) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Belarusian) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Italian) Currently translated at 100.0% (84 of 84 strings) Translated using Weblate (Czech) Currently translated at 100.0% (84 of 84 strings) Translated using Weblate (Portuguese) Currently translated at 99.8% (739 of 740 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Czech) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Russian) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Hungarian) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (French) Currently translated at 100.0% (84 of 84 strings) Translated using Weblate (Arabic) Currently translated at 100.0% (84 of 84 strings) Translated using Weblate (Arabic) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Belarusian) Currently translated at 99.5% (737 of 740 strings) Translated using Weblate (Turkish) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Hebrew) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Icelandic) Currently translated at 99.4% (736 of 740 strings) Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Greek) Currently translated at 25.0% (21 of 84 strings) Translated using Weblate (Greek) Currently translated at 23.8% (20 of 84 strings) Translated using Weblate (Estonian) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Bulgarian) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (French) Currently translated at 99.5% (737 of 740 strings) Co-authored-by: 439JBYL80IGQTF25UXNR0X1BG <439JBYL80IGQTF25UXNR0X1BG@users.noreply.hosted.weblate.org> Co-authored-by: Andrey F Co-authored-by: Anonymous Co-authored-by: Antonin Del Fabbro Co-authored-by: Christian Eichert Co-authored-by: Drugi Sapog Co-authored-by: Eduardo Calixto Co-authored-by: Emin Tufan Çetin Co-authored-by: Fjuro Co-authored-by: Ghost of Sparta Co-authored-by: Hosted Weblate Co-authored-by: Igor Rückert Co-authored-by: Ihor Hordiichuk Co-authored-by: Jan Layola Co-authored-by: Kevin Wang Co-authored-by: Linerly Co-authored-by: Massimo Pissarello Co-authored-by: Milo Ivir Co-authored-by: Petr Kadlec Co-authored-by: Priit Jõerüüt Co-authored-by: Rex_sa Co-authored-by: Sergio Marques Co-authored-by: Sveinn í Felli Co-authored-by: XxVictoriaxX Co-authored-by: Yaron Shahrabani Co-authored-by: bittin1ddc447d824349b2 Co-authored-by: trunars Co-authored-by: whistlingwoods <72640314+whistlingwoods@users.noreply.github.com> Co-authored-by: Максим Горпиніч Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ar/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/cs/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/el/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/fr/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/hi/ 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/zh_Hans/ Translation: NewPipe/Metadata --- app/src/main/res/values-ar/strings.xml | 4 +- app/src/main/res/values-be/strings.xml | 75 +++++++++---------- app/src/main/res/values-bg/strings.xml | 8 +- app/src/main/res/values-ca/strings.xml | 7 ++ app/src/main/res/values-cs/strings.xml | 4 +- app/src/main/res/values-de/strings.xml | 4 +- app/src/main/res/values-et/strings.xml | 4 +- app/src/main/res/values-fr/strings.xml | 8 +- app/src/main/res/values-he/strings.xml | 1 + app/src/main/res/values-hi/strings.xml | 4 +- app/src/main/res/values-hr/strings.xml | 9 ++- app/src/main/res/values-hu/strings.xml | 6 +- app/src/main/res/values-in/strings.xml | 4 +- app/src/main/res/values-is/strings.xml | 4 +- app/src/main/res/values-pa/strings.xml | 18 ++--- app/src/main/res/values-pt-rBR/strings.xml | 4 +- app/src/main/res/values-pt/strings.xml | 8 +- app/src/main/res/values-ru/strings.xml | 8 +- app/src/main/res/values-sv/strings.xml | 2 +- app/src/main/res/values-tr/strings.xml | 6 +- app/src/main/res/values-uk/strings.xml | 6 +- .../metadata/android/ar/changelogs/1003.txt | 10 ++- .../metadata/android/cs/changelogs/1002.txt | 5 +- .../metadata/android/cs/changelogs/1003.txt | 7 +- .../metadata/android/el/changelogs/1000.txt | 13 ++++ .../metadata/android/el/changelogs/999.txt | 1 + .../metadata/android/fr/changelogs/1003.txt | 10 +-- .../metadata/android/hi/changelogs/1001.txt | 6 ++ .../metadata/android/hi/changelogs/1002.txt | 6 +- .../metadata/android/hi/changelogs/1003.txt | 7 +- .../metadata/android/hi/changelogs/65.txt | 46 ++++++------ .../metadata/android/it/changelogs/1002.txt | 5 +- .../metadata/android/it/changelogs/1003.txt | 7 +- .../metadata/android/pa/changelogs/1001.txt | 6 ++ .../metadata/android/pa/changelogs/1002.txt | 5 +- .../metadata/android/pa/changelogs/1003.txt | 7 +- .../android/zh-Hans/changelogs/1000.txt | 13 ++++ 37 files changed, 216 insertions(+), 132 deletions(-) create mode 100644 fastlane/metadata/android/el/changelogs/1000.txt create mode 100644 fastlane/metadata/android/el/changelogs/999.txt create mode 100644 fastlane/metadata/android/hi/changelogs/1001.txt create mode 100644 fastlane/metadata/android/pa/changelogs/1001.txt create mode 100644 fastlane/metadata/android/zh-Hans/changelogs/1000.txt diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 550ff38a0..50ddcd8d3 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -83,7 +83,7 @@ استئناف التشغيل متابعة التشغيل بعد المقاطعات (مثل المكالمات الهاتفية) إظهار تلميح \"اضغط للفتح\" - إظهار التلميح عند الضغط على الخلفية أو الزر المنبثق في الفيديو \"التفاصيل:\\ + إظهار التلميح عند الضغط على الخلفية أو الزر المنبثق في الفيديو \"التفاصيل:\" المشغل السلوك تشغيل في وضع منبثق @@ -558,7 +558,7 @@ إزالة ما تمت مشاهدته ستكون النصوص الأصلية من الخدمات مرئية في عناصر البث عرض الوقت الأصلي على العناصر - قم بتشغيل \"وضع تقييد المحتوى\" في يوتيوب\\ + قم بتشغيل \"وضع تقييد المحتوى\" في يوتيوب بواسطة %s أنشأها %s الصورة الرمزية للقناة diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index 132bfc954..19f3c8b26 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -19,7 +19,7 @@ Прыбірае гук пры пэўнай раздзяляльнасці Знешні аўдыяплэер Падпісацца - Вы падпісаныя + Вы падпісаны Падпіска адменена Не ўдалося змяніць падпіску Не ўдалося абнавіць падпіску @@ -165,8 +165,9 @@ Няма падпісчыкаў %s падпісчык - %s падпісчыка + %s падпісчыкі %s падпісчыкаў + %s падпісчыкаў Няма праглядаў @@ -177,7 +178,7 @@ Няма відэа - %s Відэа + %s відэа %s відэа %s відэа %s відэа @@ -207,7 +208,7 @@ Недапушчальныя сімвалы замяняюцца на гэты Сімвал для замены Літары і лічбы - Большасць спецзнакаў + Большасць спецсімвалаў Аб NewPipe Іншыя ліцэнзіі © %1$s %2$s пад ліцэнзіяй %3$s @@ -221,7 +222,7 @@ NewPipe распрацаваны добраахвотнікамі, якія праводзяць свой вольны час, забяспечваючы лепшы карыстацкі досвед. Дапамажыце распрацоўшчыкам зрабіць NewPipe яшчэ лепшым, пакуль яны атрымліваюць асалоду ад кавы. Ахвяраваць грошы Вэб-сайт - Дзеля атрымання больш падрабязнай інфармацыі і апошніх навін аб NewPipe наведайце наш вэб-сайт. + Наведайце вэб-сайт, каб атрымаць больш інфармацыі і паглядзець апошнія навіны NewPipe. Палітыка прыватнасці NewPipe Праект NewPipe вельмі адказна ставіцца да вашай прыватнасці. Таму праграма не збірае ніякіх даных без вашай згоды. \nПалітыка прыватнасці NewPipe падрабязна тлумачыць, якія даныя адпраўляюцца і захоўваюцца пры адпраўцы справаздачы пра збой. Прачытаць палітыку прыватнасці @@ -231,9 +232,9 @@ Гісторыя Гісторыя Выдаліць гэты элемент з гісторыі пошуку? - Нядаўна прайграныя - Найбольш прайграваныя - Кантэнт галоўнай старонкі + Прайгравалася нядаўна + Прайгравалася найбольш + Змесціва галоўнай старонкі Пустая старонка Старонка кіёска Старонка канала @@ -254,13 +255,13 @@ Налады аўдыя Зацісніце, каб дадаць у чаргу Пачаць прайграванне ў фоне - Пачаць прайграванне у акне + Пачаць прайграванне ў акне Адкрыць бакавую панэль Закрыць бакавую панэль Пры адкрыцці кантэнту Пры адкрыцці спасылкі на кантэнт — %s Відэаплэер - Фонавы плэер + Фонавы прайгравальнік Аконны прайгравальнік Заўсёды пытаць Атрыманне звестак… @@ -269,7 +270,7 @@ Перайменаваць Імя Дадаць у плэйліст - Усталяваць як мініяцюру плэйліста + Зрабіць мініяцюрай плэйліста Дадаць плэйліст у закладкі Выдаліць закладку Выдаліць плэйліст\? @@ -308,7 +309,7 @@ Прапускаць цішыню Крок Скід - У адпаведнасці з Агульным рэгламентам па абароне даных ЕС (GDPR), звяртаем вашу ўвагу на палітыку прыватнасці NewPipe. Уважліва азнаёмцеся з ёй. \nВы павінны прыняць ўмовы, каб адправіць нам справаздачу пра памылку. + У адпаведнасці з Агульным рэгламентам па абароне даных ЕС (GDPR), звяртаем вашу ўвагу на палітыку прыватнасці NewPipe. Уважліва азнаёмцеся з ёй. \nВы павінны прыняць умовы, каб адправіць нам справаздачу пра памылку. Прыняць Адмовіцца Без абмежаванняў @@ -316,7 +317,7 @@ Згортванне пры пераключэнні праграмы Дзеянне пры пераключэнні з асноўнага відэаплэера на іншую праграму — %s Нічога не рабіць - Згортванне у фон + Згортванне ў фон Згортванне ў акно Адпісацца Выберыце ўкладку @@ -362,7 +363,7 @@ Спыніць Максімум спроб Колькасць спроб спампаваць да адмены - Перапыніць у платных сетках + Прыпыняць у сетках з тарыфікацыяй Карысна пры пераключэнні на мабільную сетку, хоць некаторыя спампоўванні немагчыма прыпыніць Падзеі Канферэнцыі @@ -386,7 +387,7 @@ Праграма NewPipe была закрыта падчас працы з файлам На прыладзе скончылася вольнае месца Прагрэс страчаны, бо файл быў выдалены - Час злучэння выйшла + Скончыўся час злучэння Вы хочаце ачысціць гісторыю спампоўвання ці выдаліць спампаваныя файлы? Абмежаваць чаргу спампоўвання Толькі адно адначасовае спампоўванне @@ -420,7 +421,7 @@ Не ўдалося праверыць сервер Увядзіце URL-адрас сервера Выберыце ўлюбёныя серверы PeerTube - Актыўны плэер быў зменены + Чарга актыўнага прайгравальніка будзе заменена Пераключэнне з аднаго плэера на другі можа прывесці да замены вашай чаргі Запытваць пацвярджэнне перад ачысткай чаргі Ніколі @@ -452,7 +453,7 @@ Альбомы Песні Відэа - Аўтаматычная чарга + Аўтапрайграванне Крок перамотвання Каляровыя апавяшчэнні Нічога @@ -491,8 +492,8 @@ Адключыць Няма аўдыяпатокаў даступных для знешніх плэераў Апавяшчаць - Няма даступных відэатрансляцый для знешніх плэераў - Выбраная трансляцыя не падтрымліваецца знешнімі плэерамі + Няма відэапатокаў даступных для знешніх плэераў + Выбраны паток не падтрымліваецца знешнімі плэерамі Выберыце якасць для знешніх плэераў Невядомая якасць Невядомы фармат @@ -503,7 +504,7 @@ Адкрыць праз Начная тэма Адкрыць вэб-сайт - Цяпер Вы можаце вылучаць тэкст у апісанні. Звярніце ўвагу, што ў рэжыме вылучэння старонка можа мігацець, а спасылкі могуць быць недаступныя для націскання. + Цяпер можна вылучаць тэкст у апісанні. Звярніце ўвагу, што ў рэжыме вылучэння старонка можа мільгаць, а спасылкі не націскацца. Запускаць галоўны прайгравальнік у поўнаэкранным рэжыме Паказаць дэталі канала Нізкая якасць (менш) @@ -562,8 +563,8 @@ %d хвіліна %d хвіліны - %d хвілінаў - %d хвілінаў + %d хвілін + %d хвілін Змяніць памер інтэрвалу загрузкі прагрэсіўнага змесціва (у цяперашні час %s). Меншае значэнне можа паскорыць іх першапачатковую загрузку Выключыце, каб схаваць апісанне відэа і дадатковую інфармацыю @@ -603,8 +604,8 @@ У чаргу далей У чарзе наступны Загрузка звестак аб стрыме… - Апрацоўка... Можа заняць некаторы час - Дублікат дададзены %d раз + Ідзе апрацоўка… Крыху пачакайце + Дублікат дададзены %d раз(ы) LeakCanary недаступны Паказаць уцечкі памяці Адключыце мультымедыйнае тунэляванне, калі ў вас з\'яўляецца чорны экран або заіканне падчас прайгравання відэа. @@ -613,7 +614,7 @@ Частыя пытанні Перайсці на вэб-сайт Правядзіце пальцам па элементах, каб выдаліць іх - Адмяніць пастаянную мініяцюру + Прыбраць пастаянную мініяцюру Паказваць індыкатары выяў Паказваць каляровыя стужкі Пікаса на выявах, якія пазначаюць іх крыніцу: чырвоная для сеткі, сіняя для дыска і зялёная для памяці Апрацоўка стужкі… @@ -624,7 +625,7 @@ Працэнт Відэа, якія прагледжаны перад дадаваннем і пасля дадавання ў спіс прайгравання, будуць выдалены. \nВы ўпэўнены? Гэта дзеянне немагчыма скасаваць! Паказвае варыянт збою пры выкарыстанні плэера - Выдаліць прагледжанае + Выдаліць прагледжаныя Паказаць панэль памылак Паўтон Любая сетка @@ -645,12 +646,12 @@ Выдаліць гэту групу? Новая Паказаць толькі разгрупаваныя падпіскі - Маючыя адбыцца + Запланаваныя Паказваць «Збой плэера» Запусціце праверку новых патокаў Збой праграмы - Апавяшчэнні аб новых стрымах - Апавяшчаць аб новых стрымах з падпісак + Апавяшчэнні пра новыя відэа + Апавяшчаць пра новыя відэа з падпісак Частата праверкі Неабходны тып злучэння Праверыць наяўнасць абнаўленняў @@ -693,7 +694,7 @@ Вы падпісаліся на канал Апошнія Радыё - Паказваць запланаваныя трансляцыі + Паказваць наступныя патокі Паказаць/схаваць трансляцыі Гэты кантэнт яшчэ не падтрымліваецца NewPipe. \n @@ -710,14 +711,14 @@ %s дае наступную прычыну: Вартае ўвагі Унутраная - Цалкам прагледзеў + Прагледжаныя цалкам Гэты кантэнт даступны толькі для аплачаных карыстальнікаў, таму NewPipe не можа яго трансляваць або спампоўваць. Даступны ў некаторых службах, звычайна нашмат хутчэй, але можа вяртаць абмежаваную колькасць элементаў і часта няпоўную інфармацыю (напрыклад, без працягласці, тыпу элемента, без актыўнага стану) Узроставае абмежаванне Для гэтага дзеяння не знойдзены прыдатны файлавы менеджар. \nУсталюйце файлавы менеджар, сумяшчальны з Storage Access Framework Ніякая праграма на вашай прыладзе не можа адкрыць гэта Стандартнае значэнне ExoPlayer - Часткова прагледжана + Прагледжаныя часткова Лічыце, што загрузка каналаў адбываецца занадта павольна? Калі так, паспрабуйце ўключыць хуткую загрузку (можна змяніць у наладах або націснуўшы кнопку ніжэй). \n \nNewPipe прапануе два спосабы загрузкі каналаў: \n• Атрыманне ўсяго канала падпіскі. Павольны, але інфармацыя поўная). \n• Выкарыстанне спецыяльнай канчатковай кропкі абслугоўвання. Хуткі, але звычайна інфармацыя няпоўная). \n \nРозніца паміж імі ў тым, што ў хуткім звычайна адсутнічае частка інфармацыі, напрыклад, працягласць або тып (немагчыма адрозніць трансляцыі ад звычайных відэа), і ён можа вяртаць менш элементаў. \n \nYouTube з\'яўляецца прыкладам сэрвісу, які прапануе гэты хуткі метад праз RSS-канал. \n \nТакім чынам, выбар залежыць ад таго, чаму вы аддаяце перавагу: хуткасці або дакладнасці інфармацыя. Прыватнасць Мова @@ -747,9 +748,7 @@ У гэтым патоку ўжо павінна быць гукавая дарожка Уключыце гэту опцыю, калі ў вас ёсць праблемы з ініцыялізацыяй дэкодэра, якая вяртаецца да дэкодэраў з больш нізкім прыярытэтам, калі ініцыялізацыя асноўных дэкодэраў не ўдаецца. Гэта можа прывесці да нізкай прадукцыйнасці прайгравання, чым пры выкарыстанні асноўных дэкодэраў Кіраванне некаторымі наладамі ExoPlayer. Каб гэтыя змены ўступілі ў сілу, патрабуецца перазапуск прайгравальніка - Гэты абыходны шлях вызваляе і паўторна стварае відэакодэкі, калі адбываецца змяненне паверхні, замест таго, каб усталёўваць паверхню непасрэдна для кодэка. ExoPlayer ужо выкарыстоўваецца на некаторых прыладах з гэтай праблемай, гэты параметр мае ўплыў толькі на прыладах з Android 6 і вышэй -\n -\nУключэнне гэтай опцыі можа прадухіліць памылкі прайгравання пры пераключэнні бягучага відэаплэера або пераключэнні ў поўнаэкранны рэжым + Гэты абыходны шлях вызваляе і паўторна стварае відэакодэкі, калі адбываецца змяненне паверхні, замест таго, каб зажаваць паверхню непасрэдна для кодэка. Ужо выкарыстоўваецца ExoPlayer на некаторых прыладах з такой праблемай, гэты параметр ужываецца толькі на прыладах з Android 6 і вышэй\n\nУключэнне параметра можа прадухіліць памылкі прайгравання пры пераключэнні бягучага відэаплэера або пераключэнні ў поўнаэкранны рэжым Якасць выяў Відэа \? @@ -771,7 +770,7 @@ Наступны паток Прадвызначана на вашай прыладзе адключана медыятунэляванне, бо гэтая мадэль прылады яго не падтрымлівае. Аватары падканалаў - Адкрыйце чаргу прайгравання + Адкрыць чаргу прайгравання Не загружаць выявы Высокая якасць Аб канале @@ -786,7 +785,7 @@ Банеры Плэйлісты - %1$s: %2$s - Перамясціць панэль укладак ўніз + Перамясціць панэль укладак уніз Няма жывых трансляцый Выберыце якасць выяў і ці трэба спампоўваць выявы ўвогуле, каб паменшыць выкарыстанне даных і памяці. Змены ачышчаюць кэш выяў як у памяці, так і на дыску - %s Прайграць @@ -812,7 +811,7 @@ NewPipe можа аўтаматычна правяраць наяўнасць абнаўленняў і паведаміць вам, калі яны будуць даступны. \nУключыць гэту функцыю? Налады ў імпартаваным экспарце выкарыстоўваюць уразлівы фармат, які састарэў з версіі NewPipe 0.27.0. Пераканайцеся, што імпартаваны экспарт атрыманы з надзейнай крыніцы, і ў будучыні пераважней выкарыстоўваць толькі экспарт, атрыманы з NewPipe 0.27.0 ці навей. Падтрымка імпарту налад у гэтым уразлівым фармаце хутка будзе цалкам выдаленая, і тады старыя версіі NewPipe больш не змогуць імпартаваць наладкі з экспарту з новых версій. Не - Рэзервовае капіраванне і аднаўленне + Рэзервовае капіяванне і аднаўленне Скінуць налады Скінуць усе налады на іх прадвызначаныя значэнні Пры скіданні ўсіх налад будуць адхілены ўсе вашы змены налад і праграма перазапусціцца. \n \nСапраўды хочаце працягнуць? diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index c91d00327..c9b752d05 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -192,7 +192,7 @@ © %1$s от %2$s под лиценза %3$s Съдействайте За всичко, което се сетите: превод, промени по дизайна, изчистване на кода или много сериозни промени по кода – помощта е винаги добре дошла. Колкото повече развитие, толкова по-добре! - Направете дарение + Дарение NewPipe се разработва от доброволци, които отделят от своето време, за да предоставят най-доброто потребителско изживяване. Включете се в разработката като почерпите разработчиците с една чашка кафе, които да изпият, докато правят NewPipe още по-добро приложение. Дари Уебсайт @@ -203,7 +203,7 @@ Прочетете нашата политика за поверителност Лицензът на NewPipe Липсва стрийм плейър (можете да изтеглите VLC, за да пуснете стрийма). - Покажи съвет при натискане на фона или изскачащия бутон във видеоклипа „Подробности:“ + Покажи съвет при натискане на фона или изскачащия бутон във видеоклипа \"Подробности:“ Изтрива историята на възпроизвежданите стриймове и позицията на възпроизвеждането Не са намерени видео стриймове Не са намерени аудио стриймове @@ -519,7 +519,7 @@ Полезно при превключване към мобилни данни, въпреки че някои изтегляния не поддържат възобновяване и ще започнат отначало Срив на приложението Цветът на известието да се избира според главния цвят в миниатюрата на видеото (може да не работи на всички устройства) - Използване на ограничения режим на YouTube + Включване на \"Ограничен режим“ в YouTube YouTube предлага „ограничен режим“, чрез който можете да филтрирате потенциално съдържание за възрастни Това видео е с възрастова граница. \n @@ -558,7 +558,7 @@ Покажи индикатори за позиция на възпроизвеждане в списъци Редактирайте всяко действие за известяване по-долу, като щракнете върху него. Първите три действия (възпроизвеждане/пауза, предишно и следващо) се задават от системата и не могат да бъдат конфигурирани. Изберете жест за дясната половина на екрана на плейъра - Действие с жест на дясно + Действие с жест надясно Стартирайте основния плейър на цял екран Известия за нови видеоклипове в абонаментите Известявайте за нови видеоклипове в абонаментите diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index 561be3df5..9fbc05566 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -728,4 +728,11 @@ Pista d\'àudio No Cap emissió + Notifica sobre les noves retransmissions de les subscripcions + Noves notificacions de retransmissions + Les llistes de reproducció que estan en gris ja contenen aquest element. + Desestableix la miniatura permanent + Duplicat afegit/s %d vegada/es + El túnel multimèdia s\'ha desactivat de manera predeterminada al dispositiu perquè se sap que el vostre model de dispositiu no ho permet. + Semiton diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index c9d2e1e94..f2f8da16c 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -1,6 +1,6 @@ - Publikováno na %1$s + Publikováno %1$s Nenalezen žádný přehrávač. Nainstalovat VLC? Instalovat Zrušit @@ -785,7 +785,7 @@ \? Odběratelé Které karty mají být zobrazeny na stránkách kanálů - Sdílet URL seznamu + Sdílet seznam adres Sdílet s názvy %1$s \n%2$s diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index a7c3f044d..f2d3b5698 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -63,7 +63,7 @@ Entschuldigung, etwas ist schiefgelaufen. Dein Kommentar (auf englisch): Live - Tippe auf die Lupe, um zu beginnen. + Tippe auf die Lupe, um zu suchen. Downloads Downloads Fehlerbericht @@ -425,7 +425,7 @@ Niemand schaut zu %s Zuschauer - %s Zuschauende + %s Zuschauer Niemand hört zu diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index f4f375035..f7563fa04 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -451,7 +451,7 @@ %s kuulajat Teavitused video räsimise edenemise kohta - Võta kasutusele YouTube\'i „Piiratud režiim“\\ + Võta kasutusele YouTube\'i „Piiratud režiim“ Faili asukoht on muutunud või on ta kustutatud Taasesituste asukohad on kustutatud Kas kustutame kõik taasesituste asukohad\? @@ -642,7 +642,7 @@ Kontrolli uuendusi Kontrolli uuendusi käsitsi Uued andmevoo kirjed - Näita „Jooksuta meediamängija kokku“ nupukest\\ + Näita „Jooksuta meediamängija kokku“ nupukest Näitab valikut meediamängija kokkujooksutamiseks NewPipe\'i töös tekkis viga, sellest teavitamiseks toksa Jooksuta meediamängija kokku diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 9c8a36557..63d6fb263 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -178,7 +178,7 @@ Détails Paramètres audios Afficher l\'astuce « Maintenir pour ajouter à la file » - Affiche l’astuce lors de l’appui des boutons « Arrière-plan » ou « Flottant » sur la page de détails d’une vidéo + Affiche l’astuce lors de l’appui des boutons « Arrière-plan » ou « Flottant » sur la page de détails d’une vidéo [Inconnu] Récupération depuis l’erreur du lecteur Kiosque @@ -534,7 +534,7 @@ Créé par %s Les textes originaux des services vont être visibles dans les items Afficher la date originelle sur les items - Activer le « Mode restreint » de YouTube + Activer le « Mode restreint » de YouTube Afficher uniquement les abonnements non groupés Page des listes de lecture Aucune liste de lecture encore enregistrée @@ -671,7 +671,7 @@ Vérifier les mises à jour Nouveaux éléments du flux Faire planter le lecteur - Afficher « Faire planter le lecteur » + Afficher « Faire planter le lecteur » Montrer une option de plantage lors de l\'utilisation du lecteur Notification de rapport d\'erreur Notifications pour signaler les erreurs @@ -841,4 +841,4 @@ Pas assez d\'espace disponible sur l\'appareil Les paramètres de l\'export en cours d\'importation utilisent un format vulnérable qui a été déprécié depuis NewPipe 0.27.0. Assurez-vous que l\'export en cours d\'importation provient d\'une source fiable. Privilégiez les exports obtenues à partir de NewPipe 0.27.0 ou des versions plus récentes à l\'avenir. Le support pour l\'importation des paramètres dans ce format vulnérable sera bientôt complètement supprimé et les anciennes versions de NewPipe ne pourront plus importer les paramètres des exports des nouvelles versions. secondaire - \ No newline at end of file + diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index def09a450..47eea5ee4 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -851,4 +851,5 @@ \nלהמשיך? אין מספיק מקום פנוי במכשיר ההגדרות בייצוא המיובא משתמשות בתסדיר פגיע שהוצא משימוש מאז NewPipe 0.27.0. יש לוודא שהייצוא המיובא הוא ממקור מהימן, ועדיף להשתמש רק בייצוא שהושג מ־NewPipe 0.27.0 ומעלה בעתיד. תמיכה בייבוא הגדרות בתסדיר פגיע זה תוסר בקרוב לחלוטין, ואז גרסאות ישנות של NewPipe לא יוכלו לייבא עוד הגדרות של ייצוא מגרסאות חדשות. + משני diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 4640629a4..086d200d5 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -1,7 +1,7 @@ %1$s पे प्रकाशित हुआ - स्ट्रीमिंग के लिए प्लेयर नहीं मिला। क्या आप वीएलसी इंस्टॉल करना चाहेंगे\? + स्ट्रीमिंग के लिए प्लेयर नहीं मिला। क्या आप VLC इंस्टॉल करना चाहेंगे? इंस्टॉल करें ब्राउज़र में खोलें पॉपअप मोड में खोलें @@ -183,7 +183,7 @@ कतार में जोड़ने के लिए दबाकर रखें बैकग्राउंड में चलाना शुरू करें पॉपअप में चलाना शुरू करें - स्ट्रीमिंग करने के लिए प्लेयर नहीं मिला (आप इसे चलाने के लिए वीएलसी प्लेयर इंस्टॉल कर सकते हैं)। + स्ट्रीमिंग करने के लिए प्लेयर नहीं मिला (आप इसे चलाने के लिए VLC प्लेयर इंस्टॉल कर सकते हैं)। स्ट्रीम फाइल डाउनलोड करें जानकारी दिखाएं बुकमार्क की गई प्लेलिस्टें diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 582421659..3c09a8aca 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -424,8 +424,8 @@ Želiš li izbrisati ovu grupu\? Nova Uvijek aktualiziraj - Uključi brzi način - Isključi brzi način + Uključi brzi modus + Isključi brzi modus Memorija uređaja je popunjena Najomiljeniji Pritisni „Gotovo” kad je riješeno @@ -639,7 +639,7 @@ Mapa za preuzimanje još nije postavljena, odaberi standardnu mapu za preuzimanje Komentari su isključeni Označi kao pogledano - Način rada brzog feeda ne pruža više informacija o ovome. + Brzi modus feeda ne pruža više informacija o ovome. Interno Privatnost Sada možeš odabrati tekst u opisu. Napomena: stranica će možda treperiti i možda nećeš moći kliknuti poveznice u načinu rada za odabir teksta. @@ -832,4 +832,7 @@ Obnavljanje svih postavki odbacit će sve tvoje postavljene postavke i aplikacija će se ponovo pokrenuti. \n \nStvarno želiš nastaviti? + Uvijek koristi ExoPlayer postavku zaobilaženja videa za izlaznu površinu + Kartice za dohvaćanje prilikom aktualiziranja feeda. Ova opcija nema učinka ako se kanal aktualizira pomoću brzog modusa. + sekundarno diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 216e6d733..90da929bf 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -324,7 +324,7 @@ Alkalmazásfrissítés értesítése Fájl törölve Frissítések - Tipp megjelenítése a háttér vagy a felugró gomb megnyomásakor a videó „Részletek:\\” lehetőségnél + Tipp megjelenítése a háttér vagy a felugró gomb megnyomásakor a videó „Részletek:” lehetőségnél Automatikus lejátszás Adatok törlése Lejátszási pozíciók megjelenítése a listákban @@ -534,7 +534,7 @@ Értesítések a videók ujjlenyomatkészítési folyamatához Videó ujjlenyomat-készítési értesítése A YouTube biztosít egy „Korlátozott módot”, amely elrejti a lehetséges felnőtteknek szóló tartalmat - A YouTube „Korlátozott mód\\” bekapcsolása + A YouTube „Korlátozott mód” bekapcsolása A példány már létezik A példány érvényesítése nem sikerült Adja meg a példány webcímét @@ -658,7 +658,7 @@ A szolgáltatásokból származó eredeti szövegek láthatók lesznek a közvetítési elemeken Lejátszó összeomlasztása Képjelölők megjelenítése - A „lejátszó összeomlasztása\\” lehetőség megjelenítése + A „Lejátszó összeomlasztása” lehetőség megjelenítése Megjeleníti az összeomlasztási lehetőséget a lejátszó használatakor Hangmagasság megtartása (torzítást okozhat) Frissítések keresése diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 5120a20de..fa7e82be7 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -138,7 +138,7 @@ Melanjutkan akhir dari antrean pemutaran (tak berulang) dengan menambahkan video terkait Simpan daftar video yang telah ditonton Tip \"Tahan untuk menambahkan\" - Tampilkan tip ketika menekan tombol latar belakang atau popup di dalam video \"Detail:\\ + Tampilkan tip ketika menekan tombol latar belakang atau popup di dalam video \"Detail:\" Lokasi Konten Pemutar Perilaku @@ -508,7 +508,7 @@ \nJadi pilihlah yang sesuai yang Anda inginkan: kecepatan atau kelengkapan informasi. Teks asli dari layanan akan ditampilkan di dalam video Tampilkan waktu yang lalu sebenarnya pada item - Aktifkan \"Mode Terbatas\\ + Aktifkan \"Mode Terbatas\" Oleh %s Dibuat oleh %s Thumbnail avatar channel diff --git a/app/src/main/res/values-is/strings.xml b/app/src/main/res/values-is/strings.xml index 148181861..34939c478 100644 --- a/app/src/main/res/values-is/strings.xml +++ b/app/src/main/res/values-is/strings.xml @@ -607,7 +607,7 @@ Spilunarstöður í listum Sýna spilunarstöður í listum Sýna ábendinguna „Haltu niðri til að bæta við spilunarröð“ - Sýna ábendingu þegar ýtt er á bakgrunninn eða sprettihnappinn á myndskeiðinu í „Nánar:\\ + Sýna ábendingu þegar ýtt er á bakgrunninn eða sprettihnappinn á myndskeiðinu í „Nánar:\" Óþekkt slóð. Opna með öðru forriti\? Veldu uppáhalds PeerTube tilvik þín Þú mátt finna tilviki á %s @@ -647,7 +647,7 @@ Slökktu á margmiðlunargöngum (media tunneling) ef vart verður við svartan skjá eða hökt við spilun myndskeiða. Sýna myndvísa Sýna Picasso litaða borða ofan á myndum sem gefa til kynna uppruna þeirra: rauðan fyrir netið, bláan fyrir disk og grænan fyrir minni - Sýna „Láta spilara hrynja\\ + Sýna „Láta spilara hrynja\" Sýna valkost til að hrynja spilara Hrynja forrit Búа til villutilkynningu diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml index 0da6cdd09..23ab6e013 100644 --- a/app/src/main/res/values-pa/strings.xml +++ b/app/src/main/res/values-pa/strings.xml @@ -1,7 +1,7 @@ ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਵੱਡਦਰਸ਼ੀ ਸ਼ੀਸ਼ੇ \'ਤੇ ਟੈਪ ਕਰੋ। - %1$s ਨੂੰ ਪ੍ਰਕਾਸ਼ਿਤ ਕੀਤੀ ਗਈ + %1$s ਨੂੰ ਪ੍ਰਕਾਸ਼ਿਤ ਹੋਇਆ ਸਟ੍ਰੀਮਿੰਗ ਲਈ ਪਲੇਅਰ ਨਹੀਂ ਮਿਲਿਆ। ਕੀ ਤੁਸੀਂ VLC ਸਥਾਪਤ ਕਰਨਾ ਚਾਹੋਗੇ? ਸਟ੍ਰੀਮਿੰਗ ਲਈ ਪਲੇਅਰ ਨਹੀਂ ਮਿਲਿਆ (ਤੁਸੀਂ ਇਸਨੂੰ ਚਲਾਉਣ ਲਈ VLC ਪਲੇਅਰ ਇੰਸਟਾਲ ਕਰ ਸਕਦੇ ਹੋ)। ਇੰਸਟਾਲ ਕਰੋ @@ -15,9 +15,9 @@ ਸੈਟਿੰਗਾਂ ਕੀ ਤੁਹਾਡਾ ਮਤਲਬ ਸੀ \"%1$s\"\? ਦੇ ਨਾਲ ਸਾਂਝਾ ਕਰੋ - ਬਾਹਰੀ ਵੀਡੀਓ ਪਲੇਅਰ ਵਰਤੋ + ਬਾਹਰੀ ਵੀਡੀਓ ਪਲੇਅਰ ਦੀ ਵਰਤੋਂ ਕਰੋ ਕੁਝ ਰੈਜ਼ੋਲਿਊਸ਼ਨਾਂ \'ਤੇ ਆਵਾਜ਼ ਹਟ ਸਕਦੀ ਹੈ - ਬਾਹਰੀ ਆਡੀਓ ਪਲੇਅਰ ਵਰਤੋ + ਬਾਹਰੀ ਆਡੀਓ ਪਲੇਅਰ ਦੀ ਵਰਤੋਂ ਕਰੋ ਸਬਸਕ੍ਰਾਈਬ ਕਰੋ ਸਬਸਕ੍ਰਾਈਬ ਹੈ ਚੈਨਲ ਅਨ-ਸਬਸਕ੍ਰਾਈਬ ਹੋਇਆ @@ -27,7 +27,7 @@ ਸਬਸਕ੍ਰਿਪਸ਼ਨਾਂ ਬੁੱਕਮਾਰਕ ਕੀਤੀਆਂ ਪਲੇਲਿਸਟਾਂ ਨਵਾਂ ਕੀ ਹੈ - ਬੈਕਗ੍ਰਾਊਂਡ ਆਡੀਓ + ਬੈਕਗ੍ਰਾਊਂਡ ਪੌਪ-ਅਪ ਵਿੱਚ ਸ਼ਾਮਿਲ ਕਰੋ ਵੀਡੀਓ ਲਈ ਡਾਊਨਲੋਡ ਫ਼ੋਲਡਰ @@ -52,7 +52,7 @@ ਗੂੜ੍ਹਾ ਕਾਲ਼ਾ ਪੌਪ-ਅਪ ਦਾ ਆਕਾਰ ਅਤੇ ਸਥਿਤੀ ਯਾਦ ਰੱਖੋ - ਪੌਪ-ਅਪ ਦਾ ਆਖਰੀ ਅਕਾਰ ਅਤੇ ਸਥਿਤੀ ਯਾਦ ਰੱਖੋ + ਪੌਪ-ਅਪ ਦਾ ਆਖਰੀ ਆਕਾਰ ਅਤੇ ਸਥਿਤੀ ਯਾਦ ਰੱਖੋ ਤੇਜ਼ ਤੇ ਅਣਸਟੀਕ ਭਾਲ ਦੀ ਵਰਤੋਂ ਕਰੋ ਅਣਸਟੀਕ ਭਾਲ ਨਾਲ ਪਲੇਅਰ ਘੱਟ ਸਟੀਕਤਾ ਦੇ ਪਰ ਅਧਿਕ ਤੇਜ਼ੀ ਨਾਲ ਵੀਡੀਓ ਸਥਿੱਤੀਆਂ ਦੀ ਤਲਾਸ਼ ਕਰ ਸਕਦਾ ਹੈ । ਇਸ ਨਾਲ ਅੱਗੇ-ਪਿੱਛੇ 5, 15 ਜਾਂ 25 ਸਕਿੰਟ ਲਿਜਾਣਾ ਕੰਮ ਨਹੀਂ ਕਰਦਾ ਹੈ ਚਿੱਤਰ ਕੈਸ਼ ਮਿਟਾਇਆ ਗਿਆ @@ -101,8 +101,8 @@ ਨਿਊਪਾਈਪ ਨੋਟੀਫਿਕੇਸ਼ਨ ਨਿਊਪਾਈਪ ਦੇ ਪਲੇਅਰ ਦੇ ਲਈ ਨੋਟੀਫਿਕੇਸ਼ਨ [ਅਣਜਾਣ] - ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚਲਾਓ - ਪੌਪ-ਅਪ ਵਿੱਚ ਚਲਾਓ + ਬੈਕਗ੍ਰਾਊਂਡ ਮੋਡ ਵਿੱਚ ਚਲਾਓ + ਪੌਪ-ਅਪ ਮੋਡ ਵਿੱਚ ਚਲਾਓ ਮੇਨ ਤੇ ਚਲਾਓ ਡਾਟਾਬੇਸ ਆਯਾਤ ਕਰੋ ਡਾਟਾਬੇਸ ਨਿਰਯਾਤ ਕਰੋ @@ -316,7 +316,7 @@ ਕੋਈ ਸੀਮਾ ਨਹੀਂ ਮੋਬਾਈਲ ਡਾਟਾ ਦੀ ਵਰਤੋਂ ਕਰਦੇ ਸਮੇਂ ਰੈਜ਼ੋਲਿਊਸ਼ਨ ਨੂੰ ਸੀਮਿਤ ਕਰੋ ਐਪ ਬਦਲਦੇ ਸਮੇਂ ਉਸਨੂੰ ਮਿਨੀਮਾਈਜ਼ ਕਰੋ - ਮੇਨ ਵੀਡੀਓ ਪਲੇਅਰ ਤੋਂ ਦੂਜੇ ਐਪ \'ਤੇ ਜਾਣ ਵੇਲ਼ੇ ਕਾਰਵਾਈ — %s + ਮੇਨ ਵੀਡੀਓ ਪਲੇਅਰ ਤੋਂ ਦੂਜੇ ਐਪ \'ਤੇ ਜਾਣ ਵੇਲੇ ਕਾਰਵਾਈ — %s ਕੋਈ ਨਹੀਂ ਬੈਕਗ੍ਰਾਊਂਡ ਪਲੇਅਰ ਵਿੱਚ ਬਦਲੋ ਪੌਪ-ਅਪ ਪਲੇਅਰ ਵਿੱਚ ਬਦਲੋ @@ -466,7 +466,7 @@ ਤੁਹਾਡੇ ਡਿਵਾਈਸ ਦੀ ਕੋਈ ਵੀ ਐਪ ਇਸ ਨੂੰ ਖੋਲ੍ਹ ਨਹੀਂ ਸਕਦੀ ਚੈਪਟਰ ਹਾਲੀਆ - ਥੰਮਨੇਲ ਨੂੰ ਤਾਲਾਬੱਧ ਸਕਰੀਨ ਦੇ ਪਿਛੋਕੜ ਅਤੇ ਨੋਟੀਫਿਕੇਸ਼ਨ ਦੋਵਾਂ ਲਈ ਵਰਤੋ + ਥੰਮਨੇਲ ਨੂੰ ਲਾਕ ਸਕਰੀਨ ਦੇ ਬੈਕਗ੍ਰਾਊਂਡ ਅਤੇ ਨੋਟੀਫਿਕੇਸ਼ਨ ਦੋਵਾਂ ਲਈ ਵਰਤੋ ਥੰਮਨੇਲ ਵਿਖਾਓ ਪਲੇਲਿਸਟ ਪੰਨਾ %s ਦੁਆਰਾ diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index e0b58da6a..cde34a2a6 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -174,7 +174,7 @@ Top 50 Novos e tendências Mostrar dica \"Segure para pôr na fila\" - Mostra dica ao tocar no botão segundo plano ou Popup em \"Detalhes:\\ do vídeo + Mostra dica ao tocar no botão segundo plano ou popup em \"Detalhes:\" do vídeo Reproduzir tudo Não é possível reproduzir este vídeo Ocorreu um erro irrecuperável na reprodução @@ -528,7 +528,7 @@ Remover assistidos Textos originais dos serviços serão visíveis nos itens de transmissão Mostrar tempo original nos itens - Ativar o \"Modo Restrito\\ do YouTube + Ativar o \"Modo Restrito\" do YouTube Por %s Criado por %s Foto de perfil do canal diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 9a6d6d405..340552371 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -25,7 +25,7 @@ Formato padrão de áudio Descarregar Mostrar vídeos \'Seguintes\' e \'Semelhantes\' - URL não suportado + URL não suportada Idioma padrão para conteúdo Vídeo e áudio Reproduzir vídeo, duração: @@ -281,7 +281,7 @@ Limpar histórico de visualizações Continuar (sem repetição) a fila de reprodução anexando um vídeo relacionado Mostrar dica \"Toque longo para colocar na fila\" - Mostrar dica ao premir em segundo plano ou no botão \"Detalhes\" da janela popup:\\ + Mostrar dica ao premir em segundo plano ou no botão \"Detalhes\" da janela popup: Canais Listas de reprodução Faixas @@ -528,7 +528,7 @@ Remover visualizados Os textos originais dos serviços serão visíveis nos itens do vídeo Mostrar antiguidade nos itens - Ativar \"Modo restrito\\ do YouTube + Ativar \"Modo restrito\" do YouTube Por %s Criado por %s Miniatura do avatar do canal @@ -551,7 +551,7 @@ Nunca A carregar A fila de reprodução atual será substituída - URL não reconhecido. Abrir com outra aplicação\? + URL não reconhecida. Abrir com outra aplicação? Colocar na fila automaticamente Baralhar Apenas em Wi-Fi diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 71dcdaea4..f04fef82f 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -190,7 +190,7 @@ Вы подписаны Подписка отменена Показать подсказку «Зажмите, чтобы добавить» - Показывать подсказку при нажатии на фон или всплывающую кнопку в видео \"Подробнее:\\ + Показывать подсказку при нажатии \"В фоне\" или на всплывающую кнопку \"Подробнее:\" в видео [Неизвестно] Восстановление после ошибки плеера Зажмите, чтобы добавить в очередь @@ -535,7 +535,7 @@ Удалить просмотренные видео\? Отображать сообщённое сервисом время с момента публикации Исходное время публикации - Включите на YouTube \"Ограниченный режим\\ + Включить \"Ограниченный режим\" YouTube От %s Создано %s Миниатюра значка канала @@ -690,7 +690,7 @@ Уведомлять Вы подписались на канал Переключить все - Шоу \"Разбей игрока\\ + Показывать \"Сбой плеера\" Показать функцию вызова сбоя при работе плеера Вызвать сбой плеера Уведомление отчёта об ошибке @@ -720,7 +720,7 @@ Нет аудиопотоков, доступных внешним плеерам Выберите качество для внешних плееров Неизвестное качество - Размер предварительной загрузки + Размер интервала загрузки при воспроизведении Ответы на частые вопросы Если у вас возникли проблемы с использованием приложения, обязательно ознакомьтесь с ответами на распространённые вопросы! Посмотреть на веб-сайте diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index c85d17220..5fa064124 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -91,7 +91,7 @@ Återuppta uppspelning Fortsätt uppspelning efter avbrott (t.ex. telefonsamtal) Visa \"Håll för att köa\"-tips - Visa tips när bakgrunds- eller popup-knappen trycks på sidan för video \"Detaljer:\\ + Visa tips när bakgrunds eller popup-knappen trycks på sidan för video \"Detaljer:\" Spelare Beteende Historik och cacheminne diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 2d9c282b5..8e3bf19ef 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -157,7 +157,7 @@ Geçmiş Bu ögeyi arama geçmişinden silmek istiyor musunuz\? \"Basılı tutarak kuyruğa ekle\" ipucunu göster - Şurada arka plan ya da açılır pencere düğmesine basıldığında ipucu göster: Video \"Ayrıntılar:\\ + Video \"Ayrıntılar:\" sayfasında arka plan ya da açılır pencere düğmesine basıldığında ipucu göster Tümünü Oynat [Bilinmeyen] Bu akış oynatılamadı @@ -517,7 +517,7 @@ İzleneni kaldır Akış ögelerinde hizmetlerden alınan özgün metinler görünecektir Ögelerde özgün \'… önce\'yi göster - Aç: YouTube \"Kısıtlı Kip\\ + YouTube\'un \"Kısıtlı Kip\"ini aç %s tarafından %s tarafından oluşturuldu Kanalın avatar küçük resmi @@ -658,7 +658,7 @@ Hata raporlama bildirimi NewPipe hatayla karşılaştı, bildirmek için dokun Hata oluştu, bildirime bakın - Göster: \"Oynatıcıyı çöktür\\ + \"Oynatıcıyı çöktür\"ü göster Hata bildirimi oluştur Hata balonu göster Bu eyleme uygun dosya yönetici yok. diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 22d9eb478..1ed9625e8 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -170,7 +170,7 @@ Показати інформацію Закладки відтворення Додати до - Показувати підказку під час натискання фонової або спливної кнопки у відео \"Деталі:\\ + Показувати підказку під час натискання фонової або спливної кнопки у відео \"Деталі:\" Сталася невиправна помилка програвача Зовнішні програвачі не підтримують такі види посилань Що:\\nЗапит:\\nМова вмісту:\\nКраїна вмісту:\\nМова застосунку:\\nСлужба:\\nЧас GMT:\\nПакунок:\\nВерсія:\\nВерсія ОС: @@ -529,7 +529,7 @@ \nЩоб побачити його ввімкніть «%1$s» в налаштуваннях. Ескіз аватара каналу Оригінальні тексти сервісів будуть видимі в потокових елементах - Увімкніть \"Обмежений режим\" YouTube + Увімкнути \"Обмежений режим\" YouTube Результати для: %s Створено %s Показати лише незгруповані підписки @@ -672,7 +672,7 @@ Перевірка нових версій вручну Перевірка оновлень… Нові записи стрічки - Показати \"Збій програвача\\ + Показати \"Збій програвача\" Показує параметр збою під час використання програвача Збій програвача Сповіщення про звіт про помилку diff --git a/fastlane/metadata/android/ar/changelogs/1003.txt b/fastlane/metadata/android/ar/changelogs/1003.txt index fef3a6cc3..84395a0b2 100644 --- a/fastlane/metadata/android/ar/changelogs/1003.txt +++ b/fastlane/metadata/android/ar/changelogs/1003.txt @@ -1,4 +1,6 @@ -تم إصلاح مشكلة عدم تشغيل YouTube لأي بث. - -يعالج هذا الإصدار فقط الخطأ الأكثر إلحاحًا الذي يمنع تحميل تفاصيل فيديو YouTube. -نحن ندرك وجود مشاكل أخرى، وسنقوم قريباً بإصدار إصدار منفصل لحلها. +هذا إصدار إصلاح عاجل يعمل على إصلاح أخطاء YouTube: +• [يوتيوب] إصلاح عدم تحميل أي معلومات فيديو ، وإصلاح أخطاء HTTP 403 أثناء تشغيل مقاطع الفيديو واستعادة تشغيل بعض مقاطع الفيديو المقيدة بالفئة العمرية +• إصلاح أحجام التسميات التوضيحية التي لا يتم تغييرها +• إصلاح معلومات التنزيل مرتين عند فتح البث +• [Soundcloud] قم بإزالة التدفقات المحمية بإدارة الحقوق الرقمية غير القابلة للتشغيل +• ترجمات محدثة diff --git a/fastlane/metadata/android/cs/changelogs/1002.txt b/fastlane/metadata/android/cs/changelogs/1002.txt index 7035a1112..e77bb552f 100644 --- a/fastlane/metadata/android/cs/changelogs/1002.txt +++ b/fastlane/metadata/android/cs/changelogs/1002.txt @@ -1 +1,4 @@ -Opraveno nepřehrávání jakéhokoli streamu ve službě YouTube +Opraveno nepřehrávání jakéhokoli streamu ve službě YouTube. + +Tato verze řeší pouze nejpalčivější chybu, která brání načtení detailů videa na YouTube. +Jsme si vědomi, že existují i další problémy, a brzy připravíme samostatné vydání, které je vyřeší. diff --git a/fastlane/metadata/android/cs/changelogs/1003.txt b/fastlane/metadata/android/cs/changelogs/1003.txt index 7035a1112..f9c301d33 100644 --- a/fastlane/metadata/android/cs/changelogs/1003.txt +++ b/fastlane/metadata/android/cs/changelogs/1003.txt @@ -1 +1,6 @@ -Opraveno nepřehrávání jakéhokoli streamu ve službě YouTube +Opravná verze, která opravuje chyby YouTube: +- [YouTube] Oprava nenačítání informací o videu, oprava chyb HTTP 403 při přehrávání videí a obnovení přehrávání některých videí s věkovým omezením. +- Oprava nezměněných velikostí titulků +- Oprava dvojího stahování informací při otevření streamu +- [Soundcloud] Odstranění nepřehratelných streamů chráněných DRM +- Aktualizovány překlady diff --git a/fastlane/metadata/android/el/changelogs/1000.txt b/fastlane/metadata/android/el/changelogs/1000.txt new file mode 100644 index 000000000..858bae60b --- /dev/null +++ b/fastlane/metadata/android/el/changelogs/1000.txt @@ -0,0 +1,13 @@ +Βελτιώσεις +• Κάντε κλικ στην περιγραφή της λίστας αναπαραγωγής για να εμφανίζεται περισσότερο / λιγότερο περιεχόμενο +• [PeerTube] Χειριστείτε αυτόματα συνδέσμους παρουσίας «subscribeto.me». +• Ξεκινήστε την αναπαραγωγή μόνο ενός στοιχείου στην οθόνη ιστορικού + +Διορθώσεις +• Διορθώστε την ορατότητα του κουμπιού RSS +• Διορθώστε τα σφάλματα προεπισκόπησης της γραμμής αναζήτησης +• Διορθώστε την εισχώρηση στη λίστα αναπαραγωγής ενός στοιχείου χωρίς μικρογραφίες +• Διορθώστε την έξοδο από το παράθυρο διαλόγου λήψης προτού εμφανιστεί +• Διορθώστε το αναδυόμενο παράθυρο ουράς λίστας σχετικών στοιχείων +• Διορθώστε τη σειρά στο παράθυρο διαλόγου προσθήκης στη λίστα αναπαραγωγής +• Προσαρμόστε τη διάταξη του σελιδοδείκτη της λίστας αναπαραγωγής diff --git a/fastlane/metadata/android/el/changelogs/999.txt b/fastlane/metadata/android/el/changelogs/999.txt new file mode 100644 index 000000000..c0782663d --- /dev/null +++ b/fastlane/metadata/android/el/changelogs/999.txt @@ -0,0 +1 @@ +Αυτή η έκδοση επείγουσας επιδιόρθωσης διορθώνει σφάλματα HTTP 403 στη μέση των βίντεο του YouTube. Νέος • [SoundCloud] Προσθέστε υποστήριξη για διευθύνσεις URL on.soundcloud.com Βελτιωμένο • [Bandcamp] Εμφάνιση πρόσθετων πληροφοριών στο ραδιοφωνικό κιόσκι διορθώσεις • [YouTube] Διόρθωση περιστασιακών σφαλμάτων HTTP 403 στην αρχή ή στη μέση των βίντεο • [YouTube] Εξαγωγή avatar και banner από περισσότερους τύπους κεφαλίδων καναλιού • [Bandcamp] Διορθώστε διάφορα σφάλματα και χρησιμοποιείτε πάντα HTTPS diff --git a/fastlane/metadata/android/fr/changelogs/1003.txt b/fastlane/metadata/android/fr/changelogs/1003.txt index 6b969c81a..13c76e921 100644 --- a/fastlane/metadata/android/fr/changelogs/1003.txt +++ b/fastlane/metadata/android/fr/changelogs/1003.txt @@ -1,6 +1,6 @@ -Il s'agit d'une version de correction qui résout les erreurs de YouTube : -• [YouTube] Correction du non-chargement des informations des vidéos, correction des erreurs HTTP 403 lors de la lecture des vidéos et restauration de la lecture de certaines vidéos restreintes par l'âge -• Correction des tailles de sous-titres qui ne changent pas -• Correction du téléchargement des informations deux fois lors de l'ouverture d'un flux -• [Soundcloud] Suppression des flux protégés par DRM non lisibles +Il s'agit d'une version de correction qui résout les erreurs de YouTube : +• [YouTube] Correction du non-chargement des informations des vidéos, correction des erreurs HTTP 403 lors de la lecture des vidéos et restauration de la lecture de certaines vidéos restreintes par l'âge +• Correction des tailles de sous-titres qui ne changent pas +• Correction du téléchargement des informations deux fois lors de l'ouverture d'un flux +• [Soundcloud] Suppression des flux protégés par DRM non lisibles • Traductions mises à jour diff --git a/fastlane/metadata/android/hi/changelogs/1001.txt b/fastlane/metadata/android/hi/changelogs/1001.txt new file mode 100644 index 000000000..bc92ea2f1 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/1001.txt @@ -0,0 +1,6 @@ +सुधार +• Android 13+ पर हमेशा प्लेयर नोटिफिकेशन प्राथमिकताएँ बदलने की अनुमति दें + +ठीक किया गया +• डेटाबेस/सदस्यता निर्यात करने से पहले से मौजूद फ़ाइल को छोटा नहीं किया जा सकता था, जिससे संभवतः दूषित निर्यात हो सकता था +• टाइमस्टैम्प पर क्लिक करने पर प्लेयर फिर से शुरू होने की समस्या को ठीक किया गया diff --git a/fastlane/metadata/android/hi/changelogs/1002.txt b/fastlane/metadata/android/hi/changelogs/1002.txt index 071ab64e3..d780f47a6 100644 --- a/fastlane/metadata/android/hi/changelogs/1002.txt +++ b/fastlane/metadata/android/hi/changelogs/1002.txt @@ -1 +1,5 @@ -फिक्स्ड YouTube कोई स्ट्रीम नहीं चला रहा है +YouTube द्वारा कोई भी स्ट्रीम न चलाए जाने की समस्या को ठीक किया गया। + +यह रिलीज़ केवल सबसे ज़्यादा दबाव वाली त्रुटि को संबोधित करती है जो YouTube वीडियो विवरण को लोड होने से रोकती है। + +हम जानते हैं कि अन्य समस्याएँ भी हैं, और हम जल्द ही उन्हें हल करने के लिए एक अलग रिलीज़ जारी करेंगे। diff --git a/fastlane/metadata/android/hi/changelogs/1003.txt b/fastlane/metadata/android/hi/changelogs/1003.txt index 071ab64e3..210a2566b 100644 --- a/fastlane/metadata/android/hi/changelogs/1003.txt +++ b/fastlane/metadata/android/hi/changelogs/1003.txt @@ -1 +1,6 @@ -फिक्स्ड YouTube कोई स्ट्रीम नहीं चला रहा है +यह एक हॉटफ़िक्स रिलीज़ है जो YouTube त्रुटियों को ठीक करता है: +• [YouTube] कोई भी वीडियो जानकारी लोड न होने की समस्या को ठीक करें, वीडियो चलाते समय HTTP 403 त्रुटियाँ ठीक करें और कुछ आयु-प्रतिबंधित वीडियो के प्लेबैक को पुनर्स्थापित करें +• कैप्शन का आकार न बदलने की समस्या को ठीक करें +• स्ट्रीम खोलते समय जानकारी दो बार डाउनलोड होने की समस्या को ठीक करें +• [साउंडक्लाउड] न चलाए जा सकने वाले DRM-संरक्षित स्ट्रीम हटाएँ +• अपडेट किए गए अनुवाद diff --git a/fastlane/metadata/android/hi/changelogs/65.txt b/fastlane/metadata/android/hi/changelogs/65.txt index 8570a056a..d2c2b8c71 100644 --- a/fastlane/metadata/android/hi/changelogs/65.txt +++ b/fastlane/metadata/android/hi/changelogs/65.txt @@ -1,26 +1,26 @@ -### Improvements +### सुधार -- Disable burgermenu icon animation #1486 -- undo delete of downloads #1472 -- Download option in share menu #1498 -- Added share option to long tap menu #1454 -- Minimize main player on exit #1354 -- Library version update and database backup fix #1510 -- ExoPlayer 2.8.2 Update #1392 - - Reworked the playback speed control dialog to support different step sizes for faster speed change. - - Added a toggle to fast-forward during silences in playback speed control. This should be helpful for audiobooks and certain music genres, and can bring a true seamless experience (and can break a song with lots of silences =\\). - - Refactored media source resolution to allow passing metadata alongside media internally in the player, rather than doing so manually. Now we have a single source of metadata and is directly available when playback starts. - - Fixed remote playlist metadata not updating when new metadata is available when playlist fragment is opened. - - Various UI fixes: #1383, background player notification controls now always white, easier to shutdown popup player through flinging -- Use new extractor with refactored architecture for multiservice +- बर्गरमेनू आइकन एनीमेशन को अक्षम करें #1486 +- डाउनलोड को पूर्ववत करें #1472 +- शेयर मेनू में डाउनलोड विकल्प #1498 +- लॉन्ग टैप मेनू में शेयर विकल्प जोड़ा गया #1454 +- बाहर निकलने पर मुख्य प्लेयर को छोटा करें #1354 +- लाइब्रेरी संस्करण अपडेट और डेटाबेस बैकअप फिक्स #1510 +- एक्सोप्लेयर 2.8.2 अपडेट #1392 +- तेज गति परिवर्तन के लिए विभिन्न चरण आकारों का समर्थन करने के लिए प्लेबैक गति नियंत्रण संवाद को फिर से तैयार किया गया। +- प्लेबैक गति नियंत्रण में मौन के दौरान तेजी से आगे बढ़ने के लिए एक टॉगल जोड़ा गया। यह ऑडियोबुक और कुछ संगीत शैलियों के लिए मददगार होना चाहिए, और एक सच्चा सहज अनुभव ला सकता है (और बहुत सारे मौन वाले गीत को तोड़ सकता है =\\)। +- मीडिया स्रोत रिज़ॉल्यूशन को फिर से तैयार किया गया ताकि प्लेयर में आंतरिक रूप से मीडिया के साथ मेटाडेटा को पास किया जा सके, बजाय मैन्युअल रूप से ऐसा करने के। अब हमारे पास मेटाडेटा का एक ही स्रोत है और प्लेबैक शुरू होने पर सीधे उपलब्ध है। +- जब प्लेलिस्ट का टुकड़ा खोला जाता है तो नया मेटाडेटा उपलब्ध होने पर रिमोट प्लेलिस्ट मेटाडेटा अपडेट नहीं होता है। +- विभिन्न UI फ़िक्सेस: #1383, बैकग्राउंड प्लेयर नोटिफिकेशन कंट्रोल अब हमेशा सफ़ेद रहता है, फ़्लिंगिंग के ज़रिए पॉपअप प्लेयर को बंद करना आसान है +- मल्टीसर्विस के लिए रीफ़ैक्टर्ड आर्किटेक्चर के साथ नए एक्सट्रैक्टर का उपयोग करें -### Fixes +### फ़िक्सेस -- Fix #1440 Broken Video Info Layout #1491 -- View history fix #1497 - - #1495, by updating the metadata (thumbnail, title and video count) as soon as the user access the playlist. - - #1475, by registering a view in the database when the user starts a video on external player on detail fragment. -- Fix creen timeout in case of popup mode. #1463 (Fixed #640) -- Main video player fix #1509 - - [#1412] Fixed repeat mode causing player NPE when new intent is received while player activity is in background. - - Fixed minimizing player to popup does not destroy player when popup permission is not granted. +- फ़िक्स #1440 टूटी हुई वीडियो जानकारी लेआउट #1491 +- व्यू हिस्ट्री फ़िक्स #1497 +- #1495, जैसे ही उपयोगकर्ता प्लेलिस्ट एक्सेस करता है मेटाडेटा (थंबनेल, शीर्षक और वीडियो काउंट) को अपडेट करके। +- #1475, जब उपयोगकर्ता डिटेल फ़्रैगमेंट पर बाहरी प्लेयर पर वीडियो शुरू करता है तो डेटाबेस में व्यू रजिस्टर करके। +- पॉपअप मोड के मामले में स्क्रीन टाइमआउट को ठीक करें। #1463 (फ़िक्स #640) +- मुख्य वीडियो प्लेयर फ़िक्स #1509 +- [#1412] प्लेयर गतिविधि के बैकग्राउंड में होने पर नया इंटेंट प्राप्त होने पर प्लेयर NPE का कारण बनने वाले रिपीट मोड को ठीक किया गया। +- पॉपअप के लिए प्लेयर को छोटा करने की सुविधा को ठीक किया गया, जब पॉपअप की अनुमति नहीं दी जाती है तो प्लेयर नष्ट नहीं होता है। diff --git a/fastlane/metadata/android/it/changelogs/1002.txt b/fastlane/metadata/android/it/changelogs/1002.txt index 951ffee5e..7028421cb 100644 --- a/fastlane/metadata/android/it/changelogs/1002.txt +++ b/fastlane/metadata/android/it/changelogs/1002.txt @@ -1 +1,4 @@ -Corretto problema di riproduzione di YouTube +Risolto il problema per cui YouTube non riproduceva alcun flusso + +Questa versione risolve solo l'errore più urgente che impedisce il caricamento dei dettagli dei video di YouTube. +Siamo consapevoli che ci sono altri problemi e presto pubblicheremo una versione separata per risolverli. diff --git a/fastlane/metadata/android/it/changelogs/1003.txt b/fastlane/metadata/android/it/changelogs/1003.txt index 951ffee5e..c8fa124b9 100644 --- a/fastlane/metadata/android/it/changelogs/1003.txt +++ b/fastlane/metadata/android/it/changelogs/1003.txt @@ -1 +1,6 @@ -Corretto problema di riproduzione di YouTube +Questa versione corregge gli errori di YouTube: +• [YouTube] Corretto il problema del mancato caricamento delle informazioni video, degli errori HTTP 403 durante la riproduzione dei video e ripristinata la riproduzione di alcuni video con limiti di età +• Corrette le dimensioni delle didascalie che non vengono modificate +• Corretto il download delle informazioni due volte durante l'apertura di un flusso +• [Soundcloud] Rimossi i flussi protetti da DRM non riproducibili +• Traduzioni aggiornate diff --git a/fastlane/metadata/android/pa/changelogs/1001.txt b/fastlane/metadata/android/pa/changelogs/1001.txt new file mode 100644 index 000000000..83f91c82b --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/1001.txt @@ -0,0 +1,6 @@ +ਸੁਧਾਰਿਆ ਗਿਆ +• ਐਂਡਰਾਇਡ 13+ 'ਤੇ ਪਲੇਅਰ ਸੂਚਨਾ ਤਰਜੀਹਾਂ ਨੂੰ ਹਮੇਸ਼ਾ ਬਦਲਣ ਦੀ ਆਗਿਆ ਦਿਓ + +ਠੀਕ ਕੀਤਾ ਗਿਆ +• ਡੇਟਾਬੇਸ/ਸਬਸਕ੍ਰਿਪਸ਼ਨ ਨਿਰਯਾਤ ਕਰਨ ਨਾਲ ਪਹਿਲਾਂ ਤੋਂ ਮੌਜੂਦ ਫਾਈਲ ਨੂੰ ਕੱਟਿਆ ਨਹੀਂ ਜਾਵੇਗਾ, ਜਿਸ ਨਾਲ ਸੰਭਾਵਤ ਤੌਰ 'ਤੇ ਖਰਾਬ ਨਿਰਯਾਤ ਹੋ ਸਕਦਾ ਹੈ +• ਟਾਈਮਸਟੈਂਪ 'ਤੇ ਕਲਿੱਕ ਕਰਨ 'ਤੇ ਪਲੇਅਰ ਨੂੰ ਸ਼ੁਰੂ ਤੋਂ ਮੁੜ ਸ਼ੁਰੂ ਕਰਨ ਨੂੰ ਠੀਕ ਕਰੋ diff --git a/fastlane/metadata/android/pa/changelogs/1002.txt b/fastlane/metadata/android/pa/changelogs/1002.txt index fe62a1330..3cfce7b21 100644 --- a/fastlane/metadata/android/pa/changelogs/1002.txt +++ b/fastlane/metadata/android/pa/changelogs/1002.txt @@ -1 +1,4 @@ -ਸਥਿਰ YouTube ਕੋਈ ਸਟ੍ਰੀਮ ਨਹੀਂ ਚਲਾ ਰਿਹਾ +YouTube ਵੱਲੋਂ ਕੋਈ ਵੀ ਸਟ੍ਰੀਮ ਨਾ ਚਲਾਉਣ ਨੂੰ ਠੀਕ ਕੀਤਾ ਗਿਆ ਹੈ। + +ਇਹ ਰੀਲੀਜ਼ ਸਿਰਫ਼ ਉਸ ਸਭ ਤੋਂ ਵੱਡੀ ਗਲਤੀ ਨੂੰ ਹੱਲ ਕਰਦੀ ਹੈ ਜੋ YouTube ਵੀਡੀਓ ਵੇਰਵਿਆਂ ਨੂੰ ਲੋਡ ਹੋਣ ਤੋਂ ਰੋਕਦੀ ਹੈ। +ਅਸੀਂ ਜਾਣਦੇ ਹਾਂ ਕਿ ਹੋਰ ਸਮੱਸਿਆਵਾਂ ਵੀ ਹਨ, ਅਤੇ ਅਸੀਂ ਜਲਦੀ ਹੀ ਉਨ੍ਹਾਂ ਨੂੰ ਹੱਲ ਕਰਨ ਲਈ ਇੱਕ ਵੱਖਰੀ ਰੀਲੀਜ਼ ਕਰਾਂਗੇ। diff --git a/fastlane/metadata/android/pa/changelogs/1003.txt b/fastlane/metadata/android/pa/changelogs/1003.txt index fe62a1330..0c8a5a1a0 100644 --- a/fastlane/metadata/android/pa/changelogs/1003.txt +++ b/fastlane/metadata/android/pa/changelogs/1003.txt @@ -1 +1,6 @@ -ਸਥਿਰ YouTube ਕੋਈ ਸਟ੍ਰੀਮ ਨਹੀਂ ਚਲਾ ਰਿਹਾ +ਇਹ ਇੱਕ ਹੌਟਫਿਕਸ ਰੀਲੀਜ਼ ਹੈ ਜੋ YouTube ਗਲਤੀਆਂ ਨੂੰ ਠੀਕ ਕਰਦੀ ਹੈ: +• [YouTube] ਵੀਡੀਓ ਚਲਾਉਣ ਦੌਰਾਨ ਕਿਸੇ ਵੀ ਵੀਡੀਓ ਜਾਣਕਾਰੀ ਨੂੰ ਲੋਡ ਨਾ ਹੋਣ ਨੂੰ ਠੀਕ ਕਰੋ, ਵੀਡੀਓ ਚਲਾਉਂਦੇ ਸਮੇਂ HTTP 403 ਗਲਤੀਆਂ ਨੂੰ ਠੀਕ ਕਰੋ ਅਤੇ ਕੁਝ ਉਮਰ-ਪ੍ਰਤੀਬੰਧਿਤ ਵੀਡੀਓਜ਼ ਦੇ ਪਲੇਬੈਕ ਨੂੰ ਬਹਾਲ ਕਰੋ +• ਕੈਪਸ਼ਨ ਆਕਾਰਾਂ ਨੂੰ ਨਾ ਬਦਲਣ ਨੂੰ ਠੀਕ ਕਰੋ +• ਸਟ੍ਰੀਮ ਖੋਲ੍ਹਣ ਵੇਲੇ ਦੋ ਵਾਰ ਡਾਊਨਲੋਡਿੰਗ ਜਾਣਕਾਰੀ ਨੂੰ ਠੀਕ ਕਰੋ +• [Soundcloud] ਨਾ ਚਲਾਏ ਜਾ ਸਕਣ ਵਾਲੇ DRM-ਸੁਰੱਖਿਅਤ ਸਟ੍ਰੀਮਾਂ ਨੂੰ ਹਟਾਓ +• ਅੱਪਡੇਟ ਕੀਤੇ ਅਨੁਵਾਦ diff --git a/fastlane/metadata/android/zh-Hans/changelogs/1000.txt b/fastlane/metadata/android/zh-Hans/changelogs/1000.txt new file mode 100644 index 000000000..69ceb255e --- /dev/null +++ b/fastlane/metadata/android/zh-Hans/changelogs/1000.txt @@ -0,0 +1,13 @@ +改进 +• 使播放列表简介可点击以显示更多或更少的内容 +• [PeerTube] 自动接管 `subscribeto.me` 链接 +• 在历史记录页面中仅开始播放单一项目 + +修复 +• 修复 RSS 按钮的可见度 +• 修复进度预览可能引起的崩溃 +• 修复播放列表中缺少缩略图的项目 +• 修复在下载弹窗出现之前退出的问题 +• 修复相关项目列表排序弹出 +• 修复新增至播放列表的菜单项顺序 +• 调整播放列表书签项目的布局 From 87693a2ad1eda0563d5d0979909826d7a937fc50 Mon Sep 17 00:00:00 2001 From: Miles Krell Date: Sat, 15 Mar 2025 21:44:31 -0400 Subject: [PATCH 048/143] Redirect to per-app language settings on Android 13+ --- .../settings/ContentSettingsFragment.java | 26 +++++++++++++++++++ .../org/schabi/newpipe/util/Localization.java | 6 +++++ app/src/main/res/values/settings_keys.xml | 1 + app/src/main/res/xml/content_settings.xml | 7 +++++ 4 files changed, 40 insertions(+) diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java index ec2bed67a..575d6c733 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java @@ -1,10 +1,15 @@ package org.schabi.newpipe.settings; import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Build; import android.os.Bundle; +import android.provider.Settings; import android.util.Log; import android.widget.Toast; +import androidx.appcompat.app.AppCompatDelegate; import androidx.preference.Preference; import org.schabi.newpipe.DownloaderImpl; @@ -17,6 +22,7 @@ import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.image.PreferredImageQuality; import java.io.IOException; +import java.util.Locale; public class ContentSettingsFragment extends BasePreferenceFragment { private String youtubeRestrictedModeEnabledKey; @@ -37,6 +43,26 @@ public class ContentSettingsFragment extends BasePreferenceFragment { .getPreferredContentCountry(requireContext()); initialLanguage = defaultPreferences.getString(getString(R.string.app_language_key), "en"); + if (Build.VERSION.SDK_INT >= 33) { + requirePreference(R.string.app_language_key).setVisible(false); + final Preference newAppLanguagePref = + requirePreference(R.string.app_language_android_13_and_up_key); + newAppLanguagePref.setSummaryProvider(preference -> { + final Locale customLocale = AppCompatDelegate.getApplicationLocales().get(0); + if (customLocale != null) { + return customLocale.getDisplayName(); + } + return getString(R.string.systems_language); + }); + newAppLanguagePref.setOnPreferenceClickListener(preference -> { + final Intent intent = new Intent(Settings.ACTION_APP_LOCALE_SETTINGS) + .setData(Uri.fromParts("package", requireContext().getPackageName(), null)); + startActivity(intent); + return true; + }); + newAppLanguagePref.setVisible(true); + } + final Preference imageQualityPreference = requirePreference(R.string.image_quality_key); imageQualityPreference.setOnPreferenceChangeListener( (preference, newValue) -> { diff --git a/app/src/main/java/org/schabi/newpipe/util/Localization.java b/app/src/main/java/org/schabi/newpipe/util/Localization.java index 8f8ba596f..acb0dff04 100644 --- a/app/src/main/java/org/schabi/newpipe/util/Localization.java +++ b/app/src/main/java/org/schabi/newpipe/util/Localization.java @@ -17,6 +17,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.PluralsRes; import androidx.annotation.StringRes; +import androidx.appcompat.app.AppCompatDelegate; import androidx.core.math.MathUtils; import androidx.preference.PreferenceManager; @@ -39,6 +40,7 @@ import java.time.format.FormatStyle; import java.util.Arrays; import java.util.List; import java.util.Locale; +import java.util.Objects; import java.util.stream.Collectors; @@ -101,6 +103,10 @@ public final class Localization { } public static Locale getAppLocale(@NonNull final Context context) { + if (Build.VERSION.SDK_INT >= 33) { + final Locale customLocale = AppCompatDelegate.getApplicationLocales().get(0); + return Objects.requireNonNullElseGet(customLocale, Locale::getDefault); + } return getLocaleFromPrefs(context, R.string.app_language_key); } diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index fb68a464d..61125c47f 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -353,6 +353,7 @@ playback_skip_silence_key app_language_key + app_language_android_13_and_up_key feed_update_threshold_key 300 diff --git a/app/src/main/res/xml/content_settings.xml b/app/src/main/res/xml/content_settings.xml index 2cdc6c545..f17783a22 100644 --- a/app/src/main/res/xml/content_settings.xml +++ b/app/src/main/res/xml/content_settings.xml @@ -13,6 +13,13 @@ app:iconSpaceReserved="false" app:useSimpleSummaryProvider="true" /> + + Date: Sat, 15 Mar 2025 22:13:01 -0400 Subject: [PATCH 049/143] Migrate from pre-Android 13 app language pref --- app/src/main/java/org/schabi/newpipe/App.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/app/src/main/java/org/schabi/newpipe/App.java b/app/src/main/java/org/schabi/newpipe/App.java index 8ce161eec..495ef43a5 100644 --- a/app/src/main/java/org/schabi/newpipe/App.java +++ b/app/src/main/java/org/schabi/newpipe/App.java @@ -3,11 +3,14 @@ package org.schabi.newpipe; import android.app.Application; import android.content.Context; import android.content.SharedPreferences; +import android.os.Build; import android.util.Log; import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatDelegate; import androidx.core.app.NotificationChannelCompat; import androidx.core.app.NotificationManagerCompat; +import androidx.core.os.LocaleListCompat; import androidx.preference.PreferenceManager; import com.jakewharton.processphoenix.ProcessPhoenix; @@ -122,6 +125,22 @@ public class App extends Application { configureRxJavaErrorHandler(); YoutubeStreamExtractor.setPoTokenProvider(PoTokenProviderImpl.INSTANCE); + + if (Build.VERSION.SDK_INT >= 33) { + final String appLanguageKey = getString(R.string.app_language_key); + if (prefs.contains(appLanguageKey)) { + // Migrate to Android per-app language settings + final String languageCode = prefs.getString(appLanguageKey, null); + prefs.edit().remove(appLanguageKey).apply(); + try { + AppCompatDelegate.setApplicationLocales( + LocaleListCompat.forLanguageTags(languageCode) + ); + } catch (final RuntimeException e) { + Log.e(TAG, "Error migrating to Android 13+ per-app language settings"); + } + } + } } @Override From da106e2361b9660b25e1a9a81fa5d74d37d826e2 Mon Sep 17 00:00:00 2001 From: Miles Krell Date: Sat, 15 Mar 2025 22:54:17 -0400 Subject: [PATCH 050/143] Don't try to migrate "system" app language --- app/src/main/java/org/schabi/newpipe/App.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/App.java b/app/src/main/java/org/schabi/newpipe/App.java index 495ef43a5..992651141 100644 --- a/app/src/main/java/org/schabi/newpipe/App.java +++ b/app/src/main/java/org/schabi/newpipe/App.java @@ -127,17 +127,20 @@ public class App extends Application { YoutubeStreamExtractor.setPoTokenProvider(PoTokenProviderImpl.INSTANCE); if (Build.VERSION.SDK_INT >= 33) { + final String appLanguageDefaultValue = getString(R.string.default_localization_key); final String appLanguageKey = getString(R.string.app_language_key); - if (prefs.contains(appLanguageKey)) { + final String appLanguageCurrentValue = prefs.getString(appLanguageKey, null); + if (appLanguageCurrentValue != null) { // Migrate to Android per-app language settings - final String languageCode = prefs.getString(appLanguageKey, null); prefs.edit().remove(appLanguageKey).apply(); - try { - AppCompatDelegate.setApplicationLocales( - LocaleListCompat.forLanguageTags(languageCode) - ); - } catch (final RuntimeException e) { - Log.e(TAG, "Error migrating to Android 13+ per-app language settings"); + if (!appLanguageCurrentValue.equals(appLanguageDefaultValue)) { + try { + AppCompatDelegate.setApplicationLocales( + LocaleListCompat.forLanguageTags(appLanguageCurrentValue) + ); + } catch (final RuntimeException e) { + Log.e(TAG, "Error migrating to Android 13+ per-app language settings"); + } } } } From 980a35a70835858206165e825e8f5beddd695f44 Mon Sep 17 00:00:00 2001 From: Miles Krell Date: Sat, 15 Mar 2025 23:00:31 -0400 Subject: [PATCH 051/143] Move migration to separate method --- app/src/main/java/org/schabi/newpipe/App.java | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/App.java b/app/src/main/java/org/schabi/newpipe/App.java index 992651141..d37c8bc27 100644 --- a/app/src/main/java/org/schabi/newpipe/App.java +++ b/app/src/main/java/org/schabi/newpipe/App.java @@ -127,20 +127,24 @@ public class App extends Application { YoutubeStreamExtractor.setPoTokenProvider(PoTokenProviderImpl.INSTANCE); if (Build.VERSION.SDK_INT >= 33) { - final String appLanguageDefaultValue = getString(R.string.default_localization_key); - final String appLanguageKey = getString(R.string.app_language_key); - final String appLanguageCurrentValue = prefs.getString(appLanguageKey, null); - if (appLanguageCurrentValue != null) { - // Migrate to Android per-app language settings - prefs.edit().remove(appLanguageKey).apply(); - if (!appLanguageCurrentValue.equals(appLanguageDefaultValue)) { - try { - AppCompatDelegate.setApplicationLocales( - LocaleListCompat.forLanguageTags(appLanguageCurrentValue) - ); - } catch (final RuntimeException e) { - Log.e(TAG, "Error migrating to Android 13+ per-app language settings"); - } + ensureAppLanguagePreferenceIsMigrated(prefs); + } + } + + private void ensureAppLanguagePreferenceIsMigrated(final SharedPreferences prefs) { + final String appLanguageDefaultValue = getString(R.string.default_localization_key); + final String appLanguageKey = getString(R.string.app_language_key); + final String appLanguageCurrentValue = prefs.getString(appLanguageKey, null); + if (appLanguageCurrentValue != null) { + // Migrate to Android per-app language settings + prefs.edit().remove(appLanguageKey).apply(); + if (!appLanguageCurrentValue.equals(appLanguageDefaultValue)) { + try { + AppCompatDelegate.setApplicationLocales( + LocaleListCompat.forLanguageTags(appLanguageCurrentValue) + ); + } catch (final RuntimeException e) { + Log.e(TAG, "Error migrating to Android 13+ per-app language settings"); } } } From 54bf7f0ced98641e101e539569a9c65f2262e497 Mon Sep 17 00:00:00 2001 From: Harshita Date: Sat, 8 Mar 2025 22:05:28 +0530 Subject: [PATCH 052/143] BF-11894 : Fix the Duplicate menu options in ChannelFragment --- .../newpipe/fragments/list/channel/ChannelFragment.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index d67cd11f1..adaa3bebd 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -232,6 +232,14 @@ public class ChannelFragment extends BaseStateFragment binding.subChannelTitleView.setOnClickListener(openSubChannel); } + @Override + public void onDestroyView() { + super.onDestroyView(); + if (menuProvider != null) { + activity.removeMenuProvider(menuProvider); + } + } + @Override public void onDestroy() { super.onDestroy(); @@ -240,7 +248,6 @@ public class ChannelFragment extends BaseStateFragment } disposables.clear(); binding = null; - activity.removeMenuProvider(menuProvider); menuProvider = null; } From 48b200868a455722690881f739bcd4cb96e52c74 Mon Sep 17 00:00:00 2001 From: Harshita Date: Thu, 13 Mar 2025 00:10:59 +0530 Subject: [PATCH 053/143] BF-11894 : Fix the menu disappearing on performing backGesture --- .../list/channel/ChannelFragment.java | 117 +++++++++--------- 1 file changed, 61 insertions(+), 56 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index adaa3bebd..33532d567 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -123,62 +123,6 @@ public class ChannelFragment extends BaseStateFragment @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); - menuProvider = new MenuProvider() { - @Override - public void onCreateMenu(@NonNull final Menu menu, - @NonNull final MenuInflater inflater) { - inflater.inflate(R.menu.menu_channel, menu); - - if (DEBUG) { - Log.d(TAG, "onCreateOptionsMenu() called with: " - + "menu = [" + menu + "], inflater = [" + inflater + "]"); - } - - } - - @Override - public void onPrepareMenu(@NonNull final Menu menu) { - menuRssButton = menu.findItem(R.id.menu_item_rss); - menuNotifyButton = menu.findItem(R.id.menu_item_notify); - updateRssButton(); - updateNotifyButton(channelSubscription); - } - - @Override - public boolean onMenuItemSelected(@NonNull final MenuItem item) { - switch (item.getItemId()) { - case R.id.menu_item_notify: - final boolean value = !item.isChecked(); - item.setEnabled(false); - setNotify(value); - break; - case R.id.action_settings: - NavigationHelper.openSettings(requireContext()); - break; - case R.id.menu_item_rss: - if (currentInfo != null) { - ShareUtils.openUrlInApp(requireContext(), currentInfo.getFeedUrl()); - } - break; - case R.id.menu_item_openInBrowser: - if (currentInfo != null) { - ShareUtils.openUrlInBrowser(requireContext(), - currentInfo.getOriginalUrl()); - } - break; - case R.id.menu_item_share: - if (currentInfo != null) { - ShareUtils.shareText(requireContext(), name, - currentInfo.getOriginalUrl(), currentInfo.getAvatars()); - } - break; - default: - return false; - } - return true; - } - }; - activity.addMenuProvider(menuProvider); } @Override @@ -195,6 +139,67 @@ public class ChannelFragment extends BaseStateFragment return binding.getRoot(); } + @Override + public void onViewCreated(@NonNull final View rootView, final Bundle savedInstanceState) { + super.onViewCreated(rootView, savedInstanceState); + menuProvider = new MenuProvider() { + @Override + public void onCreateMenu(@NonNull final Menu menu, + @NonNull final MenuInflater inflater) { + inflater.inflate(R.menu.menu_channel, menu); + + if (DEBUG) { + Log.d(TAG, "onCreateOptionsMenu() called with: " + + "menu = [" + menu + "], inflater = [" + inflater + "]"); + } + + } + + @Override + public void onPrepareMenu(@NonNull final Menu menu) { + menuRssButton = menu.findItem(R.id.menu_item_rss); + menuNotifyButton = menu.findItem(R.id.menu_item_notify); + updateRssButton(); + updateNotifyButton(channelSubscription); + } + + @Override + public boolean onMenuItemSelected(@NonNull final MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_item_notify: + final boolean value = !item.isChecked(); + item.setEnabled(false); + setNotify(value); + break; + case R.id.action_settings: + NavigationHelper.openSettings(requireContext()); + break; + case R.id.menu_item_rss: + if (currentInfo != null) { + ShareUtils.openUrlInApp(requireContext(), currentInfo.getFeedUrl()); + } + break; + case R.id.menu_item_openInBrowser: + if (currentInfo != null) { + ShareUtils.openUrlInBrowser(requireContext(), + currentInfo.getOriginalUrl()); + } + break; + case R.id.menu_item_share: + if (currentInfo != null) { + ShareUtils.shareText(requireContext(), name, + currentInfo.getOriginalUrl(), currentInfo.getAvatars()); + } + break; + default: + return false; + } + return true; + } + }; + activity.addMenuProvider(menuProvider); + } + @Override // called from onViewCreated in BaseFragment.onViewCreated protected void initViews(final View rootView, final Bundle savedInstanceState) { super.initViews(rootView, savedInstanceState); From f289bea6b3adbb6bfa1f5b3defe4bb471a92b59a Mon Sep 17 00:00:00 2001 From: Siddhesh Naik Date: Sun, 16 Mar 2025 12:44:01 +0530 Subject: [PATCH 054/143] Fix sonar warning --- .../newpipe/fragments/list/channel/ChannelFragment.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index 33532d567..764f03e4b 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -120,11 +120,6 @@ public class ChannelFragment extends BaseStateFragment // LifeCycle //////////////////////////////////////////////////////////////////////////*/ - @Override - public void onCreate(final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - } - @Override public void onAttach(@NonNull final Context context) { super.onAttach(context); From a0b76c3385c0629f37745d1791a23f5337bf2dab Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sun, 16 Mar 2025 21:39:55 +0100 Subject: [PATCH 055/143] Update NewPipe Extractor and add new proguard rules New rules are required since Rhino and Rhino Engine 1.8.0 --- app/build.gradle | 2 +- app/proguard-rules.pro | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index d03bd64e3..f9b2e9bd9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -208,7 +208,7 @@ dependencies { implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751' // WORKAROUND: if you get errors with the NewPipeExtractor dependency, replace `v0.24.3` with // the corresponding commit hash, since JitPack is sometimes buggy - implementation 'com.github.TeamNewPipe:NewPipeExtractor:9f83b385a' + implementation 'com.github.TeamNewPipe:NewPipeExtractor:0b99100db' implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0' /** Checkstyle **/ diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 215df0da5..0cdffbe2e 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -5,10 +5,17 @@ ## Rules for NewPipeExtractor -keep class org.schabi.newpipe.extractor.timeago.patterns.** { *; } +## Rules for Rhino and Rhino Engine +-keep class org.mozilla.javascript.* { *; } -keep class org.mozilla.javascript.** { *; } +-keep class org.mozilla.javascript.engine.** { *; } -keep class org.mozilla.classfile.ClassFileWriter -dontwarn org.mozilla.javascript.JavaToJSONConverters -dontwarn org.mozilla.javascript.tools.** +-keep class javax.script.** { *; } +-dontwarn javax.script.** +-keep class jdk.dynalink.** { *; } +-dontwarn jdk.dynalink.** ## Rules for ExoPlayer -keep class com.google.android.exoplayer2.** { *; } From 70416e73f301046b9285cca8e885445ca07ca6ea Mon Sep 17 00:00:00 2001 From: Miles Krell Date: Sun, 16 Mar 2025 19:24:04 -0400 Subject: [PATCH 056/143] Move app language setting migration to SettingMigrations --- app/src/main/java/org/schabi/newpipe/App.java | 26 -------------- .../newpipe/settings/SettingMigrations.java | 36 ++++++++++++++++++- 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/App.java b/app/src/main/java/org/schabi/newpipe/App.java index d37c8bc27..8ce161eec 100644 --- a/app/src/main/java/org/schabi/newpipe/App.java +++ b/app/src/main/java/org/schabi/newpipe/App.java @@ -3,14 +3,11 @@ package org.schabi.newpipe; import android.app.Application; import android.content.Context; import android.content.SharedPreferences; -import android.os.Build; import android.util.Log; import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatDelegate; import androidx.core.app.NotificationChannelCompat; import androidx.core.app.NotificationManagerCompat; -import androidx.core.os.LocaleListCompat; import androidx.preference.PreferenceManager; import com.jakewharton.processphoenix.ProcessPhoenix; @@ -125,29 +122,6 @@ public class App extends Application { configureRxJavaErrorHandler(); YoutubeStreamExtractor.setPoTokenProvider(PoTokenProviderImpl.INSTANCE); - - if (Build.VERSION.SDK_INT >= 33) { - ensureAppLanguagePreferenceIsMigrated(prefs); - } - } - - private void ensureAppLanguagePreferenceIsMigrated(final SharedPreferences prefs) { - final String appLanguageDefaultValue = getString(R.string.default_localization_key); - final String appLanguageKey = getString(R.string.app_language_key); - final String appLanguageCurrentValue = prefs.getString(appLanguageKey, null); - if (appLanguageCurrentValue != null) { - // Migrate to Android per-app language settings - prefs.edit().remove(appLanguageKey).apply(); - if (!appLanguageCurrentValue.equals(appLanguageDefaultValue)) { - try { - AppCompatDelegate.setApplicationLocales( - LocaleListCompat.forLanguageTags(appLanguageCurrentValue) - ); - } catch (final RuntimeException e) { - Log.e(TAG, "Error migrating to Android 13+ per-app language settings"); - } - } - } } @Override diff --git a/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java b/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java index d731f2f5e..ce5e3a341 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java +++ b/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java @@ -2,9 +2,12 @@ package org.schabi.newpipe.settings; import android.content.Context; import android.content.SharedPreferences; +import android.os.Build; import android.util.Log; import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatDelegate; +import androidx.core.os.LocaleListCompat; import androidx.preference.PreferenceManager; import org.schabi.newpipe.App; @@ -143,6 +146,36 @@ public final class SettingMigrations { } }; + public static final Migration MIGRATION_6_7 = new Migration(6, 7) { + @Override + protected void migrate(@NonNull final Context context) { + // Starting with pull request #12093, NewPipe on Android 13+ exclusively uses Android's + // public per-app language APIs to read and set the UI language for NewPipe. + // If running on Android 13+, the following migration will move any existing custom + // app language in SharedPreferences to use the public per-app language APIs instead. + if (Build.VERSION.SDK_INT >= 33) { + final String appLanguageDefaultValue = + context.getString(R.string.default_localization_key); + final String appLanguageKey = context.getString(R.string.app_language_key); + final String appLanguageCurrentValue = sp.getString(appLanguageKey, null); + if (appLanguageCurrentValue != null) { + sp.edit().remove(appLanguageKey).apply(); + if (!appLanguageCurrentValue.equals(appLanguageDefaultValue)) { + try { + AppCompatDelegate.setApplicationLocales( + LocaleListCompat.forLanguageTags(appLanguageCurrentValue) + ); + } catch (final RuntimeException e) { + Log.e(TAG, "Failed to migrate previous custom app language " + + "setting to public per-app language APIs" + ); + } + } + } + } + } + }; + /** * List of all implemented migrations. *

    @@ -156,12 +189,13 @@ public final class SettingMigrations { MIGRATION_3_4, MIGRATION_4_5, MIGRATION_5_6, + MIGRATION_6_7, }; /** * Version number for preferences. Must be incremented every time a migration is necessary. */ - private static final int VERSION = 6; + private static final int VERSION = 7; public static void runMigrationsIfNeeded(@NonNull final Context context) { From 35abb99dac89d072a5053a8c25d2fd7409411c28 Mon Sep 17 00:00:00 2001 From: Miles Krell Date: Sun, 16 Mar 2025 20:15:38 -0400 Subject: [PATCH 057/143] Only show toast on Android <13 --- .../newpipe/settings/ContentSettingsFragment.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java index 575d6c733..e3e674610 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java @@ -108,9 +108,13 @@ public class ContentSettingsFragment extends BasePreferenceFragment { if (!selectedLocalization.equals(initialSelectedLocalization) || !selectedContentCountry.equals(initialSelectedContentCountry) || !selectedLanguage.equals(initialLanguage)) { - Toast.makeText(requireContext(), R.string.localization_changes_requires_app_restart, - Toast.LENGTH_LONG).show(); - + if (Build.VERSION.SDK_INT < 33) { + Toast.makeText( + requireContext(), + R.string.localization_changes_requires_app_restart, + Toast.LENGTH_LONG + ).show(); + } NewPipe.setupLocalization(selectedLocalization, selectedContentCountry); } } From c7bf498c047a7235f9285616d726c999113a82d4 Mon Sep 17 00:00:00 2001 From: Miles Krell Date: Sun, 16 Mar 2025 20:27:05 -0400 Subject: [PATCH 058/143] Don't show toast because of changing content language or country --- .../settings/ContentSettingsFragment.java | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java index e3e674610..a8129f680 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java @@ -27,8 +27,6 @@ import java.util.Locale; public class ContentSettingsFragment extends BasePreferenceFragment { private String youtubeRestrictedModeEnabledKey; - private Localization initialSelectedLocalization; - private ContentCountry initialSelectedContentCountry; private String initialLanguage; @Override @@ -37,10 +35,6 @@ public class ContentSettingsFragment extends BasePreferenceFragment { addPreferencesFromResourceRegistry(); - initialSelectedLocalization = org.schabi.newpipe.util.Localization - .getPreferredLocalization(requireContext()); - initialSelectedContentCountry = org.schabi.newpipe.util.Localization - .getPreferredContentCountry(requireContext()); initialLanguage = defaultPreferences.getString(getString(R.string.app_language_key), "en"); if (Build.VERSION.SDK_INT >= 33) { @@ -98,16 +92,10 @@ public class ContentSettingsFragment extends BasePreferenceFragment { public void onDestroy() { super.onDestroy(); - final Localization selectedLocalization = org.schabi.newpipe.util.Localization - .getPreferredLocalization(requireContext()); - final ContentCountry selectedContentCountry = org.schabi.newpipe.util.Localization - .getPreferredContentCountry(requireContext()); final String selectedLanguage = defaultPreferences.getString(getString(R.string.app_language_key), "en"); - if (!selectedLocalization.equals(initialSelectedLocalization) - || !selectedContentCountry.equals(initialSelectedContentCountry) - || !selectedLanguage.equals(initialLanguage)) { + if (!selectedLanguage.equals(initialLanguage)) { if (Build.VERSION.SDK_INT < 33) { Toast.makeText( requireContext(), @@ -115,6 +103,10 @@ public class ContentSettingsFragment extends BasePreferenceFragment { Toast.LENGTH_LONG ).show(); } + final Localization selectedLocalization = org.schabi.newpipe.util.Localization + .getPreferredLocalization(requireContext()); + final ContentCountry selectedContentCountry = org.schabi.newpipe.util.Localization + .getPreferredContentCountry(requireContext()); NewPipe.setupLocalization(selectedLocalization, selectedContentCountry); } } From 6d6b73ef738c1a62466cc683a323a68938993bbf Mon Sep 17 00:00:00 2001 From: malania02 Date: Sat, 22 Mar 2025 16:09:58 +0100 Subject: [PATCH 059/143] textview for download date added --- app/src/main/res/layout/mission_item.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/src/main/res/layout/mission_item.xml b/app/src/main/res/layout/mission_item.xml index 5338949aa..c864f60f0 100644 --- a/app/src/main/res/layout/mission_item.xml +++ b/app/src/main/res/layout/mission_item.xml @@ -82,6 +82,18 @@ android:textColor="@color/white" android:textSize="12sp" /> + + From 536b78f2e6d2ad0fd93a04052153c300eda42732 Mon Sep 17 00:00:00 2001 From: malania02 Date: Sat, 22 Mar 2025 16:13:45 +0100 Subject: [PATCH 060/143] textview for download date added --- app/src/main/res/layout/mission_item_linear.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/src/main/res/layout/mission_item_linear.xml b/app/src/main/res/layout/mission_item_linear.xml index ce2d1af4b..b8cb762f2 100644 --- a/app/src/main/res/layout/mission_item_linear.xml +++ b/app/src/main/res/layout/mission_item_linear.xml @@ -62,6 +62,18 @@ android:textSize="12sp" android:textStyle="bold" /> + + Date: Sat, 22 Mar 2025 16:19:26 +0100 Subject: [PATCH 061/143] Show download date --- .../java/us/shandian/giga/ui/adapter/MissionAdapter.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/java/us/shandian/giga/ui/adapter/MissionAdapter.java b/app/src/main/java/us/shandian/giga/ui/adapter/MissionAdapter.java index 77d270c05..b3be8efbd 100644 --- a/app/src/main/java/us/shandian/giga/ui/adapter/MissionAdapter.java +++ b/app/src/main/java/us/shandian/giga/ui/adapter/MissionAdapter.java @@ -71,6 +71,9 @@ import java.net.URI; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; +import java.util.Date; +import java.util.Locale; +import java.text.DateFormat; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.core.Observable; @@ -213,6 +216,10 @@ public class MissionAdapter extends Adapter implements Handler.Callb h.status.setText("100%"); h.progress.setProgress(1.0f); h.size.setText(Utility.formatBytes(item.mission.length)); + + DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.getDefault()); + Date date = new Date(item.mission.timestamp); + h.date.setText(dateFormat.format(date)); } } From 7f10312d0af44bf013c5516f30c1e9b53cb64867 Mon Sep 17 00:00:00 2001 From: Miles Krell Date: Sun, 23 Mar 2025 17:38:14 -0400 Subject: [PATCH 062/143] Move migration to NewPipeSettings --- .../newpipe/settings/NewPipeSettings.java | 33 +++++++++++++++++ .../newpipe/settings/SettingMigrations.java | 36 +------------------ 2 files changed, 34 insertions(+), 35 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java b/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java index 421440ea7..93640756e 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java +++ b/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java @@ -6,9 +6,12 @@ import android.content.Context; import android.content.SharedPreferences; import android.os.Build; import android.os.Environment; +import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.StringRes; +import androidx.appcompat.app.AppCompatDelegate; +import androidx.core.os.LocaleListCompat; import androidx.preference.PreferenceManager; import org.schabi.newpipe.App; @@ -42,6 +45,7 @@ import java.util.Set; * Helper class for global settings. */ public final class NewPipeSettings { + private static final String TAG = NewPipeSettings.class.toString(); private NewPipeSettings() { } public static void initSettings(final Context context) { @@ -64,6 +68,7 @@ public final class NewPipeSettings { saveDefaultAudioDownloadDirectory(context); disableMediaTunnelingIfNecessary(context); + migrateAppLanguageSettingIfNecessary(context); } static void saveDefaultVideoDownloadDirectory(final Context context) { @@ -184,4 +189,32 @@ public final class NewPipeSettings { DeviceUtils.MEDIA_TUNNELING_DEVICE_BLACKLIST_VERSION).apply(); } } + + private static void migrateAppLanguageSettingIfNecessary(@NonNull final Context context) { + // Starting with pull request #12093, NewPipe on Android 13+ exclusively uses Android's + // public per-app language APIs to read and set the UI language for NewPipe. + // If running on Android 13+, the following migration will move any existing custom + // app language in SharedPreferences to use the public per-app language APIs instead. + if (Build.VERSION.SDK_INT >= 33) { + final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); + final String appLanguageKey = context.getString(R.string.app_language_key); + final String appLanguageValue = sp.getString(appLanguageKey, null); + if (appLanguageValue != null) { + sp.edit().remove(appLanguageKey).apply(); + final String appLanguageDefaultValue = + context.getString(R.string.default_localization_key); + if (!appLanguageValue.equals(appLanguageDefaultValue)) { + try { + AppCompatDelegate.setApplicationLocales( + LocaleListCompat.forLanguageTags(appLanguageValue) + ); + } catch (final RuntimeException e) { + Log.e(TAG, "Failed to migrate previous custom app language " + + "setting to public per-app language APIs" + ); + } + } + } + } + } } diff --git a/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java b/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java index ce5e3a341..d731f2f5e 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java +++ b/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java @@ -2,12 +2,9 @@ package org.schabi.newpipe.settings; import android.content.Context; import android.content.SharedPreferences; -import android.os.Build; import android.util.Log; import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatDelegate; -import androidx.core.os.LocaleListCompat; import androidx.preference.PreferenceManager; import org.schabi.newpipe.App; @@ -146,36 +143,6 @@ public final class SettingMigrations { } }; - public static final Migration MIGRATION_6_7 = new Migration(6, 7) { - @Override - protected void migrate(@NonNull final Context context) { - // Starting with pull request #12093, NewPipe on Android 13+ exclusively uses Android's - // public per-app language APIs to read and set the UI language for NewPipe. - // If running on Android 13+, the following migration will move any existing custom - // app language in SharedPreferences to use the public per-app language APIs instead. - if (Build.VERSION.SDK_INT >= 33) { - final String appLanguageDefaultValue = - context.getString(R.string.default_localization_key); - final String appLanguageKey = context.getString(R.string.app_language_key); - final String appLanguageCurrentValue = sp.getString(appLanguageKey, null); - if (appLanguageCurrentValue != null) { - sp.edit().remove(appLanguageKey).apply(); - if (!appLanguageCurrentValue.equals(appLanguageDefaultValue)) { - try { - AppCompatDelegate.setApplicationLocales( - LocaleListCompat.forLanguageTags(appLanguageCurrentValue) - ); - } catch (final RuntimeException e) { - Log.e(TAG, "Failed to migrate previous custom app language " - + "setting to public per-app language APIs" - ); - } - } - } - } - } - }; - /** * List of all implemented migrations. *

    @@ -189,13 +156,12 @@ public final class SettingMigrations { MIGRATION_3_4, MIGRATION_4_5, MIGRATION_5_6, - MIGRATION_6_7, }; /** * Version number for preferences. Must be incremented every time a migration is necessary. */ - private static final int VERSION = 7; + private static final int VERSION = 6; public static void runMigrationsIfNeeded(@NonNull final Context context) { From 205466c56a88ecf144bb43db02fc4bcf03a7994b Mon Sep 17 00:00:00 2001 From: Miles Krell Date: Thu, 27 Mar 2025 19:14:41 -0400 Subject: [PATCH 063/143] Move call to setApplicationLocales --- .../java/org/schabi/newpipe/MainActivity.java | 2 ++ .../newpipe/settings/NewPipeSettings.java | 33 ------------------- .../org/schabi/newpipe/util/Localization.java | 31 +++++++++++++++++ 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/MainActivity.java b/app/src/main/java/org/schabi/newpipe/MainActivity.java index b9592085b..2c7f76322 100644 --- a/app/src/main/java/org/schabi/newpipe/MainActivity.java +++ b/app/src/main/java/org/schabi/newpipe/MainActivity.java @@ -190,6 +190,8 @@ public class MainActivity extends AppCompatActivity { && ReleaseVersionUtil.INSTANCE.isReleaseApk()) { UpdateSettingsFragment.askForConsentToUpdateChecks(this); } + + Localization.migrateAppLanguageSettingIfNecessary(getApplicationContext()); } @Override diff --git a/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java b/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java index 93640756e..421440ea7 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java +++ b/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java @@ -6,12 +6,9 @@ import android.content.Context; import android.content.SharedPreferences; import android.os.Build; import android.os.Environment; -import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.StringRes; -import androidx.appcompat.app.AppCompatDelegate; -import androidx.core.os.LocaleListCompat; import androidx.preference.PreferenceManager; import org.schabi.newpipe.App; @@ -45,7 +42,6 @@ import java.util.Set; * Helper class for global settings. */ public final class NewPipeSettings { - private static final String TAG = NewPipeSettings.class.toString(); private NewPipeSettings() { } public static void initSettings(final Context context) { @@ -68,7 +64,6 @@ public final class NewPipeSettings { saveDefaultAudioDownloadDirectory(context); disableMediaTunnelingIfNecessary(context); - migrateAppLanguageSettingIfNecessary(context); } static void saveDefaultVideoDownloadDirectory(final Context context) { @@ -189,32 +184,4 @@ public final class NewPipeSettings { DeviceUtils.MEDIA_TUNNELING_DEVICE_BLACKLIST_VERSION).apply(); } } - - private static void migrateAppLanguageSettingIfNecessary(@NonNull final Context context) { - // Starting with pull request #12093, NewPipe on Android 13+ exclusively uses Android's - // public per-app language APIs to read and set the UI language for NewPipe. - // If running on Android 13+, the following migration will move any existing custom - // app language in SharedPreferences to use the public per-app language APIs instead. - if (Build.VERSION.SDK_INT >= 33) { - final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); - final String appLanguageKey = context.getString(R.string.app_language_key); - final String appLanguageValue = sp.getString(appLanguageKey, null); - if (appLanguageValue != null) { - sp.edit().remove(appLanguageKey).apply(); - final String appLanguageDefaultValue = - context.getString(R.string.default_localization_key); - if (!appLanguageValue.equals(appLanguageDefaultValue)) { - try { - AppCompatDelegate.setApplicationLocales( - LocaleListCompat.forLanguageTags(appLanguageValue) - ); - } catch (final RuntimeException e) { - Log.e(TAG, "Failed to migrate previous custom app language " - + "setting to public per-app language APIs" - ); - } - } - } - } - } } diff --git a/app/src/main/java/org/schabi/newpipe/util/Localization.java b/app/src/main/java/org/schabi/newpipe/util/Localization.java index acb0dff04..679d52bb8 100644 --- a/app/src/main/java/org/schabi/newpipe/util/Localization.java +++ b/app/src/main/java/org/schabi/newpipe/util/Localization.java @@ -12,6 +12,7 @@ import android.os.Build; import android.text.TextUtils; import android.text.format.DateUtils; import android.util.DisplayMetrics; +import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -19,6 +20,7 @@ import androidx.annotation.PluralsRes; import androidx.annotation.StringRes; import androidx.appcompat.app.AppCompatDelegate; import androidx.core.math.MathUtils; +import androidx.core.os.LocaleListCompat; import androidx.preference.PreferenceManager; import org.ocpsoft.prettytime.PrettyTime; @@ -65,6 +67,7 @@ import java.util.stream.Collectors; */ public final class Localization { + private static final String TAG = Localization.class.toString(); public static final String DOT_SEPARATOR = " • "; private static PrettyTime prettyTime; @@ -433,4 +436,32 @@ public final class Localization { final int safeCount = (int) MathUtils.clamp(count, Integer.MIN_VALUE, Integer.MAX_VALUE); return context.getResources().getQuantityString(pluralId, safeCount, formattedCount); } + + public static void migrateAppLanguageSettingIfNecessary(@NonNull final Context context) { + // Starting with pull request #12093, NewPipe on Android 13+ exclusively uses Android's + // public per-app language APIs to read and set the UI language for NewPipe. + // If running on Android 13+, the following code will migrate any existing custom + // app language in SharedPreferences to use the public per-app language APIs instead. + if (Build.VERSION.SDK_INT >= 33) { + final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); + final String appLanguageKey = context.getString(R.string.app_language_key); + final String appLanguageValue = sp.getString(appLanguageKey, null); + if (appLanguageValue != null) { + sp.edit().remove(appLanguageKey).apply(); + final String appLanguageDefaultValue = + context.getString(R.string.default_localization_key); + if (!appLanguageValue.equals(appLanguageDefaultValue)) { + try { + AppCompatDelegate.setApplicationLocales( + LocaleListCompat.forLanguageTags(appLanguageValue) + ); + } catch (final RuntimeException e) { + Log.e(TAG, "Failed to migrate previous custom app language " + + "setting to public per-app language APIs" + ); + } + } + } + } + } } From 912f07a1dd05ffe802416e28ead6ac3e5646c18a Mon Sep 17 00:00:00 2001 From: malania02 Date: Sun, 30 Mar 2025 14:50:05 +0200 Subject: [PATCH 064/143] Missing lines added --- .../main/java/us/shandian/giga/ui/adapter/MissionAdapter.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/java/us/shandian/giga/ui/adapter/MissionAdapter.java b/app/src/main/java/us/shandian/giga/ui/adapter/MissionAdapter.java index b3be8efbd..9722a9a1f 100644 --- a/app/src/main/java/us/shandian/giga/ui/adapter/MissionAdapter.java +++ b/app/src/main/java/us/shandian/giga/ui/adapter/MissionAdapter.java @@ -211,6 +211,8 @@ public class MissionAdapter extends Adapter implements Handler.Callb h.pause.setTitle(mission.unknownLength ? R.string.stop : R.string.pause); updateProgress(h); mPendingDownloadsItems.add(h); + + h.date.setText(""); } else { h.progress.setMarquee(false); h.status.setText("100%"); @@ -839,6 +841,7 @@ public class MissionAdapter extends Adapter implements Handler.Callb ImageView icon; TextView name; TextView size; + TextView date; ProgressDrawable progress; PopupMenu popupMenu; @@ -869,6 +872,7 @@ public class MissionAdapter extends Adapter implements Handler.Callb name = itemView.findViewById(R.id.item_name); icon = itemView.findViewById(R.id.item_icon); size = itemView.findViewById(R.id.item_size); + date = itemView.findViewById(R.id.item_date); name.setSelected(true); From e1dedd45ed99e2c52eb062d1fceb2d233bbeee89 Mon Sep 17 00:00:00 2001 From: FineFindus Date: Wed, 2 Apr 2025 22:14:01 +0200 Subject: [PATCH 065/143] [YouTube] Access first element if array size is one Fixes a regression, where if the challenge data array size was one, the second element would be accessed, leading to a crash. This was introduced when porting the challenge parsing from JS to Kotlin. Ref: https://github.com/TeamNewPipe/NewPipe/commit/53b599b042ff23cf2e74e3e8d90609b574a30fd1 --- .../main/java/org/schabi/newpipe/util/potoken/JavaScriptUtil.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/util/potoken/JavaScriptUtil.kt b/app/src/main/java/org/schabi/newpipe/util/potoken/JavaScriptUtil.kt index a9169e2c6..06740a00e 100644 --- a/app/src/main/java/org/schabi/newpipe/util/potoken/JavaScriptUtil.kt +++ b/app/src/main/java/org/schabi/newpipe/util/potoken/JavaScriptUtil.kt @@ -17,7 +17,7 @@ fun parseChallengeData(rawChallengeData: String): String { val descrambled = descramble(scrambled.getString(1)) JsonParser.array().from(descrambled) } else { - scrambled.getArray(1) + scrambled.getArray(0) } val messageId = challengeData.getString(0) From f39eda086f22e88ccdec47a0bbce87bad20d6ed4 Mon Sep 17 00:00:00 2001 From: malania02 Date: Wed, 9 Apr 2025 23:40:14 +0200 Subject: [PATCH 066/143] Fix for overlapping --- app/src/main/res/layout/mission_item_linear.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/layout/mission_item_linear.xml b/app/src/main/res/layout/mission_item_linear.xml index b8cb762f2..6288e4759 100644 --- a/app/src/main/res/layout/mission_item_linear.xml +++ b/app/src/main/res/layout/mission_item_linear.xml @@ -67,7 +67,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/item_name" - android:layout_alignParentRight="true" + android:layout_toLeftOf="@id/item_more" android:padding="6dp" android:singleLine="true" android:text="" From ce16c6df5fe446d2bf9a42077faf3880bddec2d5 Mon Sep 17 00:00:00 2001 From: Naveen Singh <36371707+naveensingh@users.noreply.github.com> Date: Sun, 27 Apr 2025 19:35:31 -0400 Subject: [PATCH 067/143] Fix image minimizer pattern Added non-capturing group that matches either: - `user-attachments/assets` - `owner/repo/assets/digits` --- .github/workflows/image-minimizer.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/image-minimizer.js b/.github/workflows/image-minimizer.js index 4f9ad616d..0a1e56c56 100644 --- a/.github/workflows/image-minimizer.js +++ b/.github/workflows/image-minimizer.js @@ -33,11 +33,11 @@ module.exports = async ({github, context}) => { // Regex for finding images (simple variant) ![ALT_TEXT](https://*.githubusercontent.com//.) const REGEX_USER_CONTENT_IMAGE_LOOKUP = /\!\[([^\]]*)\]\((https:\/\/[-a-z0-9]+\.githubusercontent\.com\/\d+\/[-0-9a-f]{32,512}\.(jpg|gif|png))\)/gm; - const REGEX_ASSETS_IMAGE_LOCKUP = /\!\[([^\]]*)\]\((https:\/\/github\.com\/[-\w\d]+\/[-\w\d]+\/assets\/\d+\/[\-0-9a-f]{32,512})\)/gm; + const REGEX_ASSETS_IMAGE_LOOKUP = /\!\[([^\]]*)\]\((https:\/\/github\.com\/(?:user-attachments\/assets|[-\w\d]+\/[-\w\d]+\/assets\/\d+)\/[\-0-9a-f]{32,512})\)/gm; // Check if we found something let foundSimpleImages = REGEX_USER_CONTENT_IMAGE_LOOKUP.test(initialBody) - || REGEX_ASSETS_IMAGE_LOCKUP.test(initialBody); + || REGEX_ASSETS_IMAGE_LOOKUP.test(initialBody); if (!foundSimpleImages) { console.log('Found no simple images to process'); return; @@ -52,7 +52,7 @@ module.exports = async ({github, context}) => { // Try to find and replace the images with minimized ones let newBody = await replaceAsync(initialBody, REGEX_USER_CONTENT_IMAGE_LOOKUP, minimizeAsync); - newBody = await replaceAsync(newBody, REGEX_ASSETS_IMAGE_LOCKUP, minimizeAsync); + newBody = await replaceAsync(newBody, REGEX_ASSETS_IMAGE_LOOKUP, minimizeAsync); if (!wasMatchModified) { console.log('Nothing was modified. Skipping update'); From 5ca544bc426ef460b02bb994e069007c3f5e059b Mon Sep 17 00:00:00 2001 From: Profpatsch Date: Tue, 6 May 2025 10:48:20 +0200 Subject: [PATCH 068/143] build.gradle: Improve jitpack workaround doc & fix hash --- app/build.gradle | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index f3159f741..25a1b6a2e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -211,8 +211,10 @@ dependencies { // This works thanks to JitPack: https://jitpack.io/ implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751' // WORKAROUND: if you get errors with the NewPipeExtractor dependency, replace `v0.24.3` with - // the corresponding commit hash, since JitPack is sometimes buggy - implementation 'com.github.TeamNewPipe:NewPipeExtractor:0b99100db' + // the corresponding commit hash, since JitPack sometimes deletes artifacts. + // If there’s already a git hash, just add more of it to the end (or remove a letter) + // to cause jitpack to regenerate the artifact. + implementation 'com.github.TeamNewPipe:NewPipeExtractor:0b99100dbddeca2f' implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0' /** Checkstyle **/ From 48e826e91294ccaab2388a720f2e584a0a1e655b Mon Sep 17 00:00:00 2001 From: j-haldane Date: Tue, 6 May 2025 11:07:45 -0400 Subject: [PATCH 069/143] Fix header crash in History List view (#12214) * Adapt header handling changes from other recyclerview adapters to fix issue #4475 in StatisticsPlaylistFragment * Remove unneeded LayoutInflater * Revert "Remove unneeded LayoutInflater" This reverts commit ab73dc1e7290f9e133435222bf35dee54de837f4. * Revert "Adapt header handling changes from other recyclerview adapters to fix issue #4475 in StatisticsPlaylistFragment" This reverts commit 2abe71cc986114000ecdd14aaa17850f60b9549c. * Remove header animation causing view recycling issue --- .../org/schabi/newpipe/local/BaseLocalListFragment.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/BaseLocalListFragment.java b/app/src/main/java/org/schabi/newpipe/local/BaseLocalListFragment.java index 53fe1677b..90ef8c352 100644 --- a/app/src/main/java/org/schabi/newpipe/local/BaseLocalListFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/BaseLocalListFragment.java @@ -194,9 +194,6 @@ public abstract class BaseLocalListFragment extends BaseStateFragment if (itemsList != null) { animateHideRecyclerViewAllowingScrolling(itemsList); } - if (headerRootBinding != null) { - animate(headerRootBinding.getRoot(), false, 200); - } } @Override @@ -205,9 +202,6 @@ public abstract class BaseLocalListFragment extends BaseStateFragment if (itemsList != null) { animate(itemsList, true, 200); } - if (headerRootBinding != null) { - animate(headerRootBinding.getRoot(), true, 200); - } } @Override @@ -253,9 +247,6 @@ public abstract class BaseLocalListFragment extends BaseStateFragment if (itemsList != null) { animateHideRecyclerViewAllowingScrolling(itemsList); } - if (headerRootBinding != null) { - animate(headerRootBinding.getRoot(), false, 200); - } } @Override From e7f3750f5e7c80d0e22553ca8f752ccb2d65401f Mon Sep 17 00:00:00 2001 From: Andriana Date: Thu, 24 Apr 2025 16:08:27 +0300 Subject: [PATCH 070/143] Fix timestamps not working in comment replies Use LinkMovementMethodCompat for comment links Co-authored-by: Isira Seneviratne <31027858+Isira-Seneviratne@users.noreply.github.com> Update import Use LongPressLinkMovementMethod --- .../fragments/list/comments/CommentRepliesFragment.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.java index 0514eefde..ce52c029d 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.java @@ -28,6 +28,7 @@ import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.image.ImageStrategy; import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.text.TextLinkifier; +import org.schabi.newpipe.util.text.LongPressLinkMovementMethod; import java.util.Queue; import java.util.function.Supplier; @@ -110,7 +111,7 @@ public final class CommentRepliesFragment TextLinkifier.fromDescription(binding.commentContent, item.getCommentText(), HtmlCompat.FROM_HTML_MODE_LEGACY, getServiceById(item.getServiceId()), item.getUrl(), disposables, null); - + binding.commentContent.setMovementMethod(LongPressLinkMovementMethod.getInstance()); return binding.getRoot(); }; } From d2dc20c5510360c846243924530fce8cf7c3f1eb Mon Sep 17 00:00:00 2001 From: Profpatsch Date: Wed, 7 May 2025 10:09:02 +0200 Subject: [PATCH 071/143] SearchFragment: show service name in search hint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The only hint (haha) which service one is searching in is currently the color of the background. This is super confusing, yesterday a friend tried to search for a video on youtube and the app was set to Bandcamp, and they were super confused why nothing turned up. So let’s put the name of the service in the hint! The `updateService()` thing is a little confused, but I didn’t want to refactor to improve the logic. It’s not doing anything computationally intensive anyway. For PeerTube, the sidebar calls it FramaTube but the service name is PeerTube, I’m not sure why that is the case. Looks like the string depends on the name of the instance? Hm, can be improved later I think. --- .../newpipe/fragments/list/search/SearchFragment.java | 9 +++++++++ app/src/main/res/values/strings.xml | 1 + 2 files changed, 10 insertions(+) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java index 18c60400b..4c7bb15a8 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java @@ -219,6 +219,15 @@ public class SearchFragment extends BaseListFragmentDownload Download stream file Search + Search %1$s Settings Did you mean \"%1$s\"? Showing results for: %s From 8d679626f0eeeb65aba4e858487daaddc1156362 Mon Sep 17 00:00:00 2001 From: VougJo23 Date: Wed, 16 Apr 2025 18:29:33 +0300 Subject: [PATCH 072/143] fix: support RTL usernames in comment header The `@` gets added by the youtube API and thus is a fixed member of the username, so we do some simple detection logic to handle that case (otherwise the `@` will be at the right side of a RTL username, which is different of how Youtube displays these usernames in the browser). Fixes https://github.com/TeamNewPipe/NewPipe/issues/12141 --- .../holder/CommentInfoItemHolder.java | 10 ++++++---- .../org/schabi/newpipe/util/Localization.java | 20 +++++++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentInfoItemHolder.java index 839aa1813..a19831cc7 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentInfoItemHolder.java @@ -101,14 +101,16 @@ public class CommentInfoItemHolder extends InfoItemHolder { } itemThumbnailView.setOnClickListener(view -> openCommentAuthor(item)); - // setup the top row, with pinned icon, author name and comment date itemPinnedView.setVisibility(item.isPinned() ? View.VISIBLE : View.GONE); - itemTitleView.setText(Localization.concatenateStrings(item.getUploaderName(), - Localization.relativeTimeOrTextual(itemBuilder.getContext(), item.getUploadDate(), + final String uploaderName = Localization.localizeUserName(item.getUploaderName()); + itemTitleView.setText(Localization.concatenateStrings( + uploaderName, + Localization.relativeTimeOrTextual( + itemBuilder.getContext(), + item.getUploadDate(), item.getTextualUploadDate()))); - // setup bottom row, with likes, heart and replies button itemLikesCountView.setText( Localization.likeCount(itemBuilder.getContext(), item.getLikeCount())); diff --git a/app/src/main/java/org/schabi/newpipe/util/Localization.java b/app/src/main/java/org/schabi/newpipe/util/Localization.java index 2146cf8bc..e92ad0b1c 100644 --- a/app/src/main/java/org/schabi/newpipe/util/Localization.java +++ b/app/src/main/java/org/schabi/newpipe/util/Localization.java @@ -11,6 +11,7 @@ import android.icu.text.CompactDecimalFormat; import android.os.Build; import android.text.TextUtils; import android.text.format.DateUtils; +import android.text.BidiFormatter; import android.util.DisplayMetrics; import android.util.Log; @@ -85,6 +86,25 @@ public final class Localization { .collect(Collectors.joining(delimiter)); } + /** + * Localize a user name like @foobar. + * + * Will correctly handle right-to-left usernames by using a {@link BidiFormatter}. + * + * @param plainName username, with an optional leading @ + * @return a usernames that can include RTL-characters + */ + @NonNull + public static String localizeUserName(final String plainName) { + final BidiFormatter bidi = BidiFormatter.getInstance(); + + if (plainName.startsWith("@")) { + return "@" + bidi.unicodeWrap(plainName.substring(1)); + } else { + return bidi.unicodeWrap(plainName); + } + } + public static org.schabi.newpipe.extractor.localization.Localization getPreferredLocalization( final Context context) { return org.schabi.newpipe.extractor.localization.Localization From e554c77f2e085a900d28ac83a46e6073e082f582 Mon Sep 17 00:00:00 2001 From: Profpatsch Date: Wed, 7 May 2025 14:20:44 +0200 Subject: [PATCH 073/143] Comments: Put @ on the right side of right-to-left usernames From the discussion in https://github.com/TeamNewPipe/NewPipe/pull/12188 it reads more natural for RTL readers. --- .../main/java/org/schabi/newpipe/util/Localization.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/util/Localization.java b/app/src/main/java/org/schabi/newpipe/util/Localization.java index e92ad0b1c..65cfec930 100644 --- a/app/src/main/java/org/schabi/newpipe/util/Localization.java +++ b/app/src/main/java/org/schabi/newpipe/util/Localization.java @@ -90,19 +90,14 @@ public final class Localization { * Localize a user name like @foobar. * * Will correctly handle right-to-left usernames by using a {@link BidiFormatter}. + * For right-to-left usernames, it will put the @ on the right side to read more naturally. * * @param plainName username, with an optional leading @ * @return a usernames that can include RTL-characters */ @NonNull public static String localizeUserName(final String plainName) { - final BidiFormatter bidi = BidiFormatter.getInstance(); - - if (plainName.startsWith("@")) { - return "@" + bidi.unicodeWrap(plainName.substring(1)); - } else { - return bidi.unicodeWrap(plainName); - } + return BidiFormatter.getInstance().unicodeWrap(plainName); } public static org.schabi.newpipe.extractor.localization.Localization getPreferredLocalization( From 90e2f234e72b8ce4b95aba64173db1a848c395fb Mon Sep 17 00:00:00 2001 From: Thompson3142 Date: Tue, 3 Dec 2024 00:51:15 +0100 Subject: [PATCH 074/143] Initial commit for better handling of background crashes Fix crashing behaviour with entry in SharedPreferences A few minor improvements Added docs for isInBackground Some more minor changes Overwrite methods in MainActivity instead of creating a new class --- app/build.gradle | 1 + .../java/org/schabi/newpipe/MainActivity.java | 30 ++++++++++++++----- .../org/schabi/newpipe/error/ErrorUtil.kt | 12 +++++++- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 5a5a2be1b..6fc06aadc 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -233,6 +233,7 @@ dependencies { implementation 'androidx.fragment:fragment-ktx:1.6.2' implementation "androidx.lifecycle:lifecycle-livedata-ktx:${androidxLifecycleVersion}" implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${androidxLifecycleVersion}" + implementation "androidx.lifecycle:lifecycle-process:${androidxLifecycleVersion}" implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0' implementation 'androidx.media:media:1.7.0' implementation 'androidx.preference:preference:1.2.1' diff --git a/app/src/main/java/org/schabi/newpipe/MainActivity.java b/app/src/main/java/org/schabi/newpipe/MainActivity.java index f74e8b7a7..b709c1107 100644 --- a/app/src/main/java/org/schabi/newpipe/MainActivity.java +++ b/app/src/main/java/org/schabi/newpipe/MainActivity.java @@ -126,7 +126,10 @@ public class MainActivity extends AppCompatActivity { private static final int ITEM_ID_ABOUT = 2; private static final int ORDER = 0; + public static final String KEY_IS_IN_BACKGROUND = "is_in_background"; + private SharedPreferences sharedPreferences; + private SharedPreferences.Editor sharedPrefEditor; /*////////////////////////////////////////////////////////////////////////// // Activity's LifeCycle //////////////////////////////////////////////////////////////////////////*/ @@ -156,6 +159,8 @@ public class MainActivity extends AppCompatActivity { assureCorrectAppLanguage(this); super.onCreate(savedInstanceState); + sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); + sharedPrefEditor = sharedPreferences.edit(); mainBinding = ActivityMainBinding.inflate(getLayoutInflater()); drawerLayoutBinding = mainBinding.drawerLayout; @@ -199,16 +204,29 @@ public class MainActivity extends AppCompatActivity { super.onPostCreate(savedInstanceState); final App app = App.getApp(); - final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(app); - if (prefs.getBoolean(app.getString(R.string.update_app_key), false) - && prefs.getBoolean(app.getString(R.string.update_check_consent_key), false)) { + if (sharedPreferences.getBoolean(app.getString(R.string.update_app_key), false) + && sharedPreferences + .getBoolean(app.getString(R.string.update_check_consent_key), false)) { // Start the worker which is checking all conditions // and eventually searching for a new version. NewVersionWorker.enqueueNewVersionCheckingWork(app, false); } } + @Override + protected void onStart() { + super.onStart(); + sharedPrefEditor.putBoolean(KEY_IS_IN_BACKGROUND, false).apply(); + Log.d(TAG, "App moved to foreground"); + } + + @Override + protected void onStop() { + super.onStop(); + sharedPrefEditor.putBoolean(KEY_IS_IN_BACKGROUND, true).apply(); + Log.d(TAG, "App moved to background"); + } private void setupDrawer() throws ExtractionException { addDrawerMenuForCurrentService(); @@ -508,13 +526,11 @@ public class MainActivity extends AppCompatActivity { ErrorUtil.showUiErrorSnackbar(this, "Setting up service toggle", e); } - final SharedPreferences sharedPreferences = - PreferenceManager.getDefaultSharedPreferences(this); if (sharedPreferences.getBoolean(Constants.KEY_THEME_CHANGE, false)) { if (DEBUG) { Log.d(TAG, "Theme has changed, recreating activity..."); } - sharedPreferences.edit().putBoolean(Constants.KEY_THEME_CHANGE, false).apply(); + sharedPrefEditor.putBoolean(Constants.KEY_THEME_CHANGE, false).apply(); ActivityCompat.recreate(this); } @@ -522,7 +538,7 @@ public class MainActivity extends AppCompatActivity { if (DEBUG) { Log.d(TAG, "main page has changed, recreating main fragment..."); } - sharedPreferences.edit().putBoolean(Constants.KEY_MAIN_PAGE_CHANGE, false).apply(); + sharedPrefEditor.putBoolean(Constants.KEY_MAIN_PAGE_CHANGE, false).apply(); NavigationHelper.openMainActivity(this); } diff --git a/app/src/main/java/org/schabi/newpipe/error/ErrorUtil.kt b/app/src/main/java/org/schabi/newpipe/error/ErrorUtil.kt index dcbc11413..93dd8e522 100644 --- a/app/src/main/java/org/schabi/newpipe/error/ErrorUtil.kt +++ b/app/src/main/java/org/schabi/newpipe/error/ErrorUtil.kt @@ -11,7 +11,9 @@ import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import androidx.core.app.PendingIntentCompat import androidx.fragment.app.Fragment +import androidx.preference.PreferenceManager import com.google.android.material.snackbar.Snackbar +import org.schabi.newpipe.MainActivity import org.schabi.newpipe.R /** @@ -35,12 +37,20 @@ class ErrorUtil { * activity (since the workflow would be interrupted anyway in that case). So never use this * for background services. * + * If the crashed occurred while the app was in the background open a notification instead + * * @param context the context to use to start the new activity * @param errorInfo the error info to be reported */ @JvmStatic fun openActivity(context: Context, errorInfo: ErrorInfo) { - context.startActivity(getErrorActivityIntent(context, errorInfo)) + if (PreferenceManager.getDefaultSharedPreferences(context) + .getBoolean(MainActivity.KEY_IS_IN_BACKGROUND, true) + ) { + createNotification(context, errorInfo) + } else { + context.startActivity(getErrorActivityIntent(context, errorInfo)) + } } /** From 76202e6b4b20e1d4bd17359675015cfed08ca7f5 Mon Sep 17 00:00:00 2001 From: Thompson3142 Date: Tue, 17 Dec 2024 19:49:43 +0100 Subject: [PATCH 075/143] Remove no longer needed dependency --- app/build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 6fc06aadc..5a5a2be1b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -233,7 +233,6 @@ dependencies { implementation 'androidx.fragment:fragment-ktx:1.6.2' implementation "androidx.lifecycle:lifecycle-livedata-ktx:${androidxLifecycleVersion}" implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${androidxLifecycleVersion}" - implementation "androidx.lifecycle:lifecycle-process:${androidxLifecycleVersion}" implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0' implementation 'androidx.media:media:1.7.0' implementation 'androidx.preference:preference:1.2.1' From 7dd1abdf9c87c199e108ad9e03c71702605f94f9 Mon Sep 17 00:00:00 2001 From: David <22662897+davidasunmo@users.noreply.github.com> Date: Tue, 20 May 2025 02:22:47 +0100 Subject: [PATCH 076/143] Add dev and refactor nightly build badges bottom text --- README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bf1317f17..f4548cf9e 100644 --- a/README.md +++ b/README.md @@ -8,13 +8,23 @@

    Get it on F-Droid

    - + + + + + + + +

    + +

    +

    ScreenshotsSupported ServicesDescriptionFeaturesInstallation and updatesContributionDonateLicense

    WebsiteBlogFAQPress

    From 16077dee80d2d87199b92c758fa00292a2a5072a Mon Sep 17 00:00:00 2001 From: David Asunmo Date: Wed, 21 May 2025 17:51:11 +0100 Subject: [PATCH 077/143] Add matrix chat link to all READMEs --- doc/README.ar.md | 1 + doc/README.de.md | 1 + doc/README.es.md | 1 + doc/README.fr.md | 1 + doc/README.it.md | 1 + doc/README.ja.md | 1 + doc/README.ko.md | 1 + doc/README.pl.md | 1 + doc/README.pt_BR.md | 1 + doc/README.ro.md | 1 + doc/README.ryu.md | 1 + doc/README.so.md | 1 + doc/README.sr.md | 1 + doc/README.tr.md | 1 + doc/README.zh_TW.md | 1 + 15 files changed, 15 insertions(+) diff --git a/doc/README.ar.md b/doc/README.ar.md index 242516cdc..41f498243 100644 --- a/doc/README.ar.md +++ b/doc/README.ar.md @@ -10,6 +10,7 @@ +


    لقطات الشاشةالخدمات المدعومةوصفسماتالتثبيت والتحديثاتمساهمةالتبرعاترخصة

    diff --git a/doc/README.de.md b/doc/README.de.md index 5b3275d07..a1ab2efe5 100644 --- a/doc/README.de.md +++ b/doc/README.de.md @@ -13,6 +13,7 @@ +


    ScreenshotsUnterstützte DiensteBeschreibungFeaturesInstallation und UpdatesBeitragSpendenLizenz

    diff --git a/doc/README.es.md b/doc/README.es.md index 8ec58e771..3e8744ecc 100644 --- a/doc/README.es.md +++ b/doc/README.es.md @@ -10,6 +10,7 @@ +


    diff --git a/doc/README.fr.md b/doc/README.fr.md index 772f4a1ae..026811488 100644 --- a/doc/README.fr.md +++ b/doc/README.fr.md @@ -13,6 +13,7 @@ +


    Captures d'écranServices SupportésDescriptionFonctionnalitésInstallation et mises à jourContribuerDonsLicence

    diff --git a/doc/README.it.md b/doc/README.it.md index 6c227ea2f..c42f28cfb 100644 --- a/doc/README.it.md +++ b/doc/README.it.md @@ -10,6 +10,7 @@ +


    ScreenshotServizi SupportatiDescrizioneFunzionalitàInstallazione e aggiornamentiContribuireDonareLicenza

    diff --git a/doc/README.ja.md b/doc/README.ja.md index e8f708a8a..116b8904d 100644 --- a/doc/README.ja.md +++ b/doc/README.ja.md @@ -10,6 +10,7 @@ +


    スクリーンショット説明機能インストールと更新貢献寄付ライセンス

    diff --git a/doc/README.ko.md b/doc/README.ko.md index 3215bd713..ecb68b7b3 100644 --- a/doc/README.ko.md +++ b/doc/README.ko.md @@ -10,6 +10,7 @@ +


    ScreenshotsDescriptionFeaturesUpdatesContributionDonateLicense

    diff --git a/doc/README.pl.md b/doc/README.pl.md index 96d493153..064c3b86b 100644 --- a/doc/README.pl.md +++ b/doc/README.pl.md @@ -10,6 +10,7 @@ +


    ScreenshotyOpisFunkcjeInstalacja i aktualizacjeWkładWesprzyjLicencja

    diff --git a/doc/README.pt_BR.md b/doc/README.pt_BR.md index da6c4fce6..3a99d47da 100644 --- a/doc/README.pt_BR.md +++ b/doc/README.pt_BR.md @@ -14,6 +14,7 @@ +


    ScreenshotsServiços SuportadosDescriçãoRecursosInstalação e atualizaçõesContribuiçõesDoarLicença

    diff --git a/doc/README.ro.md b/doc/README.ro.md index 29c1d3666..ec440d03c 100644 --- a/doc/README.ro.md +++ b/doc/README.ro.md @@ -10,6 +10,7 @@ +


    Capturi de ecranDescriereFuncţiiInstalare şi actualizăriContribuţieDonaţiLicenţă

    diff --git a/doc/README.ryu.md b/doc/README.ryu.md index 2e24aa41c..a5b8f1e7c 100644 --- a/doc/README.ryu.md +++ b/doc/README.ryu.md @@ -10,6 +10,7 @@ +


    スクリーンショットしちめいちぬーインストールとぅこうしんこうきんちーふライセンス

    diff --git a/doc/README.so.md b/doc/README.so.md index 640feae60..e3cfc6c8c 100644 --- a/doc/README.so.md +++ b/doc/README.so.md @@ -10,6 +10,7 @@ +


    Sawir-shaashadeedFaahfaahinWaxqabadkaKushubida iyo cusboonaysiintaKusoo KordhinUgu DeeqLaysinka

    diff --git a/doc/README.sr.md b/doc/README.sr.md index 1a9118638..28445c547 100644 --- a/doc/README.sr.md +++ b/doc/README.sr.md @@ -13,6 +13,7 @@ +


    Снимци екранаПодржане услугеОписКарактеристикеИнсталација и ажурирањаДоприносДонацијаЛиценца

    diff --git a/doc/README.tr.md b/doc/README.tr.md index bbdd85f76..9d8419311 100644 --- a/doc/README.tr.md +++ b/doc/README.tr.md @@ -10,6 +10,7 @@ +


    Ekran fotoğraflarıAçıklamaÖzelliklerKurulum ve güncellemelerKatkıda bulunmaBağışLisans

    diff --git a/doc/README.zh_TW.md b/doc/README.zh_TW.md index 760a43ad5..233f88be7 100644 --- a/doc/README.zh_TW.md +++ b/doc/README.zh_TW.md @@ -10,6 +10,7 @@ +


    截圖說明功能安裝與更新貢獻捐款授權憑證

    From de3d11568d85a526239582e3e00ced2c4b8c430a Mon Sep 17 00:00:00 2001 From: David Asunmo Date: Thu, 22 May 2025 03:15:13 +0100 Subject: [PATCH 078/143] Add nightly builds to all readmes Add matrix to .ru --- doc/README.ar.md | 10 ++++++++++ doc/README.asm.md | 10 ++++++++++ doc/README.de.md | 10 ++++++++++ doc/README.es.md | 10 ++++++++++ doc/README.fr.md | 10 ++++++++++ doc/README.hi.md | 10 ++++++++++ doc/README.it.md | 10 ++++++++++ doc/README.ja.md | 10 ++++++++++ doc/README.ko.md | 10 ++++++++++ doc/README.pa.md | 10 ++++++++++ doc/README.pl.md | 10 ++++++++++ doc/README.pt_BR.md | 10 ++++++++++ doc/README.ro.md | 10 ++++++++++ doc/README.ru.md | 13 ++++++++++++- doc/README.ryu.md | 10 ++++++++++ doc/README.so.md | 10 ++++++++++ doc/README.sr.md | 10 ++++++++++ doc/README.tr.md | 10 ++++++++++ doc/README.zh_TW.md | 10 ++++++++++ 19 files changed, 192 insertions(+), 1 deletion(-) diff --git a/doc/README.ar.md b/doc/README.ar.md index 41f498243..d40c4c2c3 100644 --- a/doc/README.ar.md +++ b/doc/README.ar.md @@ -6,12 +6,22 @@

    + + + + + + +

    + +

    +

    لقطات الشاشةالخدمات المدعومةوصفسماتالتثبيت والتحديثاتمساهمةالتبرعاترخصة

    موقعمدونةالأسئلة الشائعةإضغط

    diff --git a/doc/README.asm.md b/doc/README.asm.md index 8042b3db9..bd2058665 100644 --- a/doc/README.asm.md +++ b/doc/README.asm.md @@ -6,12 +6,22 @@

    + + + + + + +

    + +

    +

    স্ক্ৰীণশ্বটসমৰ্থিত সেৱাসমূহবিৱৰণ • diff --git a/doc/README.de.md b/doc/README.de.md index a1ab2efe5..6d93ae0b0 100644 --- a/doc/README.de.md +++ b/doc/README.de.md @@ -9,12 +9,22 @@

    + + + + + + +

    + +

    +

    ScreenshotsUnterstützte DiensteBeschreibungFeaturesInstallation und UpdatesBeitragSpendenLizenz

    WebsiteBlogFAQÜber NewPipe

    diff --git a/doc/README.es.md b/doc/README.es.md index 3e8744ecc..2a229443c 100644 --- a/doc/README.es.md +++ b/doc/README.es.md @@ -6,12 +6,22 @@

    + + + + + + +

    + +

    +

    Capturas de PantallaDescripciónCaracterísticasInstalación y ActualizacionesContribuciónDonarLicencia

    diff --git a/doc/README.fr.md b/doc/README.fr.md index 026811488..a98086265 100644 --- a/doc/README.fr.md +++ b/doc/README.fr.md @@ -9,12 +9,22 @@

    + + + + + + +

    + +

    +

    Captures d'écranServices SupportésDescriptionFonctionnalitésInstallation et mises à jourContribuerDonsLicence

    SiteBlogFAQPresse

    diff --git a/doc/README.hi.md b/doc/README.hi.md index 37ae71a4a..9d1e310f7 100644 --- a/doc/README.hi.md +++ b/doc/README.hi.md @@ -6,12 +6,22 @@

    + + + + + + +

    + +

    +

    ऐप कैसी दिखती हैसमर्थित सेवाएँविवरणसुविधाएँस्थापित करना और अपडेट करनायोगदान करेंआर्थिक योगदान करेंलाइसेंस

    वेबसाइटब्लॉगसाधारण सवाल-जवाबप्रेस

    diff --git a/doc/README.it.md b/doc/README.it.md index c42f28cfb..7b3b4ea9e 100644 --- a/doc/README.it.md +++ b/doc/README.it.md @@ -6,12 +6,22 @@

    + + + + + + +

    + +

    +

    ScreenshotServizi SupportatiDescrizioneFunzionalitàInstallazione e aggiornamentiContribuireDonareLicenza

    SitoBlogFAQStampa

    diff --git a/doc/README.ja.md b/doc/README.ja.md index 116b8904d..80a3f6316 100644 --- a/doc/README.ja.md +++ b/doc/README.ja.md @@ -6,12 +6,22 @@

    + + + + + + +

    + +

    +

    スクリーンショット説明機能インストールと更新貢献寄付ライセンス

    ウェブサイトブログFAQニュース

    diff --git a/doc/README.ko.md b/doc/README.ko.md index ecb68b7b3..ba93afd72 100644 --- a/doc/README.ko.md +++ b/doc/README.ko.md @@ -6,12 +6,22 @@

    + + + + + + +

    + +

    +

    ScreenshotsDescriptionFeaturesUpdatesContributionDonateLicense

    WebsiteBlogFAQPress

    diff --git a/doc/README.pa.md b/doc/README.pa.md index 0e254adf1..261fe5c4e 100644 --- a/doc/README.pa.md +++ b/doc/README.pa.md @@ -6,12 +6,22 @@

    + + + + + + +

    + +

    +

    ਐਪ ਕਿਹੋ-ਜਿਹੀ ਦਿਖਦੀ ਹੈਸਮਰਥਿਤ ਸੇਵਾਵਾਂਵਰਣਨਵਿਸ਼ੇਸ਼ਤਾਵਾਂਇੰਸਟਾਲੇਸ਼ਨ ਅਤੇ ਅੱਪਡੇਟਯੋਗਦਾਨਦਾਨਲਾਈਸੈਂਸ

    ਵੈੱਬਸਾਈਟਬਲੌਗਆਮ ਸਵਾਲ ਜਵਾਬਪ੍ਰੈਸ

    diff --git a/doc/README.pl.md b/doc/README.pl.md index 064c3b86b..7789cdd45 100644 --- a/doc/README.pl.md +++ b/doc/README.pl.md @@ -6,12 +6,22 @@

    + + + + + + +

    + +

    +

    ScreenshotyOpisFunkcjeInstalacja i aktualizacjeWkładWesprzyjLicencja

    StronaBlogFAQPress

    diff --git a/doc/README.pt_BR.md b/doc/README.pt_BR.md index 3a99d47da..c61750f9e 100644 --- a/doc/README.pt_BR.md +++ b/doc/README.pt_BR.md @@ -10,12 +10,22 @@

    + + + + + + +

    + +

    +

    ScreenshotsServiços SuportadosDescriçãoRecursosInstalação e atualizaçõesContribuiçõesDoarLicença

    SiteBlogFAQPress

    diff --git a/doc/README.ro.md b/doc/README.ro.md index ec440d03c..4ae789389 100644 --- a/doc/README.ro.md +++ b/doc/README.ro.md @@ -6,12 +6,22 @@

    + + + + + + +

    + +

    +

    Capturi de ecranDescriereFuncţiiInstalare şi actualizăriContribuţieDonaţiLicenţă

    WebsiteBlogFAQPresă

    diff --git a/doc/README.ru.md b/doc/README.ru.md index e3c76d329..8da329bf5 100644 --- a/doc/README.ru.md +++ b/doc/README.ru.md @@ -6,11 +6,22 @@

    + + + + + + -

    + +

    + + +

    +

    СкриншотыПоддерживаемые сервисыОписаниеВозможностиУстановка и обновленияУчастиеПожертвованиеЛицензия

    СайтБлогЧЗВПресса

    diff --git a/doc/README.ryu.md b/doc/README.ryu.md index a5b8f1e7c..d080076dc 100644 --- a/doc/README.ryu.md +++ b/doc/README.ryu.md @@ -6,12 +6,22 @@

    + + + + + + +

    + +

    +

    スクリーンショットしちめいちぬーインストールとぅこうしんこうきんちーふライセンス

    ウェブサイトブログFAQニュース

    diff --git a/doc/README.so.md b/doc/README.so.md index e3cfc6c8c..171aa903c 100644 --- a/doc/README.so.md +++ b/doc/README.so.md @@ -6,12 +6,22 @@

    + + + + + + +

    + +

    +

    Sawir-shaashadeedFaahfaahinWaxqabadkaKushubida iyo cusboonaysiintaKusoo KordhinUgu DeeqLaysinka

    Website-kaMaqaaladaSu'aalaha Aalaa La-iswaydiiyoWarbaahinta

    diff --git a/doc/README.sr.md b/doc/README.sr.md index 28445c547..22cb39457 100644 --- a/doc/README.sr.md +++ b/doc/README.sr.md @@ -9,12 +9,22 @@

    + + + + + + +

    + +

    +

    Снимци екранаПодржане услугеОписКарактеристикеИнсталација и ажурирањаДоприносДонацијаЛиценца

    Веб-сајтБлогЧППШтампа

    diff --git a/doc/README.tr.md b/doc/README.tr.md index 9d8419311..4d8cf11ea 100644 --- a/doc/README.tr.md +++ b/doc/README.tr.md @@ -6,12 +6,22 @@

    + + + + + + +

    + +

    +

    Ekran fotoğraflarıAçıklamaÖzelliklerKurulum ve güncellemelerKatkıda bulunmaBağışLisans

    Web sitesiBlogSSSBasın

    diff --git a/doc/README.zh_TW.md b/doc/README.zh_TW.md index 233f88be7..906967e8e 100644 --- a/doc/README.zh_TW.md +++ b/doc/README.zh_TW.md @@ -6,12 +6,22 @@

    + + + + + + +

    + +

    +

    截圖說明功能安裝與更新貢獻捐款授權憑證

    網站部落格FAQ媒體

    From 55bf74b4a79d509a26ba653172ef88443a9cbe46 Mon Sep 17 00:00:00 2001 From: David Asunmo <22662897+davidasunmo@users.noreply.github.com.> Date: Sat, 24 May 2025 02:15:45 +0100 Subject: [PATCH 079/143] Fix CI status badge --- README.md | 2 +- doc/README.ar.md | 2 +- doc/README.asm.md | 2 +- doc/README.de.md | 2 +- doc/README.es.md | 2 +- doc/README.fr.md | 2 +- doc/README.hi.md | 2 +- doc/README.it.md | 2 +- doc/README.ja.md | 2 +- doc/README.ko.md | 2 +- doc/README.pa.md | 2 +- doc/README.pl.md | 2 +- doc/README.pt_BR.md | 2 +- doc/README.ro.md | 2 +- doc/README.ru.md | 2 +- doc/README.ryu.md | 2 +- doc/README.so.md | 2 +- doc/README.sr.md | 2 +- doc/README.tr.md | 2 +- doc/README.zh_TW.md | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index f4548cf9e..3cd7927af 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ - +

    diff --git a/doc/README.ar.md b/doc/README.ar.md index d40c4c2c3..8747d3e2c 100644 --- a/doc/README.ar.md +++ b/doc/README.ar.md @@ -13,7 +13,7 @@ - +

    diff --git a/doc/README.asm.md b/doc/README.asm.md index bd2058665..c2d919d09 100644 --- a/doc/README.asm.md +++ b/doc/README.asm.md @@ -13,7 +13,7 @@ - +

    diff --git a/doc/README.de.md b/doc/README.de.md index 6d93ae0b0..03dd2b364 100644 --- a/doc/README.de.md +++ b/doc/README.de.md @@ -16,7 +16,7 @@ - +

    diff --git a/doc/README.es.md b/doc/README.es.md index 2a229443c..338b3242a 100644 --- a/doc/README.es.md +++ b/doc/README.es.md @@ -13,7 +13,7 @@ - +

    diff --git a/doc/README.fr.md b/doc/README.fr.md index a98086265..ee3621e27 100644 --- a/doc/README.fr.md +++ b/doc/README.fr.md @@ -16,7 +16,7 @@ - +

    diff --git a/doc/README.hi.md b/doc/README.hi.md index 9d1e310f7..ed56fca14 100644 --- a/doc/README.hi.md +++ b/doc/README.hi.md @@ -13,7 +13,7 @@ - +

    diff --git a/doc/README.it.md b/doc/README.it.md index 7b3b4ea9e..930959c77 100644 --- a/doc/README.it.md +++ b/doc/README.it.md @@ -13,7 +13,7 @@ - +

    diff --git a/doc/README.ja.md b/doc/README.ja.md index 80a3f6316..19902d57e 100644 --- a/doc/README.ja.md +++ b/doc/README.ja.md @@ -13,7 +13,7 @@ - +

    diff --git a/doc/README.ko.md b/doc/README.ko.md index ba93afd72..3c2f9f39e 100644 --- a/doc/README.ko.md +++ b/doc/README.ko.md @@ -13,7 +13,7 @@ - +

    diff --git a/doc/README.pa.md b/doc/README.pa.md index 261fe5c4e..2dbc94c14 100644 --- a/doc/README.pa.md +++ b/doc/README.pa.md @@ -13,7 +13,7 @@ - +

    diff --git a/doc/README.pl.md b/doc/README.pl.md index 7789cdd45..9d216c590 100644 --- a/doc/README.pl.md +++ b/doc/README.pl.md @@ -13,7 +13,7 @@ - +

    diff --git a/doc/README.pt_BR.md b/doc/README.pt_BR.md index c61750f9e..d65fa9790 100644 --- a/doc/README.pt_BR.md +++ b/doc/README.pt_BR.md @@ -17,7 +17,7 @@ - +

    diff --git a/doc/README.ro.md b/doc/README.ro.md index 4ae789389..5363ef7bc 100644 --- a/doc/README.ro.md +++ b/doc/README.ro.md @@ -13,7 +13,7 @@ - +

    diff --git a/doc/README.ru.md b/doc/README.ru.md index 8da329bf5..894e5f2e0 100644 --- a/doc/README.ru.md +++ b/doc/README.ru.md @@ -13,7 +13,7 @@ - +

    diff --git a/doc/README.ryu.md b/doc/README.ryu.md index d080076dc..8676f1bfd 100644 --- a/doc/README.ryu.md +++ b/doc/README.ryu.md @@ -13,7 +13,7 @@ - +

    diff --git a/doc/README.so.md b/doc/README.so.md index 171aa903c..82e544d93 100644 --- a/doc/README.so.md +++ b/doc/README.so.md @@ -13,7 +13,7 @@ - +

    diff --git a/doc/README.sr.md b/doc/README.sr.md index 22cb39457..d8b0fe435 100644 --- a/doc/README.sr.md +++ b/doc/README.sr.md @@ -16,7 +16,7 @@ - +

    diff --git a/doc/README.tr.md b/doc/README.tr.md index 4d8cf11ea..c6610d97d 100644 --- a/doc/README.tr.md +++ b/doc/README.tr.md @@ -13,7 +13,7 @@ - +

    diff --git a/doc/README.zh_TW.md b/doc/README.zh_TW.md index 906967e8e..04a8355cb 100644 --- a/doc/README.zh_TW.md +++ b/doc/README.zh_TW.md @@ -13,7 +13,7 @@ - +

    From aa0b45c05f70b981107a09c7574fb0270f538f20 Mon Sep 17 00:00:00 2001 From: Diana Victoria Furrer Date: Fri, 30 May 2025 13:21:45 +0200 Subject: [PATCH 080/143] ChannelTab.equals fix comparison --- app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java b/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java index 7e3f5d0c8..dd2ff0582 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java +++ b/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java @@ -458,7 +458,7 @@ public abstract class Tab { final ChannelTab other = (ChannelTab) obj; return super.equals(obj) && channelServiceId == other.channelServiceId - && channelUrl.equals(other.channelName) + && channelUrl.equals(other.channelUrl) && channelName.equals(other.channelName); } From 86869f0a1415b67f82e2b69687a431679e596743 Mon Sep 17 00:00:00 2001 From: Diana Victoria Furrer Date: Fri, 30 May 2025 16:55:07 +0200 Subject: [PATCH 081/143] Copied SelectFeedGroupFragment from SelectChannelFragment --- .../settings/SelectFeedGroupFragment.java | 213 ++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 app/src/main/java/org/schabi/newpipe/settings/SelectFeedGroupFragment.java diff --git a/app/src/main/java/org/schabi/newpipe/settings/SelectFeedGroupFragment.java b/app/src/main/java/org/schabi/newpipe/settings/SelectFeedGroupFragment.java new file mode 100644 index 000000000..76ba57b96 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/settings/SelectFeedGroupFragment.java @@ -0,0 +1,213 @@ +package org.schabi.newpipe.settings; + +import android.content.DialogInterface; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.ProgressBar; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.DialogFragment; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import org.schabi.newpipe.R; +import org.schabi.newpipe.database.subscription.SubscriptionEntity; +import org.schabi.newpipe.error.ErrorUtil; +import org.schabi.newpipe.local.subscription.SubscriptionManager; +import org.schabi.newpipe.util.ThemeHelper; +import org.schabi.newpipe.util.image.PicassoHelper; + +import java.util.List; +import java.util.Vector; + +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.core.Observer; +import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.schedulers.Schedulers; + +/** + * Created by Christian Schabesberger on 26.09.17. + * SelectChannelFragment.java is part of NewPipe. + *

    + * NewPipe 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. + *

    + *

    + * NewPipe 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 NewPipe. If not, see . + *

    + */ + +public class SelectFeedGroupFragment extends DialogFragment { + + private OnSelectedListener onSelectedListener = null; + private OnCancelListener onCancelListener = null; + + private ProgressBar progressBar; + private TextView emptyView; + private RecyclerView recyclerView; + + private List subscriptions = new Vector<>(); + + public void setOnSelectedListener(final OnSelectedListener listener) { + onSelectedListener = listener; + } + + public void setOnCancelListener(final OnCancelListener listener) { + onCancelListener = listener; + } + + /*////////////////////////////////////////////////////////////////////////// + // Init + //////////////////////////////////////////////////////////////////////////*/ + + @Override + public void onCreate(@Nullable final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setStyle(STYLE_NO_TITLE, ThemeHelper.getMinWidthDialogTheme(requireContext())); + } + + @Override + public View onCreateView(@NonNull final LayoutInflater inflater, final ViewGroup container, + final Bundle savedInstanceState) { + final View v = inflater.inflate(R.layout.select_channel_fragment, container, false); + recyclerView = v.findViewById(R.id.items_list); + recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + final SelectChannelAdapter channelAdapter = new SelectChannelAdapter(); + recyclerView.setAdapter(channelAdapter); + + progressBar = v.findViewById(R.id.progressBar); + emptyView = v.findViewById(R.id.empty_state_view); + progressBar.setVisibility(View.VISIBLE); + recyclerView.setVisibility(View.GONE); + emptyView.setVisibility(View.GONE); + + + final SubscriptionManager subscriptionManager = new SubscriptionManager(requireContext()); + subscriptionManager.subscriptions().toObservable() + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(getSubscriptionObserver()); + + return v; + } + + /*////////////////////////////////////////////////////////////////////////// + // Handle actions + //////////////////////////////////////////////////////////////////////////*/ + + @Override + public void onCancel(@NonNull final DialogInterface dialogInterface) { + super.onCancel(dialogInterface); + if (onCancelListener != null) { + onCancelListener.onCancel(); + } + } + + private void clickedItem(final int position) { + if (onSelectedListener != null) { + final SubscriptionEntity entry = subscriptions.get(position); + onSelectedListener + .onChannelSelected(entry.getServiceId(), entry.getUrl(), entry.getName()); + } + dismiss(); + } + + /*////////////////////////////////////////////////////////////////////////// + // Item handling + //////////////////////////////////////////////////////////////////////////*/ + + private void displayChannels(final List newSubscriptions) { + this.subscriptions = newSubscriptions; + progressBar.setVisibility(View.GONE); + if (newSubscriptions.isEmpty()) { + emptyView.setVisibility(View.VISIBLE); + return; + } + recyclerView.setVisibility(View.VISIBLE); + + } + + private Observer> getSubscriptionObserver() { + return new Observer>() { + @Override + public void onSubscribe(@NonNull final Disposable disposable) { } + + @Override + public void onNext(@NonNull final List newSubscriptions) { + displayChannels(newSubscriptions); + } + + @Override + public void onError(@NonNull final Throwable exception) { + ErrorUtil.showUiErrorSnackbar(SelectFeedGroupFragment.this, + "Loading subscription", exception); + } + + @Override + public void onComplete() { } + }; + } + + /*////////////////////////////////////////////////////////////////////////// + // Interfaces + //////////////////////////////////////////////////////////////////////////*/ + + public interface OnSelectedListener { + void onChannelSelected(int serviceId, String url, String name); + } + + public interface OnCancelListener { + void onCancel(); + } + + private class SelectChannelAdapter + extends RecyclerView.Adapter { + @NonNull + @Override + public SelectChannelItemHolder onCreateViewHolder(final ViewGroup parent, + final int viewType) { + final View item = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.select_channel_item, parent, false); + return new SelectChannelItemHolder(item); + } + + @Override + public void onBindViewHolder(final SelectChannelItemHolder holder, final int position) { + final SubscriptionEntity entry = subscriptions.get(position); + holder.titleView.setText(entry.getName()); + holder.view.setOnClickListener(view -> clickedItem(position)); + PicassoHelper.loadAvatar(entry.getAvatarUrl()).into(holder.thumbnailView); + } + + @Override + public int getItemCount() { + return subscriptions.size(); + } + + public class SelectChannelItemHolder extends RecyclerView.ViewHolder { + public final View view; + final ImageView thumbnailView; + final TextView titleView; + SelectChannelItemHolder(final View v) { + super(v); + this.view = v; + thumbnailView = v.findViewById(R.id.itemThumbnailView); + titleView = v.findViewById(R.id.itemTitleView); + } + } + } +} From e6c4690e7da2679f9700816f4d9288442b4782c1 Mon Sep 17 00:00:00 2001 From: Diana Victoria Furrer Date: Fri, 30 May 2025 17:07:19 +0200 Subject: [PATCH 082/143] # Copied Layouts Copied select_channel_fragment to select_feed_group_fragment Copied select_channel_item to select_feed_group_item # Change Replaced the Layout references in the new Class SelectFeedGroupFragment --- .../settings/SelectFeedGroupFragment.java | 4 +- .../res/layout/select_feed_group_fragment.xml | 42 +++++++++++++++++++ .../res/layout/select_feed_group_item.xml | 39 +++++++++++++++++ 3 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 app/src/main/res/layout/select_feed_group_fragment.xml create mode 100644 app/src/main/res/layout/select_feed_group_item.xml diff --git a/app/src/main/java/org/schabi/newpipe/settings/SelectFeedGroupFragment.java b/app/src/main/java/org/schabi/newpipe/settings/SelectFeedGroupFragment.java index 76ba57b96..c6cc28a60 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SelectFeedGroupFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/SelectFeedGroupFragment.java @@ -83,7 +83,7 @@ public class SelectFeedGroupFragment extends DialogFragment { @Override public View onCreateView(@NonNull final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) { - final View v = inflater.inflate(R.layout.select_channel_fragment, container, false); + final View v = inflater.inflate(R.layout.select_feed_group_fragment, container, false); recyclerView = v.findViewById(R.id.items_list); recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); final SelectChannelAdapter channelAdapter = new SelectChannelAdapter(); @@ -181,7 +181,7 @@ public class SelectFeedGroupFragment extends DialogFragment { public SelectChannelItemHolder onCreateViewHolder(final ViewGroup parent, final int viewType) { final View item = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.select_channel_item, parent, false); + .inflate(R.layout.select_feed_group_item, parent, false); return new SelectChannelItemHolder(item); } diff --git a/app/src/main/res/layout/select_feed_group_fragment.xml b/app/src/main/res/layout/select_feed_group_fragment.xml new file mode 100644 index 000000000..bd62aefea --- /dev/null +++ b/app/src/main/res/layout/select_feed_group_fragment.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/layout/select_feed_group_item.xml b/app/src/main/res/layout/select_feed_group_item.xml new file mode 100644 index 000000000..c5fd51bb8 --- /dev/null +++ b/app/src/main/res/layout/select_feed_group_item.xml @@ -0,0 +1,39 @@ + + + + + + + + From 7c3989ff93cf709f2319b5fd5c2ffabd486f56e3 Mon Sep 17 00:00:00 2001 From: Diana Victoria Furrer Date: Fri, 30 May 2025 17:45:51 +0200 Subject: [PATCH 083/143] # Change Adjusted the new Class SelectFeedGroupFragment for its Role - Renamed Variables - adjusted Imports - adjusted Interface with FeedGroupEntity Values --- .../settings/SelectFeedGroupFragment.java | 61 ++++++++++--------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/SelectFeedGroupFragment.java b/app/src/main/java/org/schabi/newpipe/settings/SelectFeedGroupFragment.java index c6cc28a60..662379369 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SelectFeedGroupFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/SelectFeedGroupFragment.java @@ -15,12 +15,12 @@ import androidx.fragment.app.DialogFragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import org.schabi.newpipe.NewPipeDatabase; import org.schabi.newpipe.R; -import org.schabi.newpipe.database.subscription.SubscriptionEntity; +import org.schabi.newpipe.database.AppDatabase; +import org.schabi.newpipe.database.feed.model.FeedGroupEntity; import org.schabi.newpipe.error.ErrorUtil; -import org.schabi.newpipe.local.subscription.SubscriptionManager; import org.schabi.newpipe.util.ThemeHelper; -import org.schabi.newpipe.util.image.PicassoHelper; import java.util.List; import java.util.Vector; @@ -60,7 +60,7 @@ public class SelectFeedGroupFragment extends DialogFragment { private TextView emptyView; private RecyclerView recyclerView; - private List subscriptions = new Vector<>(); + private List feedGroups = new Vector<>(); public void setOnSelectedListener(final OnSelectedListener listener) { onSelectedListener = listener; @@ -86,8 +86,8 @@ public class SelectFeedGroupFragment extends DialogFragment { final View v = inflater.inflate(R.layout.select_feed_group_fragment, container, false); recyclerView = v.findViewById(R.id.items_list); recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); - final SelectChannelAdapter channelAdapter = new SelectChannelAdapter(); - recyclerView.setAdapter(channelAdapter); + final SelectFeedGroupAdapter feedGroupAdapter = new SelectFeedGroupAdapter(); + recyclerView.setAdapter(feedGroupAdapter); progressBar = v.findViewById(R.id.progressBar); emptyView = v.findViewById(R.id.empty_state_view); @@ -96,11 +96,11 @@ public class SelectFeedGroupFragment extends DialogFragment { emptyView.setVisibility(View.GONE); - final SubscriptionManager subscriptionManager = new SubscriptionManager(requireContext()); - subscriptionManager.subscriptions().toObservable() + final AppDatabase database = NewPipeDatabase.getInstance(requireContext()); + database.feedGroupDAO().getAll().toObservable() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) - .subscribe(getSubscriptionObserver()); + .subscribe(getFeedGroupObserver()); return v; } @@ -119,9 +119,10 @@ public class SelectFeedGroupFragment extends DialogFragment { private void clickedItem(final int position) { if (onSelectedListener != null) { - final SubscriptionEntity entry = subscriptions.get(position); + final FeedGroupEntity entry = feedGroups.get(position); onSelectedListener - .onChannelSelected(entry.getServiceId(), entry.getUrl(), entry.getName()); + .onFeedGroupSelected(entry.getUid(), entry.getName(), + entry.getIcon().getDrawableResource()); } dismiss(); } @@ -130,10 +131,10 @@ public class SelectFeedGroupFragment extends DialogFragment { // Item handling //////////////////////////////////////////////////////////////////////////*/ - private void displayChannels(final List newSubscriptions) { - this.subscriptions = newSubscriptions; + private void displayFeedGroups(final List newFeedGroups) { + this.feedGroups = newFeedGroups; progressBar.setVisibility(View.GONE); - if (newSubscriptions.isEmpty()) { + if (newFeedGroups.isEmpty()) { emptyView.setVisibility(View.VISIBLE); return; } @@ -141,20 +142,20 @@ public class SelectFeedGroupFragment extends DialogFragment { } - private Observer> getSubscriptionObserver() { - return new Observer>() { + private Observer> getFeedGroupObserver() { + return new Observer>() { @Override public void onSubscribe(@NonNull final Disposable disposable) { } @Override - public void onNext(@NonNull final List newSubscriptions) { - displayChannels(newSubscriptions); + public void onNext(@NonNull final List newGroups) { + displayFeedGroups(newGroups); } @Override public void onError(@NonNull final Throwable exception) { ErrorUtil.showUiErrorSnackbar(SelectFeedGroupFragment.this, - "Loading subscription", exception); + "Loading Feed Groups", exception); } @Override @@ -167,42 +168,42 @@ public class SelectFeedGroupFragment extends DialogFragment { //////////////////////////////////////////////////////////////////////////*/ public interface OnSelectedListener { - void onChannelSelected(int serviceId, String url, String name); + void onFeedGroupSelected(Long groupId, String name, int icon); } public interface OnCancelListener { void onCancel(); } - private class SelectChannelAdapter - extends RecyclerView.Adapter { + private class SelectFeedGroupAdapter + extends RecyclerView.Adapter { @NonNull @Override - public SelectChannelItemHolder onCreateViewHolder(final ViewGroup parent, + public SelectFeedGroupItemHolder onCreateViewHolder(final ViewGroup parent, final int viewType) { final View item = LayoutInflater.from(parent.getContext()) .inflate(R.layout.select_feed_group_item, parent, false); - return new SelectChannelItemHolder(item); + return new SelectFeedGroupItemHolder(item); } @Override - public void onBindViewHolder(final SelectChannelItemHolder holder, final int position) { - final SubscriptionEntity entry = subscriptions.get(position); + public void onBindViewHolder(final SelectFeedGroupItemHolder holder, final int position) { + final FeedGroupEntity entry = feedGroups.get(position); holder.titleView.setText(entry.getName()); holder.view.setOnClickListener(view -> clickedItem(position)); - PicassoHelper.loadAvatar(entry.getAvatarUrl()).into(holder.thumbnailView); + holder.thumbnailView.setImageResource(entry.getIcon().getDrawableResource()); } @Override public int getItemCount() { - return subscriptions.size(); + return feedGroups.size(); } - public class SelectChannelItemHolder extends RecyclerView.ViewHolder { + public class SelectFeedGroupItemHolder extends RecyclerView.ViewHolder { public final View view; final ImageView thumbnailView; final TextView titleView; - SelectChannelItemHolder(final View v) { + SelectFeedGroupItemHolder(final View v) { super(v); this.view = v; thumbnailView = v.findViewById(R.id.itemThumbnailView); From 436626fa8394a79c36ee71b7150f83cb39b88095 Mon Sep 17 00:00:00 2001 From: Diana Victoria Furrer Date: Fri, 30 May 2025 17:54:49 +0200 Subject: [PATCH 084/143] # Change Adjusted select_feed_group_fragment Layout - reference select_feed_group_item layout - use new Strings Added strings: - select_a_feed_group - no_feed_group_created_yet --- app/src/main/res/layout/select_feed_group_fragment.xml | 6 +++--- app/src/main/res/values/strings.xml | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/layout/select_feed_group_fragment.xml b/app/src/main/res/layout/select_feed_group_fragment.xml index bd62aefea..bb17d5f6e 100644 --- a/app/src/main/res/layout/select_feed_group_fragment.xml +++ b/app/src/main/res/layout/select_feed_group_fragment.xml @@ -15,14 +15,14 @@ android:layout_marginEnd="5dp" android:layout_marginRight="5dp" android:layout_marginBottom="10dp" - android:text="@string/select_a_channel" + android:text="@string/select_a_feed_group" android:textAppearance="?android:attr/textAppearanceLarge" /> + tools:listitem="@layout/select_feed_group_item" /> Do you want to also import settings?
    Could not load comments The language will change once the app is restarted + Select a feed group + No feed group created yet Trending Top 50 From f8ed8e575ed05c832f28ddaa3aba675004a3df2e Mon Sep 17 00:00:00 2001 From: Diana Victoria Furrer Date: Fri, 30 May 2025 20:47:37 +0200 Subject: [PATCH 085/143] # Change Added FEEDGROUP Tab Code to - ChooseTabsFragment - Tab Added strings: - feed_group_page_summary --- .../settings/tabs/ChooseTabsFragment.java | 17 ++++ .../org/schabi/newpipe/settings/tabs/Tab.java | 94 ++++++++++++++++++- app/src/main/res/values/strings.xml | 1 + 3 files changed, 111 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/tabs/ChooseTabsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/tabs/ChooseTabsFragment.java index 289c824ba..585d00260 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/tabs/ChooseTabsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/tabs/ChooseTabsFragment.java @@ -34,6 +34,7 @@ import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.settings.SelectChannelFragment; import org.schabi.newpipe.settings.SelectKioskFragment; import org.schabi.newpipe.settings.SelectPlaylistFragment; +import org.schabi.newpipe.settings.SelectFeedGroupFragment; import org.schabi.newpipe.settings.tabs.AddTabDialog.ChooseTabListItem; import org.schabi.newpipe.util.ThemeHelper; @@ -203,6 +204,14 @@ public class ChooseTabsFragment extends Fragment { }); selectPlaylistFragment.show(getParentFragmentManager(), "select_playlist"); return; + case FEEDGROUP: + final SelectFeedGroupFragment selectFeedGroupFragment = + new SelectFeedGroupFragment(); + selectFeedGroupFragment.setOnSelectedListener( + (groupId, name, iconId) -> + addTab(new Tab.FeedGroupTab(groupId, name, iconId))); + selectFeedGroupFragment.show(getParentFragmentManager(), "select_feed_group"); + return; default: addTab(type.getTab()); break; @@ -244,6 +253,11 @@ public class ChooseTabsFragment extends Fragment { getString(R.string.playlist_page_summary), tab.getTabIconRes(context))); break; + case FEEDGROUP: + returnList.add(new ChooseTabListItem(tab.getTabId(), + getString(R.string.feed_group_page_summary), + tab.getTabIconRes(context))); + break; default: if (!tabList.contains(tab)) { returnList.add(new ChooseTabListItem(context, tab)); @@ -396,6 +410,9 @@ public class ChooseTabsFragment extends Fragment { ? getString(R.string.local) : getNameOfServiceById(serviceId); return serviceName + "/" + tab.getTabName(requireContext()); + case FEEDGROUP: + return getString(R.string.feed_groups_header_title) + + "/" + tab.getTabName(requireContext()); default: return tab.getTabName(requireContext()); } diff --git a/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java b/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java index 7e3f5d0c8..d44badd68 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java +++ b/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java @@ -93,6 +93,8 @@ public abstract class Tab { return new ChannelTab(jsonObject); case PLAYLIST: return new PlaylistTab(jsonObject); + case FEEDGROUP: + return new FeedGroupTab(jsonObject); } } @@ -162,7 +164,8 @@ public abstract class Tab { HISTORY(new HistoryTab()), KIOSK(new KioskTab()), CHANNEL(new ChannelTab()), - PLAYLIST(new PlaylistTab()); + PLAYLIST(new PlaylistTab()), + FEEDGROUP(new FeedGroupTab()); private final Tab tab; @@ -652,4 +655,93 @@ public abstract class Tab { return playlistType; } } + public static class FeedGroupTab extends Tab { + public static final int ID = 9; + private static final String JSON_FEED_GROUP_ID_KEY = "feed_group_id"; + private static final String JSON_FEED_GROUP_NAME_KEY = "feed_group_name"; + private static final String JSON_FEED_GROUP_ICON_KEY = "feed_group_icon"; + private Long feedGroupId; + private String feedGroupName; + private int iconId; + + private FeedGroupTab() { + this((long) -1, NO_NAME, R.drawable.ic_asterisk); + } + + public FeedGroupTab(final Long feedGroupId, final String feedGroupName, + final int iconId) { + this.feedGroupId = feedGroupId; + this.feedGroupName = feedGroupName; + this.iconId = iconId; + + } + + public FeedGroupTab(final JsonObject jsonObject) { + super(jsonObject); + } + + @Override + public int getTabId() { + return ID; + } + + @Override + public String getTabName(final Context context) { + return feedGroupName; + } + + @DrawableRes + @Override + public int getTabIconRes(final Context context) { + return this.iconId; + } + + @Override + public FeedFragment getFragment(final Context context) { + return FeedFragment.newInstance(feedGroupId, feedGroupName); + } + + @Override + protected void writeDataToJson(final JsonStringWriter writerSink) { + writerSink.value(JSON_FEED_GROUP_ID_KEY, feedGroupId) + .value(JSON_FEED_GROUP_NAME_KEY, feedGroupName) + .value(JSON_FEED_GROUP_ICON_KEY, iconId); + } + + @Override + protected void readDataFromJson(final JsonObject jsonObject) { + feedGroupId = jsonObject.getLong(JSON_FEED_GROUP_ID_KEY, -1); + feedGroupName = jsonObject.getString(JSON_FEED_GROUP_NAME_KEY, NO_NAME); + iconId = jsonObject.getInt(JSON_FEED_GROUP_ICON_KEY, R.drawable.ic_asterisk); + } + + @Override + public boolean equals(final Object obj) { + if (!(obj instanceof FeedGroupTab)) { + return false; + } + final FeedGroupTab other = (FeedGroupTab) obj; + return super.equals(obj) + && feedGroupId.equals(other.feedGroupId) + && feedGroupName.equals(other.feedGroupName) + && iconId == other.iconId; + } + + @Override + public int hashCode() { + return Objects.hash(getTabId(), feedGroupId, feedGroupName, iconId); + } + + public Long getFeedGroupId() { + return feedGroupId; + } + + public String getFeedGroupName() { + return feedGroupName; + } + + public int getIconId() { + return iconId; + } + } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b90482812..1015dea08 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -689,6 +689,7 @@
    What\'s New + Channel group page Channel groups Feed last updated: %s Not loaded: %d From 279caac91529d40b611581422591ed81801cddff Mon Sep 17 00:00:00 2001 From: Diana Victoria Furrer Date: Fri, 30 May 2025 21:00:37 +0200 Subject: [PATCH 086/143] # Change Layout select_feed_group_item (FeedGroup Picker in the Settings) Remove rounded style from the icons --- app/src/main/res/layout/select_feed_group_item.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/res/layout/select_feed_group_item.xml b/app/src/main/res/layout/select_feed_group_item.xml index c5fd51bb8..e40fe6727 100644 --- a/app/src/main/res/layout/select_feed_group_item.xml +++ b/app/src/main/res/layout/select_feed_group_item.xml @@ -20,7 +20,6 @@ android:layout_marginStart="3dp" android:layout_marginRight="8dp" android:src="@drawable/placeholder_person" - app:shapeAppearance="@style/CircularImageView" tools:ignore="RtlHardcoded" /> Date: Sat, 31 May 2025 01:30:49 +0200 Subject: [PATCH 087/143] # Fixed Feed Group Titlebar - use default fragment_feed_title for TabName - only clear FeedFragment bar subtitle when it matches the groupName to clear. --- .../org/schabi/newpipe/local/feed/FeedFragment.kt | 15 +++++++++++++-- .../org/schabi/newpipe/settings/tabs/Tab.java | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt b/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt index 61eb4c8d2..91f98f5d2 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt @@ -269,7 +269,12 @@ class FeedFragment : BaseStateFragment() { override fun onDestroyOptionsMenu() { super.onDestroyOptionsMenu() - activity?.supportActionBar?.subtitle = null + if ( + (groupName != "") && + (activity?.supportActionBar?.subtitle == groupName) + ) { + activity?.supportActionBar?.subtitle = null + } } override fun onDestroy() { @@ -281,7 +286,13 @@ class FeedFragment : BaseStateFragment() { } super.onDestroy() - activity?.supportActionBar?.subtitle = null + + if ( + (groupName != "") && + (activity?.supportActionBar?.subtitle == groupName) + ) { + activity?.supportActionBar?.subtitle = null + } } override fun onDestroyView() { diff --git a/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java b/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java index d44badd68..83abf87d4 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java +++ b/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java @@ -687,7 +687,7 @@ public abstract class Tab { @Override public String getTabName(final Context context) { - return feedGroupName; + return context.getString(R.string.fragment_feed_title); } @DrawableRes From 712724211cac5a4ba7bfba927a7940cc1018f541 Mon Sep 17 00:00:00 2001 From: Diana Victoria Furrer Date: Sat, 31 May 2025 01:41:06 +0200 Subject: [PATCH 088/143] added FeedGroup to Tab Settings UnitTest --- .../newpipe/settings/tabs/TabsJsonHelperTest.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/src/test/java/org/schabi/newpipe/settings/tabs/TabsJsonHelperTest.java b/app/src/test/java/org/schabi/newpipe/settings/tabs/TabsJsonHelperTest.java index bddb130fe..561a8cbec 100644 --- a/app/src/test/java/org/schabi/newpipe/settings/tabs/TabsJsonHelperTest.java +++ b/app/src/test/java/org/schabi/newpipe/settings/tabs/TabsJsonHelperTest.java @@ -93,9 +93,11 @@ public class TabsJsonHelperTest { final Tab.ChannelTab channelTab = new Tab.ChannelTab( 666, "https://example.org", "testName"); final Tab.KioskTab kioskTab = new Tab.KioskTab(123, "trending_key"); + final Tab.FeedGroupTab feedGroupTab = new Tab.FeedGroupTab( + 1L, "x", 123); final List tabs = Arrays.asList( - blankTab, defaultKioskTab, subscriptionsTab, channelTab, kioskTab); + blankTab, defaultKioskTab, subscriptionsTab, channelTab, kioskTab, feedGroupTab); final String returnedJson = TabsJsonHelper.getJsonToSave(tabs); // Reading @@ -130,5 +132,13 @@ public class TabsJsonHelperTest { assertEquals(kioskTab.getTabId(), kioskTabFromReturnedJson.getTabId()); assertEquals(kioskTab.getKioskServiceId(), kioskTabFromReturnedJson.getKioskServiceId()); assertEquals(kioskTab.getKioskId(), kioskTabFromReturnedJson.getKioskId()); + + final Tab.FeedGroupTab grpTabFromReturnedJson = requireNonNull( + (Tab.FeedGroupTab) Tab.from((JsonObject) tabsFromArray.get(5) + )); + assertEquals(feedGroupTab.getTabId(), grpTabFromReturnedJson.getTabId()); + assertEquals(feedGroupTab.getFeedGroupId(), grpTabFromReturnedJson.getFeedGroupId()); + assertEquals(feedGroupTab.getIconId(), grpTabFromReturnedJson.getIconId()); + assertEquals(feedGroupTab.getFeedGroupName(), grpTabFromReturnedJson.getFeedGroupName()); } } From 205d18f4c4763e0dfbc8f516c713d93f3c8ae4ea Mon Sep 17 00:00:00 2001 From: Diana Victoria Furrer Date: Sat, 31 May 2025 14:11:26 +0200 Subject: [PATCH 089/143] Use GroupName for the Settings Text. The Tabname displays the default Feed title. --- .../org/schabi/newpipe/settings/tabs/ChooseTabsFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/tabs/ChooseTabsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/tabs/ChooseTabsFragment.java index 585d00260..738a9c926 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/tabs/ChooseTabsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/tabs/ChooseTabsFragment.java @@ -412,7 +412,7 @@ public class ChooseTabsFragment extends Fragment { return serviceName + "/" + tab.getTabName(requireContext()); case FEEDGROUP: return getString(R.string.feed_groups_header_title) - + "/" + tab.getTabName(requireContext()); + + "/" + ((Tab.FeedGroupTab) tab).getFeedGroupName(); default: return tab.getTabName(requireContext()); } From 571b7bc74bcb35153532efd4e2430e6e6537a422 Mon Sep 17 00:00:00 2001 From: Stypox Date: Wed, 4 Jun 2025 11:18:04 +0200 Subject: [PATCH 090/143] Improve layout of select_feed_group_item --- app/src/main/res/layout/select_feed_group_item.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/src/main/res/layout/select_feed_group_item.xml b/app/src/main/res/layout/select_feed_group_item.xml index e40fe6727..ccce555f5 100644 --- a/app/src/main/res/layout/select_feed_group_item.xml +++ b/app/src/main/res/layout/select_feed_group_item.xml @@ -1,6 +1,5 @@ Date: Wed, 4 Jun 2025 11:54:31 +0200 Subject: [PATCH 091/143] Show search filter in search bar hint --- .../newpipe/fragments/list/search/SearchFragment.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java index 4c7bb15a8..8e46716a8 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java @@ -945,6 +945,15 @@ public class SearchFragment extends BaseListFragment Date: Thu, 5 Jun 2025 14:30:04 +0200 Subject: [PATCH 092/143] SearchFragment: show filter in brackets behind service name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is still not perfect, but it will show the selected search filter in addition to the service name, like: “Search YouTube (Playlists)”. It will not distinguish between a YouTube Music and Youtube filter, so it will display the same thing. Could be improved, but then the text gets too long! :( --- .../fragments/list/search/SearchFragment.java | 19 ++++++++++++------- app/src/main/res/values/strings.xml | 1 + 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java index 8e46716a8..fa1669093 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java @@ -945,13 +945,18 @@ public class SearchFragment extends BaseListFragmentDownload stream file
    Search Search %1$s + Search %1$s (%2$s) Settings Did you mean \"%1$s\"? Showing results for: %s From aa75a1449f16db356af3b21e95639b7b1d7fccd7 Mon Sep 17 00:00:00 2001 From: Diana Victoria Furrer Date: Sun, 15 Jun 2025 02:19:56 +0200 Subject: [PATCH 093/143] use MimeTypeMap from android webkit to check if the json MimeType is unsupported --- .../local/subscription/SubscriptionFragment.kt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt index 7288d9103..077d69622 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt @@ -13,6 +13,7 @@ import android.view.MenuItem import android.view.SubMenu import android.view.View import android.view.ViewGroup +import android.webkit.MimeTypeMap import android.widget.Toast import androidx.activity.result.ActivityResult import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult @@ -460,6 +461,14 @@ class SubscriptionFragment : BaseStateFragment() { } companion object { - const val JSON_MIME_TYPE = "application/json" + val JSON_MIME_TYPE = getMimeType() + + private fun getMimeType(): String { + val mimeTypeJson = MimeTypeMap.getSingleton().getMimeTypeFromExtension("json") + return if (mimeTypeJson.isNullOrBlank()) + "application/octet-stream" + else + mimeTypeJson + } } } From 0c9f5ddcaf1c4d0667de07eb73b5c00fbaef96ee Mon Sep 17 00:00:00 2001 From: Diana Victoria Furrer Date: Tue, 17 Jun 2025 15:42:01 +0200 Subject: [PATCH 094/143] change according to Isira-Seneviratne suggestion --- .../local/subscription/SubscriptionFragment.kt | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt index 077d69622..8e758adef 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt @@ -461,14 +461,7 @@ class SubscriptionFragment : BaseStateFragment() { } companion object { - val JSON_MIME_TYPE = getMimeType() - - private fun getMimeType(): String { - val mimeTypeJson = MimeTypeMap.getSingleton().getMimeTypeFromExtension("json") - return if (mimeTypeJson.isNullOrBlank()) - "application/octet-stream" - else - mimeTypeJson - } + val JSON_MIME_TYPE = MimeTypeMap.getSingleton() + .getMimeTypeFromExtension("json") ?: "application/octet-stream" } } From d048bca8b44c5f8ca2a2ef36a02b9eb18aa8ced2 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sat, 28 Jun 2025 15:17:18 +0200 Subject: [PATCH 095/143] Temporarily disable sonarcloud CI step --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 54415858e..f6708fa83 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -111,6 +111,7 @@ jobs: path: app/build/reports/androidTests/connected/** sonar: + if: ${{ false }} # the key has expired and needs to be regenerated by the sonar admins runs-on: ubuntu-latest permissions: From a0adeb009930449cff2b3582b8d37a9a94643014 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 6 Jul 2025 13:51:59 +0200 Subject: [PATCH 096/143] Fix "Get it on F-Droid" appearing giant in README --- README.md | 2 +- doc/README.ar.md | 2 +- doc/README.asm.md | 2 +- doc/README.de.md | 2 +- doc/README.es.md | 2 +- doc/README.fr.md | 2 +- doc/README.hi.md | 2 +- doc/README.it.md | 2 +- doc/README.ja.md | 2 +- doc/README.ko.md | 2 +- doc/README.pa.md | 2 +- doc/README.pl.md | 2 +- doc/README.pt_BR.md | 2 +- doc/README.ro.md | 2 +- doc/README.ru.md | 2 +- doc/README.ryu.md | 2 +- doc/README.so.md | 2 +- doc/README.sr.md | 2 +- doc/README.tr.md | 2 +- doc/README.zh_TW.md | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 3cd7927af..095c3c43a 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@

    NewPipe

    A libre lightweight streaming front-end for Android.

    -

    Get it on F-Droid

    +

    Get it on F-Droid

    diff --git a/doc/README.ar.md b/doc/README.ar.md index 8747d3e2c..f005050c7 100644 --- a/doc/README.ar.md +++ b/doc/README.ar.md @@ -2,7 +2,7 @@

    NewPipe

    .Android واجهة أمامية متدفقة خفيفة الوزن لنظام

    -

    Get it on F-Droid

    +

    Get it on F-Droid

    diff --git a/doc/README.asm.md b/doc/README.asm.md index c2d919d09..37d0949b7 100644 --- a/doc/README.asm.md +++ b/doc/README.asm.md @@ -2,7 +2,7 @@

    NewPipe

    এণ্ড্ৰইডৰ বাবে এটা লিব্ৰে লাইটৱেট ষ্ট্ৰীমিং ফ্ৰন্ট-এণ্ড।

    -

    Get it on F-Droid

    +

    Get it on F-Droid

    diff --git a/doc/README.de.md b/doc/README.de.md index 03dd2b364..5cbb4e6dd 100644 --- a/doc/README.de.md +++ b/doc/README.de.md @@ -5,7 +5,7 @@

    NewPipe

    Eine freie, offene und leichtgewichtige Streaming App für Android.

    -

    Hole es dir auf F-Droid

    +

    Hole es dir auf F-Droid

    diff --git a/doc/README.es.md b/doc/README.es.md index 338b3242a..4a08cba08 100644 --- a/doc/README.es.md +++ b/doc/README.es.md @@ -2,7 +2,7 @@

    NewPipe

    Una interfaz de streaming ligera y libre para Android.

    -

    Get it on F-Droid

    +

    Get it on F-Droid

    diff --git a/doc/README.fr.md b/doc/README.fr.md index ee3621e27..cfebcb2a6 100644 --- a/doc/README.fr.md +++ b/doc/README.fr.md @@ -5,7 +5,7 @@

    NewPipe

    Un front-end de streaming libre et léger pour Android.

    -

    Get it on F-Droid

    +

    Get it on F-Droid

    diff --git a/doc/README.hi.md b/doc/README.hi.md index ed56fca14..6098c6c26 100644 --- a/doc/README.hi.md +++ b/doc/README.hi.md @@ -2,7 +2,7 @@

    NewPipe

    Android के लिए एक ओपन सोर्स, हल्का YouTube ऐप।

    -

    इसे F-Droid पर पाएँ

    +

    इसे F-Droid पर पाएँ

    diff --git a/doc/README.it.md b/doc/README.it.md index 930959c77..d926db6bc 100644 --- a/doc/README.it.md +++ b/doc/README.it.md @@ -2,7 +2,7 @@

    NewPipe

    Un frontend di streaming libero e leggero per Android.

    -

    Scaricalo su F-Droid

    +

    Scaricalo su F-Droid

    diff --git a/doc/README.ja.md b/doc/README.ja.md index 19902d57e..1e751855b 100644 --- a/doc/README.ja.md +++ b/doc/README.ja.md @@ -2,7 +2,7 @@

    NewPipe

    自由で軽量な Android 向けストリーミングフロントエンド

    -

    Get it on F-Droid

    +

    Get it on F-Droid

    diff --git a/doc/README.ko.md b/doc/README.ko.md index 3c2f9f39e..39fb7e11c 100644 --- a/doc/README.ko.md +++ b/doc/README.ko.md @@ -2,7 +2,7 @@

    NewPipe

    A libre lightweight streaming frontend for Android.

    -

    Get it on F-Droid

    +

    Get it on F-Droid

    diff --git a/doc/README.pa.md b/doc/README.pa.md index 2dbc94c14..9b84ded18 100644 --- a/doc/README.pa.md +++ b/doc/README.pa.md @@ -2,7 +2,7 @@

    NewPipe

    ਐਂਡਰੌਇਡ ਲਈ ਇੱਕ ਮੁਫ਼ਤ ਹਲਕਾ-ਫੁਲਕਾ ਸਟ੍ਰੀਮਿੰਗ ਯੂਟਿਊਬ ਫਰੰਟ-ਐਂਡ।

    -

    Get it on F-Droid

    +

    Get it on F-Droid

    diff --git a/doc/README.pl.md b/doc/README.pl.md index 9d216c590..9574491c7 100644 --- a/doc/README.pl.md +++ b/doc/README.pl.md @@ -2,7 +2,7 @@

    NewPipe

    Wolny, lekki streamingowy frontend na Androida.

    -

    Pobierz z F-Droid

    +

    Pobierz z F-Droid

    diff --git a/doc/README.pt_BR.md b/doc/README.pt_BR.md index d65fa9790..b73da2de1 100644 --- a/doc/README.pt_BR.md +++ b/doc/README.pt_BR.md @@ -6,7 +6,7 @@

    NewPipe

    Uma interface de streaming leve e gratuita para Android.

    -

    Get it on F-Droid

    +

    Get it on F-Droid

    diff --git a/doc/README.ro.md b/doc/README.ro.md index 5363ef7bc..3f146f7e4 100644 --- a/doc/README.ro.md +++ b/doc/README.ro.md @@ -2,7 +2,7 @@

    NewPipe

    Un front-end de streaming „uşor” liber, pentru Android.

    -

    Get it on F-Droid

    +

    Get it on F-Droid

    diff --git a/doc/README.ru.md b/doc/README.ru.md index 894e5f2e0..8a9955707 100644 --- a/doc/README.ru.md +++ b/doc/README.ru.md @@ -2,7 +2,7 @@

    NewPipe

    Свободный и легковесный клиент потоковых сервисов для Android.

    -

    Скачать на F-Droid

    +

    Скачать на F-Droid

    diff --git a/doc/README.ryu.md b/doc/README.ryu.md index 8676f1bfd..f3ca31af0 100644 --- a/doc/README.ryu.md +++ b/doc/README.ryu.md @@ -2,7 +2,7 @@

    NewPipe

    じゆーいっしけいりょうなAndroidんきーストリーミングフロントエンド

    -

    Get it on F-Droid

    +

    Get it on F-Droid

    diff --git a/doc/README.so.md b/doc/README.so.md index 82e544d93..843bed749 100644 --- a/doc/README.so.md +++ b/doc/README.so.md @@ -2,7 +2,7 @@

    NewPipe

    App bilaash ah oo fudud looguna talagalay in Android-ka wax loogu daawado.

    -

    Get it on F-Droid

    +

    Get it on F-Droid

    diff --git a/doc/README.sr.md b/doc/README.sr.md index d8b0fe435..21e4d857c 100644 --- a/doc/README.sr.md +++ b/doc/README.sr.md @@ -5,7 +5,7 @@

    NewPipe

    Бесплатна и лагана апликација за стримовање за Android.

    -

    Набавите на F-Droid

    +

    Набавите на F-Droid

    diff --git a/doc/README.tr.md b/doc/README.tr.md index c6610d97d..6e95e54de 100644 --- a/doc/README.tr.md +++ b/doc/README.tr.md @@ -2,7 +2,7 @@

    NewPipe

    Android için hafif ve özgür bir akış arayüzü.

    -

    Get it on F-Droid

    +

    Get it on F-Droid

    diff --git a/doc/README.zh_TW.md b/doc/README.zh_TW.md index 04a8355cb..05518624f 100644 --- a/doc/README.zh_TW.md +++ b/doc/README.zh_TW.md @@ -2,7 +2,7 @@

    NewPipe

    輕巧的 Android 串流前端

    -

    Get it on F-Droid

    +

    Get it on F-Droid

    From 834c93f22add0046470583625d788518a0553fe2 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 6 Jul 2025 14:49:09 +0200 Subject: [PATCH 097/143] Fix thumbnails appearing on Android Auto even if disabled --- .../player/mediabrowser/MediaBrowserImpl.kt | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserImpl.kt b/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserImpl.kt index 3108da80f..c52f78250 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserImpl.kt +++ b/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserImpl.kt @@ -8,6 +8,7 @@ import android.support.v4.media.MediaBrowserCompat import android.support.v4.media.MediaDescriptionCompat import android.util.Log import androidx.annotation.DrawableRes +import androidx.core.net.toUri import androidx.media.MediaBrowserServiceCompat import androidx.media.MediaBrowserServiceCompat.Result import androidx.media.utils.MediaConstants @@ -185,7 +186,7 @@ class MediaBrowserImpl( builder .setMediaId(createMediaIdForInfoItem(playlist is PlaylistRemoteEntity, playlist.uid)) .setTitle(playlist.orderingName) - .setIconUri(playlist.thumbnailUrl?.let { Uri.parse(it) }) + .setIconUri(imageUriOrNullIfDisabled(playlist.thumbnailUrl)) val extras = Bundle() extras.putString( @@ -212,7 +213,7 @@ class MediaBrowserImpl( } ImageStrategy.choosePreferredImage(item.thumbnails)?.let { - builder.setIconUri(Uri.parse(it)) + builder.setIconUri(imageUriOrNullIfDisabled(it)) } return MediaBrowserCompat.MediaItem( @@ -258,7 +259,7 @@ class MediaBrowserImpl( builder.setMediaId(createMediaIdForPlaylistIndex(false, playlistId, index)) .setTitle(item.streamEntity.title) .setSubtitle(item.streamEntity.uploader) - .setIconUri(Uri.parse(item.streamEntity.thumbnailUrl)) + .setIconUri(imageUriOrNullIfDisabled(item.streamEntity.thumbnailUrl)) return MediaBrowserCompat.MediaItem( builder.build(), @@ -277,7 +278,7 @@ class MediaBrowserImpl( .setSubtitle(item.uploaderName) ImageStrategy.choosePreferredImage(item.thumbnails)?.let { - builder.setIconUri(Uri.parse(it)) + builder.setIconUri(imageUriOrNullIfDisabled(it)) } return MediaBrowserCompat.MediaItem( @@ -316,7 +317,7 @@ class MediaBrowserImpl( builder.setMediaId(mediaId) .setTitle(streamHistoryEntry.streamEntity.title) .setSubtitle(streamHistoryEntry.streamEntity.uploader) - .setIconUri(Uri.parse(streamHistoryEntry.streamEntity.thumbnailUrl)) + .setIconUri(imageUriOrNullIfDisabled(streamHistoryEntry.streamEntity.thumbnailUrl)) return MediaBrowserCompat.MediaItem( builder.build(), @@ -395,5 +396,13 @@ class MediaBrowserImpl( companion object { private val TAG: String = MediaBrowserImpl::class.java.getSimpleName() + + fun imageUriOrNullIfDisabled(url: String?): Uri? { + return if (ImageStrategy.shouldLoadImages()) { + url?.toUri() + } else { + null + } + } } } From a4d457b2b2eac7ca9a0b30b430327c05cc61cb8c Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 6 Jul 2025 14:49:49 +0200 Subject: [PATCH 098/143] Use Kotlin's .toUri() instead of Uri.parse() --- .../org/schabi/newpipe/player/mediabrowser/MediaBrowserImpl.kt | 2 +- .../player/mediabrowser/MediaBrowserPlaybackPreparer.kt | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserImpl.kt b/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserImpl.kt index c52f78250..f15d7ab08 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserImpl.kt +++ b/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserImpl.kt @@ -104,7 +104,7 @@ class MediaBrowserImpl( private fun onLoadChildren(parentId: String): Single> { try { - val parentIdUri = Uri.parse(parentId) + val parentIdUri = parentId.toUri() val path = ArrayList(parentIdUri.pathSegments) if (path.isEmpty()) { diff --git a/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserPlaybackPreparer.kt b/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserPlaybackPreparer.kt index f34677a29..a3791e2e7 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserPlaybackPreparer.kt +++ b/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserPlaybackPreparer.kt @@ -6,6 +6,7 @@ import android.os.Bundle import android.os.ResultReceiver import android.support.v4.media.session.PlaybackStateCompat import android.util.Log +import androidx.core.net.toUri import com.google.android.exoplayer2.Player import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector.PlaybackPreparer import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers @@ -137,7 +138,7 @@ class MediaBrowserPlaybackPreparer( private fun extractPlayQueueFromMediaId(mediaId: String): Single { try { - val mediaIdUri = Uri.parse(mediaId) + val mediaIdUri = mediaId.toUri() val path = ArrayList(mediaIdUri.pathSegments) if (path.isEmpty()) { throw parseError(mediaId) From 705b5e558096b8321dbac36ba952cec3dedb7b30 Mon Sep 17 00:00:00 2001 From: Stypox Date: Mon, 7 Jul 2025 01:04:45 +0200 Subject: [PATCH 099/143] Fix ghost notifications on Android 10 Fixes #12400, see there for explanation. Citing from there: So apparently the problem is onGetRoot always returning a BrowserRoot instance. Making it return null solved the issue (but again, breaks Android Auto compatibility). It turns out (see https://stackoverflow.com/q/63818988/) that onGetRoot is also used for media resumption https://developer.android.com/media/implement/surfaces/mobile#mediabrowserservice_implementation, which causes a new notification to pop up (in this case a useless notification because our onGetRoot does not return something that can be used for resumption). So what needs to be done is to check if rootHints?.getBoolean(EXTRA_RECENT) == true and if that's the case not return anything (as EXTRA_RECENT is used by the system for resumption). The PackageValidator file is taken from https://github.com/android/uamp/blob/329a21b63c247e9bd35f6858d4fc0e448fa38603/common/src/main/java/com/example/android/uamp/media/PackageValidator.kt . --- .../schabi/newpipe/player/PlayerService.java | 1 - .../player/mediabrowser/MediaBrowserImpl.kt | 15 +- .../player/mediabrowser/PackageValidator.kt | 243 ++++++++++++++++++ 3 files changed, 257 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/org/schabi/newpipe/player/mediabrowser/PackageValidator.kt diff --git a/app/src/main/java/org/schabi/newpipe/player/PlayerService.java b/app/src/main/java/org/schabi/newpipe/player/PlayerService.java index 1888bce01..5455d4c19 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PlayerService.java +++ b/app/src/main/java/org/schabi/newpipe/player/PlayerService.java @@ -330,7 +330,6 @@ public final class PlayerService extends MediaBrowserServiceCompat { public BrowserRoot onGetRoot(@NonNull final String clientPackageName, final int clientUid, @Nullable final Bundle rootHints) { - // TODO check if the accessing package has permission to view data return mediaBrowserImpl.onGetRoot(clientPackageName, clientUid, rootHints); } diff --git a/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserImpl.kt b/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserImpl.kt index 3108da80f..3b4e5e07b 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserImpl.kt +++ b/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserImpl.kt @@ -9,6 +9,7 @@ import android.support.v4.media.MediaDescriptionCompat import android.util.Log import androidx.annotation.DrawableRes import androidx.media.MediaBrowserServiceCompat +import androidx.media.MediaBrowserServiceCompat.BrowserRoot.EXTRA_RECENT import androidx.media.MediaBrowserServiceCompat.Result import androidx.media.utils.MediaConstants import io.reactivex.rxjava3.core.Flowable @@ -47,6 +48,7 @@ class MediaBrowserImpl( private val context: Context, notifyChildrenChanged: Consumer, // parentId ) { + private val packageValidator = PackageValidator(context) private val database = NewPipeDatabase.getInstance(context) private var disposables = CompositeDisposable() @@ -68,11 +70,22 @@ class MediaBrowserImpl( clientPackageName: String, clientUid: Int, rootHints: Bundle? - ): MediaBrowserServiceCompat.BrowserRoot { + ): MediaBrowserServiceCompat.BrowserRoot? { if (DEBUG) { Log.d(TAG, "onGetRoot($clientPackageName, $clientUid, $rootHints)") } + if (!packageValidator.isKnownCaller(clientPackageName, clientUid)) { + // this is a caller we can't trust (see PackageValidator's rules taken from uamp) + return null + } + + if (rootHints?.getBoolean(EXTRA_RECENT, false) == true) { + // the system is asking for a root to do media resumption, but we can't handle that yet, + // see https://developer.android.com/media/implement/surfaces/mobile#mediabrowserservice_implementation + return null + } + val extras = Bundle() extras.putBoolean( MediaConstants.BROWSER_SERVICE_EXTRAS_KEY_SEARCH_SUPPORTED, true diff --git a/app/src/main/java/org/schabi/newpipe/player/mediabrowser/PackageValidator.kt b/app/src/main/java/org/schabi/newpipe/player/mediabrowser/PackageValidator.kt new file mode 100644 index 000000000..973b11b37 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/player/mediabrowser/PackageValidator.kt @@ -0,0 +1,243 @@ +/* + * Copyright 2018 Google Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// THIS FILE WAS TAKEN FROM UAMP, EXCEPT FOR THINGS RELATED TO THE WHITELIST. UPDATE IT WHEN NEEDED. +// https://github.com/android/uamp/blob/329a21b63c247e9bd35f6858d4fc0e448fa38603/common/src/main/java/com/example/android/uamp/media/PackageValidator.kt + +package org.schabi.newpipe.player.mediabrowser + +import android.Manifest.permission.MEDIA_CONTENT_CONTROL +import android.annotation.SuppressLint +import android.content.Context +import android.content.pm.PackageInfo +import android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED +import android.content.pm.PackageManager +import android.os.Process +import android.support.v4.media.session.MediaSessionCompat +import android.util.Log +import androidx.core.app.NotificationManagerCompat +import androidx.media.MediaBrowserServiceCompat +import org.schabi.newpipe.BuildConfig +import java.security.MessageDigest +import java.security.NoSuchAlgorithmException + +/** + * Validates that the calling package is authorized to browse a [MediaBrowserServiceCompat]. + * + * The list of allowed signing certificates and their corresponding package names is defined in + * res/xml/allowed_media_browser_callers.xml. + * + * If you want to add a new caller to allowed_media_browser_callers.xml and you don't know + * its signature, this class will print to logcat (INFO level) a message with the proper + * xml tags to add to allow the caller. + * + * For more information, see res/xml/allowed_media_browser_callers.xml. + */ +internal class PackageValidator(context: Context) { + private val context: Context = context.applicationContext + private val packageManager: PackageManager = this.context.packageManager + private val platformSignature: String = getSystemSignature() + private val callerChecked = mutableMapOf>() + + /** + * Checks whether the caller attempting to connect to a [MediaBrowserServiceCompat] is known. + * See [MusicService.onGetRoot] for where this is utilized. + * + * @param callingPackage The package name of the caller. + * @param callingUid The user id of the caller. + * @return `true` if the caller is known, `false` otherwise. + */ + fun isKnownCaller(callingPackage: String, callingUid: Int): Boolean { + // If the caller has already been checked, return the previous result here. + val (checkedUid, checkResult) = callerChecked[callingPackage] ?: Pair(0, false) + if (checkedUid == callingUid) { + return checkResult + } + + /** + * Because some of these checks can be slow, we save the results in [callerChecked] after + * this code is run. + * + * In particular, there's little reason to recompute the calling package's certificate + * signature (SHA-256) each call. + * + * This is safe to do as we know the UID matches the package's UID (from the check above), + * and app UIDs are set at install time. Additionally, a package name + UID is guaranteed to + * be constant until a reboot. (After a reboot then a previously assigned UID could be + * reassigned.) + */ + + // Build the caller info for the rest of the checks here. + val callerPackageInfo = buildCallerInfo(callingPackage) + ?: throw IllegalStateException("Caller wasn't found in the system?") + + // Verify that things aren't ... broken. (This test should always pass.) + if (callerPackageInfo.uid != callingUid) { + throw IllegalStateException("Caller's package UID doesn't match caller's actual UID?") + } + + val callerSignature = callerPackageInfo.signature + + val isCallerKnown = when { + // If it's our own app making the call, allow it. + callingUid == Process.myUid() -> true + // If the system is making the call, allow it. + callingUid == Process.SYSTEM_UID -> true + // If the app was signed by the same certificate as the platform itself, also allow it. + callerSignature == platformSignature -> true + /** + * [MEDIA_CONTENT_CONTROL] permission is only available to system applications, and + * while it isn't required to allow these apps to connect to a + * [MediaBrowserServiceCompat], allowing this ensures optimal compatability with apps + * such as Android TV and the Google Assistant. + */ + callerPackageInfo.permissions.contains(MEDIA_CONTENT_CONTROL) -> true + /** + * If the calling app has a notification listener it is able to retrieve notifications + * and can connect to an active [MediaSessionCompat]. + * + * It's not required to allow apps with a notification listener to + * connect to your [MediaBrowserServiceCompat], but it does allow easy compatibility + * with apps such as Wear OS. + */ + NotificationManagerCompat.getEnabledListenerPackages(this.context) + .contains(callerPackageInfo.packageName) -> true + + // If none of the previous checks succeeded, then the caller is unrecognized. + else -> false + } + + if (!isCallerKnown) { + logUnknownCaller(callerPackageInfo) + } + + // Save our work for next time. + callerChecked[callingPackage] = Pair(callingUid, isCallerKnown) + return isCallerKnown + } + + /** + * Logs an info level message with details of how to add a caller to the allowed callers list + * when the app is debuggable. + */ + private fun logUnknownCaller(callerPackageInfo: CallerPackageInfo) { + if (BuildConfig.DEBUG) { + Log.w(TAG, "Unknown caller $callerPackageInfo") + } + } + + /** + * Builds a [CallerPackageInfo] for a given package that can be used for all the + * various checks that are performed before allowing an app to connect to a + * [MediaBrowserServiceCompat]. + */ + private fun buildCallerInfo(callingPackage: String): CallerPackageInfo? { + val packageInfo = getPackageInfo(callingPackage) ?: return null + + val appName = packageInfo.applicationInfo.loadLabel(packageManager).toString() + val uid = packageInfo.applicationInfo.uid + val signature = getSignature(packageInfo) + + val requestedPermissions = packageInfo.requestedPermissions + val permissionFlags = packageInfo.requestedPermissionsFlags + val activePermissions = mutableSetOf() + requestedPermissions?.forEachIndexed { index, permission -> + if (permissionFlags[index] and REQUESTED_PERMISSION_GRANTED != 0) { + activePermissions += permission + } + } + + return CallerPackageInfo(appName, callingPackage, uid, signature, activePermissions.toSet()) + } + + /** + * Looks up the [PackageInfo] for a package name. + * This requests both the signatures (for checking if an app is on the allow list) and + * the app's permissions, which allow for more flexibility in the allow list. + * + * @return [PackageInfo] for the package name or null if it's not found. + */ + @Suppress("deprecation") + @SuppressLint("PackageManagerGetSignatures") + private fun getPackageInfo(callingPackage: String): PackageInfo? = + packageManager.getPackageInfo( + callingPackage, + PackageManager.GET_SIGNATURES or PackageManager.GET_PERMISSIONS + ) + + /** + * Gets the signature of a given package's [PackageInfo]. + * + * The "signature" is a SHA-256 hash of the public key of the signing certificate used by + * the app. + * + * If the app is not found, or if the app does not have exactly one signature, this method + * returns `null` as the signature. + */ + @Suppress("deprecation") + private fun getSignature(packageInfo: PackageInfo): String? = + if (packageInfo.signatures == null || packageInfo.signatures.size != 1) { + // Security best practices dictate that an app should be signed with exactly one (1) + // signature. Because of this, if there are multiple signatures, reject it. + null + } else { + val certificate = packageInfo.signatures[0].toByteArray() + getSignatureSha256(certificate) + } + + /** + * Finds the Android platform signing key signature. This key is never null. + */ + private fun getSystemSignature(): String = + getPackageInfo(ANDROID_PLATFORM)?.let { platformInfo -> + getSignature(platformInfo) + } ?: throw IllegalStateException("Platform signature not found") + + /** + * Creates a SHA-256 signature given a certificate byte array. + */ + private fun getSignatureSha256(certificate: ByteArray): String { + val md: MessageDigest + try { + md = MessageDigest.getInstance("SHA256") + } catch (noSuchAlgorithmException: NoSuchAlgorithmException) { + Log.e(TAG, "No such algorithm: $noSuchAlgorithmException") + throw RuntimeException("Could not find SHA256 hash algorithm", noSuchAlgorithmException) + } + md.update(certificate) + + // This code takes the byte array generated by `md.digest()` and joins each of the bytes + // to a string, applying the string format `%02x` on each digit before it's appended, with + // a colon (':') between each of the items. + // For example: input=[0,2,4,6,8,10,12], output="00:02:04:06:08:0a:0c" + return md.digest().joinToString(":") { String.format("%02x", it) } + } + + /** + * Convenience class to hold all of the information about an app that's being checked + * to see if it's a known caller. + */ + private data class CallerPackageInfo( + val name: String, + val packageName: String, + val uid: Int, + val signature: String?, + val permissions: Set + ) +} + +private const val TAG = "PackageValidator" +private const val ANDROID_PLATFORM = "android" From 79084568f2d827588b963a246e623830ebdca4d1 Mon Sep 17 00:00:00 2001 From: Stypox Date: Mon, 7 Jul 2025 15:07:46 +0200 Subject: [PATCH 100/143] Fix fullscreen eliciting "clear queue" prompt --- .../org/schabi/newpipe/player/helper/PlayerHolder.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java index 20a0f3766..97f2d6717 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHolder.java @@ -159,6 +159,11 @@ public final class PlayerHolder { private boolean playAfterConnect = false; + /** + * @param playAfterConnection Sets the value of `playAfterConnect` to pass to the {@link + * PlayerServiceExtendedEventListener#onPlayerConnected(Player, boolean)} the next time it + * is called. The value of `playAfterConnect` will be reset to false after that. + */ public void doPlayAfterConnect(final boolean playAfterConnection) { this.playAfterConnect = playAfterConnection; } @@ -183,7 +188,6 @@ public final class PlayerHolder { playerService = localBinder.getService(); if (listener != null) { listener.onServiceConnected(playerService); - getPlayer().ifPresent(p -> listener.onPlayerConnected(p, playAfterConnect)); } startPlayerListener(); // ^ will call listener.onPlayerConnected() down the line if there is an active player @@ -357,6 +361,8 @@ public final class PlayerHolder { listener.onPlayerDisconnected(); } else { listener.onPlayerConnected(player, serviceConnection.playAfterConnect); + // reset the value of playAfterConnect: if it was true before, it is now "consumed" + serviceConnection.playAfterConnect = false; player.setFragmentListener(internalListener); } } From f0b26e208bef1b0b1710d219f8eb5ac8ffaa00b5 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 6 Jul 2025 14:00:54 +0200 Subject: [PATCH 101/143] Update notice about rewrite in the README --- README.md | 4 ++-- doc/README.de.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 095c3c43a..c19144064 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -

    We are planning to rewrite large chunks of the codebase, to bring about a new, modern and stable NewPipe!

    -

    Please do not open pull requests for new features now, only bugfix PRs will be accepted.

    +

    We are rewriting large chunks of the codebase, to bring about a modern and stable NewPipe! You can download nightly builds here.

    +

    Please work on the refactor branch if you want to contribute new features. The current codebase is in maintenance mode and will only receive bugfixes.

    NewPipe

    diff --git a/doc/README.de.md b/doc/README.de.md index 5cbb4e6dd..34ad94ab1 100644 --- a/doc/README.de.md +++ b/doc/README.de.md @@ -1,5 +1,5 @@ -

    Wir planen große Teile des Quellcodes neu zu schreiben, um NewPipe neu, modern und stabiler zu machen!

    -

    Öffne keine neuen Pull Requests für neue Features, es werden nur Fehlerbehebungen akzeptiert.

    +

    Wir sind im Prozess, größere Teile unseres Codes neuzuschreiben, um eine moderne und stabile NewPipe App zu kreieren! Du kannst nightly builds hier herunterladen.

    +

    Bitte nutze den refactor branch als Arbeitsgrundlage, wenn du neue Funktionen beitragen willst. Die aktuelle Codebase ist im reinen Maintenance mode und bekommt nur noch Fehlerbehebungen.

    NewPipe

    From f119a368d82efea5f8d86846aecb359df1813a01 Mon Sep 17 00:00:00 2001 From: watermelon42 Date: Wed, 18 Jun 2025 17:19:54 +0300 Subject: [PATCH 102/143] Added support for importing Soundcloud likes as a new tab before `About` in a user's channel. The likes are also retrieved in the feed if the user is subscribed to. --- app/build.gradle | 2 +- .../java/org/schabi/newpipe/util/ChannelTabHelper.java | 7 +++++++ app/src/main/res/values/settings_keys.xml | 6 ++++++ app/src/main/res/values/strings.xml | 1 + 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 5a5a2be1b..144d29113 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -214,7 +214,7 @@ dependencies { // the corresponding commit hash, since JitPack sometimes deletes artifacts. // If there’s already a git hash, just add more of it to the end (or remove a letter) // to cause jitpack to regenerate the artifact. - implementation 'com.github.TeamNewPipe.NewPipeExtractor:NewPipeExtractor:v0.24.6' + implementation 'com.github.TeamNewPipe.NewPipeExtractor:NewPipeExtractor:v0.24.7' implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0' /** Checkstyle **/ diff --git a/app/src/main/java/org/schabi/newpipe/util/ChannelTabHelper.java b/app/src/main/java/org/schabi/newpipe/util/ChannelTabHelper.java index 8e8d38490..cde6e3fef 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ChannelTabHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ChannelTabHelper.java @@ -24,6 +24,7 @@ public final class ChannelTabHelper { switch (tab) { case ChannelTabs.VIDEOS: case ChannelTabs.TRACKS: + case ChannelTabs.LIKES: case ChannelTabs.SHORTS: case ChannelTabs.LIVESTREAMS: return true; @@ -62,6 +63,8 @@ public final class ChannelTabHelper { return R.string.show_channel_tabs_playlists; case ChannelTabs.ALBUMS: return R.string.show_channel_tabs_albums; + case ChannelTabs.LIKES: + return R.string.show_channel_tabs_likes; default: return -1; } @@ -78,6 +81,8 @@ public final class ChannelTabHelper { return R.string.fetch_channel_tabs_shorts; case ChannelTabs.LIVESTREAMS: return R.string.fetch_channel_tabs_livestreams; + case ChannelTabs.LIKES: + return R.string.fetch_channel_tabs_likes; default: return -1; } @@ -100,6 +105,8 @@ public final class ChannelTabHelper { return R.string.channel_tab_playlists; case ChannelTabs.ALBUMS: return R.string.channel_tab_albums; + case ChannelTabs.LIKES: + return R.string.channel_tab_likes; default: return R.string.unknown_content; } diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index 61125c47f..f98639e04 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -294,6 +294,7 @@ show_channel_tabs_channels show_channel_tabs_playlists show_channel_tabs_albums + show_channel_tabs_likes show_channel_tabs_about @string/show_channel_tabs_videos @@ -303,6 +304,7 @@ @string/show_channel_tabs_channels @string/show_channel_tabs_playlists @string/show_channel_tabs_albums + @string/show_channel_tabs_likes @string/show_channel_tabs_about @@ -313,6 +315,7 @@ @string/channel_tab_channels @string/channel_tab_playlists @string/channel_tab_albums + @string/channel_tab_likes @string/channel_tab_about show_search_suggestions @@ -390,17 +393,20 @@ fetch_channel_tabs_tracks fetch_channel_tabs_shorts fetch_channel_tabs_livestreams + fetch_channel_tabs_likes @string/fetch_channel_tabs_videos @string/fetch_channel_tabs_tracks @string/fetch_channel_tabs_shorts @string/fetch_channel_tabs_livestreams + @string/fetch_channel_tabs_likes @string/channel_tab_videos @string/channel_tab_tracks @string/channel_tab_shorts @string/channel_tab_livestreams + @string/channel_tab_likes import_export_data_path diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1015dea08..4a9bfd14b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -828,6 +828,7 @@ Channels Playlists Albums + Likes About Channel tabs What tabs are shown on the channel pages From 1c0eabf75c7f154fdfff4b8e401a3c542348c3b2 Mon Sep 17 00:00:00 2001 From: watermelon42 Date: Wed, 18 Jun 2025 19:31:58 +0300 Subject: [PATCH 103/143] Updated extractor version to latest commit --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 144d29113..0e59d524a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -214,7 +214,7 @@ dependencies { // the corresponding commit hash, since JitPack sometimes deletes artifacts. // If there’s already a git hash, just add more of it to the end (or remove a letter) // to cause jitpack to regenerate the artifact. - implementation 'com.github.TeamNewPipe.NewPipeExtractor:NewPipeExtractor:v0.24.7' + implementation 'com.github.TeamNewPipe.NewPipeExtractor:NewPipeExtractor:71b335128e8b66ecc0cd45379dd11a0865973065' implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0' /** Checkstyle **/ From 58b5ccb66f36e85ac730b906615d899203fc26f1 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Thu, 17 Jul 2025 09:16:37 +0200 Subject: [PATCH 104/143] Translated using Weblate (Czech) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (85 of 85 strings) Translated using Weblate (Estonian) Currently translated at 100.0% (747 of 747 strings) Translated using Weblate (Bulgarian) Currently translated at 100.0% (747 of 747 strings) Translated using Weblate (Hebrew) Currently translated at 100.0% (747 of 747 strings) Translated using Weblate (Hebrew) Currently translated at 100.0% (747 of 747 strings) Translated using Weblate (Chinese (Traditional Han script)) Currently translated at 100.0% (745 of 745 strings) Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (745 of 745 strings) Translated using Weblate (Polish) Currently translated at 100.0% (747 of 747 strings) Translated using Weblate (Polish) Currently translated at 100.0% (747 of 747 strings) Translated using Weblate (Turkish) Currently translated at 100.0% (745 of 745 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (745 of 745 strings) Translated using Weblate (Czech) Currently translated at 100.0% (747 of 747 strings) Translated using Weblate (Slovak) Currently translated at 100.0% (747 of 747 strings) Translated using Weblate (Italian) Currently translated at 100.0% (747 of 747 strings) Translated using Weblate (Italian) Currently translated at 100.0% (747 of 747 strings) Translated using Weblate (Serbian) Currently translated at 99.7% (745 of 747 strings) Translated using Weblate (Hungarian) Currently translated at 100.0% (747 of 747 strings) Translated using Weblate (French) Currently translated at 100.0% (747 of 747 strings) Translated using Weblate (Tigrinya) Currently translated at 12.6% (94 of 744 strings) Translated using Weblate (Tigrinya) Currently translated at 12.6% (94 of 744 strings) Translated using Weblate (Tigrinya) Currently translated at 12.6% (94 of 744 strings) Translated using Weblate (Tigrinya) Currently translated at 12.6% (94 of 744 strings) Translated using Weblate (Tigrinya) Currently translated at 12.6% (94 of 744 strings) Translated using Weblate (Tigrinya) Currently translated at 12.6% (94 of 744 strings) Translated using Weblate (Tigrinya) Currently translated at 12.6% (94 of 744 strings) Translated using Weblate (Tigrinya) Currently translated at 12.6% (94 of 744 strings) Translated using Weblate (Tigrinya) Currently translated at 12.6% (94 of 744 strings) Translated using Weblate (Tigrinya) Currently translated at 12.6% (94 of 744 strings) Translated using Weblate (Tigrinya) Currently translated at 12.6% (94 of 744 strings) Translated using Weblate (Tigrinya) Currently translated at 12.6% (94 of 744 strings) Translated using Weblate (Tigrinya) Currently translated at 12.6% (94 of 744 strings) Translated using Weblate (Tigrinya) Currently translated at 12.6% (94 of 744 strings) Translated using Weblate (Tigrinya) Currently translated at 12.6% (94 of 744 strings) Translated using Weblate (Tigrinya) Currently translated at 12.6% (94 of 744 strings) Translated using Weblate (English (United Kingdom)) Currently translated at 8.2% (7 of 85 strings) Translated using Weblate (Serbian) Currently translated at 16.4% (14 of 85 strings) Translated using Weblate (Portuguese (Portugal)) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Portuguese) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Serbian) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Azerbaijani (Southern)) Currently translated at 1.1% (1 of 85 strings) Added translation using Weblate (Azerbaijani (Southern)) Translated using Weblate (Azerbaijani) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Slovak) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Hungarian) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Serbian) Currently translated at 16.4% (14 of 85 strings) Translated using Weblate (Greek) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Tamil) Currently translated at 100.0% (85 of 85 strings) Translated using Weblate (Danish) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Tamil) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Arabic) Currently translated at 100.0% (85 of 85 strings) Translated using Weblate (Romanian) Currently translated at 99.7% (742 of 744 strings) Translated using Weblate (Serbian) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Catalan) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Russian) Currently translated at 100.0% (85 of 85 strings) Translated using Weblate (Belarusian) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Arabic) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Russian) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Bulgarian) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Swedish) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Hebrew) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Chinese (Traditional Han script)) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Turkish) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Indonesian) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Italian) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Dutch) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Hungarian) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (French) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Estonian) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Polish) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Czech) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (German) Currently translated at 100.0% (744 of 744 strings) Translated using Weblate (Persian) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Arabic) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Portuguese (Portugal)) Currently translated at 97.6% (83 of 85 strings) Translated using Weblate (Hebrew) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Hebrew) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Hebrew) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Hebrew) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Hebrew) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Hebrew) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Hebrew) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Hungarian) Currently translated at 100.0% (85 of 85 strings) Translated using Weblate (Kabyle) Currently translated at 29.0% (215 of 741 strings) Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (741 of 741 strings) Added translation using Weblate (Luri (Bakhtiari)) Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Persian) Currently translated at 94.3% (699 of 741 strings) Translated using Weblate (Estonian) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Serbian) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Persian) Currently translated at 94.1% (698 of 741 strings) Translated using Weblate (Belarusian) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Punjabi) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Belarusian) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Finnish) Currently translated at 98.5% (730 of 741 strings) Translated using Weblate (French) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Swedish) Currently translated at 100.0% (85 of 85 strings) Translated using Weblate (French) Currently translated at 100.0% (85 of 85 strings) Translated using Weblate (German) Currently translated at 100.0% (85 of 85 strings) Translated using Weblate (Sardinian) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (German) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Portuguese (Brazil)) Currently translated at 69.4% (59 of 85 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Latvian) Currently translated at 21.4% (18 of 84 strings) Translated using Weblate (Latvian) Currently translated at 99.7% (739 of 741 strings) Translated using Weblate (Latvian) Currently translated at 20.2% (17 of 84 strings) Translated using Weblate (Latvian) Currently translated at 16.6% (14 of 84 strings) Translated using Weblate (Greek) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (French) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Greek) Currently translated at 32.1% (27 of 84 strings) Translated using Weblate (Greek) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Portuguese (Portugal)) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Portuguese) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Dutch) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Romanian) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Urdu) Currently translated at 69.2% (513 of 741 strings) Translated using Weblate (Hungarian) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Hungarian) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Catalan) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Catalan) Currently translated at 90.2% (669 of 741 strings) Translated using Weblate (Estonian) Currently translated at 17.8% (15 of 84 strings) Translated using Weblate (Spanish) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Russian) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Dutch (Belgium)) Currently translated at 76.7% (569 of 741 strings) Translated using Weblate (Dutch (Belgium)) Currently translated at 76.2% (565 of 741 strings) Translated using Weblate (Lithuanian) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Hebrew) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Hebrew) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Danish) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Czech) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Kabyle) Currently translated at 28.8% (214 of 741 strings) Translated using Weblate (Indonesian) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Hungarian) Currently translated at 100.0% (84 of 84 strings) Translated using Weblate (Arabic) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Italian) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Serbian) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Dutch) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Spanish) Currently translated at 99.8% (740 of 741 strings) Translated using Weblate (Chinese (Traditional Han script)) Currently translated at 67.8% (57 of 84 strings) Translated using Weblate (Chinese (Traditional Han script)) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Slovak) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Icelandic) Currently translated at 99.4% (737 of 741 strings) Translated using Weblate (Swedish) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Turkish) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (French) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Azerbaijani) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (German) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Estonian) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Polish) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Belarusian) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Breton) Currently translated at 13.6% (101 of 741 strings) Translated using Weblate (Bulgarian) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Czech) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Hungarian) Currently translated at 100.0% (741 of 741 strings) Translated using Weblate (Breton) Currently translated at 12.1% (90 of 741 strings) Translated using Weblate (Breton) Currently translated at 7.6% (57 of 741 strings) Translated using Weblate (Breton) Currently translated at 7.4% (55 of 741 strings) Translated using Weblate (Breton) Currently translated at 7.4% (55 of 741 strings) Translated using Weblate (Breton) Currently translated at 7.4% (55 of 741 strings) Translated using Weblate (Belarusian) Currently translated at 99.8% (740 of 741 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (741 of 741 strings) Added translation using Weblate (Breton) Translated using Weblate (Romanian) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Chinese (Traditional Han script)) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Portuguese (Portugal)) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Portuguese) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Arabic) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Swedish) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Japanese) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Serbian) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Danish) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Estonian) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Finnish) Currently translated at 98.5% (729 of 740 strings) Translated using Weblate (Italian) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (French) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Icelandic) Currently translated at 99.4% (736 of 740 strings) Translated using Weblate (Bulgarian) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Indonesian) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Slovak) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (German) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Polish) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Polish) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Azerbaijani) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Czech) Currently translated at 100.0% (740 of 740 strings) Translated using Weblate (Hungarian) Currently translated at 100.0% (740 of 740 strings) Co-authored-by: 439JBYL80IGQTF25UXNR0X1BG <439JBYL80IGQTF25UXNR0X1BG@users.noreply.hosted.weblate.org> Co-authored-by: AP Co-authored-by: Abu Sarim Hindi Co-authored-by: Agnieszka C Co-authored-by: Ajeje Brazorf Co-authored-by: Alex25820 Co-authored-by: Balázs Meskó Co-authored-by: Bastian Co-authored-by: ButterflyOfFire Co-authored-by: Danial Behzadi Co-authored-by: Darth23G (DarthGamer23) Co-authored-by: Deleted User Co-authored-by: Dream X Co-authored-by: Drugi Sapog Co-authored-by: Emin Tufan Çetin Co-authored-by: Fareedar Islami Co-authored-by: Femini Co-authored-by: Fjuro Co-authored-by: Fjuro Co-authored-by: Fjuro Co-authored-by: Ghost of Sparta Co-authored-by: GiannosOB Co-authored-by: Hosted Weblate Co-authored-by: Igor Rückert Co-authored-by: Igor Sorocean Co-authored-by: Ihor Hordiichuk Co-authored-by: J. Lavoie Co-authored-by: Jay Tromp Co-authored-by: Jeff Huang Co-authored-by: Jordi Cambrells Co-authored-by: Jordi Cambrells Co-authored-by: Juzé Co-authored-by: KaGaster Co-authored-by: Languages add-on Co-authored-by: Linerly Co-authored-by: MS-PC Co-authored-by: Mandeep Co-authored-by: Massimo Pissarello Co-authored-by: Michael Moroni Co-authored-by: Mickaël Binos Co-authored-by: Milan Co-authored-by: Mohammed al-Qubati Co-authored-by: Mücteba Co-authored-by: NEXI Co-authored-by: Nick Wick Co-authored-by: Philip Goto Co-authored-by: Priit Jõerüüt Co-authored-by: Priit Jõerüüt Co-authored-by: Q. Boii Co-authored-by: Random Co-authored-by: Rex_sa Co-authored-by: Sveinn í Felli Co-authored-by: THANOS SIOURDAKIS Co-authored-by: Trunars Co-authored-by: Vasilis K Co-authored-by: VfBFan Co-authored-by: Yaron Shahrabani Co-authored-by: Yasser Althuwaini Co-authored-by: Yauhen Co-authored-by: ab_09 Co-authored-by: cat Co-authored-by: dekiw39846 Co-authored-by: elid Co-authored-by: gfbdrgn Co-authored-by: late Co-authored-by: moton03 Co-authored-by: rehork Co-authored-by: rimasx Co-authored-by: ssantos Co-authored-by: trunars Co-authored-by: Максим Горпиніч Co-authored-by: Максим Горпиніч Co-authored-by: Максим Горпиніч Co-authored-by: Саша Петровић Co-authored-by: தமிழ்நேரம் Co-authored-by: ℂ𝕠𝕠𝕠𝕝 (𝕘𝕚𝕥𝕙𝕦𝕓.𝕔𝕠𝕞/ℂ𝕠𝕠𝕠𝕝) Co-authored-by: 大王叫我来巡山 Co-authored-by: 李恩霆 Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ar/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/azb/ 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/el/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/en_GB/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/et/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/fr/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/hu/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/lv/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pt_BR/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/pt_PT/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ru/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/sr/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/sv/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ta/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/zh_Hant/ Translation: NewPipe/Metadata --- app/src/main/res/values-ar/strings.xml | 7 +- app/src/main/res/values-az/strings.xml | 5 + app/src/main/res/values-azb/strings.xml | 3 + app/src/main/res/values-be/strings.xml | 73 ++++---- app/src/main/res/values-bg/strings.xml | 8 + app/src/main/res/values-bqi/strings.xml | 2 + app/src/main/res/values-br/strings.xml | 121 +++++++++++++ app/src/main/res/values-ca/strings.xml | 137 ++++++++++++--- app/src/main/res/values-cs/strings.xml | 14 +- app/src/main/res/values-da/strings.xml | 5 + app/src/main/res/values-de/strings.xml | 7 +- app/src/main/res/values-el/strings.xml | 17 +- app/src/main/res/values-es/strings.xml | 70 ++++---- app/src/main/res/values-et/strings.xml | 18 +- app/src/main/res/values-fa/strings.xml | 55 ++++++ app/src/main/res/values-fi/strings.xml | 5 + app/src/main/res/values-fr/strings.xml | 10 +- app/src/main/res/values-he/strings.xml | 12 +- app/src/main/res/values-hu/strings.xml | 163 ++++++++---------- app/src/main/res/values-in/strings.xml | 5 + app/src/main/res/values-is/strings.xml | 2 + app/src/main/res/values-it/strings.xml | 8 + app/src/main/res/values-ja/strings.xml | 2 + app/src/main/res/values-kab/strings.xml | 13 +- app/src/main/res/values-lt/strings.xml | 5 +- app/src/main/res/values-lv/strings.xml | 17 +- app/src/main/res/values-nl-rBE/strings.xml | 14 +- app/src/main/res/values-nl/strings.xml | 9 +- app/src/main/res/values-pa/strings.xml | 8 +- app/src/main/res/values-pl/strings.xml | 8 + app/src/main/res/values-pt-rBR/strings.xml | 48 +++--- app/src/main/res/values-pt-rPT/strings.xml | 5 + app/src/main/res/values-pt/strings.xml | 9 +- app/src/main/res/values-ro/strings.xml | 3 + app/src/main/res/values-ru/strings.xml | 7 +- app/src/main/res/values-sc/strings.xml | 3 + app/src/main/res/values-sk/strings.xml | 8 + app/src/main/res/values-sr/strings.xml | 22 ++- app/src/main/res/values-sv/strings.xml | 5 + app/src/main/res/values-ta/strings.xml | 15 +- app/src/main/res/values-ti/strings.xml | 41 ++++- app/src/main/res/values-tr/strings.xml | 8 +- app/src/main/res/values-uk/strings.xml | 6 + app/src/main/res/values-ur/strings.xml | 7 +- app/src/main/res/values-zh-rCN/strings.xml | 6 + app/src/main/res/values-zh-rTW/strings.xml | 6 + .../metadata/android/ar/changelogs/1004.txt | 4 +- .../android/azb/short_description.txt | 1 + .../metadata/android/cs/changelogs/1004.txt | 4 +- .../metadata/android/de/changelogs/1004.txt | 4 +- .../metadata/android/el/changelogs/1001.txt | 6 + .../metadata/android/el/changelogs/1002.txt | 4 + .../metadata/android/el/changelogs/1003.txt | 6 + .../metadata/android/el/changelogs/66.txt | 26 +++ .../metadata/android/el/changelogs/68.txt | 31 ++++ .../metadata/android/el/changelogs/69.txt | 19 ++ .../android/en_GB/changelogs/1000.txt | 13 ++ .../android/en_GB/changelogs/1001.txt | 6 + .../android/en_GB/changelogs/1002.txt | 4 + .../android/en_GB/changelogs/1003.txt | 6 + .../android/en_GB/changelogs/1004.txt | 3 + .../android/en_GB/full_description.txt | 1 + .../android/en_GB/short_description.txt | 1 + .../metadata/android/et/changelogs/64.txt | 8 + .../metadata/android/fr/changelogs/1003.txt | 8 +- .../metadata/android/hu/changelogs/1004.txt | 4 +- .../metadata/android/hu/full_description.txt | 2 +- .../metadata/android/lv/changelogs/1001.txt | 6 + .../metadata/android/lv/changelogs/64.txt | 8 +- .../metadata/android/lv/changelogs/989.txt | 3 + .../metadata/android/lv/changelogs/998.txt | 4 + .../metadata/android/lv/short_description.txt | 2 +- .../android/pt-BR/changelogs/1001.txt | 6 + .../metadata/android/pt-BR/changelogs/961.txt | 12 ++ .../metadata/android/pt-BR/changelogs/964.txt | 8 + .../metadata/android/pt-BR/changelogs/965.txt | 6 + .../metadata/android/pt-PT/changelogs/951.txt | 2 + .../metadata/android/ru/changelogs/1000.txt | 35 ++-- .../metadata/android/sr/full_description.txt | 2 +- .../metadata/android/sr/short_description.txt | 2 +- .../metadata/android/sv/changelogs/1004.txt | 4 +- .../metadata/android/ta/changelogs/1000.txt | 8 +- .../metadata/android/ta/changelogs/1002.txt | 4 + .../metadata/android/ta/changelogs/1003.txt | 6 + .../android/zh-Hant/changelogs/1001.txt | 6 + 85 files changed, 988 insertions(+), 319 deletions(-) create mode 100644 app/src/main/res/values-azb/strings.xml create mode 100644 app/src/main/res/values-bqi/strings.xml create mode 100644 app/src/main/res/values-br/strings.xml create mode 100644 fastlane/metadata/android/azb/short_description.txt create mode 100644 fastlane/metadata/android/el/changelogs/1001.txt create mode 100644 fastlane/metadata/android/el/changelogs/1002.txt create mode 100644 fastlane/metadata/android/el/changelogs/1003.txt create mode 100644 fastlane/metadata/android/el/changelogs/66.txt create mode 100644 fastlane/metadata/android/el/changelogs/68.txt create mode 100644 fastlane/metadata/android/el/changelogs/69.txt create mode 100644 fastlane/metadata/android/en_GB/changelogs/1000.txt create mode 100644 fastlane/metadata/android/en_GB/changelogs/1001.txt create mode 100644 fastlane/metadata/android/en_GB/changelogs/1002.txt create mode 100644 fastlane/metadata/android/en_GB/changelogs/1003.txt create mode 100644 fastlane/metadata/android/en_GB/changelogs/1004.txt create mode 100644 fastlane/metadata/android/en_GB/full_description.txt create mode 100644 fastlane/metadata/android/en_GB/short_description.txt create mode 100644 fastlane/metadata/android/et/changelogs/64.txt create mode 100644 fastlane/metadata/android/lv/changelogs/1001.txt create mode 100644 fastlane/metadata/android/lv/changelogs/989.txt create mode 100644 fastlane/metadata/android/lv/changelogs/998.txt create mode 100644 fastlane/metadata/android/pt-BR/changelogs/1001.txt create mode 100644 fastlane/metadata/android/pt-BR/changelogs/961.txt create mode 100644 fastlane/metadata/android/pt-BR/changelogs/964.txt create mode 100644 fastlane/metadata/android/pt-BR/changelogs/965.txt create mode 100644 fastlane/metadata/android/ta/changelogs/1002.txt create mode 100644 fastlane/metadata/android/ta/changelogs/1003.txt create mode 100644 fastlane/metadata/android/zh-Hant/changelogs/1001.txt diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 50ddcd8d3..c4eee0835 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -37,7 +37,7 @@ اعرض خيار لتشغيل الفيديو عبر مركز وسائط Kodi عرض خيار التشغيل بواسطة كودي السمة - تم النشر في %1$s + منشورة على %1$s رابط غير مدعوم استخدام مشغل صوت خارجي استخدام مشغل فيديو خارجي @@ -881,4 +881,9 @@ لا تستخدم الإعدادات الموجودة في عملية التصدير التي يتم استيرادها تنسيقًا عرضة للاختراق تم إهماله منذ NewPipe 0.27.0. تأكد من أن التصدير الذي يتم استيراده من مصدر موثوق به، ويفضل استخدام عمليات التصدير التي تم الحصول عليها من NewPipe 0.27.0 أو الأحدث في المستقبل فقط. سيتم قريبًا إزالة دعم استيراد الإعدادات بهذا التنسيق الضعيف تمامًا، وبعد ذلك لن تتمكن الإصدارات القديمة من NewPipe من استيراد إعدادات التصدير من الإصدارات الجديدة بعد الآن. الثانوي + المشاركة كقائمة تشغيل مؤقتة على YouTube + قوائم التشغيل + صفحة مجموعة القناة + حدد مجموعة المحتوى + لم تنشئ مجموعة محتوى diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml index 7fe5bf335..ee35996a6 100644 --- a/app/src/main/res/values-az/strings.xml +++ b/app/src/main/res/values-az/strings.xml @@ -803,4 +803,9 @@ Məlumat və yaddaş istifadəsini azaltmaq üçün şəkillərin keyfiyyətini və ya şəkillərin əsla yüklənib-yüklənilməməsini seçin. Dəyişikliklər həm yaddaşdaxili, həm də diskdə olan təsvir qalığın təmizləyir — %s URL siyahısını paylaşın ikinci dərəcəli + YouTube müvəqqəti pleylisti kimi paylaş + Pleylistlər + Axın qrupu seçin + Hələ heç bir axın qrupu yaradılmayıb + Kanal qrupu səhifəsi diff --git a/app/src/main/res/values-azb/strings.xml b/app/src/main/res/values-azb/strings.xml new file mode 100644 index 000000000..55344e519 --- /dev/null +++ b/app/src/main/res/values-azb/strings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index 19f3c8b26..f8d4a3670 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -92,7 +92,7 @@ Справаздача пра памылку Усе Каналы - Плэйлісты + Плэй-лісты Трэкі Карыстальнікі Адключана @@ -111,8 +111,8 @@ Перайсці ў галоўнае акно Імпартаваць даныя Экспартаваць даныя - Перавызначае вашу бягучую гісторыю, падпіскі, плэйлісты і (неабавязкова) налады - Экспарт гісторыі, падпісак, плэйлістоў і налад + Перавызначае вашу бягучую гісторыю, падпіскі, плэй-лісты і (неабавязкова) налады + Экспарт гісторыі, падпісак, плэй-лістоў і налад Ачысціць гісторыю праглядаў Выдаліць гісторыю прайграных патокаў і пазіцыі прайгравання Выдаліць усю гісторыю праглядаў\? @@ -135,7 +135,7 @@ Відэапатокі не знойдзены Аўдыяпатокі не знойдзены Такой папкі не існуе - Крыніца кантэнту або файла не існуе + Такога файла або крыніцы кантэнту не існуе Файл не існуе або няма дазволу на яго чытанне ці запіс Імя файла не можа быць пустым Адбылася памылка: %1$s @@ -147,7 +147,7 @@ Інфармацыя: Што адбылося: Што:\\nЗапыт:\\nМова кантэнту:\\nКраіна кантэнту:\\nМова праграмы:\\nСэрвіс:\\nЧас GMT:\\nПакет:\\nВерсія:\\nВерсія АС: - Ваш каментарый (на англійскай): + Ваш каментарый (па-англійску): Падрабязнасці: Прайграць відэа, працягласць: Мініяцюра аватара карыстальніка @@ -266,17 +266,17 @@ Заўсёды пытаць Атрыманне звестак… Загрузка запытанага кантэнту - Стварыць плэйліст + Стварыць плэй-ліст Перайменаваць Імя - Дадаць у плэйліст - Зрабіць мініяцюрай плэйліста - Дадаць плэйліст у закладкі + Дадаць у плэй-ліст + Зрабіць мініяцюрай плэй-ліста + Дадаць плэй-ліст у закладкі Выдаліць закладку - Выдаліць плэйліст\? - Плэйліст створаны - Дададзена ў плэйліст - Мініяцюра плэйліста зменена. + Выдаліць плэй-ліст? + Плэй-ліст створаны + Дададзена ў плэй-ліст + Мініяцюра плэй-ліста зменена. Без субцітраў Падагнаць Запоўніць @@ -330,7 +330,7 @@ Памылка чытання захаваных укладак. Выкарыстоўваюцца ўкладкі па змаўчанні Аднавіць прадвызначаныя значэнні Аднавіць прадвызначаныя значэнні? - Колькасць падпісчыкаў недаступная + Колькасць падпісчыкаў недаступна Укладкі, бачныя на галоўнай старонцы Абнаўленні Паказваць апавяшчэнне пры наяўнасці новай версіі @@ -379,7 +379,7 @@ Адлюстроўваць індыкатары пазіцый прагляду ў спісах Ачыстка даных Пазіцыі прайгравання выдалены - Файл перамешчаны ці выдалены + Файл перамешчаны або выдалены Файл з такім імем ужо існуе Файл з такім імем ужо існуе немагчыма перазапісаць файл @@ -388,7 +388,7 @@ На прыладзе скончылася вольнае месца Прагрэс страчаны, бо файл быў выдалены Скончыўся час злучэння - Вы хочаце ачысціць гісторыю спампоўвання ці выдаліць спампаваныя файлы? + Ачысціць гісторыю спампоўвання або выдаліць спампаваныя файлы? Абмежаваць чаргу спампоўвання Толькі адно адначасовае спампоўванне Пачаць спампоўванне @@ -397,7 +397,7 @@ Пры кожным спампоўванні вам будзе прапанавана выбраць месца захавання. \nУключыце сістэмны сродак выбару папак (SAF), калі хочаце спампоўваць файлы на знешнюю SD-карту Выкарыстоўваць сістэмны сродак выбару папак (SAF) «Storage Access Framework» дазваляе выконваць спампоўванне на знешнюю SD-карту - Пераключыць службу, выбраную ў дадзены момант: + Пераключэнне сэрвісу, зараз выбраны: Выдаліць усе пазіцыі прайгравання Уключыць «Абмежаваны рэжым» YouTube Падтрымліваюцца толькі URL-адрасы HTTPS @@ -435,15 +435,15 @@ Найбольш папулярнае Лакальнае Нядаўна дададзенае - Плэйлісты яшчэ не дададзены - Выберыце плэйліст + Плэй-лісты яшчэ не дададзены + Выберыце плэй-ліст Прадвызначаны кіёск Так Па завяршэнні націсніце «Гатова» ∞ відэа 100+ відэа - Багрэпарт на GitHub - Скапіруйце адфарматаваны багрэпарт + Паведаміць на GitHub + Скапіяваць адфарматаваную справаздачу Дайце дазвол на адлюстраванне паверх іншых праграм Выдаліць усе пазіцыі прайгравання\? Выдаліць пазіцыі прайгравання @@ -485,7 +485,7 @@ Выберыце любімую начную тэму - %s Дазвол вылучэння тэксту ў апісанні Вы можаце выбраць сваю любімую начную тэму ніжэй - Гэта опцыя даступна толькі тады, калі %s будзе выбранай тэмаю + Параметр даступны, толькі калі выбрана тэма %s Спампоўванне пачалося Апавяшчэнні адключаны Рэжым планшэта @@ -505,7 +505,7 @@ Начная тэма Адкрыць вэб-сайт Цяпер можна вылучаць тэкст у апісанні. Звярніце ўвагу, што ў рэжыме вылучэння старонка можа мільгаць, а спасылкі не націскацца. - Запускаць галоўны прайгравальнік у поўнаэкранным рэжыме + Запускаць асноўны прайгравальнік у поўнаэкранным рэжыме Паказаць дэталі канала Нізкая якасць (менш) Апавяшчэнне пра відэахэшаванне @@ -576,12 +576,12 @@ Апавяшчэнне аб памылцы Апавяшчэнні для паведамлення аб памылках Адбылася памылка NewPipe, націсніце, каб адправіць справаздачу - Запускаць відэа ва ўвесь экран, калі адключаны аўтапаварот. Міні-плэер даступны пры выхадзе з поўнаэкраннага рэжыму + Калі аўтапаварот адключаны, відэа адразу запускаецца ў поўнаэкранным рэжыме. Міні-плэер застаецца даступным, трэба толькі выйсці з поўнаэкраннага рэжыму Шукайце серверы, якія вам даспадобы, на %s Паказваць метаданыя Ігнараваць падзеі апаратных медыякнопак Паказваць змесціва, магчыма непрыдатнае для дзяцей, таму што яно мае ўзроставыя абмежаванні (напрыклад, 18+) - Калі ласка, праверце, ці існуе ўжо праблема з абмеркаваннем вашага збою. Пры стварэнні дублікатаў тыкетаў вы забіраеце ў нас час, які мы маглі б патраціць на выпраўленне фактычнай памылкі. + Праверце, ці не існуе заяўкі з абмеркаваннем вашай праблемы. Дублікаты марнуюць наш час і праз гэта адцягваецца вырашэнне сапраўдных задач. Адбылася памылка, глядзіце апавяшчэнне Збой плэера Карысна, напрыклад, калі вы карыстаецеся гарнітурай са зламанымі фізічнымі кнопкамі @@ -593,7 +593,7 @@ Разлік хэша Вырашана Створана аўтаматычна (запампавальнік не знойдзены) - Плэйлісты, якія пазначаны шэрым, ужо ўтрымліваюць гэты элемент. + Плэй-лісты, якія пазначаны шэрым, ужо ўтрымліваюць гэты элемент. %s новая трансляцыя %s новыя трансляцыі @@ -667,13 +667,13 @@ Заўсёды абнаўляць Парог абнаўлення стужкі - Немагчыма загрузіць канал для «%s». + Не ўдалося загрузіць канал для «%s». Стужка Час пасля апошняга абнаўлення, перш чым падпіска лічыцца састарэлай — %s Памылка загрузкі канала Уліковы запіс аўтара быў спынены. \nNewPipe не зможа загрузіць гэты канал у будучыні. \nАдпісацца ад канала? Рэжым хуткай загрузкі стужкі не дае дадатковай інфармацыі аб гэтым. - Атрымлівайце са спецыяльнага канала, калі ён даступны + Атрыманне даных са спецыяльнага канала, калі ён ёсць Уключыць хуткі рэжым Катэгорыя Тэгі @@ -686,7 +686,7 @@ Трансляцыі, спампоўванне якіх яшчэ не падтрымліваецца, не паказваюцца Мініяцюра аватара канала Аўтар: %s - Аўтару відэа спадабалася гэта + Спадабалася аўтару відэа Створана %s Адключыць хуткі рэжым Публічная @@ -699,7 +699,7 @@ Гэты кантэнт яшчэ не падтрымліваецца NewPipe. \n \nСпадзяюся, ён будзе падтрымлівацца ў наступных версіях. - Старонка плэйліста + Старонка плэй-ліста Паказваць мініяцюру Выкарыстоўваць мініяцюру як фон для экрана блакіроўкі і апавяшчэнняў Для гэтага дзеяння не знойдзены прыдатны файлавы менеджар. \nУсталюйце файлавы менеджар або паспрабуйце адключыць «%s» у наладах спампоўвання @@ -713,7 +713,7 @@ Унутраная Прагледжаныя цалкам Гэты кантэнт даступны толькі для аплачаных карыстальнікаў, таму NewPipe не можа яго трансляваць або спампоўваць. - Даступны ў некаторых службах, звычайна нашмат хутчэй, але можа вяртаць абмежаваную колькасць элементаў і часта няпоўную інфармацыю (напрыклад, без працягласці, тыпу элемента, без актыўнага стану) + Даступна для некаторых сэрвісаў, звычайна значна хутчэй, але можа перадаваць абмежаваную колькасць элементаў і не ўсю інфармацыю (можа адсутнічаць працягласць, тып элемента, паказчык трансляцыі) Узроставае абмежаванне Для гэтага дзеяння не знойдзены прыдатны файлавы менеджар. \nУсталюйце файлавы менеджар, сумяшчальны з Storage Access Framework Ніякая праграма на вашай прыладзе не можа адкрыць гэта @@ -774,16 +774,16 @@ Не загружаць выявы Высокая якасць Аб канале - Абагуліць плэйліст + Абагуліць плэй-ліст Пераматаць наперад Альбомы Пераматаць назад Паўтарыць - Атрыманыя ўкладкі пры абнаўленні стужкі. Гэты параметр не прымяняецца, калі канал абнаўляецца ў хуткім рэжыме. + Укладкі, для якіх атрымліваюцца даныя пры абнаўленні стужкі. Гэты параметр не дзейнічае, калі канал абнаўляецца з выкарыстаннем хуткага рэжыму. Сярэдняя якасць Загрузнік аватараў Банеры - Плэйлісты + Плэй-лісты - %1$s: %2$s Перамясціць панэль укладак уніз Няма жывых трансляцый @@ -816,4 +816,9 @@ Скінуць усе налады на іх прадвызначаныя значэнні Пры скіданні ўсіх налад будуць адхілены ўсе вашы змены налад і праграма перазапусціцца. \n \nСапраўды хочаце працягнуць? другасны + Абагуліць як часовы плэйліст YouTube + Плэй-лісты + Выберыце групу каналаў + Група каналаў яшчэ не створана + Старонка групы каналаў diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index c9b752d05..c38ea7952 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -810,4 +810,12 @@ Винаги използвайте заобикаляне на настройката на повърхността на видеоизхода на ExoPlayer Изтрий позиции за възпроизвеждане вторичен + Споделяне като временен плейлист в YouTube + Плейлисти + Все още няма създадена група за емисии + Страница на групата канали + Изберете група емисии + Търсене %1$s + Търсене %1$s (%2$s) + Харесвания diff --git a/app/src/main/res/values-bqi/strings.xml b/app/src/main/res/values-bqi/strings.xml new file mode 100644 index 000000000..a6b3daec9 --- /dev/null +++ b/app/src/main/res/values-bqi/strings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/app/src/main/res/values-br/strings.xml b/app/src/main/res/values-br/strings.xml new file mode 100644 index 000000000..a0a7744f6 --- /dev/null +++ b/app/src/main/res/values-br/strings.xml @@ -0,0 +1,121 @@ + + + Nullañ + Mat eo + Ket + Digeriñ e-barzh ar merdeer + Digeriñ gant + Rannañ + Pellgargañ + Klask a raec\'h \"%1$s\"? + Rannañ gant + Arverañ ul lenner aodio diavaez + Koumanantiñ + Digoumanantiñ + N\'haller ket kemmañ ar c\'houmanant + N\'haller ket hizivaat ar c\'houmanant + Diskouez an titouroù + Rolloù-lenn enrollet + Rolloù-lenn + Dibab un ivinell + Drekleur + Diflugell + Ouzhpennañ da + Teuliad pellgargañ ar videoioù + Amañ e vez kadavet ar restroù aodio pellgarget + Amañ e vez kadavet ar restroù video pellgarget + O kargañ + Netra + Mentrezh aodio dre ziouer + Dodenn + Dodenn noz + Sklaer + Teñval + Tregern + Roll istor enklask + Pellgargañ + Lañsañ al lenner pennañ e mod skramm a-bezh + Lenn emgefreek + Bro an endalc\'had dre ziouer + Erioloù PeerTube + Tra ebet + Mentrezh video dre ziouer + Lenn mell-divell + Aodio + Lenn gant Kodi + Lintr + Skarzhañ ar roadennoù + Klask + Arverañ ul lenner video diavaez + Teuliad pellgargañ ar restroù aodio + Du + Kinnigoù enklask + Kenderc\'hel al lenn + URL anskor + Yezh an endalc\'had dre ziouer + Pellgargañ restr al lanv + Staliañ + Ya + Koumanantoù + Arventennoù + Setu an disoc\'hoù evit: %s + Lamet e vez an aodio gant diarunustedoù \'zo + Digoumanantet oc\'h bet d\'ar chadenn + Sellet ouzh ar roll istor + Koumanantet + Diarunusted dre ziouer + Diuzit hoc\'h erioloù PeerTube gwell ganeoc\'h + Kavit an erioloù a blij deoc\'h war %s + Ouzhpennañ un eriol + Lenner + Video hag aodio + Roll istor ha krubuilh + Neuz + Diveugañ + Hizivadurioù + Rebuzadur al lenner + Assav ha gwarediñ + War-eeun + Pellgargadurioù + Pep tra + Chadennoù + Videoioù + Loabroù + Arveriaded + Degouezhioù + Tonioù + Albomoù + Arzourien + Diweredekaet + Skarzhañ + Dizober + Dilamet eo bet ar restr + Lenn pep tra + Atav + Restr + Rebuzadurioù + Rebuzadur NewPipe + Rebuzadurioù evit al lenner NewPipe + Rebuzadurioù evit handelvoù nevez NewPipe + Lanvioù nevez + Ur wech nemetken + Diarunusted wellañ + Fazi + Rebuzadur hizivadur an arload + Endalc\'had + Emzalc\'h + Rolloù-lenn + Pellgargadurioù + Sevel un danevell + Munudoù: + Aodio + Klask en-dro + Deskrivadur + Disoc\'h ebet + Endalc’had ebet + Petra zo c\'hoarvezet: + Lenn ar video, pad: + Titouroù: + Video + + diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index 9fbc05566..a4ed02801 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -54,6 +54,7 @@ Àudio %s subscriptor + %s subscriptors %s subscriptors D\'acord @@ -169,11 +170,13 @@ Cap reproducció %s reproducció + %s reproduccions %s reproduccions Cap vídeo %s vídeo + %s vídeos %s vídeos Pausa @@ -274,15 +277,7 @@ La supervisió de fugues de memòria pot fer que l\'aplicació deixi de respondre mentre es bolca la memòria Informa d\'errors fora del cicle de vida Força l\'informe d\'excepcions Rx que no es puguin transmetre que tinguin lloc fora del cicle de vida d\'un fragment o activitat després de disposar-los - Importeu les vostres subscripcions de YouTube mitjançant la còpia de contingut de Google Takeout: -\n -\n1. Aneu a : %1$s -\n2. Inicieu la sessió si se us demana -\n3. Premeu \"Totes les dades incloses\", després \"Dessel·lecciona-ho tot\", llavors sel·leccioneu només \"Subscripcions\" i finalment premeu \"D\'acord\". -\n4. Premeu \"Pas següent\" i llavors a \"Crea una exportació\" -\n5. Premeu el botó \"Baixa\" un cop hagi aparegut -\n6. Premeu a IMPORTA EL FITXER i sel·leccioneu el fitxer .zip descarregat -\n7. [En cas que la importació del fitxer .zip hagi fallat] extreieu-ne el fitxer subscripcions.csv (es troba generalment a \"Takeout/YouTube i YouTube Music/subscripcions/subscripcions.csv\"), premeu a IMPORTA EL FITXER i sel·leccioneu el fitxer .csv extret. + Importeu les vostres subscripcions de YouTube mitjançant la còpia de contingut de Google Takeout: \n \n1. Aneu a : %1$s \n2. Inicieu la sessió si se us demana \n3. Premeu \"Totes les dades incloses\", després \"Dessel·lecciona-ho tot\", llavors sel·leccioneu només \"Subscripcions\" i finalment premeu \"D\'acord\". \n4. Premeu \"Pas següent\" i llavors a \"Crea una exportació\" \n5. Premeu el botó \"Baixa\" un cop hagi aparegut \n6. Premeu a IMPORTA EL FITXER i sel·leccioneu el fitxer .zip descarregat \n7. [En cas que la importació del fitxer .zip hagi fallat] extreieu-ne el fitxer subscripcions.csv (es troba generalment a \"Takeout/YouTube i YouTube Music/subscripcions/subscripcions.csv\"), premeu a IMPORTA EL FITXER i sel·leccioneu el fitxer .csv extret Importeu un perfil del SoundCloud mitjançant l\'URL o l\'identificador del vostre perfil: \n \n1. Activeu el «Mode d\'ordinador» en un navegador (el lloc web no està disponible per a dispositius mòbils) @@ -407,7 +402,7 @@ El fitxer s\'ha mogut o suprimit Només una baixada alhora Fes servir el SAF - El SAF (Storage Access Framework; estructura d\'accés a l\'emmagatzematge) us permet realitzar baixades a una memòria externa com una targeta SD. + El SAF (Storage Access Framework; estructura d\'accés a l\'emmagatzematge) us permet realitzar baixades a una memòria externa com una targeta SD Esborra les posicions de reproducció Esborra totes les posicions de reproducció Voleu suprimir tots els punts de reproducció\? @@ -415,11 +410,13 @@ Cap visualització %s visualització + %s visualitzacions %s visualitzacions Cap reproducció %s escoltant + %s escoltants %s escoltants Es canviarà l\'idioma en reiniciar l\'aplicació @@ -477,17 +474,18 @@ Actualitza sempre Temps que ha de passar perquè una subscripció es consideri obsoleta — %s Llindar d\'actualització del contingut - Feed + Flux Mostra només les subscripcions sense grup Nou Esteu segurs de voler suprimir aquest grup\? Nom de grup buit - %d de sel·leccionat - %d de sel·leccionats + %d de seleccionat + %d de seleccionats + %d de seleccionats - Cap subscripció sel·leccionada - Sel·leccioneu les subscripcions + Cap subscripció seleccionada + Selecciona subscripcions Processant el contingut… Carregant el contingut… No carregat: %d @@ -495,18 +493,22 @@ Grups de canals %d dia + %d dies %d dies %d hora + %d hores %d hores %d minut + %d minuts %d minuts %d segon + %d segons %d segons A causa de les limitacions d\'ExoPlayer, la durada de cerca és de %d segons @@ -626,7 +628,7 @@ Baixa qualitat (més petit) Alta qualitat (més gran) Mostra indicadors de la imatge - Desactiva l\'entunelament del contingut si en els videos hi ha una pantalla negre o tartamudegen + Desactiva l\'entunelament del contingut si en reproduir el vídeos la pantalla se\'n va a negre o s\'entretallen. Mostra detalls del canal No s\'ha establert una carpeta de descàrregues, selecciona la carpeta per defecte ara Els comentaris estan desactivats @@ -644,13 +646,12 @@ Comprovar manualment si hi ha noves versions Baixada finalitzada + %s baixades finalitzades %s baixades finalitzades Vista prèvia de les miniatures de la barra de cerca - No s\'ha trobat cap gestor de fitxers adequat per a aquesta acció. -\nInstal·leu un gestor de fitxers compatible amb l\'entorn d\'accés d\'emmagatzematge. - No s\'ha trobat cap gestor de fitxers adequat per a aquesta acció. -\nInstal·leu un gestor de fitxers o intenteu desactivar «%s» als paràmetres de baixada. + No s\'ha trobat cap gestor de fitxers adequat per a aquesta acció. \nInstal·leu un gestor de fitxers compatible amb l\'entorn d\'accés d\'emmagatzematge + No s\'ha trobat cap gestor de fitxers adequat per a aquesta acció. \nInstal·leu un gestor de fitxers o intenteu desactivar «%s» als paràmetres de baixada S\'ha produït un error, consulteu la notificació Afegit el següent vídeo a la cua NewPipe ha trobat un error, toca per informar @@ -661,6 +662,7 @@ S\'estan comprovant les actualitzacions… S\'ha suprimit %1$s baixada + S\'han suprimit %1$s baixades S\'han suprimit %1$s baixades A partir de l\'Android 10 només s\'admet el \"Sistema d\'Accés a l\'Emmagatzematge\" @@ -691,8 +693,8 @@ Format desconegut Cualitat desconeguda Ordenar - Configura la notificació de reproducció actual. - Canvia la mida de l\'interval de càrrega en continguts progressius (actualment %s). Un valor inferior pot accelerar la càrrega inicial del vídeo. + Configura la notificació de reproducció actual + Canvia la mida de l\'interval de càrrega en continguts progressius (actualment %s). Un valor inferior pot accelerar la càrrega inicial del vídeo Ignora els esdeveniments dels botons de reproducció físics Útil, per exemple, si feu servir uns auriculars amb els botons físicament trencats Trieu un gest per la part esquerra de la pantalla @@ -735,4 +737,95 @@ Duplicat afegit/s %d vegada/es El túnel multimèdia s\'ha desactivat de manera predeterminada al dispositiu perquè se sap que el vostre model de dispositiu no ho permet. Semiton + Estàs fent servir la darrera versió de NewPipe + No hi ha prou espai lliure al dispositiu + Llistes de reproducció + Targeta + Vols suprimir tots els elements duplicats d\'aquesta llista de reproducció? + Llistes de reproducció + Suprimeix els duplicats + Restableix la configuració + NewPipe pot cercar automàticament actualitzacions i fer-t\'ho saber en estar disponibles.\nVols habilitar-ho? + Suprimeixo els duplicats? + Restableix tots els paràmetres als valors per defecte + Restablir tots els paràmetres descartarà els teus paràmetres preferits i reiniciarà l\'aplicació.\n\nN\'estàs segur? + Clica per descarregar%s + doblat + Commuta-ho tot + Pròximament + En directe + Reprodueix + Torna a reproduir + Més opcions + Comparteix la llista dels URLs + - %1$s: %2$s + Avatars de l\'autor + Avatars del sots-canal + Subscriptors + Ja hi hauria d\'haver una pista d\'àudio en aquest flux + El contingut escollit no és suportat per cap reproductor extern + No hi ha cap flux de vídeo disponible per a reproductors externs + Escull la pista d\'àudio per a reproductors externs + Desconegut + %1$s%2$s + original + descriptiu + Vídeos + Quines pestanyes es mostren a les pàgines del canal + Obre la cua de reproducció + Canvia l\'orientació de la pantalla + Vídeo anterior + Avança + Qualitat de la imatge + No carregues les imatges + Qualitat mitjana + Qualitat baixa + Comparteix com a llista de reproducció temporal de Youtube + %1$s\n%2$s + Mostra més + Avatars + Bàners + Durada + Rebobina + Comparteix amb els títols + No es mostren els contiguts que no suporten descàrrega + Mostra els vídeos següents + No hi ha cap flux d\'àudio disponible per a reproductors externs + Mostra/Amaga els vídeos + Aquesta opció només està disponible si%ss\'ha seleccionat per al tema + Vídeo següent + + %sresposta + %srespostes + %srespostes + + Recupera les pestanyes del canal + Valor per defecte d\'ExoPlayer + Miniatures + Quant a + Usa sempre la sortida de vídeo d\'ExoPlayer com a solució de contingència + La configuració exportada que vols importar té un format vulnerable que és obsolet des de NewPipe 0.27.0. Assegura\'t que l\'exportació que vols importar prové d\'una font de confiança i prefereix només les exportacions fetes amb NewPipe 0.27.0 o posterior d\'ara endavant. El suport a la importació de configuracions en aquest format vulnerable aviat serà suprimit completament i aleshores les antigues versions de NewPipe ja no podran importar les exportacions de les configuracions des de les noves versions. + Àlbums + Pestanyes del canal + Qualitat alta + Tria la qualitat de les imatges i si carregar-les totalment o no per reduir l\'ús de les dades i la memòria. Els canvis suprimiran la memòria cau de les imatges a la memòria i al disc — %s + Pestanyes que es recuperaran en actualitzar el contingut. Aquesta opció no s\'aplica si el canal s\'actualitza en mode ràpid. + Vist parcialment + Vist completament + Paràmetres d\'ExoPlayer + Gestiona alguns paràmetres d\'ExoPlayer. Caldrà reinciciar el reproductor per activar-los + Usa la funció de suport de decodificació d\'ExoPlayer + Habilita aquesta opció si tens problemes en iniciar el decodificador. S\'usaran decodificadors alternatius de baixa prioritat si falla el decodificador primari. Això pot provocar una disminució de la qualitat de la reproducció en relació a l\'ús del decodificador primari + Aquesta alternativa allibera i reinstancia els còdecs de vídeo si hi ha un canvi de màscara en lloc de configurar-la directament al còdec. ExoPlayer ja ho aplica en alguns dispositius amb aquest problema. Aquesta configuració només té efecte en Android 6 i posteriors\n\nHabilitar aquest opció pot prevenir errors de reproducció en canviar el reproductor actual o en passar a pantalla completa + Pistes + Curts + Canvia a pantalla completa + \? + Comparteix la llista de reproducció + Mostra menys + secundària + Canals + Encara no s\'ha creat cap grup de continguts + Tria un grup de continguts + Pàgina del grup de canals diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index f2f8da16c..a144e996a 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -139,9 +139,9 @@ Žádná videa - %s Video - %s Videa - %s Videí + %s video + %s videa + %s videí Stahování Povolené znaky v názvech souborů @@ -839,4 +839,12 @@ \nChcete tuto funkci povolit? Nastavení v importovaném exportu používají zranitelný formát. NewPipe používá nový formát od verze 0.27.0. Ujistěte se, že export importujete z důvěryhodného zdroje a v budoucnu upřednostňujte používání exportů získaných z NewPipe 0.27.0 nebo novějších. Podpora importu nastavení v tomto zranitelném formátu bude brzy kompletně odstraněna, kvůli čemuž staré verze NewPipe nebudou moci importovat nastavení z exportů z nových verzí. sekundární + Sdílet jako dočasný playlist YouTube + Playlisty + Vybrat skupinu kanálů + Zatím nebyla vytvořena žádná skupina kanálů + Stránka skupiny kanálů + Hledat %1$s + Hledat %1$s (%2$s) + Líbí se diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index f1afafa5f..86be3084a 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -825,4 +825,9 @@ Indstillingerne i den eksport, der importeres, bruger et sårbart format, der er blevet forældet siden NewPipe 0.27.0. Sørg for, at den eksport, der importeres, er fra en pålidelig kilde, og brug helst kun eksport fra NewPipe 0.27.0 eller nyere i fremtiden. Understøttelse af import af indstillinger i dette sårbare format fjernes snart helt, og så vil gamle versioner af NewPipe ikke længere være i stand til at importere indstillinger fra eksport fra nye versioner. Sikkerhedskopiering og gendannelse sekundær + Del som midlertidig YouTube-playliste + Playlister + Kanalgruppeside + Vælg en feed-gruppe + Ingen feed-gruppe oprettet endnu diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index f2d3b5698..416f9d584 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -587,7 +587,7 @@ Keine App auf deinem Gerät kann dies öffnen Dieser Inhalt ist privat, kann also nicht von NewPipe gestreamt oder heruntergeladen werden. Diese Inhalte sind nur für Benutzer verfügbar, die bezahlt haben, können also nicht von NewPipe gestreamt oder heruntergeladen werden. - Dieses Video ist nur für YouTube Music Premium-Mitglieder verfügbar und kann daher nicht von NewPipe gestreamt oder heruntergeladen werden. + Dieses Video ist nur für YouTube-Music-Premium-Mitglieder verfügbar und kann daher nicht von NewPipe gestreamt oder heruntergeladen werden. Dies ist ein SoundCloud Go+ Track, zumindest in deinem Land, kann er von NewPipe nicht gestreamt oder heruntergeladen werden. Dieser Inhalt ist in deinem Land nicht verfügbar. App abstürzen lassen @@ -825,4 +825,9 @@ \nMöchtest du wirklich fortfahren?
    Die Einstellungen in dem zu importierenden Export verwenden ein angreifbares Format, das seit NewPipe 0.27.0 veraltet ist. Stellen Sie sicher, dass der zu importierende Export aus einer vertrauenswürdigen Quelle stammt, und verwenden Sie in Zukunft nur noch Exporte, die aus NewPipe 0.27.0 oder neuer stammen. Die Unterstützung für den Import von Einstellungen in diesem angreifbaren Format wird bald vollständig entfernt werden, und dann werden alte Versionen von NewPipe nicht mehr in der Lage sein, Einstellungen von Exporten aus neuen Versionen zu importieren. Sekundär + Als temporäre YouTube-Wiedergabeliste teilen + Wiedergabelisten + Eine Feed-Gruppe auswählen + Kanalgruppen-Seite + Es wurde noch keine Feed-Gruppe erstellt diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 66c16c0b9..f871e9146 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -1,7 +1,7 @@ Δημοσιεύθηκε στις %1$s - Δε βρέθηκε πρόγραμμα αναπαραγωγής. Εγκατάσταση του VLC; + Δε βρέθηκε αναπαραγωγός ροής δεδομένων. Εγκατάσταση του VLC; Εγκατάσταση Άκυρο Άνοιγμα σε πρόγραμμα περιήγησης @@ -71,7 +71,7 @@ Ιστορικό Εμφάνιση πληροφοριών Πατήστε το μεγεθυντικό φακό για να ξεκινήσετε. - Δε βρέθηκε πρόγραμμα αναπαραγωγής ροής δεδομένων (μπορείτε να εγκαταστήσετε το VLC για να κάνετε αναπαραγωγή). + Δε βρέθηκε αναπαραγωγός ροής δεδομένων (μπορείτε να εγκαταστήσετε το VLC για να κάνετε αναπαραγωγή). Λήψη του αρχείου ροής Αφαιρείται ο ήχος από κάποιες αναλύσεις Το κανάλι διαγράφηκε @@ -103,7 +103,7 @@ Ανάκτηση αναπαραγωγής Συνέχιση της αναπαραγωγής έπειτα από διακοπές (π.χ. κλήσεις) Εμφάνιση επεξήγησης του «Πιέστε παρατεταμένα για προσθήκη στην ουρά» - Εμφάνιση υπόδειξης όταν πατηθεί το κουμπί παρασκηνίου ή αναδυόμενου παραθύρου στις \"Λεπτομέρειες:\\ στο βίντεο + Εμφάνιση συμβουλής κατά το πάτημα του φόντου ή του αναδυόμενου κουμπιού στο βίντεο «Λεπτομέρειες:» Προεπιλεγμένη χώρα περιεχομένου Αναπαραγωγός Συμπεριφορά @@ -184,7 +184,7 @@ Κανένα βίντεο %s βίντεο - %s βίντεο + %s βίντεο(πολλά) Εκκίνηση Δημιουργία @@ -472,7 +472,7 @@ Αυτό το βίντεο έχει περιορισμό ηλικίας. \n \nΕνεργοποιήστε το «%1$s» στις ρυθμίσεις εάν θέλετε να το δείτε. - Ενεργοποίηση \"Περιορισμένη Λειτουργία\\ του YouTube + Ενεργοποίηση \"Περιορισμένη Λειτουργία\" του YouTube Δεν ήταν δυνατή η αναγνώριση της διεύθυνσης URL. Άνοιγμα με άλλη εφαρμογή; Αυτόματη προσθήκη στην ουρά Η ουρά του ενεργού αναπαραγωγού θα αντικατασταθεί @@ -656,7 +656,7 @@ Χειροκίνητος έλεγχος για νέα έκδοση Έλεγχος αναβάθμισης Νέα αντικείμενα τροφοδοσίας - Εμφάνιση «Κατάρρευση αναπαραγωγέα\\ + Εμφάνιση \"Κατάρρευση αναπαραγωγέα\" Εμφανίζει μια επιλογή κατάρρευσης κατά τη χρήση του αναπαραγωγέα Κατάρρευση αναπαραγωγέα Ειδοποίηση αναφοράς σφάλματος @@ -825,4 +825,9 @@ \nΕίστε βέβαιοι ότι θέλετε να συνεχίσετε;
    Οι ρυθμίσεις στην εξαγωγή που εισάγεται χρησιμοποιούν μια ευάλωτη μορφή που είχε καταργηθεί από το NewPipe 0.27.0. Βεβαιωθείτε ότι η εξαγωγή που εισάγεται προέρχεται από αξιόπιστη πηγή και προτιμήστε να χρησιμοποιείτε μόνο εξαγωγές που λαμβάνονται από το NewPipe 0.27.0 ή νεότερο στο μέλλον. Η υποστήριξη για εισαγωγή ρυθμίσεων σε αυτήν την ευάλωτη μορφή θα καταργηθεί σύντομα εντελώς και, στη συνέχεια, οι παλιές εκδόσεις του NewPipe δεν θα μπορούν πλέον να εισάγουν ρυθμίσεις εξαγωγών από νέες εκδόσεις. δευτερεύων + Λίστες αναπαραγωγής + Μοιραστείτε ως προσωρινή λίστα αναπαραγωγής στο YouTube + Επιλογή ομάδας τροφοδοσίας + Δεν δημιουργήθηκε ομάδα τροφοδοσίας ακόμα + Σελίδα καναλιού ομάδας diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 8e0de7864..43df8dcfd 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -47,7 +47,7 @@ Miniatura del avatar del usuario Contenido Mostrar contenido con restricción de edad - Toca la lupa para comenzar.. + Toca la lupa para comenzar. En directo Descargas Descargas @@ -78,7 +78,7 @@ Copiado al portapapeles Defina una carpeta de descargas más tarde en los ajustes La interfaz de la aplicación dejó de funcionar - Qué:\\nSolicitar:\\nIntenga de contenido:\\nPaíse de contenido:\\nIdiomaño de la aplicación:\\nServicio:\\nTiempo de GTT:\\nPaquete:\\nVersión:\\nVersion de SO: + Qué:\\nSolicitud:\\nIdioma del contenido:\\nPaís del contenido:\\nIdioma de la aplicación:\\nServicio:\\nMarca de tiempo:\\nPaquete:\\nVersión:\\nVersión del SO: Negro Todo k @@ -91,7 +91,7 @@ Reto reCAPTCHA requerido Reproduciendo en modo emergente Formato de vídeo predefinido - Desactivado + Deshabilitado Mostrar resoluciones más altas Solo algunos dispositivos pueden reproducir vídeos en 2K / 4K Resolución predefinida de emergente @@ -130,7 +130,7 @@ Carácter de reemplazo Letras y dígitos La mayoría de los caracteres especiales - Historial de búsquedas + Historial de búsqueda Almacenar búsquedas localmente Historial de vistas Almacenar historial de vídeos vistos @@ -184,7 +184,7 @@ Comenzar a reproducir en segundo plano Reproducir en modo emergente Mostrar la sugerencia \"Mantener presionado para poner a la cola\" - Nuevo y lo mejor + Lo nuevo y lo mejor Mantener pulsado para añadir a la cola Donar NewPipe es desarrollado por voluntarios que emplean su tiempo libre para brindarle la mejor experiencia. Haz una aportación para ayudarlos a crear un NewPipe mejor mientras disfrutan de una taza de café. @@ -277,12 +277,7 @@ \n5. Haga clic en el botón de \"Descargar\" una vez que aparezca \n6. Haga clic en el botón IMPORTAR ARCHIVO que se muestra abajo y seleccione el archivo zip descargado \n7. [En caso de que la importación falle] Extraiga el archivo .csv (generalmente dentro de \"Youtube y Youtube Music/suscripciones/suscripciones.csv\"), haga clic en IMPORTAR ARCHIVO y seleccione el archivo csv extraído anteriormente
    - Importe un perfil de SoundCloud escribiendo la URL o su ID: -\n -\n1. Active el «modo escritorio» en un navegador web (el sitio no está disponible para dispositivos móviles) -\n2. Vaya a esta URL: %1$s -\n3. Inicie sesión cuando se le pida -\n4. Copie la URL del perfil a la que fue redireccionado. + Importa un perfil de SoundCloud escribiendo la URL o tu ID: \n \n1. Habilita el «modo escritorio» en un navegador web (el sitio no está disponible para dispositivos móviles) \n2. Ve a esta URL: %1$s \n3. Inicia sesión cuando se te pida \n4. Copia la URL del perfil a la que fuiste redireccionado. tuID, soundcloud.com/tuID Esta operación puede causar un uso intensivo de la red. \n @@ -381,8 +376,7 @@ El tiempo de conexión expiro No se puede recuperar esta descarga Preguntar dónde descargar - Se le preguntará dónde guardar cada descarga. -\nHabilite Elegir carpetas del sistema (SAF) si desea guardar las descargas en una tarjeta SD externa + Se te preguntará dónde guardar cada descarga. \nHabilita elegir carpetas del sistema (SAF) si quieres guardar las descargas en una tarjeta SD externa Usar Elegir carpetas del sistema (SAF) El \'Sistema de Acceso al Almacenamiento\' permite descargar en una tarjeta SD externa Desuscribirse @@ -405,7 +399,7 @@ Automático ¡Actualización de NewPipe disponible! Mostrar comentarios - Desactivar para ocultar comentarios + Deshabilitar para ocultar comentarios Reproducción automática Sin comentarios No se pudieron cargar los comentarios @@ -433,7 +427,7 @@ %s oyentes %s oyentes - El idioma cambiará luego de que se reinicie la aplicación + El idioma cambiará después del reinicio de la aplicación Duración de búsqueda al avanzar y/o retroceder Instancias de PeerTube Selecciona tus instancias favoritas de PeerTube @@ -494,14 +488,14 @@ Nombre de grupo vacío ¿Quieres borrar este grupo? Nuevo - Fuente + Contenido Velocidad de actualización del contenido Tiempo para que una suscripción se considere desactualizada — %s Actualizar siempre Extraer desde feed dedicado cuando esté disponible Disponible para algunos servicios, suele ser más rápido pero puede mostrar una cantidad limitada de ítems y a menudo información incompleta (por ejemplo falta de duración, tipo de ítem o estado) - Activar modo rápido - Desactivar modo rápido + Habilitar modo rápido + Deshabilitar modo rápido ¿Piensas que la carga de contenidos es muy lenta\? Entonces intenta habilitar la carga rápida (puedes cambiarlo en los ajustes o pulsando el botón debajo). \n \nNewpipe ofrece dos formas de cargar los contenidos: @@ -521,9 +515,7 @@ Artistas Álbumes Canciones - Este vídeo tiene restricción de edad. -\n -\nActivar \"%1$s\" en los ajustes si quieres verlo. + Este vídeo tiene restricción de edad. \n \nHabilitar \"%1$s\" en los ajustes si quieres verlo. Sí, y también vídeos vistos parcialmente Los vídeos que ya se hayan visto luego de añadidos a la lista de reproducción, serán quitados. \n¿Estás seguro\? ¡Esta acción no se puede deshacer! @@ -534,7 +526,7 @@ Miniatura de avatar del canal Los textos originales de los servicios serán visibles en los ítems de transmisiones Mostrar tiempo atrás original en ítems - Activar el «Modo restringido» de YouTube + Habilitar el «Modo restringido» de YouTube Página de lista de reproducción Mostrar solo suscripciones desagrupadas Aún no hay marcadores para listas de reproducción @@ -577,8 +569,8 @@ Hacer que Android personalice el color de la notificación de acuerdo con el color principal de la miniatura (tenga en cuenta que esto no está disponible en todos los dispositivos) Usar miniatura como fondo de pantalla de bloqueo y notificaciones Mostrar vista previa - Desactivar para ocultar información adicional sobre el creador o contenido de la transmisión - Desactivar para ocultar la descripción del vídeo y la información adicional + Deshabilitar para ocultar información adicional sobre el creador o contenido de la transmisión + Deshabilitar para ocultar la descripción del vídeo y la información adicional Ninguna aplicación en su dispositivo puede abrir esto Capítulos Reciente @@ -614,24 +606,24 @@ No listado Público Soporte - Lenguaje + Idioma Límite de edad Privacidad Licencia Etiquetas Categoría - Inhabilitar la selección de texto de la descripción + Deshabilitar la selección de texto de la descripción Habilitar la selección de texto de la descripción Ahora puede seleccionar el texto dentro de la descripción. Note que la página puede parpadear y los links no serán cliqueables mientras está en el modo de selección. %s da esta razón: - No fue posible cargar el muro por \'%s\'. + No fue posible cargar el feed por \'%s\'. Cuenta cancelada El modo de muro rápido no arroja más información sobre esto. La cuenta del autor ha sido cancelada.\nNewPipe no podrá acceder a ella en el futuro.\n¿Quieres desuscribirte de este canal? Error al cargar el muro Desde Android 10 solo el \'Sistema de Acceso al Almacenamiento\' es soportado Se le preguntará dónde guardar cada descarga - Desactiva la tunelización de los medios si experimentas una pantalla negra durante la reproducción o si la visualización de la imagen es intermitente. + Deshabilita la tunelización de medios si experimentas una pantalla negra durante la reproducción o si la visualización de la imagen es intermitente. Deshabilitar el túnel de medios Aún no se ha seleccionado ninguna carpeta de descargas, elija la carpeta de descargas por defecto ahora Anfitrión @@ -668,7 +660,7 @@ Buscar actualizaciones Buscar nuevas versiones manualmente Buscando actualizaciones… - Nuevos elementos en el muro + Nuevos elementos en el feed Cerrar abruptamente el reproductor Muestra una opción de cierre abrupto al usar el reproductor Mostrar \"Cerrar abruptamente el reproductor\" @@ -678,8 +670,7 @@ Se produjo un error, vea la notificación Crear una notificación de error Mostrar una barra de error - No se ha encontrado un gestor de archivos apropiado para esta acción. -\nPor favor, instale un gestor de archivos o intente desactivar \'%s\' en los ajustes de la descarga + No se ha encontrado un gestor de archivos apropiado para esta acción. \nPor favor, instala un gestor de archivos o intenta deshabilitarlo \'%s\' en los ajustes de la descarga No se encontró ningún administrador de archivos apropiado para esta acción. \n Instale un administrador de archivos compatible con Storage Access Framework Comentario fijado @@ -697,7 +688,7 @@ Notificar de nuevos directos desde las suscripciones Frecuencia de comprobación ¿Desea borrar del disco todos los archivos descargados\? - Las notificaciones están desactivadas + Las notificaciones están deshabilitadas Recibir notificaciones Conmutar todo Cargando detalles del directo… @@ -737,7 +728,7 @@ ¿Eliminar los duplicados\? ¿Quieres eliminar todas las secuencias duplicadas de esta lista de reproducción? Mostrar las siguientes secuencias - Mostrar/Ocultar secuencias + Mostrar/ocultar secuencias Próximamente Eliminar los duplicados Completamente visto @@ -767,7 +758,7 @@ Cambia el tamaño del intervalo de carga en contenidos progresivos (actualmente %s). Un valor más bajo puede acelerar la carga inicial Ajustes de ExoPlayer Gestiona algunos ajustes de ExoPlayer. Estos cambios requieren reiniciar el reproductor para que surtan efecto - Habilite esta opción si tiene problemas con la inicialización del decodificador recurriendo a decodificadores de menor prioridad si el decodificador principal no se inicializa. Esto puede dar como resultado un rendimiento de reproducción más bajo que cuando se usan decodificadores primarios + Habilita esta opción si tiene problemas con la inicialización del decodificador recurriendo a decodificadores de menor prioridad si el decodificador principal no se inicializa. Esto puede dar como resultado un rendimiento de reproducción más bajo que cuando se usan decodificadores primarios Esta solución alternativa libera los códecs de video y los vuelve a instanciar cuando cambia la máscara, en lugar de configurar la máscara directamente en el códec. ExoPlayer ya usa esta configuración en algunos dispositivos con este problema y solo afecta a Android 6 y versiones posteriores \n \nHabilitar esta opción puede evitar errores de reproducción al cambiar el reproductor de video actual o cambiar al modo de pantalla completa @@ -778,7 +769,7 @@ Sin transmisiones en directo Vídeos Suscriptores - Qué pestañas se muestran en las páginas de los canales + Qué pestañas se muestran en las páginas del canal Pestañas del canal Shorts Cargando metadatos… @@ -831,13 +822,16 @@ Respaldar y restaurar Restablecer ajustes Restablecer todos los ajustes a sus valores predeterminados - Restablecer todos los ajustes descartará todos sus ajustes preferidos y reiniciará la aplicación. -\n -\n¿Estas seguro que deseas continuar? + Restablecer todos los ajustes descartará todos sus ajustes preferidos y reiniciará la aplicación. \n \n¿Estás seguro que quieres continuar? No NewPipe puede buscar automáticamente nuevas versiones de vez en cuando y notificarle cuando estén disponibles. \n¿Quieres habilitar esto? La configuración de la exportación que se importa utiliza un formato vulnerable que quedó obsoleto desde NewPipe 0.27.0. Asegúrese de que la exportación que se está importando provenga de una fuente confiable y prefiera usar solo exportaciones obtenidas de NewPipe 0.27.0 o posterior en el futuro. La compatibilidad con la importación de configuraciones en este formato vulnerable pronto se eliminará por completo y, luego, las versiones antiguas de NewPipe ya no podrán importar configuraciones de exportaciones desde las nuevas versiones. secundaria + Compartir como lista de reproducción temporal de YouTube + Lista de reproducción + Selecciona un grupo de feed + Aún no se ha creado ningún grupo de feed + Página de grupo de canales diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index f7563fa04..5e62c98a2 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -146,7 +146,7 @@ Üksikasjad: Esita video, kestus: Üleslaadiaja avatari pisipilt - Meeldib + Meeldimisi Ei meeldi Tulemusi pole Siin pole veel midagi @@ -206,8 +206,8 @@ Anneta Veebisait Täiendava info ja uudiste lugemiseks külasta NewPipe\'i veebisaiti. - NewPipe\'i privaatsuspoliitika - Loe privaatsuspoliitikat + NewPipe\'i andmekaitsepõhimõtted + Loe andmekaitsepõhimõtteid NewPipe\'i litsents Loe litsentsi Ajalugu @@ -305,7 +305,7 @@ Kui sul on ideid kujunduse muutmisest, koodi puhastamisest või suurtest koodi muudatustest - abi on alati teretulnud. Mida rohkem tehtud, seda paremaks läheb! NewPipe\'i arendajad on vabatahtlikud, kes kulutavad oma vaba aega, toomaks sulle parimat kasutuskogemust. On aeg anda tagasi aidates arendajaid ja muuta NewPipe veel paremaks, nautides ise tassi kohvi. Anneta - NewPipe võtab privaatsust väga tõsiselt. Seetõttu ei kogu rakendus ilma nõusolekuta mingeid andmeid. \nNewPipe\'i privaatsuspoliitika selgitab üksikasjalikult, milliseid andmeid saadetakse ja kogutakse veateate saatmisel. + NewPipe võtab privaatsust väga tõsiselt. Seetõttu ei kogu rakendus ilma nõusolekuta mingeid andmeid. \nNewPipe\'i andmekaitsepõhimõtted selgitavad üksikasjalikult, milliseid andmeid saadetakse ja kogutakse veateate saatmisel. NewPipe on vaba ja avatud lähtekoodiga tarkvara. Seada võid kasutada, uurida, jagada ja parandada nii, nagu õigemaks pead. Täpsemalt - seda võid levitada ja/või muuta vastavalt Vaba Tarkvara Sihtasutuse avaldatud GNU Üldise Avaliku Litsentsi v.3 (või sinu valikul hilisema versiooni) tingimustele. Teavita elutsüklist väljas vigadest Impordi SoundCloudi profiil trükkides URL või oma ID: @@ -320,7 +320,7 @@ Keri helitu koht edasi Samm Lähtesta - Selleks, et täita Euroopa Üldist Andmekaitse Määrust (GDPR), juhime tähelepanu NewPipe\'i privaatsuspoliitikale. Palun loe seda hoolikalt. \nMeile veateate saatmiseks pead sellega nõustuma. + Selleks, et täita Euroopa Üldist Andmekaitse Määrust (GDPR), juhime tähelepanu NewPipe\'i andmekaitsepõhimõtetele. Palun loe seda hoolikalt. \nMeile veateate saatmiseks pead sellega nõustuma. Minimeeri, kui kasutad teisi rakendusi Tegevus lülitusel peamiselt videopleierilt teisele rakendusele — %s Pole @@ -810,4 +810,12 @@ Ei Imporditavad andmed kasutavad turvaprobleemidega vormingut, mida alates versioonist 0.27.0 NewPipe enam kasutada ei suuda. Palun kontrolli, et impordifail on loodud usaldusväärse osapoole poolt ning eelista ekspordifaile, mis on loodud NewPipe\'i versiooniga 0.27.0 või uuemaga. Tugi sellise vana vormingu kasutamisele kaob õige pea ja seejärel NewPipe\'i uuemad ja vanemad versioonid ei saa omavahel andmeid enam vahetada. täiendav + Jaga YouTube\'i ajutise esitusloendina + Esitusloendid + Vali andmevoo grupp + Ühtegi andmevoo gruppi pole veel loodud + Kanalirühmade leht + Otsi: %1$s + Otsi: %1$s (%2$s) + Meeldimisi diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index b5e5de31c..6fef73fc7 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -766,4 +766,59 @@ ؟ پشتیبان‌گیری و بازیابی بدون جریان زنده + کیفیت تصویر + کیفیت متوسّط + کیفیت زیاد + ترجیح صدای اصلی + هم‌رسانی سیاههٔ پخش + کیفیت کم + سیاهه‌های پخش + بازنشانی تنظیمات + ثانویه + نمایش کم‌تر + جابه‌جایی گزینشگر زبانهٔ اصلی به پایین + تونل زدن رسانه به صورت پیش‌گزیده روی افزاره‌تان از کار افتاده چرا که از آن پشتیبانی نمی‌کند. + کنش ژست راست + قطعه‌ای صوتی باید از پیش در این جریان موجود باشد + برای نمونه اگر از گوشی‌ای با دکمه‌های خراب استفاده می‌کنید مفید است + بازنشانی همهٔ تنظیمات همهٔ تنظیمات ترجیحیتان را دور اندعخته و کاره را دوباره آغاز می‌کند.\n\nمطمئنید که می‌خواهید ادامه دهید؟ + استفاده از ویژگی پشتیبان کدگشای اگزوپلیر + زبانه‌های نشان داده شده روی صفحه‌های کانال + تغییر جهت صفحه + بار نکردن تصویرها + هم‌رسانی سیاههٔ نشانی + هم‌رسانی به شکل سیاههٔ پخش موقّتی یوتوب + - %1$s: %2$s + %1$s\n%2$s + استفادهٔ همیشگی از دور زدن تنظیمات سطح خروجی ویدیوی اگزوپلیر + موقعیت زبانه‌های اصلی + واکشی زبانه‌های کانال + گزینش قطعهٔ صوتی برای پخش کننده‌های خارجی + + %s پاسخ + %s پاسخ + + هم‌رسانی با عنوان‌ها + گزینش قطعهٔ صوتی با شرح برای افزار کم‌بینا در صورت وجود + ترجیح صدای شرح دهنده + گزینش کنش ژست نیمهٔ راست صفحه + تعداد %d بار تکرار شده + چهرک‌های بارکننده + چهرک‌های زیرکانال + کنش ژست چپ + گزینش کیفیت تصویرها و این که اصلاً بار شوند یا نه، برای کاهش استفادهٔ حافظه و داده. تغییرات انبارهٔ تصویر حافظه و دیسک را پاک می‌کند — %s + اگر مشکل شروع رمزگشایی دارید ، این گزینه را فعال کنید ، که اگر رمزگشایی اولیه شکست بخورد ، به رمزگشایی های با اولویت پایین تر باز می گردد. این ممکن است منجر به عملکرد پخش ضعیف نسبت به هنگام استفاده از رمزگشایان اولیه شود + این روش دور زدن مشکل به جای تنظیم مستقیم سطح روی رمزینه، آن‌ها را هنگام تغییر سطح آزاد کرده و دوباره راه‌اندازی می‌کند. این تنظیم که از پیش روی برخی افزاره‌ها به دست اگزوپلیر استفاده می‌شد فقط روی اندروید ۶ و بالاتر تأثیر دارد\n\nبه کار انداختن این گزینه می‌تواند از خطاهای پخش هنگام تغییر پخش‌کنندهٔ ویدیوی کنونی یا تغییر به حالت تمام‌صفحه جلوگیری کند + مدیریت برخی تنظیمات اگزوپلیر. اعمال این تغییرات نیازمند آغاز دوبارهٔ پخش‌کننده است + سیاهه‌های پخشی که خاکستری شده‌اند این مورد را از پیش دارند. + ویرایش هر کنش آگاهی زیر با زدن رویش. سه کنش نخست (پخش/مکث، پیشین و بعدی) به دست سامانه تنظیم شده و قابل سفارشی سازی نیستند. + گزینش کنش ژست نیمهٔ چپ صفحه + گزینش قطعهٔ صوتی اصلی فارغ از زبان + نیوپایپ می‌تواند گه‌گاه به صورت خودکار نگارش‌های جدید را بررسی کرده و از وجودشان آگاهتان کند.\nمی‌خواهید به کارش بیندازید؟ + بازنشانی همهٔ تنظیمات به مقدارهای پیش‌گزیده‌شان + نمایش بیش‌تر + تنظیمات داخل برون‌ریزی‌ از قالبی آسیب‌پذیر استفاده می‌کند که از نگارش ۰٫۲۷٫۰ منسوخ شده. مطمئن شوید برون‌ریزی از منبعی مطمئن آمده و ترجیحاً فقط از برون‌ریزی‌های آمده از نگارش ۰٫۲۷٫۰ به بعد استفاده کنید. پشتیبانی از درون‌ریزی تنظیمات به این قالب آسیب‌پذیر به زودی کاملاً‌برداشته خواهد شد و دیگر نگارش‌خای قدیمی‌تر قادر به درون ریزی تنظیمات از نگارش‌های جدید نخواهند بود. + گشودن صف پخش + می‌خواهید همهٔ جریان‌های تکراری را در این سیاههٔ پخش بردارید؟ + زبانه‌هایی که هنگام به‌روز رسانی خوراک واکشی می‌شوند. این گزینه تأثیری روی کانال‌هایی که با ساتفاده از حالت سریع به‌روز می‌شوند ندارد. diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 3aae66640..0bc4f4692 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -809,4 +809,9 @@ NewPipe voi automaattisesti tarkistaa päivitysten saatavuuden silloin tällöin ja ilmoittaa kun niitä on saatavilla. \nHaluatko ottaa tämän käyttöön? Laitteella ei ole riittävästi vapaata tilaa + Jaa tilapäisenä YouTube-soittolistana + Raidat + \? + toissijainen + Soittolistat diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 63d6fb263..cf6c50a76 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -5,7 +5,7 @@ Vouliez-vous dire « %1$s » \? Télécharger Dossier de téléchargement vidéo - Choisissez le dossier de téléchargement des vidéos + Choisissez le dossier de téléchargement pour les fichiers vidéos Les vidéos téléchargées sont stockées ici Installer Installer l’application Kore manquante \? @@ -841,4 +841,12 @@ Pas assez d\'espace disponible sur l\'appareil Les paramètres de l\'export en cours d\'importation utilisent un format vulnérable qui a été déprécié depuis NewPipe 0.27.0. Assurez-vous que l\'export en cours d\'importation provient d\'une source fiable. Privilégiez les exports obtenues à partir de NewPipe 0.27.0 ou des versions plus récentes à l\'avenir. Le support pour l\'importation des paramètres dans ce format vulnérable sera bientôt complètement supprimé et les anciennes versions de NewPipe ne pourront plus importer les paramètres des exports des nouvelles versions. secondaire + Partager comme liste de lecture YouTube temporaire + Listes de lecture + Sélectionnez un groupe de flux + Aucun groupe de flux n\'a encore été créé + Page du groupe de chaînes + Rechercher %1$s + Rechercher %1$s (%2$s) + Likes diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index 47eea5ee4..83c85cc9e 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -105,7 +105,7 @@ פרטים: נגינת סרטון, משך: תמונה ייצוגית של המפרסם - אהבו + לייקים לא אהבו אין תוצאות אין כאן כלום מלבד צרצרים @@ -196,7 +196,7 @@ להתחיל לנגן בנגן צף הורדת קובץ הזרמה הצגת מידע - רשימות נגינה מסומנות + רשימות השמעה מסומנות הוספה אל מדינת תוכן כברירת מחדל ניפוי שגיאות @@ -852,4 +852,12 @@ אין מספיק מקום פנוי במכשיר ההגדרות בייצוא המיובא משתמשות בתסדיר פגיע שהוצא משימוש מאז NewPipe 0.27.0. יש לוודא שהייצוא המיובא הוא ממקור מהימן, ועדיף להשתמש רק בייצוא שהושג מ־NewPipe 0.27.0 ומעלה בעתיד. תמיכה בייבוא הגדרות בתסדיר פגיע זה תוסר בקרוב לחלוטין, ואז גרסאות ישנות של NewPipe לא יוכלו לייבא עוד הגדרות של ייצוא מגרסאות חדשות. משני + רשימות נגינה + שיתוף כרשימת נגינה זמנית של YouTube + הגדרת קבוצת ערוצי עדכונים + לא נוצרו עדיין קבוצות ערוצי עדכונים + עמוד קבוצת ערוצים + חיפוש ב־%1$s + חיפוש ב־%1$s‏ (%2$s) + לייקים diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 90da929bf..e55471d48 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -49,7 +49,7 @@ Jelentés Információ: Ez történt: - Az Ön megjegyzése (angolul): + Saját hozzászólás (angolul): Részletek: Elnézést, valami balul sült el. Elnézést, ennek nem kellett volna megtörténnie. @@ -127,18 +127,18 @@ Az alkalmazás/kezelőfelület összeomlott Nem sikerült a videó lejátszása A külső lejátszó nem támogatja az ilyen típusú hivatkozásokat - Nem található videó adatfolyam - Nem található hang adatfolyam + Nem található videófolyam + Nem található hangfolyam Mi:\\nKérés:\\nTartalom nyelve:\\nTartalom származási országa:\\nAlkalmazás nyelve:\\nSzolgáltatás:\\nGMT idő:\\nCsomag:\\nVerzió:\\nOperációs rendszer verzió: Nincs találat Közvetítési fájl letöltése Hozzáadás ehhez Gyorsabb, de pontatlan tekerés használata A pontatlan tekerés lehetővé teszi, hogy gyorsabban ugorjon a pozíciókra, de kisebb pontossággal. Az 5, 15, vagy 25 másodperces tekerés nem működik ebben a módban - A bélyegkép gyorsítótára törölve + Bélyegkép gyorsítótára törölve Gyorsítótárazott metaadatok törlése - Minden gyorsítótárazott weboldaladat törlése - A metaadatok gyorsítótára törölve lett + Minden gyorsítótárazott weboldaladat törölve + Metaadatok gyorsítótára törölve Következő videó automatikus sorba állítása Keresési előzmények helyi tárolása Csatornák @@ -202,13 +202,13 @@ Licencek Szabad, egyszerű közvetítésnézés Androidon. Közreműködés - Legyen ötleted a fordítással, a dizájnnal, a forráskód tisztításával vagy egy komolyabb átszervezésével kapcsolatban, bármilyen segítséget szívesen fogadunk. Minél több minden készül el, annál jobb lesz! + Akár fordítással, tervezési változtatásokkal, kódtisztítással, vagy valódi nehéz kódváltoztatással kapcsolatos ötletei vannak, bármilyen segítséget szívesen fogadunk. Minél több minden készül el, annál jobb lesz! Megtekintés a GitHubon Adományozás A NewPipe alkalmazást önkéntesek fejlesztik a szabadidejükben, hogy a lehető legjobb felhasználói élményt nyújtsák. Járuljon hozzá, hogy a fejlesztők még jobbá tegyék alkalmazást, miközben egy csésze kávét szürcsölnek. Hozzájárulás - Honlap - Látogassa meg a NewPipe honlapját további információkért és hírekért. + Weboldal + Látogasson el a NewPipe weboldalára további információkért és hírekért. A NewPipe adatvédelmi irányelvei A NewPipe projekt komolyan veszi az adatvédelmét. Az alkalmazás nem gyűjt semmilyen adatot a beleegyezése nélkül. \nA NewPipe adatvédelmi irányelve részletesen elmagyarázza, mely adatok kerülnek elküldésre és tárolásra az alkalmazás összeomlásának jelentésekor. @@ -270,23 +270,10 @@ Exportálás… Fájl importálása Előző exportálás - A feliratkozások importálása nem sikerült - A feliratkozások exportálása nem sikerült - YouTube feliratkozások importálása a Google Takeoutból: -\n -\n1. Navigáljon erre az oldalra: %1$s -\n2. Jelentkezzen be, ha kérik -\n3. Kattintson „Az összes adatot tartalmazza” gombra, majd a „Kijelölések megszüntetése” gombra, majd válassza ki a „feliratkozások” lehetőséget és kattintson az „OK” gombra -\n4. Kattintson a „Következő lépés”, majd az \"Exportálás indítása” gombra -\n5. Kattintson a „Letöltés” gombra, amikor megjelenik, -\n6. Kattintson a lenti FÁJL IMPORTÁLÁSA gombra, és válassza ki a letöltött ZIP-fájlt -\n7. [Ha a ZIP-fájl importálása nem sikerül] Bontsa ki a .csv fájlt (általában: „YouTube és YouTube Music/feliratkozások/feliratkozások.csv\"), majd kattintson lent a FÁJL IMPORTÁLÁSA gombra, és válassza az exportált CSV-fájlt - SoundCloud-profil importálása a webcím vagy az azonosítójának begépelésével: -\n -\n1. A webböngészőben engedélyezze az „asztali módot” (az oldal nem érhető el mobileszközökön) -\n2. Navigáljon erre a webcímre: %1$s -\n3. Jelentkezzen be, ha kéri -\n4. Másolja ki a profil webcímét, ahova át lett irányítva. + A feliratkozások importálása sikertelen + A feliratkozások exportálása sikertelen + YouTube feliratkozások importálása a Google Takeoutból: \n \n1. Navigáljon erre az oldalra: %1$s \n2. Jelentkezzen be, ha kérik \n3. Kattintson „Az összes adatot tartalmazza” gombra, majd a „Kijelölések megszüntetése” gombra, majd válassza ki a „feliratkozások” lehetőséget és kattintson az „OK” gombra \n4. Kattintson a „Következő lépés”, majd az \"Exportálás indítása” gombra \n5. Kattintson a „Letöltés” gombra, amikor megjelenik, \n6. Kattintson a lenti FÁJL IMPORTÁLÁSA gombra, és válassza ki a letöltött ZIP-fájlt \n7. [Ha a ZIP-fájl importálása nem sikerül] Bontsa ki a .csv fájlt (általában: „YouTube és YouTube Music/feliratkozások/feliratkozások.csv”), majd kattintson lent a FÁJL IMPORTÁLÁSA gombra, és válassza az exportált CSV-fájlt + SoundCloud-profil importálása a webcím vagy az azonosítójának begépelésével: \n \n1. A webböngészőben engedélyezze az „asztali módot” (az oldal nem érhető el mobileszközökön) \n2. Navigáljon a következő webcímre: %1$s \n3. Jelentkezzen be, ha kéri \n4. Másolja ki a profil webcímét, ahova át lett irányítva. saját azonosítója, soundcloud.com/azonosító Ez a művelet adatforgalom-igényes lehet. \n @@ -305,11 +292,11 @@ Lejátszás folytatása a háttérben Lejátszás folytatása felugró ablakban Lejátszás folytatása - A „Tartsa lenyomva a sorba állításhoz\" tipp megjelenítése + A „Tartsa lenyomva a sorba állításhoz” tipp megjelenítése Leiratkozás Válasszon lapot - Megjegyzések megjelenítése - Kapcsolja ki a megjegyzések elrejtéséhez + Hozzászólások megjelenítése + Kapcsolja ki a hozzászólások elrejtéséhez Tartalom alapértelmezett országa Folytatás főnézetben Eltüntetés @@ -350,7 +337,7 @@ Az előrehaladás elveszett, mert a fájlt törölték Nincs hely az eszközön A NewPipe leállt a fájl feldolgozása közben - Utófeldolgozás sikertelen + Az utófeldolgozás sikertelen Nincs talalat A kiszolgáló nem fogad többszálú letöltést, próbálkozzon újra ezzel: @string/msg_threads = 1 A kiszolgáló nem küld adatokat @@ -366,7 +353,7 @@ Ilyen névű fájl már létezik Felülírás Egyedi név előállítása - Letöltés sikertelen + A letöltés sikertelen helyrehozás utófeldolgozás sorba állítva @@ -398,10 +385,9 @@ Automatikus sorba állítás Kapcsolja ki, hogy elrejtse a videó leírását és a további információkat Visszaállítja az alapértelmezéseket\? - Ez a videó korhatáros. -\nAz új, korhatáros videókkal kapcsolatos YouTube irányelvek miatt a NewPipe nem férhet hozzá a videóhoz, így nem tudja lejátszani. + Ez a videó korhatáros. \nAz új, korhatáros videókkal kapcsolatos YouTube irányelvek miatt a NewPipe nem férhet hozzá a videófolyamokhoz, így nem tudja lejátszani. Leírás - Megjegyzések + Hozzászólások Formázott jelentés másolása Adjon engedélyt a más alkalmazások feletti megjelenéshez Még nincs könyvjelző lejátszási listához @@ -421,8 +407,7 @@ Az ExoPlayer korlátai miatt az előre- és visszatekerés időtartama %d másodpercre lett állítva Csatornacsoportok Rendszer alapértelmezése - Az Általános adatvédelmi rendeletnek (GDPR) való megfelelés érdekében felhívjuk figyelmét a NewPipe adatvédelmi nyilatkozatára. Olvassa el figyelmesen. -\nEl kell fogadnia, ha hibajelentést szeretne küldeni. + Az Általános adatvédelmi rendeletnek (GDPR) való megfelelés érdekében felhívjuk figyelmét a NewPipe adatvédelmi irányelveire. Olvassa el figyelmesen. \nEl kell fogadnia, ha hibajelentést szeretne küldeni. Alkalmazás összeomlasztása Memóriaszivárgások megjelenítése A memóriaszivárgás-monitorozás az alkalmazás megállását okozhatja, amíg a dinamikus memória mentése folyik @@ -444,7 +429,7 @@ A feliratkozók száma nem érhető el Helyi A nyelv az alkalmazás újraindításakor fog megváltozni - Megjegyzések betöltése sikertelen + A megjegyzések betöltése sikertelen Válasszon egy lejátszási listát Lejátszás automatikus indítása — %s Lejátszás sebességének beállítása @@ -458,7 +443,7 @@ © %1$s %2$s, %3$s licenc alatt Harmadik féltől származó licencek Kész - Nincs megjegyzés + Nincsenek hozzászólások ∞ videó 100+ videó Jelentés a GitHubon @@ -468,7 +453,7 @@ reCAPTCHA sütik törlése Előadók Albumok - Számok + Dalok Események Videók Ez a videó korhatáros. @@ -516,7 +501,7 @@ Ezt a tartalmat még nem támogatja a NewPipe. \n \nRemélhetőleg egy következő verzióban már támogatott lesz. - Nincs a készülékén olyan alkalmazás, amely meg tudja ezt nyitni + Az eszközön nincs olyan alkalmazás, amely meg tudja ezt nyitni Ez a videó csak YouTube Music Prémium előfizetők számára érhető el, így nem tekinthető meg és nem tölthető le a NewPipe-pal. Automatikus (rendszertéma) Ez a tartalom csak előfizetőknek érhető el, nem tekinthető meg és nem tölthető le a NewPipe-pal. @@ -536,7 +521,7 @@ A YouTube biztosít egy „Korlátozott módot”, amely elrejti a lehetséges felnőtteknek szóló tartalmat A YouTube „Korlátozott mód” bekapcsolása A példány már létezik - A példány érvényesítése nem sikerült + A példány érvényesítése sikertelen Adja meg a példány webcímét Példány hozzáadása Találjon Önnek tetsző példányokat itt: %s @@ -562,7 +547,7 @@ A fő lejátszó teljes képernyős indítása A videókat ne a kis lejátszóban indítsa el, hanem kapcsolja be a teljes képernyős módot, ha az automatikus forgatás zárolva van. Továbbra is elérheti a kis lejátszót, ha kilép a teljes képernyőből Szolgáltatás be/ki, jelenleg kiválasztott: - A megjegyzések ki vannak kapcsolva + A hozzászólások ki vannak kapcsolva Húzza oldalra az elemeket az eltávolításukhoz A következő sorba állítása A következő sorba állítva @@ -573,29 +558,17 @@ Picasso színes szalagok megjelenítése a képek fölött, megjelölve a forrásukat: piros a hálózathoz, kék a lemezhez, zöld a memóriához Minden letöltésnél meg fogja kérdezni, hogy hova mentse el Válasszon egy példányt - Lista legutóbbi frissítése: %s - Lista betöltése… + Hírfolyam utoljára frissítve: %s + Hírfolyam betöltése… Csak a nem csoportosított feliratkozások megjelenítése - Lista - Lista frissítési küszöb + Hírfolyam + Hírfolyam frissítési küszöb A legutóbbi frissítés óta eltelt idő, ami után a feliratkozás elavultnak számít – %s - A szerző fiókját eltávolították. -\nA NewPipe nem fogja tudni betölteni ezt a listát a jövőben. -\nLeiratkozik erről a csatornáról\? - A gyors listamód nem ad ennél több információt. - Lekérés egy dedikált listából, ha lehetséges + A szerző fiókját eltávolították. \nA NewPipe nem fogja tudni betölteni ezt a hírfolyamot a jövőben. \nLeiratkozik erről a csatornáról? + A gyors hírfolyammód nem szolgáltat több információt. + Lekérés egy dedikált hírfolyamból, ha lehetséges Gyors mód engedélyezése - Úgy gondolja, hogy a lista betöltése lassú\? Ha így van, akkor próbálja engedélyezni a gyors betöltést (ezt a beállításokban változtathatja meg, vagy a lenti gomb megnyomásával). -\n -\nA NewPipe két listabetöltési stratégiát kínál: -\n• A teljes feliratkozott csatorna lekérése, amely lassú, de teljes. -\n• Egy dedikált szolgáltatási végpont, amely gyors, de általában nem teljes. -\n -\nA különbség a kettő között az, hogy a gyorsból általában hiányoznak egyes információk, mint az elem hossza vagy a típusa (nem lehet megkülönböztetni az élő videókat a normálaktól), valamint kevesebb elemet adhat vissza. -\n -\nA YouTube például egy olyan szolgáltatás, amely ezt a gyors módot RSS hírcsatornával kínálja. -\n -\nÍgy a választása azon múlik, hogy melyiket tartja fontosabbnak: a sebességet vagy a pontos információkat. + Úgy gondolja, hogy a hírfolyam betöltése lassú? Ha így van, akkor próbálja engedélyezni a gyors betöltést (ezt a beállításokban változtathatja meg, vagy a lenti gomb megnyomásával). \n \nA NewPipe két hírfolyam betöltési stratégiát kínál: \n• A teljes feliratkozott csatorna lekérése, amely lassú, de teljes. \n• Egy dedikált szolgáltatási végpont, amely gyors, de általában nem teljes. \n \nA különbség a kettő között az, hogy a gyorsból általában hiányoznak egyes információk, mint az elem hossza vagy a típusa (nem lehet megkülönböztetni az élő videókat a normálaktól), valamint kevesebb elemet adhat vissza. \n \nA YouTube például egy olyan szolgáltatás, amely ezt a gyors módot RSS hírcsatornával kínálja. \n \nÍgy a választása azon múlik, hogy melyiket tartja fontosabbnak: a sebességet vagy a pontos információkat. Csatorna profilképének bélyegképe Legutóbbi Kiemelt @@ -613,25 +586,25 @@ Letöltés befejezve %s letöltés befejezve - Lista feldolgozása… + Hírfolyam feldolgozása… Egyes szolgáltatásoknál érhető el, általában sokkal gyorsabb, és korlátozott számú elemet adhat vissza, gyakran hiányos információkkal (például nincs hossz, elemtípus, vagy élő videó állapot) Fiók eltávolítva Megjelölés megnézettként Még nincs letöltési mappa beállítva, válassza ki az alapértelmezett letöltési mappát most Tekerősáv bélyegkép-előnézete Magas minőségű (nagyobb) - Hiba a lista betöltésekor + Hiba a hírfolyam betöltésekor Nyelv Támogatás Weboldal megnyitása Táblagép mód Az Android 10-től kezdve, csak a „Storage Access Framework” támogatott - Új listaelemek + Új hírfolyamelemek Privát Belső Készítő által szívecskézve Be - A(z) „%s” listája nem tölthető be. + A(z) „%s” hírfolyam nem tölthető be. Ez egy SoundCloud Go+ szám, legalábbis az Ön országában, így nem játszható le vagy tölthető le a NewPipe-pal. Kapcsolja ki, hogy elrejtse a metainformációs dobozokat, melyek további információkat tartalmaznak a közvetítés létrehozójáról, annak tartalmáról vagy egy keresési kérésről Hibajelentési értesítés @@ -669,9 +642,9 @@ %1$s letöltés törölve %1$s letöltés törölve - Rögzített megjegyzés + Kitűzött hozzászólás LeakCanary nem elérhető - Lejátszó értesítés + Lejátszási értesítés Módosítsa a progresszív tartalmak betöltési intervallumának méretét (jelenleg %s). Az alacsonyabb érték felgyorsíthatja a kezdeti betöltésüket. Jelenleg játszott közvetítés értesítésének testreszabása Értesítések @@ -679,14 +652,14 @@ Értesítések új élő közvetítésekről a feliratkozott csatornák esetén Közvetítés részleteinek betöltése.… Keressen új élő közvetítést - Új közvetítésértesítések + Új közvetítések értesítései Értesítésen új élő közvetítés esetén a feliratkozott csatornákhoz Ellenőrzési gyakoriság Szükséges hálózati kapcsolat Bármilyen hálózat Törli az összes letöltött fájlt a lemezről\? Értesítsen - Értesítéstek kikapcsolva + Az értesítések le vannak tiltva Lejátszás betöltési intervallumának mérete Százaléka @@ -694,14 +667,14 @@ %s új elő közvetítés ExoPlayer alapértelmezett - Feliratkoztál erre a csatornára + Feliratkozott erre a csatornára , Azok az élő adások melyek nem támogatottak a letöltő által, rejtve vannak A választott élő adást nem lehet külső lejátszóval lejátszani - Összes váltása - Külső lejátszók számára nem érhető el az hang csatorna - Külső lejátszók számára nem érhető el videó - Válassz minőséget külső lejátszókhoz + Összes be/ki + Külső lejátszók számára nem érhető el hangfolyam + Külső lejátszók számára nem érhető el videófolyamok + Válasszon minőséget a külső lejátszókhoz Ismeretlen formátum Ismeretlen minőség Félhang @@ -721,11 +694,11 @@ A kiszürkített lejátszólisták már tartalmazzák ezt az elemet. Állandó bélyegkép feloldása Ismétlődések eltávolítása - Végignézve - Részben megnézve + Teljesen megtekintett + Részben megtekintett Kártya Ez a beállítás csak a(z) %s téma esetén érhető el - Hardveresmédiagomb-események figyelmen kívül hagyása + Hardveres médialejátszó gombok eseményeinek figyelmen kívül hagyása A következő közvetítések megjelenítése Az eredeti hangsáv választása, a nyelvtől függetlenül A látássérülteknek szóló leírást tartalmazó hangsáv választása, ha van ilyen @@ -742,9 +715,7 @@ Az ExoPlayer dekódoló tartalék funkciójának használata Engedélyezze ezt a beállítást, ha dekóder előkészítési problémái vannak, ami alacsonyabb prioritású dekóderekre váltást okoz, ha az elsődleges dekóderek előkészítése sikertelen. Ez rosszabb lejátszási teljesítményt eredményezhet, mint az elsődleges dekóderek használata. Kerülőmegoldás: mindig az ExoPlayer videokimeneti felületének használata - Ez a kerülőmegoldás elengedi és újból előkészíti a videokodekeket, ha felületváltozás történik, ahelyett, hogy közvetlenül a kodeknél állítaná be a felületet. Ez már alapból használatban van egyes, az ezzel a problémával érintett eszközöknél, a beállításnak Android 6 vagy újabb esetén van hatása. -\n -\nA beállítás bekapcsolása megakadályozhatja a lejátszási hibákat, ha átváltja a jelenlegi videolejátszót, vagy teljes képernyőre vált. + Ez a kerülőmegoldás elengedi és újból előkészíti a videokodekeket, ha felületváltozás történik, ahelyett, hogy közvetlenül a kodeknél állítaná be a felületet. Ez már alapból használatban van egyes, az ezzel a problémával érintett eszközöknél, a beállításnak Android 6 vagy újabb esetén van hatása\n\nA beállítás bekapcsolása megakadályozhatja a lejátszási hibákat abban az esetben, ha átváltja a jelenlegi videolejátszót, vagy teljes képernyőre vált %1$s %2$s szinkronizált leíró @@ -758,18 +729,18 @@ Eltávolítja az összes ismétlődő közvetítést ebből a lejátszólistáról\? eredeti Kezdőlap pozíciója - A médiacsatornázás alapértelmezés szerint le van tiltva az Ön készülékén, mivel az Ön készülékmodellje nem támogatja azt. + A médiacsatornázás alapértelmezés szerint le van tiltva a saját eszközén, mivel a saját eszközmodellje nem támogatja azt. Kezdőlapválasztó alulra helyezése Nincs élő közvetítés Nincs adatfolyam Az alábbi értesítési műveletek szerkesztéséhez koppintson rá. Az első három műveletet (lejátszás/szünet, előző és következő) a rendszer állítja be, és nem szabhatók testre. Csatornalapok lekérése - A hírcsatorna frissítésekor lekérendő lapok. Ennek az opciónak nincs hatása, ha egy csatorna frissítése gyors módban történik. + A hírfolyam frissítésekor lekérendő lapok. Ennek a beállításnak nincs hatása, ha egy csatorna frissítése gyors módban történik. Miniatűrök - Feltöltő avatarjai - Alcsatorna avatarok - Avatarok - Bannerek + Feltöltő profilképei + Alcsatorna profilképei + Profilképek + Borítóképek Feliratkozók Csatornák Lejátszási listák @@ -778,13 +749,13 @@ Csatorna fülek Milyen lapok jelennek meg a csatornaoldalakon Lejátszási sor megnyitása - Képernyő tájolásának váltása - Teljes képernyőre váltás + Képernyő tájolás be/ki + Teljes képernyő be/ki Következő közvetítés Előző közvetítés Lejátszás Visszajátszás - További opciók + További lehetőségek Időtartam Visszatekerés Előre @@ -809,7 +780,7 @@ Webcímlista megosztása - %1$s: %2$s Videók - Dalok + Zeneszámok Rövidek Élő Nincs elég szabad hely az eszközön @@ -823,6 +794,14 @@ Az összes beállítás visszaállítása elveti az összes preferált beállítást, és újraindítja az alkalmazást. \n \nBiztosan folytatja? - Az importálandó exportban lévő beállítások sérülékeny formátumot használnak, amely a NewPipe 0.27.0-s verziója óta elavult. Győződjön meg arról, hogy megbízható forrásból importálja, és a jövőben csak a NewPipe 0.27.0-s vagy újabb verziójából származó exportokat használjon. A beállítások ebből a sérülékeny forrásból történő importálása hamarosan végleg el lesz távolítva, és a NewPipe régi verziói nem fogják tudni importálni az újabb verziókból származó exportokat. + Az importálandó exportban lévő beállítások sérülékeny formátumot használnak, amely a NewPipe 0.27.0-ás verziója óta elavult. Győződjön meg arról, hogy megbízható forrásból importálja, és a jövőben csak a NewPipe 0.27.0-ás vagy újabb verziójából származó exportokat használjon. A beállítások ebből a sérülékeny forrásból történő importálása hamarosan végleg el lesz távolítva, és a NewPipe régi verziói nem fogják tudni importálni az újabb verziókból származó exportokat. másodlagos + Megosztás YouTube ideiglenes lejátszási listaként + Lejátszási listák + Válasszon ki egy hírfolyamcsoportot + Még nincs létrehozott hírfolyamcsoport + Csatornacsoport-oldal + Keresés %1$s + Keresés %1$s (%2$s) + Kedvelések diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index fa7e82be7..0bc414a92 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -811,4 +811,9 @@ Cadangkan dan pulihkan Pengaturan dalam ekspor yang diimpor menggunakan format rentan yang tidak digunakan lagi sejak NewPipe 0.27.0. Pastikan ekspor yang diimpor berasal dari sumber tepercaya, dan lebih memilih hanya menggunakan ekspor yang diperoleh dari NewPipe 0.27.0 atau yang lebih baru di masa mendatang. Dukungan untuk mengimpor pengaturan dalam format rentan ini akan segera dihapus sepenuhnya, dan NewPipe versi lama tidak akan dapat lagi mengimpor pengaturan ekspor dari versi baru. sekunder + Daftar putar + Daftar putar + Halaman grup saluran + Belum ada grup umpan yang dibuat + Pilih grup umpan diff --git a/app/src/main/res/values-is/strings.xml b/app/src/main/res/values-is/strings.xml index 34939c478..986ae282c 100644 --- a/app/src/main/res/values-is/strings.xml +++ b/app/src/main/res/values-is/strings.xml @@ -804,4 +804,6 @@ Sýna villustiku Veldu gæði mynda og hvort eigi að hlaða myndum inn yfirhöfuð, til að minnka notun gagna og minnis. Breytingar munu hreinsa bæði vinnsluminni og diskminni - %s auka + Deila sem YouTube-bráðabirgðaspilunarlista + Spilunarlistar diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 542040d26..654a4c181 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -839,4 +839,12 @@ \nVuoi attivarlo? Le impostazioni nell\'export che viene importato usano un formato vulnerabile che è stato deprecato dalla versione 0.27.0 di NewPipe. Assicuratevi che l\'export importato venga da una fonte fidata, sarebbe preferibile usare solo exports ottenuti da NewPipe 0.27.0 o superiori, nel futuro. Il supporto all\'importazione di Impostazioni in questo formato vulnerabile sarà presto rimosso completamente, da quel momento le versioni di NewPipe più vecchie non saranno più in grado di importare impostazioni tramite export di versioni più recenti. secondaria + Condividi come playlist YouTube temporanea + Playlist + Seleziona un gruppo di feed + Ancora nessun gruppo di feed creato + Pagina gruppo canali + Cerca %1$s (%2$s) + Cerca su %1$s + Mi piace diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 04e54348d..fda1e2e21 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -810,4 +810,6 @@ \n \n続行しますか? インポートされているエクスポートの設定は、NewPipe 0.27.0以降は非推奨であった脆弱な形式を使用します。 インポートされているエクスポートは信頼できる情報源からであり、将来的にはNewPipe 0.27.0かこれより新しいバージョンから得られるエクスポートのみを優先して使用します。 この脆弱な形式で設定をインポートするための対応はすぐに完全に削除され、新しいバージョンからエクスポートの設定をインポートすることは出来ません。 + YouTubeの一時的なプレイリストとして共有 + 二次的 diff --git a/app/src/main/res/values-kab/strings.xml b/app/src/main/res/values-kab/strings.xml index eccaaccb9..97476fc46 100644 --- a/app/src/main/res/values-kab/strings.xml +++ b/app/src/main/res/values-kab/strings.xml @@ -1,7 +1,7 @@ - Tavidyutt akked d imesli - Γef + Avidyu akked d imesli + Ɣef & ISTEQSIYEN Amaynut Akk Sbedd asnas n Kore yexxuṣen\? @@ -90,7 +90,7 @@ Iseqdacen Sfeḍ isefka Ulac - Aḍris yettwanγel γef afus + Yettwanɣel ɣef afus Tibdarin n tɣuri Aneggaru yettwaslekmen Taɣuri tawurmant @@ -116,7 +116,7 @@ Beqqeḍ iwenniten Ameɣri Isaragen - Isedγiten + Ileqman Asentel Ubrik Bḍu @@ -131,7 +131,7 @@ o Aɣawas n deffir Amazray - Asteεfu + yesteɛfay Snifel isem Tividyutin Ldi deg uminig @@ -224,4 +224,5 @@ Amaṭṭaf Tibzimin Asebter d ilem - \ No newline at end of file + Iɣewwaṛen n ExoPlayer + diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index 23476bf36..2ff3f1165 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -6,7 +6,7 @@ Įdiegti Atšaukti Atverti naršyklėje - Atverti iššokančio lango rėžime + Atverti iššokančio lango režime Dalintis Atsisiųsti Paieška @@ -838,4 +838,7 @@ \n%2$s \? - %1$s: %2$s + Grojaraščiai + Antrinis + Dalintis kaip laikinuoju youtube grojaraščiu diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml index 2f528a346..9372d3c3f 100644 --- a/app/src/main/res/values-lv/strings.xml +++ b/app/src/main/res/values-lv/strings.xml @@ -414,7 +414,7 @@ \n2. Dodieties uz šo URL:%1$s \n3. Ierakstaties, kad tiek prasīts \n4. Nokopējiet profila URL, uz kuru tikāt novirzīts. - YouTube abonementu importēšana no Google Takeout:\n\n1. Dodieties uz šo vietni: %1$s\n2. Autorizējieties, ja nepieciešams\n3. Noklikšķiniet uz \"Visi dati iekļauti\", pēc tam uz \"Atcelt visu atlasi\", pēc tam atlasiet tikai \"Abonementi\" un noklikšķiniet uz \"Labi\"\n4. Noklikšķiniet uz \"Nākamais solis\" un pēc tam uz \"Izveidot eksportu\"\n5. Pēc tam, kad tā parādās, noklikšķiniet uz pogas \"Lejupielādēt\"\n6. Noklikšķiniet IMPORTĒT DATNI zemāk un izvēlaties lejupielādēto .zip failu\n7. [Ja .zip failu neizdodas importēt] Izvelciet .csv failu (parasti zem \"YouTube un YouTube Music/subscriptions/subscriptions.csv\") no arhīva, tad noklikšķiniet uz IMPORTĒT DATNI zemāk un izvēlaties tikko izvilkto csv failu + Ievietot YouTube abonementus no Google Takeout:\n\n1. Dodieties uz šo vietni: %1$s\n2. Autorizējieties, ja nepieciešams\n3. Noklikšķiniet uz \"Visi dati iekļauti\", pēc tam uz \"Atcelt visu atlasi\", pēc tam atlasiet tikai \"Abonementi\" un noklikšķiniet uz \"Labi\"\n4. Noklikšķiniet uz \"Nākamais solis\" un pēc tam uz \"Izveidot eksportu\"\n5. Pēc tam, kad tā parādās, noklikšķiniet uz pogas \"Lejupielādēt\"\n6. Noklikšķiniet IEVIETOT DATNI zemāk un izvēlaties lejupielādēto .zip failu\n7. [Ja .zip failu neizdodas ievietot] Izvelciet .csv failu (parasti zem \"YouTube un YouTube Music/subscriptions/subscriptions.csv\") no arhīva, tad noklikšķiniet uz IEVIETOT DATNI zemāk un atlasiet tikko izvilkto csv failu Noklusējuma darbība, kad atver saturu — %s Pakalpojumu oriģinālteksti būs redzami video vienumos Pēc izdzēšanas, piespiedu kārtā ziņot par nepiegādātiem Rx izņēmumiem, ārpus fragmenta vai darbības dzīves cikla @@ -527,7 +527,7 @@ Atvērt pārlūkā Atcelt Uzstādīt - Netika atrasts video atskaņotājs (jūs varat uzstādīt VLC, lai to atskaņotu). + Netika atrasts video atskaņotājs (jūs variet uzstādīt VLC, lai to atskaņotu). Netika atrasts video atskaņotājs. Uzstādīt VLC? Publicēts %1$s Nospiediet uz meklēšanas ikonas, lai sāktu. @@ -560,7 +560,7 @@ Video lejupielādes mape Pievienot Fonā - Izvēlieties Cilni + Atlasiet cilni Saglabātie saraksti Abonementi Rādīt informāciju @@ -574,11 +574,11 @@ Noņem skaņu dažās izšķirtspējās Izmantot ārējo video atskaņotāju Kopīgot ar - Tiek rādīti rezultāti priekš: %s + Tiek rādīti %s rezultāti Vai jūs domājāt \"%1$s\"\? Iestatījumi Meklēt - Lejupielādēt video failu + Lejupielādēt video datni Lejupielādēt Populāri Lejupielāde ir sākusies @@ -645,7 +645,7 @@ Privātums Sarakstā neiekļauts Uzņēmums - Attālinātie meklēšanas ieteikumi + Servera meklēšanas ieteikumi Atzīmēt kā skatītu Apstrādā... Var aizņemt kādu laiku @@ -828,4 +828,7 @@ Kopīgot nosaukumus Importētā eksporta iestatījumi izmanto ievainojamo formātu, kas tika pārtraukts kopš NewPipe 0.27.0 versijas. Pārliecinieties, ka importētie dati ir no uzticama avota, un turpmāk ir vēlams izmantot tikai datus, kas veikti NewPipe 0.27.0 vai jaunākās versijās. Iestatījumu importēšanas atbalsts šajā neaizsargātajā formātā drīzumā tiks pilnībā aizvākts, un tad vecās NewPipe versijas vairs nevarēs importēt iestatījumus, kas veikti jaunajās versijās. Šis risinājums problēmas novēršanai atbrīvo un atkārtoti instantiē video kodekus, kad notiek virsmas maiņa, nevis tieši iestatīt virsmu kodekam. ExoPlayer jau izmanto šo risinājumu dažās ierīcēs, kurām ir šī problēma. Šis iestatījums darbosies tikai ierīcēs, kurās uzstādīta operētājsistēma Android 6 un jaunāka.\n\nIespējojot šo iestatījumu, var novērst atskaņošanas kļūdas, pārslēdzot pašreizējo video atskaņotāju vai pārejot uz pilnekrāna režīmu - \ No newline at end of file + Atskaņošanas saraksti + Kopīgot kā pagaidu YouTube atskaņošanas sarakstu + sekundārais + diff --git a/app/src/main/res/values-nl-rBE/strings.xml b/app/src/main/res/values-nl-rBE/strings.xml index cb9fd0170..733689524 100644 --- a/app/src/main/res/values-nl-rBE/strings.xml +++ b/app/src/main/res/values-nl-rBE/strings.xml @@ -551,7 +551,7 @@ Shuffle Herhaal Je kan maximaal drie acties selecteren om te tonen in de compacte notificatie! - Pas elke notificatie actie hieronder aan door er op te tikken. Selecteer tot drie acties die getoond worden in de compacte notificatie door gebruik te maken van de selectie vakjes aan de rechterkant + Pas elke notificatie actie hieronder aan door er op te tikken. Selecteer tot drie acties die getoond worden in de compacte notificatie door gebruik te maken van de selectie vakjes aan de rechterkant. Vijfde actie knop Vierde actie knop Derde actie knop @@ -580,7 +580,7 @@ \nAls gevolg van het nieuwe YouTube-beleid met video\'s met leeftijdsbeperkingen heeft NewPipe geen toegang tot deze videostreams en kan deze dus niet afspelen. Zet uit om videobeschrijving en extra informatie te verbergen Toon beschrijving - Nacht Thema + Nacht thema Open met Featured Deze inhoud is privé, waardoor het niet kan worden gestreamd of gedownload door NewPipe. @@ -629,4 +629,14 @@ Meldingen om fouten te rapporteren Verwerken... Dit kan even duren LeakCanary is niet beschikbaar + Verander de intervalgrootte voor het laden van progressieve inhoud (momenteel %s). Een lagere waarde kan het initiële laden versnellen + Afspeellijsten + Bewerk elke meldingsactie hieronder door erop te tikken. De eerste drie acties (afspelen/pauzeren, vorige en volgende) zijn ingesteld door het systeem en kunnen niet worden aangepast. + Intervalgrootte voor afspelen laden + Ja + Nee + Handig, bijvoorbeeld, als je een hoofdtelefoon gebruikte met kapotte fysieke knoppen + Verkies beschrijvende audio + Verkies originele audio + Selecteer het oorspronkelijke audiospoor, ongeacht de taal diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 33ed4d26d..e3e49fc72 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -59,7 +59,7 @@ Video Geluid Opnieuw proberen - Druk op het vergrootglas om te beginnen. + Tik op het vergrootglas om te beginnen. Live Downloads Downloads @@ -68,7 +68,7 @@ Wat:\\nVerzoek:\\nInhoudstaal:\\nInhoudsland:\\nApp-taal:\\nDienst:\\nGMT-tijd:\\nPakket:\\nVersie:\\nVersie van besturingssysteem: Starten Pauzeren - Verwijderen + Verwijderen Controlesom Oké Bestandsnaam @@ -825,4 +825,9 @@ Instellingen resetten De instellingen in de export die wordt geïmporteerd, gebruiken een kwetsbaar formaat dat verouderd is sinds NewPipe 0.27.0. Zorg ervoor dat de export die wordt geïmporteerd afkomstig is van een vertrouwde bron, en geef er de voorkeur aan om in de toekomst alleen exporten te gebruiken die zijn verkregen van NewPipe 0.27.0 of nieuwer. Ondersteuning voor het importeren van instellingen in dit kwetsbare formaat zal binnenkort volledig worden verwijderd, en oude versies van NewPipe zullen dan geen export­instellingen meer uit nieuwe versies kunnen importeren. secundair + Delen als tijdelijke YouTube-afspeel­lijst + Afspeel­lijsten + Selecteer een feedgroep + Kanaalgroep­pagina + Nog geen feedgroep geselecteerd diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml index 23ab6e013..56cbd6ead 100644 --- a/app/src/main/res/values-pa/strings.xml +++ b/app/src/main/res/values-pa/strings.xml @@ -159,7 +159,7 @@ ਕੋਈ ਸਬਸਕ੍ਰਾਈਬਰ ਨਹੀਂ %s ਸਬਸਕ੍ਰਾਈਬਰ - %s ਸਬਸਕ੍ਰਾਈਬਰ + %s ਸਬਸਕ੍ਰਾਈਬਰਸ ਕੋਈ ਵਿਊ ਨਹੀਂ @@ -613,8 +613,8 @@ ਆਨ , - ਡਾਉਨਲੋਡ ਮੁਕੰਮਲ - %s ਡਾਉਨਲੋਡ ਮੁਕੰਮਲ + %s ਡਾਉਨਲੋਡ ਮੁਕੰਮਲ + %s ਡਾਊਨਲੋਡਾਂ ਮੁਕੰਮਲ ਆਫ ਕਤਾਰ ਵਿੱਚ ਅੱਗੇ ਸ਼ਾਮਿਲ ਕਰੋ @@ -825,4 +825,6 @@ ਨਹੀਂ ਇੰਪੋਰਟ ਕੀਤੇ ਜਾ ਰਹੇ ਐਕਸਪੋਰਟ ਵਿੱਚ ਸੈਟਿੰਗਾਂ ਇੱਕ ਕਮਜ਼ੋਰ ਫਾਰਮੈਟ ਦੀ ਵਰਤੋਂ ਕਰਦੀਆਂ ਹਨ ਜੋ ਨਿਊਪਾਈਪ 0.27.0 ਤੋਂ ਬਰਤਰਫ਼ ਕੀਤਾ ਗਿਆ ਸੀ। ਯਕੀਨੀ ਬਣਾਓ ਕਿ ਇੰਪੋਰਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਨਿਰਯਾਤ ਇੱਕ ਭਰੋਸੇਯੋਗ ਸਰੋਤ ਤੋਂ ਹੈ, ਅਤੇ ਸਿਰਫ਼ ਨਿਊਪਾਈਪ 0.27.0 ਜਾਂ ਇਸਤੋਂ ਨਵੇਂ ਤੋਂ ਪ੍ਰਾਪਤ ਕੀਤੇ ਐਕਸਪੋਰਟ ਦੀ ਵਰਤੋਂ ਕਰਨ ਨੂੰ ਤਰਜੀਹ ਦਿਓ। ਇਸ ਕਮਜ਼ੋਰ ਫਾਰਮੈਟ ਵਿੱਚ ਸੈਟਿੰਗਾਂ ਨੂੰ ਆਯਾਤ ਕਰਨ ਲਈ ਸਮਰਥਨ ਜਲਦੀ ਹੀ ਪੂਰੀ ਤਰ੍ਹਾਂ ਹਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ ਅਤੇ ਫਿਰ ਨਿਊਪਾਈਪ ਦੇ ਪੁਰਾਣੇ ਸੰਸਕਰਣ ਹੁਣ ਨਵੇਂ ਸੰਸਕਰਣਾਂ ਤੋਂ ਐਕਸਪੋਰਟ ਦੀਆਂ ਸੈਟਿੰਗਾਂ ਨੂੰ ਇੰਪੋਰਟ ਕਰਨ ਦੇ ਯੋਗ ਨਹੀਂ ਹੋਣਗੇ। ਸੈਕੰਡਰੀ + ਟੈਂਪਰੇਰੀ ਯੂਟਿਊਬ ਪਲੇਲਿਸਟ ਵੱਜੋਂ ਸ਼ੇਅਰ ਕਰੋ + ਪਲੇਲਿਸਟਾਂ diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 63768acb5..1a426b8dd 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -848,4 +848,12 @@ \nCzy chcesz to włączyć?
    Ustawienia w importowanym eksporcie korzystają z podatnego na ataki formatu, który został wycofany od wersji NewPipe 0.27.0. Upewnij się, że importowany eksport pochodzi z zaufanego źródła, i w przyszłości używaj wyłącznie eksportów uzyskanych z NewPipe 0.27.0 lub nowszego. Obsługa importowania ustawień w tym podatnym formacie zostanie wkrótce całkowicie usunięta, a wtedy starsze wersje NewPipe nie będą już mogły importować ustawień z eksportu z nowych wersji. dodatkowa + Udostępnij jako tymczasową playlistę YouTube + Playlisty + Wybierz grupę kanałów + Strona grupy kanałów + Nie utworzono jeszcze grupy kanałów + Szukaj %1$s + Szukaj %1$s (%2$s) + Polubienia diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index cde34a2a6..5988038e5 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -76,7 +76,7 @@ O site não pôde ser analisado Áudio Reproduzir no Kodi - Pesquisar + Buscar Mostrar opção para reproduzir o vídeo no Kodi Usar player de áudio externo Usar player de vídeo externo @@ -101,7 +101,7 @@ Lembrar propriedades do Popup Lembrar último tamanho e posição do Popup Remove áudio em algumas resoluções - Sugestões de pesquisa + Sugestões de busca Escolha as sugestões a serem exibidas enquanto estiver buscando Melhor resolução Licenças de Terceiros @@ -111,7 +111,7 @@ Ver no GitHub Licença do NewPipe Se você tem ideias de: tradução, mudança no design, limpeza de código ou grandes mudanças de código — ajuda é sempre bem-vinda. Quanto mais se faz, melhor fica! - Ler licença + Ver licença Colaborar © %1$s %2$s protegido pela licença %3$s Sobre o NewPipe @@ -129,9 +129,9 @@ Inscrições Novidades Continuar reprodução - Continua vídeo após interrupções (ex: ligações) - Histórico de pesquisa - Armazena o histórico de pesquisa localmente + Continuar a reprodução após interrupções (por exemplo, chamadas telefônicas) + Histórico de busca + Armazena o histórico de busca localmente Histórico de exibição Mantenha o controle dos vídeos assistidos Histórico @@ -163,7 +163,7 @@ Player Nada aqui além de grilos Deseja excluir este item do histórico de busca\? - Conteúdo da página inicial + Conteúdo da tela inicial Página em branco Página do Kiosk Página do canal @@ -186,7 +186,7 @@ [Desconhecido] Reproduzir em segundo plano Reproduzir em um Popup - Doar + Fazer doação O NewPipe é desenvolvido por voluntários que usam seu tempo livre para trazer a você a melhor experiência de usuário. Retribua e ajude os desenvolvedores a tornarem o NewPipe ainda melhor enquanto eles desfrutam de uma xícara de café. Retribuir Site oficial @@ -208,7 +208,7 @@ Carregando conteúdo solicitado Importar base de dados Exportar base de dados - Substitui seu histórico atual, inscrições, playlists e (opcionalmente) configurações + Substitui seu histórico atual, inscrições, playlists e configurações (opcional) Exporta histórico, inscrições, playlists e configurações Exportado Importado @@ -291,7 +291,7 @@ Velocidade Afinação Desvincular (pode causar distorção) - Ação de \'abrir\' preferida + Ação preferida ao tocar em \'Abrir\' Ação padrão ao abrir conteúdo — %s Nenhum vídeo disponível para download Abrir gaveta @@ -302,10 +302,10 @@ Remove o histórico de vídeos assistidos e as posições de reprodução Remover todo o histórico de exibição? Histórico de exibição removido - Remover histórico de pesquisas - Remove o histórico de pesquisas - Remover todo o histórico de pesquisas? - Histórico de pesquisa removido + Remover histórico de buscas + Remove o histórico de buscas + Remover todo o histórico de buscas? + Histórico de busca removido 1 item excluído. NewPipe é um copyleft de software livre: Você pode usar, estudar, compartilhar e melhorar a seu gosto. Especificamente você pode redistribuir e/ou modificá-lo sob os termos da GNU General Public License como publicado pela Fundação de Software Livre, na versão 3 da Licença, ou (a seu critério) qualquer versão posterior. Você também quer importar as configurações? @@ -341,7 +341,7 @@ Notificações para novas versões do NewPipe Armazenamento externo indisponível Não é possível baixar para o cartão SD externo. Redefinir o local da pasta de download\? - Não foi possível ler as guias salvas, portanto, usamos as guias padrão + Não foi possível carregar as guias salvas, portanto, usamos as guias padrão Restaurar configurações Deseja restaurar os padrões? Número de inscritos indisponível @@ -554,7 +554,7 @@ Nada Repetir Você pode selecionar até no máximo três botões para mostrar na notificação compacta! - Edite os botões de ação de notificação abaixo tocando em cada um. Selecione até três deles para serem mostrados na notificação compacta usando as caixas de seleção à direita. + Edite os botões de ação da notificação abaixo tocando em cada um. Selecione até três deles para serem mostrados na notificação compacta usando as caixas de seleção à direita. Quinto botão de ação Quarto botão de ação Terceiro botão de ação @@ -577,7 +577,7 @@ Calculando hash Notificações sobre o progresso do hashing de vídeo Notificar hash de vídeo - Desative para ocultar as caixas de informações de metadados com informações adicionais sobre o criador, conteúdo da transmissão ou uma solicitação de pesquisa + Desative para ocultar as caixas de informações de metadados com informações adicionais sobre o autor, conteúdo da transmissão ou uma solicitação de busca Mostrar informação de metadados Recente Capítulos @@ -638,9 +638,9 @@ Ativado Modo tablet Não mostrar - Baixa qualidade (pior) + Baixa qualidade (menor) Alta qualidade (melhor) - Pré visualização da miniatura da barra de busca + Pré visualização da miniatura na barra de busca Os comentários estão desabilitados Marcar como assistido Curtido pelo criador @@ -660,7 +660,7 @@ Enfileira a próxima Deslize os itens para remove-los Não inicie os vídeos no mini player, mas vá diretamente para o modo de tela cheia, se a rotação automática estiver bloqueada. Você ainda pode acessar o mini player saindo da tela cheia - Iniciar player principal em tela cheia + Iniciar reprodução principal em tela cheia Sugestões de busca remotas Sugestões de busca locais Processando… Pode demorar um pouco @@ -717,7 +717,7 @@ Formato desconhecido Qualidade desconhecida Tamanho do intervalo de carregamento da reprodução - Visualizar no site + Ver no site Se você está com problemas ao usar o aplicativo, confira estas respostas para perguntas comuns! Perguntas frequentes Classificar @@ -731,7 +731,7 @@ Falha ao copiar para a área de transferência Duplicata adicionada %d vez(es) As playlists em cinza já contêm este item. - Ignorar eventos de botão de mídia de hardware + Ignorar eventos de botões físicos (hardware) Útil, por exemplo, se você estiver usando um fone de ouvido com botões físicos quebrados Remover duplicados Remover duplicados\? @@ -840,4 +840,8 @@ \nTem certeza de que deseja continuar?
    As configurações na exportação que está sendo importada usam um formato vulnerável que foi descontinuado desde o NewPipe 0.27.0. Certifique-se de que a exportação que está sendo importada seja de uma fonte confiável e prefira usar apenas exportações obtidas do NewPipe 0.27.0 ou mais recente no futuro. O suporte para importação de configurações neste formato vulnerável será completamente removido em breve e as versões antigas do NewPipe não poderão mais importar configurações de exportações de novas versões. secundário + Playlists + Selecione um grupo de feeds + Nenhum grupo de feeds criado ainda + Página do grupo do canal diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index 85e951b8e..36d3c5e42 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -839,4 +839,9 @@ Não há espaço suficiente no aparelho As configurações na exportação a serem importadas usam um formato vulnerável depreciado desde NewPipe 0.27.0. Certifique-se de que a exportação que é importada é de uma fonte confiável e prefira usar apenas as exportações obtidas do NewPipe 0.27.0 ou mais recentes no futuro. O suporte para importar configurações neste formato vulnerável será removido em breve completamente e, em seguida, versões antigas do NewPipe não serão capazes de importar configurações de exportações de novas versões. secundário + Partilhar como lista de reprodução temporária do YouTube + Listas de reprodução + Selecione um grupo de feeds + Ainda nenhum grupo de feeds criado + Página do grupo do canal diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 340552371..b1a27b772 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -281,7 +281,7 @@ Limpar histórico de visualizações Continuar (sem repetição) a fila de reprodução anexando um vídeo relacionado Mostrar dica \"Toque longo para colocar na fila\" - Mostrar dica ao premir em segundo plano ou no botão \"Detalhes\" da janela popup: + Mostrar dica ao premir em segundo plano ou no botão \"Detalhes:\" da janela popup Canais Listas de reprodução Faixas @@ -654,7 +654,7 @@ %1$s descargas eliminadas - Descarga concluída + %s descarga concluída %s descargas concluídas %s descargas concluídas @@ -839,4 +839,9 @@ \nDeseja ativar essa opção?
    As configurações na exportação a serem importadas usam um formato vulnerável depreciado desde NewPipe 0.27.0. Certifique-se de que a exportação que é importada é de uma fonte confiável e prefira usar apenas as exportações obtidas do NewPipe 0.27.0 ou mais recentes no futuro. O suporte para importar configurações neste formato vulnerável será removido em breve completamente e, em seguida, versões antigas do NewPipe não serão capazes de importar configurações de exportações de novas versões. secundário + Partilhar como lista de reprodução temporária do YouTube + Listas de reprodução + Selecione um grupo de feeds + Ainda nenhum grupo de feeds criado + Página do grupo do canal diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index fc62b5d1e..42f464d96 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -839,4 +839,7 @@ \nSigur doriți să continuați?
    Setările din exportul importat folosesc un format vulnerabil care a fost depreciat de la NewPipe 0.27.0. Asigurați-vă că exportul care este importat este dintr-o sursă de încredere și preferați să utilizați numai exporturi obținute din NewPipe 0.27.0 sau mai nou în viitor. Suportul pentru importul setărilor în acest format vulnerabil va fi în curând eliminat complet, iar versiunile vechi ale NewPipe nu vor mai putea importa setările exporturilor din versiunile noi. secundar + Distribuie ca listă de redare temporară YouTube + Liste de redare + Pagina grupului de canale diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index f04fef82f..d7fbdeb09 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -221,7 +221,7 @@ Загрузка запрошенного контента Скачать файл трансляции Показать сведения - Плейлисты + Плейлисты в закладках В плейлист Быстрый поиск позиции Выполняется быстрее, но менее точно. Не работает для перемотки на 5, 15 или 25 секунд @@ -844,4 +844,9 @@ \nВы уверены, что хотите продолжить?
    Настройки в импортируемом экспорте используют уязвимый формат, который устарел с версии NewPipe 0.27.0. Убедитесь, что импортируемый экспорт получен из надёжного источника, и в будущем предпочтительнее использовать только экспорт, полученный из NewPipe 0.27.0 или новее. Поддержка импорта настроек в этом уязвимом формате скоро будет полностью удалена, и тогда старые версии NewPipe больше не смогут импортировать настройки из экспорта из новых версий. вторичный + Поделиться как временным плейлистом YouTube + Плейлисты + Страница группы каналов + Выберите группу кормов + Группа кормов еще не создана diff --git a/app/src/main/res/values-sc/strings.xml b/app/src/main/res/values-sc/strings.xml index d92532c31..549e8f88b 100644 --- a/app/src/main/res/values-sc/strings.xml +++ b/app/src/main/res/values-sc/strings.xml @@ -824,4 +824,7 @@ \n \nSes seguru de bòlere sighire?
    Sas impostatziones in s\'esportatzione chi benit importada impreant unu formadu vulneràbile chi est disusadu dae sa versione 0.27.0 de NewPipe. Assegura·ti chi s\'esportatzione importada bèngiat dae una fonte fidada, e preferi a impreare petzi esportatziones otentas dae NewPipe 0.27.0 o prus nou, in su benidore. Su suportu a s\'importatzione de impostatziones in custu formadu vulneràbile at a èssere luego bogadu de su totu, e dae cussu momentu sas versiones de NewPipe prus betzas no ant a èssere prus in gradu de importare impostatziones pro mèdiu de esportatziones de versiones prus noas. + Iscalitas + Cumpartzi comente un\'iscalita temporànea de YouTube + segundàriu diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index dee7b1264..1e7337311 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -839,4 +839,12 @@ \nChcete to povoliť?
    Nastavenia v importovanom exporte používajú zraniteľný formát, ktorý bol od verzie NewPipe 0.27.0 zrušený. Uistite sa, že importovaný export pochádza z dôveryhodného zdroja, a v budúcnosti radšej používajte len exporty získané z verzie NewPipe 0.27.0 alebo novšej. Podpora importu nastavení v tomto zraniteľnom formáte bude čoskoro úplne odstránená a potom už staré verzie programu NewPipe nebudú môcť importovať nastavenia exportov z nových verzií. sekundárny + Zdieľať ako dočasný playlist YouTube + Playlisty + Vybrať skupinu kanálov + Skupina kanálov zatiaľ nie je vytvorená + Stránka skupiny kanálov + Hľadať %1$s (%2$s) + Hľadať %1$s + Páči sa diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index 5c8c28a57..99542e72c 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -1,7 +1,7 @@ Објављено %1$s - Нема плејера стримова. Инсталирати VLC\? + Нема извођача довода. Да ли уградити ВЛЦ? Инсталирај Откажи Отвори у прегледачу @@ -60,7 +60,7 @@ Аудио снимак Покушај поново Уживо - Додирните лупу да бисте започели. + Додирните лупу ради почетка. Почни Паузирај Избриши @@ -86,7 +86,7 @@ хиљ. мил. млрд. - Отвори у искачућем режиму + Отвори у искачућем облику Ова дозвола је потребна за \nотварање у искачућем режиму Пуштање у режиму искачућег прозора @@ -181,7 +181,7 @@ Уклони Детаљи Подешавања аудио снимка - Није пронађен ниједан плејер стримова (можете инсталирати VLC да бисте га покренули). + Није пронађен ниједан извођач довода (можете уградити ВЛЦ ради извођења садржаја). Преузимање фајла стрима Прикажи информације Обележене плејлисте @@ -376,8 +376,8 @@ Нема важећег ZIP фајла Увезено Извезено - Још нема обележивача на листи - Изаберите листу пуштања + Још нема обележивача плејлисте + Изаберите плејлисту Подразумевани киоск Које картице се приказују на главној страници Највише пуштано @@ -411,7 +411,7 @@ Нико не гледа Број пратилаца није доступан - Изабери услугу, тренутно изабрана: + Изаберите услугу, тренутно изабрана: Превуците за преуређивање Опис Коментари @@ -515,7 +515,7 @@ Мешање Понављање Можете да изаберете највише три радње за приказ у компактном обавештењу! - Измените сваку радњу обавештења додиром на њу. Означите до три радње које ће се приказивати у компактном обавештењу помоћу поља за потврду са десне стране + Измените сваку радњу обавештења додиром на њу. Означите до три радње које ће се приказивати у компактном обавештењу помоћу поља за потврду са десне стране. Дугме пете радње Дугме четврте радње Дугме треће радње @@ -839,4 +839,10 @@ \nЖелите ли да омогућите ово?
    Подешавања у извозу који се увозе користе рањив формат који је застарео од NewPipe верзије 0.27.0. Уверите се да извоз који се увози долази из поузданог извора и радије користите само извозе добијене из NewPipe 0.27.0 или новије верзије, у будућности. Подршка за увоз подешавања у овом рањивом формату ће ускоро бити потпуно уклоњена и тада старе NewPipe верзије више неће моћи да увозе подешавања извоза из нових верзија. секундарни + Дели као YouTube привремену плејлисту + Плејлисте + Још није направљена ниједна група фидова + Изаберите групу фидова + Страница групе канала + Ликовања diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 5fa064124..2eff9567c 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -825,4 +825,9 @@ \nÄr du säker på att du vill fortsätta?
    Inställningarna i exporten som importeras använder ett sårbart format som fasades ut i NewPipe 0.27.0. Se till att exporten som importeras är från en betrodd källa, och överväg att endast använda exporter som erhållits från NewPipe 0.27.0 eller nyare i framtiden. Stöd för import av inställningar från detta sårbara format kommer snart att tas bort helt, och sedan kommer gamla versioner av NewPipe inte att kunna importera inställningar av exporter från nya versioner längre. sekundär + Dela som YouTube temporär spellista + Spellistor + Välj en flödesgrupp + Ingen flödesgrupp har skapats ännu + Kanalgruppsida diff --git a/app/src/main/res/values-ta/strings.xml b/app/src/main/res/values-ta/strings.xml index 0056f7416..71771ddae 100644 --- a/app/src/main/res/values-ta/strings.xml +++ b/app/src/main/res/values-ta/strings.xml @@ -145,8 +145,8 @@ %s பார்வைகள் - %sகாணொளிகள் - %sகாணொளிகள் + %s காணொளி + %s காணொளிகள் முதற்பக்கத்துக்கு மாற்று எந்த காணொலியும் இல்லை @@ -459,7 +459,7 @@ அண்மைக் கால பாடங்கள் அகவை வரம்பு - கூகிள் டேக்அவுட்டிலிருந்து YouTube சந்தாக்களை இறக்குமதி செய்க:\n\n 1. இந்த முகவரி க்குச் செல்லுங்கள்: %1$s\n 2. கேட்டபோது உள்நுழைக\n 3. \"அனைத்து தரவுகளும் சேர்க்கப்பட்டுள்ளன\" என்பதைக் சொடுக்கு செய்க, பின்னர் \"அனைத்தையும் தேர்வு செய்யுங்கள்\", பின்னர் \"சந்தாக்கள்\" மட்டுமே தேர்ந்தெடுத்து \"சரி\" என்பதைக் சொடுக்கு செய்க\n 4. \"அடுத்த படி\" என்பதைக் சொடுக்கு செய்து, பின்னர் \"ஏற்றுமதி உருவாக்கு\"\n 5. \"பதிவிறக்கு\" பொத்தானைக் சொடுக்கு செய்த பிறகு சொடுக்கு செய்க\n 6. கீழே உள்ள இறக்குமதி கோப்பைக் சொடுக்கு செய்து பதிவிறக்கம் செய்யப்பட்ட .zip கோப்பைத் தேர்ந்தெடுக்கவும்\n 7. + கூகிள் டேக்அவுட்டிலிருந்து YouTube சந்தாக்களை இறக்குமதி செய்க:\n\n 1. இந்த முகவரி க்குச் செல்லுங்கள்: %1$s\n 2. கேட்டபோது உள்நுழைக\n 3. \"அனைத்து தரவுகளும் சேர்க்கப்பட்டுள்ளன\" என்பதைக் சொடுக்கு செய்க, பின்னர் \"அனைத்தையும் தேர்வு செய்யுங்கள்\", பின்னர் \"சந்தாக்கள்\" மட்டுமே தேர்ந்தெடுத்து \"சரி\" என்பதைக் சொடுக்கு செய்க\n 4. \"அடுத்த படி\" என்பதைக் சொடுக்கு செய்து, பின்னர் \"ஏற்றுமதி உருவாக்கு\"\n 5. \"பதிவிறக்கு\" பொத்தானைக் சொடுக்கு செய்த பிறகு சொடுக்கு செய்க\n 6. கீழே உள்ள இறக்குமதி கோப்பைக் சொடுக்கு செய்து பதிவிறக்கம் செய்யப்பட்ட .zip கோப்பைத் தேர்ந்தெடுக்கவும்\n 7.[.zip இறக்குமதி தோல்வியடைந்தால்] .csv கோப்பை பிரித்தெடுக்கவும் (வழக்கமாக \"YouTube மற்றும் YouTube Music/subscriptions/subscriptions.csv\" என்பதன் கீழ்), கீழே உள்ள IMPORT FILE என்பதைக் கிளிக் செய்து, பிரித்தெடுக்கப்பட்ட csv கோப்பைத் தேர்ந்தெடு பிளேலிச்ட்டில் சேர்க்கப்படுவதற்கு முன்னும் பின்னும் பார்க்கப்பட்ட வீடியோக்கள் அகற்றப்படும்.\n நீங்கள் உறுதியாக இருக்கிறீர்களா? இதை செயல்தவிர்க்க முடியாது! இந்த செயலுக்கு பொருத்தமான கோப்பு மேலாளர் எதுவும் கிடைக்கவில்லை.\n சேமிப்பக அணுகல் கட்டமைப்பு இணக்கமான கோப்பு மேலாளரை நிறுவவும் இரண்டாம் நிலை @@ -602,7 +602,7 @@ மேலும் செய்தி மற்றும் செய்திகளுக்கு நியூபைப் வலைத்தளத்தைப் பார்வையிடவும். நியூபைப் திட்டம் உங்கள் தனியுரிமையை மிகவும் தீவிரமாக எடுத்துக்கொள்கிறது. எனவே, பயன்பாடு உங்கள் அனுமதியின்றி எந்த தரவையும் சேகரிக்காது.\n நீங்கள் ஒரு செயலிழப்பு அறிக்கையை அனுப்பும்போது என்ன தரவு அனுப்பப்படுகிறது மற்றும் சேமிக்கப்படுகிறது என்பதை நியூபிப்பின் தனியுரிமைக் கொள்கை விரிவாக விளக்குகிறது. நியூபைப்பின் உரிமம் - நியூபைப் என்பது நகலெடுக்கப்பட்ட லிப்ரே மென்பொருள்: நீங்கள் அதைப் பயன்படுத்தலாம், படிக்கலாம், பகிரலாம் மற்றும் மேம்படுத்தலாம். குறிப்பாக நீங்கள் இலவச மென்பொருள் அறக்கட்டளையால் வெளியிடப்பட்ட குனு பொது பொது உரிமத்தின் விதிமுறைகளின் கீழ் மறுபகிர்வு மற்றும்/அல்லது மாற்றியமைக்கலாம், உரிமத்தின் பதிப்பு 3 அல்லது (உங்கள் விருப்பத்தில்) பின்னர் எந்த பதிப்பையும் மாற்றலாம். + நியூபைப் என்பது நகலெடுக்கப்பட்ட லிப்ரே மென்பொருள்: நீங்கள் அதைப் பயன்படுத்தலாம், படிக்கலாம், பகிரலாம் மற்றும் மேம்படுத்தலாம். குறிப்பாக நீங்கள் இலவச மென்பொருள் அறக்கட்டளையால் வெளியிடப்பட்ட குனு பொது பொதுமக்கள் உரிமத்தின் விதிமுறைகளின் கீழ் மறுபகிர்வு மற்றும்/அல்லது மாற்றியமைக்கலாம், உரிமத்தின் பதிப்பு 3 அல்லது (உங்கள் விருப்பத்தில்) பின்னர் எந்தப் பதிப்பையும் மாற்றலாம். பயன்பாட்டைப் பயன்படுத்துவதில் சிக்கல் இருந்தால், பொதுவான கேள்விகளுக்கு இந்த பதில்களைப் பார்க்கவும்! இணையதளத்தில் காண்க கடைசியாக விளையாடியது @@ -715,7 +715,7 @@ சந்தா எதுவும் தேர்ந்தெடுக்கப்படவில்லை %d தேர்ந்தெடுக்கப்பட்டது - %d தேர்ந்தெடுக்கப்பட்டது + %d தேர்ந்தெடுக்கப்பட்டன புதிய எப்போதும் புதுப்பிக்கவும் @@ -783,4 +783,9 @@ அடுத்த ச்ட்ரீம் மீண்டும் தரவு மற்றும் நினைவக பயன்பாட்டைக் குறைக்க, படங்களின் தகுதி மற்றும் படங்களை ஏற்ற வேண்டுமா என்பதைத் தேர்வுசெய்க. மாற்றங்கள் நினைவகம் மற்றும் ஆன்-வட்டு பட தற்காலிக சேமிப்பு இரண்டையும் அழிக்கின்றன- %s + YouTube தற்காலிக பிளேலிச்ட்டாக பகிரவும் + பிளேலிச்ட்கள் + தீவனக் குழுவைத் தேர்ந்தெடுக்கவும் + இதுவரை எந்த ஊட்டக் குழுவும் உருவாக்கப்படவில்லை + சேனல் குழு பக்கம் diff --git a/app/src/main/res/values-ti/strings.xml b/app/src/main/res/values-ti/strings.xml index 252f13954..c6edbe4c3 100644 --- a/app/src/main/res/values-ti/strings.xml +++ b/app/src/main/res/values-ti/strings.xml @@ -2,22 +2,22 @@ ሰረዝ ኣብ መርበብ-ሓበሬታ ክፉት - ውጽኢት ምርኣዩ ን፦ %s - መጀመርታ ምእንቲ ኽትጅምር ነቲ ዜጕልሕ መረጼን ጠውቆ። - ኣብ %1$s እተሓትመ - ወሓይዝ ዚጻወት ኣይተረኽበን። VLC፧ + ውጽኢት ናይ፦ %s + ንኽትጅምር ነቲ ምድላይ ምልክት ጠውቆ። + ኣብ %1$s ዝተሓትመ + ናይ ዥረት ተጻዋታይ ኣይተረኽበን። VLC ኣውርድ፧ ሐራይ ቅጥዕታት \"%1$s\" ማለቱ ድዩ፧ ዚተሪየ ጋባራ ክፉቴ ምሲ - ፋይል ውሕጅ ኣራግፍ + ስትሪም ፋይል ኣውርድ ድለ ኣካፍሎ ኣራግፍ ኣካፍሎም ምሲ መስመር ኣይትጽንበሩ - ኣብ ሓፍ፡ሓፍ ቅዲ ክፉት + ኣብ ፖፕኣፕ ኣገባብ ክፉት ሰዓብካ\'ኪ ክቕይር ኣይከኣለን ምዝገብ ድምጺታት ኣብ ገለ ርዝነት የወግድ @@ -47,7 +47,7 @@ ፖፕኣፕ ትሑዝ ድንቀት ዝወረዱ ናይ ተንቃሳቀሴ-ምስሌ ፋይላት ኣብዚ ይኽዘኑ - + ነባሪ ቪድዮ ፎርማት ናይ እኽሊ ምስሊ ምስ ናይ 1:1 ርክባት ቀዳማይ ወሰን ተጠዋቃ ደገመ @@ -70,5 +70,28 @@ እወ ኣይፋልን ጸሊም - ኣርእስቲ - \ No newline at end of file + ቆርበት + ለይታው ቆርበት + ናይ ፖፕኣፕ ባህርያት ዘክር + ናይ ፖፕኣፕ ዝነበሮ ቦታ ዘክር + ቅድሚ ምጽራይ ተራታት ናይ መረጋገጺ ሕተት + ርእይቶታት ኣርእዩ + ርእይቶታት ንምሕባእ እዚ ኣጥፍእ + ዋላ-ሓደ + ውራድ + ኣጻዋታይ + ትርኢት + ትሕዝቶ + ህያው + ርጋፍታት + ርጋፍታት + ኵሉ + መስመርት + ዝርዝር-ጸወታ + ቅዳሒት + ተጠቀምቲ + ፍጻመታት + ደርፍታት + ኣልበማት + ስነ-ጥበባውያን + diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 8e3bf19ef..66a393f6d 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -212,7 +212,7 @@ Bu, var olan kurulumunuzu geçersiz kılacaktır. Akış dosyasını indir Bilgi göster - İmlenen Çalma Listeleri + İmlenen Oynatma Listeleri Ekle Yeniden düzenlemek için sürükleyin Oluştur @@ -825,4 +825,10 @@ \nBunu etkinleştirmek istiyor musunuz?
    İçe aktarılmakta olan dışa aktarımdaki ayarlar, NewPipe 0.27.0\'dan itibaren kullanımdan kaldırılan güvenlik açığı olan bir biçim kullanmaktadır. İçe aktarılmakta olan dışa aktarımın güvenilir bir kaynaktan alındığından emin olun ve gelecekte yalnızca NewPipe 0.27.0 veya daha yeni sürümlerden alınan dışa aktarımları kullanmayı tercih edin. Bu güvenlik açığı bulunan biçimdeki ayarları içe aktarma desteği yakında tamamen kaldırılacak ve ardından NewPipe\'ın eski sürümleri artık yeni sürümlerden dışa aktarılan ayarların içe aktarımını yapamayacaktır. ikincil + Oynatma Listeleri + YouTube geçici oynatma listesi olarak paylaş + Besleme kümesi seç + Kanal küme sayfası + Besleme kümesi oluşturulmadı + Beğeni diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 1ed9625e8..5c4034f4b 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -844,4 +844,10 @@ \nВи впевнені, що хочете продовжити?
    Параметри експорту, який імпортується, використовують вразливий формат, який не підтримується з NewPipe 0.27.0. Переконайтеся, що експорт, який імпортується, походить із надійного джерела, і в майбутньому віддайте перевагу використанню лише експорту, отриманого з NewPipe 0.27.0 або новішої версії. Підтримку імпорту налаштувань у цьому вразливому форматі незабаром буде повністю припинено, і тоді старі версії NewPipe більше не зможуть імпортувати налаштування експорту з нових версій. вторинний + Поділитися як тимчасовим списком відтворення YouTube + Списки відтворення + Сторінка групи каналів + Виберіть групу каналів + Групу каналів ще не створено + Вподобання diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml index 3bfa5deff..99839de69 100644 --- a/app/src/main/res/values-ur/strings.xml +++ b/app/src/main/res/values-ur/strings.xml @@ -478,7 +478,7 @@ شفل دوہرائیں آپ کومپیکٹ نوٹیفکیشن میں زیادہ سے زیادہ تین ایکشن منتخب کرسکتے ہیں! - ذیل میں ہر اطلاع کی کارروائی پر ٹیپ کرکے اس میں ترمیم کریں۔ دائیں طرف کے چیک باکسز کا استعمال کرکے کمپیکٹ نوٹیفکیشن میں دکھائے جانے والے ان میں سے تین تک کا انتخاب کریں: + ذیل میں ہر اطلاع کی کارروائی پر ٹیپ کرکے اس میں ترمیم کریں۔ دائیں طرف کے چیک باکسز کا استعمال کرکے کمپیکٹ نوٹیفکیشن میں دکھائے جانے والے ان میں سے تین تک کا انتخاب کریں۔ پانچواں ایکشن بٹن چوتھا ایکشن بٹن تیسرا ایکشن بٹن @@ -555,4 +555,9 @@ مستقل تھمب نیل کو ان سیٹ کریں ہارڈ ویئر میڈیا بٹن کے واقعات کو نظر انداز کریں کار آمد، مثلاً، اگر آپ ہیڈسیٹ ٹوٹے ہوئے فزیکل بٹن کے ساتھ استعمال کر رہے ہیں + ذیل میں ہر اطلاعی کارروائی پر ٹیپ کرکے ترمیم کریں۔ پہلے تین ایکشن (پلے/پاؤز، پچھلی اور اگلی) سسٹم کے ذریعے سیٹ کیے گئے ہیں اور انہیں اپنی مرضی کے مطابق نہیں بنایا جا سکتا۔ + پروگریسو مواد پر لوڈ وقفہ کا سائز تبدیل کریں (فی الحال %s)۔ کم کیمیت ان کی ابتدائی لوڈنگ کو تیز کر سکتی ہے + پلے لسٹ + ہاں + نہیں diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index e8d19cb8b..013669e80 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -811,4 +811,10 @@ 正导入的导出文件中的设置使用了有漏洞的格式,该格式已从 NewPipe 0.27.0 版本起被弃用。请确保导入的导出文件来自可信来源,今后最好只使用从 NewPipe 0.27.0 或更新版本获取的导出文件。不久后将完全不支持导入这一有漏洞格式的设置,到时旧版 NewPipe 再不能导入来自新版应用的设置导出文件。 第二 + 分享为 YouTube 临时播放列表 + 播放列表 + 频道组页面 + 选择一个订阅源组 + 尚未创建订阅源组 + diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 030c23f60..b1443f17f 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -811,4 +811,10 @@ \n您想要啟用此功能嗎? 匯入的匯出中的設定使用自 NewPipe 0.27.0 起已廢棄的脆弱格式。請確定匯入的匯出是來自可信賴的來源,並在未來只使用從 NewPipe 0.27.0 或更新版本取得的匯出。對於匯入此脆弱格式設定的支援即將完全移除,屆時舊版本的 NewPipe 將無法再匯入新版本匯出的設定。 次要 + 分享為 YouTube 臨時播放清單 + 播放清單 + 頻道群組頁面 + 選取 feed 群組 + 尚未建立 feed 群組 + 喜歡 diff --git a/fastlane/metadata/android/ar/changelogs/1004.txt b/fastlane/metadata/android/ar/changelogs/1004.txt index 562f16944..27c377cf2 100644 --- a/fastlane/metadata/android/ar/changelogs/1004.txt +++ b/fastlane/metadata/android/ar/changelogs/1004.txt @@ -1 +1,3 @@ -تم إصلاح YouTube الذي لا يقوم بتشغيل أي دفق +يعمل هذا الإصدار على إصلاح YouTube الذي يوفر دفق 360 بكسل فقط. + +لاحظ أن الحل المستخدم في هذا الإصدار مؤقت على الأرجح، وعلى المدى الطويل يجب تنفيذ بروتوكول فيديو SABR، لكن أعضاء TeamNewPipe مشغولون حاليًا، لذا فإن أي مساعدة ستكون موضع تقدير كبير! https://github.com/TeamNewPipe/NewPipe/issues/12248 diff --git a/fastlane/metadata/android/azb/short_description.txt b/fastlane/metadata/android/azb/short_description.txt new file mode 100644 index 000000000..4f991f505 --- /dev/null +++ b/fastlane/metadata/android/azb/short_description.txt @@ -0,0 +1 @@ +اندرویددا یوتیوب اوچون بیر اؤزگور و یونگول قاپاخ. diff --git a/fastlane/metadata/android/cs/changelogs/1004.txt b/fastlane/metadata/android/cs/changelogs/1004.txt index 7035a1112..2568518e7 100644 --- a/fastlane/metadata/android/cs/changelogs/1004.txt +++ b/fastlane/metadata/android/cs/changelogs/1004.txt @@ -1 +1,3 @@ -Opraveno nepřehrávání jakéhokoli streamu ve službě YouTube +Tato verze opravuje problém, kdy YouTube poskytoval stream pouze v rozlišení 360p. + +Upozorňujeme, že použité řešení je pravděpodobně dočasné a z dlouhodobého hlediska bude potřeba implementovat video protokol SABR, ale členové týmu TeamNewPipe jsou momentálně zaneprázdnění, takže jakákoli pomoc bude velmi vítána! https://github.com/TeamNewPipe/NewPipe/issues/12248 diff --git a/fastlane/metadata/android/de/changelogs/1004.txt b/fastlane/metadata/android/de/changelogs/1004.txt index 43623578f..0e1705c34 100644 --- a/fastlane/metadata/android/de/changelogs/1004.txt +++ b/fastlane/metadata/android/de/changelogs/1004.txt @@ -1 +1,3 @@ -Behoben, dass YouTube keinen Stream abspielte +Behoben, dass YouTube nur einen 360p-Stream bereitstellt. + +Beachte, dass die in dieser Version verwendete Lösung wahrscheinlich nur vorübergehend ist und langfristig das SABR-Videoprotokoll implementiert werden muss, aber die Mitglieder von TeamNewPipe sind derzeit sehr beschäftigt, daher wäre jede Hilfe sehr willkommen! https://github.com/TeamNewPipe/NewPipe/issues/12248 diff --git a/fastlane/metadata/android/el/changelogs/1001.txt b/fastlane/metadata/android/el/changelogs/1001.txt new file mode 100644 index 000000000..a6b41b138 --- /dev/null +++ b/fastlane/metadata/android/el/changelogs/1001.txt @@ -0,0 +1,6 @@ +Βελτιωμένο +- Επιτρέπει πάντα την αλλαγή των προτιμήσεων ειδοποίησης παίκτη στο Android 13+ + +Διορθωμένο +- Διόρθωση Η εξαγωγή βάσης δεδομένων/συνδρομών δεν έκοβε ένα ήδη υπάρχον αρχείο, οδηγώντας ενδεχομένως σε κατεστραμμένη εξαγωγή +- Διόρθωση της συνέχισης του παίκτη από την αρχή όταν κάνετε κλικ σε μια χρονοσφραγίδα diff --git a/fastlane/metadata/android/el/changelogs/1002.txt b/fastlane/metadata/android/el/changelogs/1002.txt new file mode 100644 index 000000000..0d790eba9 --- /dev/null +++ b/fastlane/metadata/android/el/changelogs/1002.txt @@ -0,0 +1,4 @@ +Διορθώθηκε το YouTube που δεν αναπαράγει καμία ροή. + +Αυτή η έκδοση αντιμετωπίζει μόνο το πιο πιεστικό σφάλμα που εμποδίζει τη φόρτωση λεπτομερειών βίντεο του YouTube. +Γνωρίζουμε ότι υπάρχουν και άλλα προβλήματα και σύντομα θα προβούμε σε ξεχωριστή έκδοση για την επίλυσή τους. diff --git a/fastlane/metadata/android/el/changelogs/1003.txt b/fastlane/metadata/android/el/changelogs/1003.txt new file mode 100644 index 000000000..dbc62399e --- /dev/null +++ b/fastlane/metadata/android/el/changelogs/1003.txt @@ -0,0 +1,6 @@ +Αυτή είναι μια έκδοση hotfix που διορθώνει σφάλματα του YouTube: +- [YouTube] Διόρθωση της μη φόρτωσης πληροφοριών βίντεο, διόρθωση σφαλμάτων HTTP 403 κατά την αναπαραγωγή βίντεο και αποκατάσταση της αναπαραγωγής ορισμένων βίντεο με περιορισμούς ηλικίας. +- Διόρθωση της μη αλλαγής των μεγεθών των λεζάντων +- Διόρθωση της λήψης πληροφοριών δύο φορές κατά το άνοιγμα μιας ροής +- [Soundcloud] Αφαίρεση μη αναπαραγώγιμων ροών με προστασία DRM +- Ενημερωμένες μεταφράσεις diff --git a/fastlane/metadata/android/el/changelogs/66.txt b/fastlane/metadata/android/el/changelogs/66.txt new file mode 100644 index 000000000..0417512c7 --- /dev/null +++ b/fastlane/metadata/android/el/changelogs/66.txt @@ -0,0 +1,26 @@ +### Βελτιώσεις + +- Απενεργοποίηση της κίνησης του εικονιδίου του burgermenu #1486 +- Αναίρεση διαγραφής λήψεων #1472 +- Επιλογή λήψης στο μενού κοινής χρήσης #1498 +- Προστέθηκε επιλογή κοινής χρήσης στο μενού παρατεταμένου πατήματος #1454 +- Ελαχιστοποίηση του κύριου προγράμματος αναπαραγωγής κατά την έξοδο #1354 +- Ενημέρωση της έκδοσης της βιβλιοθήκης και διόρθωση αντιγράφων ασφαλείας της βάσης δεδομένων #1510 +- Ενημέρωση ExoPlayer 2.8.2 #1392 + - Ανασχεδιάστηκε ο διάλογος ελέγχου της ταχύτητας αναπαραγωγής ώστε να υποστηρίζει διαφορετικά μεγέθη βημάτων για ταχύτερη αλλαγή ταχύτητας. + - Προστέθηκε μια εναλλαγή για γρήγορη μετακίνηση προς τα εμπρός κατά τη διάρκεια σιωπής στον έλεγχο ταχύτητας αναπαραγωγής. Αυτό θα πρέπει να είναι χρήσιμο για τα ακουστικά βιβλία και ορισμένα είδη μουσικής και μπορεί να φέρει μια πραγματικά απρόσκοπτη εμπειρία (και μπορεί να σπάσει ένα τραγούδι με πολλές σιωπές =\\). + - Αναδιαμόρφωση της ανάλυσης πηγής πολυμέσων ώστε να επιτρέπεται η μετάδοση μεταδεδομένων μαζί με τα πολυμέσα εσωτερικά στον αναπαραγωγέα, αντί να γίνεται χειροκίνητα. Τώρα έχουμε μια ενιαία πηγή μεταδεδομένων και είναι άμεσα διαθέσιμα κατά την έναρξη της αναπαραγωγής. + - Διορθώθηκε η μη ενημέρωση των απομακρυσμένων μεταδεδομένων της λίστας αναπαραγωγής όταν είναι διαθέσιμα νέα μεταδεδομένα κατά το άνοιγμα του τμήματος της λίστας αναπαραγωγής. + - Διάφορες διορθώσεις στο UI: #1383, τα στοιχεία ελέγχου ειδοποίησης αναπαραγωγής στο παρασκήνιο είναι τώρα πάντα λευκά, είναι ευκολότερο να κλείσετε το αναδυόμενο πρόγραμμα αναπαραγωγής μέσω εκτίναξης +- Χρήση νέου εξαηωγέα με ανασχεδιασμένη αρχιτεκτονική για πολλαπλές υπηρεσίες + +### Διορθώσεις + +- Διόρθωση #1440 Προβληματική διάταξη πληροφοριών βίντεο #1491 +- Διόρθωση ιστορικού προβολής #1497 + - #1495, ενημέρωση των μεταδεδομένων (μικρογραφία, τίτλος και αριθμός βίντεο) μόλις ο χρήστης αποκτήσει πρόσβαση στη λίστα αναπαραγωγής. + - #1475, με την καταχώριση μιας προβολής στη βάση δεδομένων όταν ο χρήστης ξεκινάει ένα βίντεο σε εξωτερική συσκευή αναπαραγωγής σε λεπτομερές θραύσμα. +- Διόρθωση του χρονικού ορίου creen σε περίπτωση λειτουργίας αναδυόμενου παραθύρου. #1463 (Διορθώθηκε το #640) +- Διόρθωση του κύριου προγράμματος αναπαραγωγής βίντεο #1509 + - #1412] Διορθώθηκε η λειτουργία επανάληψης που προκαλεί NPE του αναπαραγωγέα όταν λαμβάνεται νέα εντολή ενώ εργάζεται στο παρασκήνιο. + - Διορθώθηκε κατά την ελαχιστοποίηση του αναπαραγωγέα σε αναδυόμενο παράθυρο, να μην τον καταστρέφει όταν δεν έχει χορηγηθεί άδεια αναδυόμενου παραθύρου. diff --git a/fastlane/metadata/android/el/changelogs/68.txt b/fastlane/metadata/android/el/changelogs/68.txt new file mode 100644 index 000000000..307e9d647 --- /dev/null +++ b/fastlane/metadata/android/el/changelogs/68.txt @@ -0,0 +1,31 @@ +# αλλαγές της v0.14.1 + +### Διορθώθηκε +- Διορθώθηκε η αποτυχία αποκρυπτογράφησης url βίντεο #1659 +- Διορθώθηκε ο σύνδεσμος περιγραφής που δεν εξάγεται καλά #1657 + +# αλλαγές της v0.14.0 + +### Νέα +- Νέος σχεδιασμός συρταριού #1461 +- Νέα προσαρμόσιμη αρχική σελίδα #1461 + +### Βελτιώσεις +- Αναθεωρημένοι έλεγχοι χειρονομιών #1604 +- Νέος τρόπος για να κλείσετε το αναδυόμενο πρόγραμμα αναπαραγωγής #1597 + +### Διορθώσεις +- Διόρθωση σφάλματος όταν ο αριθμός των συνδρομών δεν είναι διαθέσιμος. Κλείνει το #1649. + - Εμφάνιση της φράσης «Ο αριθμός των συνδρομητών δεν είναι διαθέσιμος» σε αυτές τις περιπτώσεις. +- Διόρθωση NPE όταν μια λίστα αναπαραγωγής του YouTube είναι κενή +- Γρήγορη διόρθωση για τα περίπτερα στο SoundCloud +- Αναδιαμόρφωση και διόρθωση σφάλματος #1623 + - Διόρθωση κυκλικού αποτελέσματος αναζήτησης #1562 + - Διόρθωση της γραμμής αναζήτησης που δεν είναι στατικά τοποθετημένη + - Διόρθωση Τα βίντεο YT Premium δεν μπλοκάρονται σωστά + - Διόρθωση Βίντεο που μερικές φορές δεν φορτώνονται (λόγω ανάλυσης DASH) + - Διόρθωση συνδέσμων στην περιγραφή βίντεο + - Εμφάνιση προειδοποίησης όταν κάποιος προσπαθεί να κάνει λήψη σε εξωτερική sdcard + - διόρθωση της εξαίρεσης που δεν εμφανίζεται τίποτα προκαλεί αναφορά + - η μικρογραφία δεν εμφανίζεται στο πρόγραμμα αναπαραγωγής στο παρασκήνιο για το Android 8.1 [δείτε εδώ](https://github.com/TeamNewPipe/NewPipe/issues/943) +- Διορθώστε την εγγραφή του δέκτη εκπομπής. Κλείνει το #1641. diff --git a/fastlane/metadata/android/el/changelogs/69.txt b/fastlane/metadata/android/el/changelogs/69.txt new file mode 100644 index 000000000..d3f51f3f3 --- /dev/null +++ b/fastlane/metadata/android/el/changelogs/69.txt @@ -0,0 +1,19 @@ +### New +- Μεγάλο πάτημα διαγραφής και κοινής χρήσης στις συνδρομές #1516 +- UI tablet και διάταξη λίστας πλέγματος #1617 + +### Βελτιώσεις +- αποθήκευση και επαναφόρτωση της τελευταίας χρησιμοποιούμενης αναλογίας διαστάσεων #1748 +- Ενεργοποίηση γραμμικής διάταξης στη δραστηριότητα «Λήψεις» με πλήρη ονόματα βίντεο #1771 +- Διαγραφή και κοινή χρήση συνδρομών απευθείας από την καρτέλα συνδρομών #1516 +- Η δημιουργία ουράς ενεργοποιεί τώρα την αναπαραγωγή βίντεο εάν η ουρά αναπαραγωγής έχει ήδη ολοκληρωθεί #1783 +- Ξεχωριστές ρυθμίσεις για τις χειρονομίες έντασης και φωτεινότητας #1644 +- Προσθήκη υποστήριξης για την τοπική προσαρμογή #1792 + +### Διορθώσεις +- Διορθώστε την ανάλυση της ώρας για τη μορφή ., ώστε το NewPipe να μπορεί να χρησιμοποιηθεί στη Φινλανδία +- Διορθώστε την καταμέτρηση συνδρομών +- Προσθήκη δικαιώματος υπηρεσίας foreground για συσκευές API 28+ #1830 + +### Γνωστά σφάλματα +- Η κατάσταση αναπαραγωγής δεν μπορεί να αποθηκευτεί στο Android P diff --git a/fastlane/metadata/android/en_GB/changelogs/1000.txt b/fastlane/metadata/android/en_GB/changelogs/1000.txt new file mode 100644 index 000000000..6a884f967 --- /dev/null +++ b/fastlane/metadata/android/en_GB/changelogs/1000.txt @@ -0,0 +1,13 @@ +Improved +• Make playlist description clickable to show more / less content +• [PeerTube] Handle `subscribeto.me` instance links automatically +• Only start playing single item in history screen + +Fixed +• Fix RSS button visibility +• Fix seekbar preview crashes +• Fix playlisting a thumbnail-less item +• Fix exiting the download dialog before it appears +• Fix related items list enqueue popup +• Fix order in add to playlist dialog +• Adjust the playlist bookmark item layout diff --git a/fastlane/metadata/android/en_GB/changelogs/1001.txt b/fastlane/metadata/android/en_GB/changelogs/1001.txt new file mode 100644 index 000000000..8d74eef7b --- /dev/null +++ b/fastlane/metadata/android/en_GB/changelogs/1001.txt @@ -0,0 +1,6 @@ +Improved +• Always allow changing player notification preferences on Android 13+ + +Fixed +• Fix exporting database/subscriptions would not truncate an already existing file, possibly leading to a corrupted export +• Fix player resuming from start when clicking on a timestamp diff --git a/fastlane/metadata/android/en_GB/changelogs/1002.txt b/fastlane/metadata/android/en_GB/changelogs/1002.txt new file mode 100644 index 000000000..f05e351e4 --- /dev/null +++ b/fastlane/metadata/android/en_GB/changelogs/1002.txt @@ -0,0 +1,4 @@ +Fixed YouTube not playing any stream. + +This release only addresses the most pressing error that prevents YouTube video details from loading. +We are aware there are other problems, and we will soon make a separate release to solve them. diff --git a/fastlane/metadata/android/en_GB/changelogs/1003.txt b/fastlane/metadata/android/en_GB/changelogs/1003.txt new file mode 100644 index 000000000..211c5a55b --- /dev/null +++ b/fastlane/metadata/android/en_GB/changelogs/1003.txt @@ -0,0 +1,6 @@ +This is a hotfix release that fixes YouTube errors: +• [YouTube] Fix not loading any video information, fix HTTP 403 errors while playing videos and restore playback of some age-restricted videos +• Fix caption sizes not being changed +• Fix downloading info twice when opening a stream +• [Soundcloud] Remove unplayable DRM-protected streams +• Updated translations diff --git a/fastlane/metadata/android/en_GB/changelogs/1004.txt b/fastlane/metadata/android/en_GB/changelogs/1004.txt new file mode 100644 index 000000000..1d3485059 --- /dev/null +++ b/fastlane/metadata/android/en_GB/changelogs/1004.txt @@ -0,0 +1,3 @@ +This release fixes YouTube only providing a 360p stream. + +Note that the solution employed in this version is likely temporary, and in the long run the SABR video protocol needs to be implemented, but TeamNewPipe members are currently busy so any help would be greatly appreciated! https://github.com/TeamNewPipe/NewPipe/issues/12248 diff --git a/fastlane/metadata/android/en_GB/full_description.txt b/fastlane/metadata/android/en_GB/full_description.txt new file mode 100644 index 000000000..4284b3a4a --- /dev/null +++ b/fastlane/metadata/android/en_GB/full_description.txt @@ -0,0 +1 @@ +NewPipe does not use any Google framework libraries, or the YouTube API. It only parses the website in order to gain the information it needs. Therefore this app can be used on devices without Google Services installed. Also, you don't need a YouTube account to use NewPipe, and it's FLOSS. diff --git a/fastlane/metadata/android/en_GB/short_description.txt b/fastlane/metadata/android/en_GB/short_description.txt new file mode 100644 index 000000000..1a5d9fc28 --- /dev/null +++ b/fastlane/metadata/android/en_GB/short_description.txt @@ -0,0 +1 @@ +A free lightweight YouTube frontend for Android. diff --git a/fastlane/metadata/android/et/changelogs/64.txt b/fastlane/metadata/android/et/changelogs/64.txt new file mode 100644 index 000000000..17290e39d --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/64.txt @@ -0,0 +1,8 @@ +### Täiustused +- Lisatud võimalus piirata videokvaliteeti mobiilse andmeside kasutamisel. #1339 +- Pea seansi heledus meeles #1442 +- Parandatud allalaadimise jõudlust nõrgematel protsessoritel #1431 +- Lisatud (töötav) tugi meediaseansile #1433 + +### Parandus +- Parandatud allalaadimiste avamisel tekkinud krahh #1441 diff --git a/fastlane/metadata/android/fr/changelogs/1003.txt b/fastlane/metadata/android/fr/changelogs/1003.txt index 13c76e921..161ee7fbb 100644 --- a/fastlane/metadata/android/fr/changelogs/1003.txt +++ b/fastlane/metadata/android/fr/changelogs/1003.txt @@ -1,6 +1,6 @@ -Il s'agit d'une version de correction qui résout les erreurs de YouTube : -• [YouTube] Correction du non-chargement des informations des vidéos, correction des erreurs HTTP 403 lors de la lecture des vidéos et restauration de la lecture de certaines vidéos restreintes par l'âge +Ceci est une version de correction qui résout les erreurs de YouTube : +• [YouTube] Correction du non-chargement des informations des vidéos, correction des erreurs HTTP 403 lors de la lecture des vidéos et restauration de la lecture de certaines vidéos à âge restreint • Correction des tailles de sous-titres qui ne changent pas -• Correction du téléchargement des informations deux fois lors de l'ouverture d'un flux -• [Soundcloud] Suppression des flux protégés par DRM non lisibles +• Correction du téléchargement des informations deux fois lors de l'ouverture d'un stream +• [Soundcloud] Suppression des streams protégés par DRM non lisibles • Traductions mises à jour diff --git a/fastlane/metadata/android/hu/changelogs/1004.txt b/fastlane/metadata/android/hu/changelogs/1004.txt index f4de95e68..97e36d1b0 100644 --- a/fastlane/metadata/android/hu/changelogs/1004.txt +++ b/fastlane/metadata/android/hu/changelogs/1004.txt @@ -1 +1,3 @@ -Immáron minden YouTube videó lejátszásra kerül +Ez a kiadás javítja, hogy a YouTube csak 360p felbontásban képes lejátszani. + +Vegyük figyelembe, hogy az ebben a verzióban alkalmazott megoldás valószínűleg ideiglenes, és hosszú távon a SABR videó protokollt kell megvalósítani, de a TeamNewPipe tagjai jelenleg elfoglaltak, így minden segítséget nagyra értékelnénk! https://github.com/TeamNewPipe/NewPipe/issues/12248 diff --git a/fastlane/metadata/android/hu/full_description.txt b/fastlane/metadata/android/hu/full_description.txt index 14b11b201..c822f8486 100644 --- a/fastlane/metadata/android/hu/full_description.txt +++ b/fastlane/metadata/android/hu/full_description.txt @@ -1 +1 @@ -A NewPipe nem használ semmilyen Google keretrendszer programkönyvtárat, sem YouTube API-t. Csupán a weboldalt dolgozza fel, hogy kinyerje a szükséges információkat. Így ez az alkalmazás a Google Szolgáltatások nélküli eszközökön is használható. Továbbá a NewPipe használatához nincs szükség YouTube fiókra, emellett szabad és nyílt forráskódú szoftver (FLOSS). +A NewPipe nem használ semmilyen Google keretrendszer-programkönyvtárat, sem a YouTube API-t. Csupán a weboldalt dolgozza fel, hogy kinyerje a szükséges információkat. Így ez az alkalmazás a Google Szolgáltatások nélküli eszközökön is használható. Továbbá a NewPipe használatához nincs szükség YouTube-fiókra, emellett szabad és nyílt forráskódú szoftver (FLOSS). diff --git a/fastlane/metadata/android/lv/changelogs/1001.txt b/fastlane/metadata/android/lv/changelogs/1001.txt new file mode 100644 index 000000000..4525874fd --- /dev/null +++ b/fastlane/metadata/android/lv/changelogs/1001.txt @@ -0,0 +1,6 @@ +Uzlabojumi +• Vienmēr atļauj nomainīt atskaņotāja paziņojumu iestatījumus uz ierīcēm ar Android 13+ + +Salabots +• Datubāzes/abonementu izgūšana vairs neapcērp iepriekš eksistējošo datni, kas, iespējams, izraisīja bojātu datni +• Novērsta atskaņotāja atsākšana no paša sākuma, kad noklikšķina uz laika zīmoga diff --git a/fastlane/metadata/android/lv/changelogs/64.txt b/fastlane/metadata/android/lv/changelogs/64.txt index 3d49ae26b..9a362aa95 100644 --- a/fastlane/metadata/android/lv/changelogs/64.txt +++ b/fastlane/metadata/android/lv/changelogs/64.txt @@ -1,8 +1,8 @@ ### Uzlabojumi - Pievienota iespēja ierobežot video kvalitāti, ja tiek lietoti mobilie dati. #1339 -- Iegaumē spilgtuma iestatījumu visu sesijas laiku #1442 -- Uzlabots lejupielāžu ātrums uz vājākiem procesoriem #1431 -- pievienots (working) mēdiju sesijas atbalsts #1433 +- Iegaumē spilgtuma iestatījumus visu sesijas laiku #1442 +- Uzlabots lejupielāžu ātrums uz vājākiem procesoriem #1431 +- pievienots (darbojošs) multimediju sesijas atbalsts #1433 ### Salabots -- Salabota aplikācijas nobrukšana, kad atver lejupielādes (labojums pieejams relīzes laidienos) #1441 +- Salabota lietotnes nobrukšana, kad atvēra Lejupielādes (labojums pieejams relīzes laidienos) #1441 diff --git a/fastlane/metadata/android/lv/changelogs/989.txt b/fastlane/metadata/android/lv/changelogs/989.txt new file mode 100644 index 000000000..f680eced4 --- /dev/null +++ b/fastlane/metadata/android/lv/changelogs/989.txt @@ -0,0 +1,3 @@ +• [YouTube] Novērsta bezgalīgā video ielāde pie jebkuru video atskaņošanu +• [YouTube] Novērsta dažu videoklipu lēnā ielāde (straumēšanas ierobežošanas problēma) +• Atjaunināta jsoup bibliotēka uz 1.15.3 versiju, kas ietver drošības labojumus diff --git a/fastlane/metadata/android/lv/changelogs/998.txt b/fastlane/metadata/android/lv/changelogs/998.txt new file mode 100644 index 000000000..79e4f3162 --- /dev/null +++ b/fastlane/metadata/android/lv/changelogs/998.txt @@ -0,0 +1,4 @@ +Salabota YouTube nespēja atskaņot jebkādu straumi HTTP 403 kļūdu dēļ. + +Nejaušas HTTP 403 kļūdas YouTube video skatīšanās laikā vēl nav novērstas. +Konkrētā problēma tiks atrisināta nākamajā labojumfailu laidienā, cik drīz vien iespējams. diff --git a/fastlane/metadata/android/lv/short_description.txt b/fastlane/metadata/android/lv/short_description.txt index d947cb8f1..231c57069 100644 --- a/fastlane/metadata/android/lv/short_description.txt +++ b/fastlane/metadata/android/lv/short_description.txt @@ -1 +1 @@ -Viegla, bezmaksas YouTube aplikācija priekš Android. +Viegla, bezmaksas YouTube Android lietotne. diff --git a/fastlane/metadata/android/pt-BR/changelogs/1001.txt b/fastlane/metadata/android/pt-BR/changelogs/1001.txt new file mode 100644 index 000000000..50dd12a29 --- /dev/null +++ b/fastlane/metadata/android/pt-BR/changelogs/1001.txt @@ -0,0 +1,6 @@ +Melhorado +• Sempre permitir alterar preferências de notificação do player no 13+ + +Corrigido +• Corrigido exportar banco de dados/inscrições não truncaria um arquivo já existente, podendo levar a uma exportação corrompida +• Corrigido o player retomando do início ao clicar em um tempo específico diff --git a/fastlane/metadata/android/pt-BR/changelogs/961.txt b/fastlane/metadata/android/pt-BR/changelogs/961.txt new file mode 100644 index 000000000..301637b3a --- /dev/null +++ b/fastlane/metadata/android/pt-BR/changelogs/961.txt @@ -0,0 +1,12 @@ +• [YouTube] Suporte a mixagem +• [YouTube] Exibição de informações sobre emissoras públicas e Covid-19 +• [media.ccc.de] Adicionado vídeos recentes +• Adicionada tradução para Somali + +• Vários melhoramentos internos + +• Corrigido compartilhar vídeos a partir do player +• Corrigido ReCaptcha no webview em branco +• Corrigido travamento que ocorre ao remover um stream da lista +• [PeerTube] Corrigidos streams relacionados +• [YouTube] Corrigida a pesquisa do YouTube Music diff --git a/fastlane/metadata/android/pt-BR/changelogs/964.txt b/fastlane/metadata/android/pt-BR/changelogs/964.txt new file mode 100644 index 000000000..f27426074 --- /dev/null +++ b/fastlane/metadata/android/pt-BR/changelogs/964.txt @@ -0,0 +1,8 @@ +• Suporte para capítulos adicionado nos controles do player +• [PeerTube] Busca Sépia adicionada +• Botão de compartilhamento adicionado novamente na visualização de detalhes do vídeo e descrição da transmissão movida para o layout de abas +• Desativação da restauração do brilho se o gesto de brilho estiver desativado +• Item de lista adicionado para reproduzir vídeo no Kodi +• Travamento corrigido quando nenhum navegador padrão está definido em alguns dispositivos e diálogos de compartilhamento aprimorados +• Alternar reprodução/pausa com o botão de espaço físico no player em tela cheia +• [media.ccc.de] Diversas correções e melhorias diff --git a/fastlane/metadata/android/pt-BR/changelogs/965.txt b/fastlane/metadata/android/pt-BR/changelogs/965.txt new file mode 100644 index 000000000..9862a1a4f --- /dev/null +++ b/fastlane/metadata/android/pt-BR/changelogs/965.txt @@ -0,0 +1,6 @@ +Corrigida a falha que ocorria ao reordenar grupos de canais. +Corrigida a obtenção de mais vídeos do YouTube de canais e playlists. +Corrigida a obtenção de comentários do YouTube. +Adicionado suporte para subcaminhos /watch/, /v/ e /w/ em URLs do YouTube. +Corrigida a extração do ID do cliente do SoundCloud e de conteúdo com restrição geográfica. +Adicionada a localização para o Curdo do Norte. diff --git a/fastlane/metadata/android/pt-PT/changelogs/951.txt b/fastlane/metadata/android/pt-PT/changelogs/951.txt index c391aa519..d48369bac 100644 --- a/fastlane/metadata/android/pt-PT/changelogs/951.txt +++ b/fastlane/metadata/android/pt-PT/changelogs/951.txt @@ -13,3 +13,5 @@ Melhorado Fixo • Desync de áudio/vídeo • [PeerTube] Gerir comentários apagados + +... diff --git a/fastlane/metadata/android/ru/changelogs/1000.txt b/fastlane/metadata/android/ru/changelogs/1000.txt index 735794877..90c03f3cf 100644 --- a/fastlane/metadata/android/ru/changelogs/1000.txt +++ b/fastlane/metadata/android/ru/changelogs/1000.txt @@ -1,24 +1,13 @@ -Улучшенный +Улучшения +• Сделать описание плейлиста кликабельным, чтобы показать больше/меньше контента. +• [PeerTube] Автоматически обрабатывать ссылки экземпляра `subscribeto.me`. +• Начинать воспроизведение только одного элемента на экране истории. -- Сделайте описание плейлиста кликабельным, чтобы показать больше/меньше контента - -- [PeerTube] Автоматически обрабатывать ссылки экземпляра `subscribeto.me - -- Запуск воспроизведения только одного элемента на экране истории - - -Исправлено - -- Исправление видимости кнопки RSS - -- Исправление сбоев предварительного просмотра панели поиска - -- Исправление создания плейлиста без миниатюр - -- Исправление выхода из диалога загрузки до его появления - -- Исправить всплывающее окно списка связанных элементов - -- Исправить порядок в диалоге добавления в плейлист - -- Настроить расположение элементов закладок плейлиста +Исправления +• Исправить видимость кнопки RSS. +• Исправить сбои при предварительном просмотре полосы прокрутки. +• Исправить добавление в плейлист элемента без миниатюры. +• Исправить выход из диалогового окна загрузки до его появления. +• Исправить всплывающее окно с списком связанных элементов. +• Исправлена последовательность в диалоговом окне добавления в плейлист. +• Настроена компоновка элементов закладок плейлиста. diff --git a/fastlane/metadata/android/sr/full_description.txt b/fastlane/metadata/android/sr/full_description.txt index e488a0ea4..42f1ef8f2 100644 --- a/fastlane/metadata/android/sr/full_description.txt +++ b/fastlane/metadata/android/sr/full_description.txt @@ -1 +1 @@ -NewPipe не користи никакве библиотеке Google оквира, нити YouTube API. Само анализира веб-сајт како би добио потребне информације. Из тог разлога, ова апликација се може користити на уређајима без инсталираних Google услуга. Такође, није Вам потребан YouTube налог да бисте користили NewPipe, a чак је и слободног, отвореног кода. +Њупипе не користи никакве књижнице радног окврира Гугла, нити АПИ Јутуба. Само рашчлањује мрежне странице како би добио потребне податке. Из тог разлога, овај програм се може користити на уређајима без уграђених услуга Гугла. Такође, није Вам потребан налог Јутуба ради коришћења Њупипе, a чак је и слободна мекотворина. diff --git a/fastlane/metadata/android/sr/short_description.txt b/fastlane/metadata/android/sr/short_description.txt index 82608e9db..4e963ee94 100644 --- a/fastlane/metadata/android/sr/short_description.txt +++ b/fastlane/metadata/android/sr/short_description.txt @@ -1 +1 @@ -Бесплатна и лагана замена за YouTube за Android. +Слободно и лако сучеље Јутуба за Андроид. diff --git a/fastlane/metadata/android/sv/changelogs/1004.txt b/fastlane/metadata/android/sv/changelogs/1004.txt index 35f298dbf..a9a551885 100644 --- a/fastlane/metadata/android/sv/changelogs/1004.txt +++ b/fastlane/metadata/android/sv/changelogs/1004.txt @@ -1 +1,3 @@ -Åtgärdat att YouTube inte spelar någon stream +Denna version fixar att enbart 360p strömmar var tillgängliga för YouTube. + +Observera att den lösning som används i den här versionen är sannolikt tillfällig, och i det långa loppet måste SABR-videoprotokollet implementeras, men TeamNewPipe-medlemmarna är för närvarande upptagna så all hjälp uppskattas! https://github.com/TeamNewPipe/NewPipe/issues/12248 diff --git a/fastlane/metadata/android/ta/changelogs/1000.txt b/fastlane/metadata/android/ta/changelogs/1000.txt index 2e7774ce0..43842685f 100644 --- a/fastlane/metadata/android/ta/changelogs/1000.txt +++ b/fastlane/metadata/android/ta/changelogs/1000.txt @@ -1,13 +1,13 @@ மேம்படுத்தப்பட்டது - / மேலும் / குறைவான உள்ளடக்கத்தைக் காட்ட பிளேலிச்ட் விளக்கத்தை சொடுக்கு செய்யவும் - • [PEERTUBE] `charbisto.me` உதாரணமாக இணைப்புகளை தானாகவே கையாளவும் + / மேலும் / குறைவான உள்ளடக்கத்தைக் காட்ட பிளேலிச்ட் விளக்கத்தைச் சொடுக்கு செய்யவும் + • [PEERTUBE] `charbisto.me` உதாரணமாக இணைப்புகளைத் தானாகவே கையாளவும் The வரலாற்றுத் திரையில் ஒற்றை உருப்படியை மட்டுமே இயக்கத் தொடங்குங்கள் சரி RS RSS பொத்தான் தெரிவுநிலையை சரிசெய்யவும் See gaekbar முன்னோட்ட செயலிழப்புகளை சரிசெய்யவும் - Play ஒரு சிறுபடம் இல்லாத உருப்படியை பிளேலிச்டிங் சரிசெய்யவும் + Play ஒரு சிறுபடம் இல்லாத உருப்படியைப் பிளேலிச்டிங் சரிசெய்யவும் The பதிவிறக்க உரையாடல் தோன்றுவதற்கு முன்பு வெளியேறுவதை சரிசெய்யவும் - Tied தொடர்புடைய உருப்படிகளை சரிசெய்யவும் பட்டியல் enqueue பாப்அப் + Tied தொடர்புடைய உருப்படிகளைச் சரிசெய்யவும் பட்டியல் enqueue பாப்அப் Plale பிளேலிச்ட் உரையாடலில் கூட்டு இல் ஆர்டரை சரிசெய்யவும் Plale பிளேலிச்ட் புத்தகக்குறி உருப்படி தளவமைப்பை சரிசெய்யவும் diff --git a/fastlane/metadata/android/ta/changelogs/1002.txt b/fastlane/metadata/android/ta/changelogs/1002.txt new file mode 100644 index 000000000..8e2bb3642 --- /dev/null +++ b/fastlane/metadata/android/ta/changelogs/1002.txt @@ -0,0 +1,4 @@ +நிலையான YouTube எந்த ச்ட்ரீமையும் இயக்கவில்லை. + +இந்த வெளியீடு யூடியூப் வீடியோ விவரங்களை ஏற்றுவதைத் தடுக்கும் மிக அழுத்தமான பிழையை மட்டுமே குறிக்கிறது. +வேறு சிக்கல்கள் இருப்பதை நாங்கள் அறிவோம், அவற்றை தீர்க்க விரைவில் ஒரு தனி வெளியீட்டை உருவாக்குவோம். diff --git a/fastlane/metadata/android/ta/changelogs/1003.txt b/fastlane/metadata/android/ta/changelogs/1003.txt new file mode 100644 index 000000000..95bc6e7b4 --- /dev/null +++ b/fastlane/metadata/android/ta/changelogs/1003.txt @@ -0,0 +1,6 @@ +இது YouTube பிழைகளை சரிசெய்யும் ஆட்ஃபிக்ச் வெளியீடு: +• [YouTube] எந்த வீடியோ தகவலையும் ஏற்றாததை சரிசெய்யவும், வீடியோக்களை இயக்கும்போது HTTP 403 பிழைகளை சரிசெய்யவும், சில வயதுக்கு தடைசெய்யப்பட்ட வீடியோக்களின் பின்னணியை மீட்டெடுக்கவும் +• தலைப்பு அளவுகள் மாற்றப்படவில்லை +Stramp ஒரு ச்ட்ரீமை திறக்கும்போது தகவலைப் பதிவிறக்குவதை இரண்டு முறை சரிசெய்யவும் +• [சவுண்ட்க்ளூட்] விளையாட முடியாத டிஆர்எம்-பாதுகாக்கப்பட்ட நீரோடைகளை அகற்று +• புதுப்பிக்கப்பட்ட மொழிபெயர்ப்புகள் diff --git a/fastlane/metadata/android/zh-Hant/changelogs/1001.txt b/fastlane/metadata/android/zh-Hant/changelogs/1001.txt new file mode 100644 index 000000000..033b9460e --- /dev/null +++ b/fastlane/metadata/android/zh-Hant/changelogs/1001.txt @@ -0,0 +1,6 @@ +改進 +• 一直允許在Android 13以上的裝置更改通知欄播放器 + +修正 +• 修復匯出資料庫/訂閱不會截斷已存在的文件,可能導致匯出損壞的問題 +• 修正點擊時間戳記時播放器從頭開始撥放的問題 From ba4e7a3c7fad782f6f3e28b422863b1da51cc0fe Mon Sep 17 00:00:00 2001 From: Stypox Date: Thu, 17 Jul 2025 10:18:10 +0200 Subject: [PATCH 105/143] Add changelog for v0.28.0 (1005) --- .../metadata/android/en-US/changelogs/1005.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 fastlane/metadata/android/en-US/changelogs/1005.txt diff --git a/fastlane/metadata/android/en-US/changelogs/1005.txt b/fastlane/metadata/android/en-US/changelogs/1005.txt new file mode 100644 index 000000000..35a5eab31 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/1005.txt @@ -0,0 +1,17 @@ +New +• Add support for Android Auto +• Allow setting feed groups as main screen tabs +• [YouTube] Share as temporary playlist +• [SoundCloud] Likes channel tab + +Improved +• Better search bar hints +• Show download date in Downloads +• Use Android 13 per-app language + +Fixed +• Fix broken text colors in dark mode +• [YouTube] Fix playlists not loading more than 100 items +• [YouTube] Fix missing recommended videos +• Fix crashes in History list view +• Fix timestamps in comment replies \ No newline at end of file From 938265d1273d0fca21df26ff9e016a244ce360c5 Mon Sep 17 00:00:00 2001 From: Stypox Date: Thu, 17 Jul 2025 10:31:47 +0200 Subject: [PATCH 106/143] Update NewPipeExtractor --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 0e59d524a..652eeb792 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -209,12 +209,12 @@ dependencies { // Or you can use a commit you pushed to GitHub by just replacing TeamNewPipe with your GitHub // name and the commit hash with the commit hash of the (pushed) commit you want to test // This works thanks to JitPack: https://jitpack.io/ - implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751' + implementation 'com.github.TeamNewPipe:nanojson:e9d656ddb49a412a5a0a5d5ef20ca7ef09549996' // WORKAROUND: if you get errors with the NewPipeExtractor dependency, replace `v0.24.3` with // the corresponding commit hash, since JitPack sometimes deletes artifacts. // If there’s already a git hash, just add more of it to the end (or remove a letter) // to cause jitpack to regenerate the artifact. - implementation 'com.github.TeamNewPipe.NewPipeExtractor:NewPipeExtractor:71b335128e8b66ecc0cd45379dd11a0865973065' + implementation 'com.github.TeamNewPipe:NewPipeExtractor:68b4c9acbae2d167e7b1209bb6bf0ae086dd427e' implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0' /** Checkstyle **/ From 4a41214df435b6b2c9623c7cdde957c70690a37f Mon Sep 17 00:00:00 2001 From: tobigr Date: Fri, 18 Jul 2025 10:28:59 +0200 Subject: [PATCH 107/143] Do not capitalize "page" for main page content options --- app/src/main/res/values/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c909a0632..5f995db4b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -397,10 +397,10 @@ Content of main page What tabs are shown on the main page Swipe items to remove them - Blank Page - Kiosk Page + Blank page + Kiosk page Default Kiosk - Channel Page + Channel page Select a channel No channel subscriptions yet Select a playlist From 7e0ee4eb7adcc8b8bfb3127bd2f43a56827bb307 Mon Sep 17 00:00:00 2001 From: tobigr Date: Fri, 18 Jul 2025 11:00:20 +0200 Subject: [PATCH 108/143] Update Extractor and add migration to remove SoundCloud Top 50 kiosk --- app/build.gradle | 2 +- .../newpipe/settings/SettingMigrations.java | 29 +++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 652eeb792..094cc7b47 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -214,7 +214,7 @@ dependencies { // the corresponding commit hash, since JitPack sometimes deletes artifacts. // If there’s already a git hash, just add more of it to the end (or remove a letter) // to cause jitpack to regenerate the artifact. - implementation 'com.github.TeamNewPipe:NewPipeExtractor:68b4c9acbae2d167e7b1209bb6bf0ae086dd427e' + implementation 'com.github.TeamNewPipe:NewPipeExtractor:7adbc48a0aa872c016b8ec089e278d5e12772054' implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0' /** Checkstyle **/ diff --git a/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java b/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java index d731f2f5e..6bdfc287e 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java +++ b/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java @@ -12,13 +12,19 @@ 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.ServiceList; +import org.schabi.newpipe.settings.tabs.Tab; +import org.schabi.newpipe.settings.tabs.TabsManager; import org.schabi.newpipe.util.DeviceUtils; import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Set; +import java.util.stream.Collectors; import static org.schabi.newpipe.MainActivity.DEBUG; +import static org.schabi.newpipe.extractor.ServiceList.SoundCloud; /** * In order to add a migration, follow these steps, given P is the previous version:
    @@ -129,7 +135,7 @@ public final class SettingMigrations { } }; - public static final Migration MIGRATION_5_6 = new Migration(5, 6) { + private static final Migration MIGRATION_5_6 = new Migration(5, 6) { @Override protected void migrate(@NonNull final Context context) { final boolean loadImages = sp.getBoolean("download_thumbnail_key", true); @@ -143,6 +149,24 @@ public final class SettingMigrations { } }; + private static final Migration MIGRATION_6_7 = new Migration(6, 7) { + @Override + protected void migrate(@NonNull final Context context) { + // The SoundCloud Top 50 Kiosk was removed in the extractor, + // so we remove the corresponding tab if it exists. + final TabsManager tabsManager = TabsManager.getManager(context); + final List tabs = tabsManager.getTabs(); + final List cleanedTabs = tabs.stream() + .filter(tab -> !(tab instanceof Tab.KioskTab kioskTab + && kioskTab.getKioskServiceId() == SoundCloud.getServiceId() + && kioskTab.getKioskId().equals("Top 50"))) + .collect(Collectors.toUnmodifiableList()); + if (tabs.size() != cleanedTabs.size()) { + tabsManager.saveTabs(cleanedTabs); + } + } + }; + /** * List of all implemented migrations. *

    @@ -156,12 +180,13 @@ public final class SettingMigrations { MIGRATION_3_4, MIGRATION_4_5, MIGRATION_5_6, + MIGRATION_6_7 }; /** * Version number for preferences. Must be incremented every time a migration is necessary. */ - private static final int VERSION = 6; + private static final int VERSION = 7; public static void runMigrationsIfNeeded(@NonNull final Context context) { From 941f85781b7ad63f97f1a2c21eb07bc907de9fb9 Mon Sep 17 00:00:00 2001 From: tobigr Date: Fri, 18 Jul 2025 12:13:51 +0200 Subject: [PATCH 109/143] Display dialog informing the user about the removal of the Top 50 kiosk --- .../java/org/schabi/newpipe/MainActivity.java | 2 ++ .../newpipe/settings/SettingMigrations.java | 33 ++++++++++++++++++- app/src/main/res/values/strings.xml | 2 ++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/MainActivity.java b/app/src/main/java/org/schabi/newpipe/MainActivity.java index b709c1107..ef0f78fc0 100644 --- a/app/src/main/java/org/schabi/newpipe/MainActivity.java +++ b/app/src/main/java/org/schabi/newpipe/MainActivity.java @@ -80,6 +80,7 @@ import org.schabi.newpipe.player.Player; import org.schabi.newpipe.player.event.OnKeyDownListener; import org.schabi.newpipe.player.helper.PlayerHolder; import org.schabi.newpipe.player.playqueue.PlayQueue; +import org.schabi.newpipe.settings.SettingMigrations; import org.schabi.newpipe.settings.UpdateSettingsFragment; import org.schabi.newpipe.util.Constants; import org.schabi.newpipe.util.DeviceUtils; @@ -197,6 +198,7 @@ public class MainActivity extends AppCompatActivity { } Localization.migrateAppLanguageSettingIfNecessary(getApplicationContext()); + SettingMigrations.showUserInfoIfPresent(this); } @Override diff --git a/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java b/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java index 6bdfc287e..88ab3eaeb 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java +++ b/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java @@ -5,6 +5,8 @@ import android.content.SharedPreferences; import android.util.Log; import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; +import androidx.core.util.Consumer; import androidx.preference.PreferenceManager; import org.schabi.newpipe.App; @@ -12,11 +14,11 @@ 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.ServiceList; import org.schabi.newpipe.settings.tabs.Tab; import org.schabi.newpipe.settings.tabs.TabsManager; import org.schabi.newpipe.util.DeviceUtils; +import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -38,6 +40,12 @@ public final class SettingMigrations { private static final String TAG = SettingMigrations.class.toString(); private static SharedPreferences sp; + /** + * List of UI actions that are performed after the UI is initialized + * to inform the user about changes that were applied by migrations. + */ + private static final List> MIGRATION_INFO = new ArrayList<>(); + private static final Migration MIGRATION_0_1 = new Migration(0, 1) { @Override public void migrate(@NonNull final Context context) { @@ -163,6 +171,14 @@ public final class SettingMigrations { .collect(Collectors.toUnmodifiableList()); if (tabs.size() != cleanedTabs.size()) { tabsManager.saveTabs(cleanedTabs); + // create an AlertDialog to inform the user about the change + MIGRATION_INFO.add((Context uiContext) -> new AlertDialog.Builder(uiContext) + .setTitle(R.string.migration_info_6_7_title) + .setMessage(R.string.migration_info_6_7_message) + .setPositiveButton(R.string.ok, null) + .setCancelable(false) + .create() + .show()); } } }; @@ -233,6 +249,21 @@ public final class SettingMigrations { sp.edit().putInt(lastPrefVersionKey, currentVersion).apply(); } + /** + * Perform UI actions informing about migrations that took place if they are present. + * @param context Context that can be used to show dialogs/snackbars/toasts + */ + public static void showUserInfoIfPresent(@NonNull final Context context) { + for (final Consumer consumer : MIGRATION_INFO) { + try { + consumer.accept(context); + } catch (final Exception e) { + ErrorUtil.showUiErrorSnackbar(context, "Showing migration info to the user", e); + } + } + MIGRATION_INFO.clear(); + } + private SettingMigrations() { } abstract static class Migration { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c909a0632..ddf49c65b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -865,4 +865,6 @@ Show more Show less The settings in the export being imported use a vulnerable format that was deprecated since NewPipe 0.27.0. Make sure the export being imported is from a trusted source, and prefer using only exports obtained from NewPipe 0.27.0 or newer in the future. Support for importing settings in this vulnerable format will soon be removed completely, and then old versions of NewPipe will not be able to import settings of exports from new versions anymore. + SoundCloud Top 50 page removed + SoundCloud has discontinued the original Top 50 charts. The corresponding tab has been removed from your main page. From fe58ec85ed8013626a9bdde4e8cff864513086d3 Mon Sep 17 00:00:00 2001 From: tobigr Date: Fri, 18 Jul 2025 19:06:26 +0200 Subject: [PATCH 110/143] Fix error detection when loading main page tabs Do not crash if something unexpected happens. --- .../main/java/org/schabi/newpipe/fragments/MainFragment.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java index 381de5003..4df905a31 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java @@ -37,7 +37,6 @@ import org.schabi.newpipe.BaseFragment; import org.schabi.newpipe.R; import org.schabi.newpipe.databinding.FragmentMainBinding; import org.schabi.newpipe.error.ErrorUtil; -import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.local.playlist.LocalPlaylistFragment; import org.schabi.newpipe.settings.tabs.Tab; import org.schabi.newpipe.settings.tabs.TabsManager; @@ -303,8 +302,9 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte final Fragment fragment; try { fragment = tab.getFragment(context); - } catch (final ExtractionException e) { + } catch (final Exception e) { ErrorUtil.showUiErrorSnackbar(context, "Getting fragment item", e); + // TODO: show an error fragment instead return new BlankFragment(); } From 9bf01e1241d033630c10af2724d79c7cebc31b7e Mon Sep 17 00:00:00 2001 From: litetex <40789489+litetex@users.noreply.github.com> Date: Wed, 16 Jul 2025 21:39:30 +0200 Subject: [PATCH 111/143] Fix new badge links on Readme being rendered incorrectly --- README.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index c19144064..aa4332165 100644 --- a/README.md +++ b/README.md @@ -9,12 +9,8 @@

    - - - - - - + + From f64dba0107d7e65a70b22c81bed77c89df19e61e Mon Sep 17 00:00:00 2001 From: litetex <40789489+litetex@users.noreply.github.com> Date: Thu, 17 Jul 2025 19:42:20 +0200 Subject: [PATCH 112/143] Fix new badge links on Readme being rendered incorrectly For all non default Readmes --- doc/README.ar.md | 8 ++------ doc/README.asm.md | 8 ++------ doc/README.de.md | 8 ++------ doc/README.es.md | 8 ++------ doc/README.fr.md | 8 ++------ doc/README.hi.md | 8 ++------ doc/README.it.md | 8 ++------ doc/README.ja.md | 8 ++------ doc/README.ko.md | 8 ++------ doc/README.pa.md | 8 ++------ doc/README.pl.md | 8 ++------ doc/README.pt_BR.md | 8 ++------ doc/README.ro.md | 8 ++------ doc/README.ru.md | 8 ++------ doc/README.ryu.md | 8 ++------ doc/README.so.md | 8 ++------ doc/README.sr.md | 8 ++------ doc/README.tr.md | 8 ++------ doc/README.zh_TW.md | 8 ++------ 19 files changed, 38 insertions(+), 114 deletions(-) diff --git a/doc/README.ar.md b/doc/README.ar.md index f005050c7..0d89e5d59 100644 --- a/doc/README.ar.md +++ b/doc/README.ar.md @@ -6,12 +6,8 @@

    - - - - - - + + diff --git a/doc/README.asm.md b/doc/README.asm.md index 37d0949b7..5958fe280 100644 --- a/doc/README.asm.md +++ b/doc/README.asm.md @@ -6,12 +6,8 @@

    - - - - - - + + diff --git a/doc/README.de.md b/doc/README.de.md index 34ad94ab1..ab1ab2727 100644 --- a/doc/README.de.md +++ b/doc/README.de.md @@ -9,12 +9,8 @@

    - - - - - - + + diff --git a/doc/README.es.md b/doc/README.es.md index 4a08cba08..155b004a1 100644 --- a/doc/README.es.md +++ b/doc/README.es.md @@ -6,12 +6,8 @@

    - - - - - - + + diff --git a/doc/README.fr.md b/doc/README.fr.md index cfebcb2a6..7b450b04d 100644 --- a/doc/README.fr.md +++ b/doc/README.fr.md @@ -9,12 +9,8 @@

    - - - - - - + + diff --git a/doc/README.hi.md b/doc/README.hi.md index 6098c6c26..3f51960b5 100644 --- a/doc/README.hi.md +++ b/doc/README.hi.md @@ -6,12 +6,8 @@

    - - - - - - + + diff --git a/doc/README.it.md b/doc/README.it.md index d926db6bc..b8621a8fe 100644 --- a/doc/README.it.md +++ b/doc/README.it.md @@ -6,12 +6,8 @@

    - - - - - - + + diff --git a/doc/README.ja.md b/doc/README.ja.md index 1e751855b..13ddebb02 100644 --- a/doc/README.ja.md +++ b/doc/README.ja.md @@ -6,12 +6,8 @@

    - - - - - - + + diff --git a/doc/README.ko.md b/doc/README.ko.md index 39fb7e11c..5f731d076 100644 --- a/doc/README.ko.md +++ b/doc/README.ko.md @@ -6,12 +6,8 @@

    - - - - - - + + diff --git a/doc/README.pa.md b/doc/README.pa.md index 9b84ded18..12229f1d8 100644 --- a/doc/README.pa.md +++ b/doc/README.pa.md @@ -6,12 +6,8 @@

    - - - - - - + + diff --git a/doc/README.pl.md b/doc/README.pl.md index 9574491c7..f95b62e33 100644 --- a/doc/README.pl.md +++ b/doc/README.pl.md @@ -6,12 +6,8 @@

    - - - - - - + + diff --git a/doc/README.pt_BR.md b/doc/README.pt_BR.md index b73da2de1..c8257ce3e 100644 --- a/doc/README.pt_BR.md +++ b/doc/README.pt_BR.md @@ -10,12 +10,8 @@

    - - - - - - + + diff --git a/doc/README.ro.md b/doc/README.ro.md index 3f146f7e4..5ce14ca1d 100644 --- a/doc/README.ro.md +++ b/doc/README.ro.md @@ -6,12 +6,8 @@

    - - - - - - + + diff --git a/doc/README.ru.md b/doc/README.ru.md index 8a9955707..56d3b48ed 100644 --- a/doc/README.ru.md +++ b/doc/README.ru.md @@ -6,12 +6,8 @@

    - - - - - - + + diff --git a/doc/README.ryu.md b/doc/README.ryu.md index f3ca31af0..23081f70d 100644 --- a/doc/README.ryu.md +++ b/doc/README.ryu.md @@ -6,12 +6,8 @@

    - - - - - - + + diff --git a/doc/README.so.md b/doc/README.so.md index 843bed749..a66f7d12b 100644 --- a/doc/README.so.md +++ b/doc/README.so.md @@ -6,12 +6,8 @@

    - - - - - - + + diff --git a/doc/README.sr.md b/doc/README.sr.md index 21e4d857c..9dbb439d0 100644 --- a/doc/README.sr.md +++ b/doc/README.sr.md @@ -9,12 +9,8 @@

    - - - - - - + + diff --git a/doc/README.tr.md b/doc/README.tr.md index 6e95e54de..5a0096e55 100644 --- a/doc/README.tr.md +++ b/doc/README.tr.md @@ -6,12 +6,8 @@

    - - - - - - + + diff --git a/doc/README.zh_TW.md b/doc/README.zh_TW.md index 05518624f..8cfcbd640 100644 --- a/doc/README.zh_TW.md +++ b/doc/README.zh_TW.md @@ -6,12 +6,8 @@

    - - - - - - + + From 9697112db632a6b7b7076e32b803c3d9b9d250d0 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sat, 19 Jul 2025 19:41:13 +0200 Subject: [PATCH 113/143] Show error panel in EmptyFragment --- .../schabi/newpipe/error/ErrorPanelHelper.kt | 17 ++++---- .../org/schabi/newpipe/error/UserAction.java | 3 +- .../newpipe/fragments/BlankFragment.java | 40 ++++++++++++++++++- .../newpipe/fragments/MainFragment.java | 9 +++-- app/src/main/res/layout/fragment_blank.xml | 4 +- 5 files changed, 59 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/error/ErrorPanelHelper.kt b/app/src/main/java/org/schabi/newpipe/error/ErrorPanelHelper.kt index fcc062102..14ec41148 100644 --- a/app/src/main/java/org/schabi/newpipe/error/ErrorPanelHelper.kt +++ b/app/src/main/java/org/schabi/newpipe/error/ErrorPanelHelper.kt @@ -35,7 +35,7 @@ import java.util.concurrent.TimeUnit class ErrorPanelHelper( private val fragment: Fragment, rootView: View, - onRetry: Runnable + onRetry: Runnable?, ) { private val context: Context = rootView.context!! @@ -56,12 +56,15 @@ class ErrorPanelHelper( errorPanelRoot.findViewById(R.id.error_open_in_browser) private var errorDisposable: Disposable? = null + private var retryShouldBeShown: Boolean = (onRetry != null) init { - errorDisposable = errorRetryButton.clicks() - .debounce(300, TimeUnit.MILLISECONDS) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe { onRetry.run() } + if (onRetry != null) { + errorDisposable = errorRetryButton.clicks() + .debounce(300, TimeUnit.MILLISECONDS) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { onRetry.run() } + } } private fun ensureDefaultVisibility() { @@ -101,7 +104,7 @@ class ErrorPanelHelper( errorActionButton.setOnClickListener(null) } - errorRetryButton.isVisible = true + errorRetryButton.isVisible = retryShouldBeShown showAndSetOpenInBrowserButtonAction(errorInfo) } else if (errorInfo.throwable is AccountTerminatedException) { errorTextView.setText(R.string.account_terminated) @@ -130,7 +133,7 @@ class ErrorPanelHelper( errorInfo.throwable !is ContentNotSupportedException ) { // show retry button only for content which is not unavailable or unsupported - errorRetryButton.isVisible = true + errorRetryButton.isVisible = retryShouldBeShown } showAndSetOpenInBrowserButtonAction(errorInfo) } diff --git a/app/src/main/java/org/schabi/newpipe/error/UserAction.java b/app/src/main/java/org/schabi/newpipe/error/UserAction.java index 6ca66e0d2..afb880a29 100644 --- a/app/src/main/java/org/schabi/newpipe/error/UserAction.java +++ b/app/src/main/java/org/schabi/newpipe/error/UserAction.java @@ -32,7 +32,8 @@ public enum UserAction { PREFERENCES_MIGRATION("migration of preferences"), SHARE_TO_NEWPIPE("share to newpipe"), CHECK_FOR_NEW_APP_VERSION("check for new app version"), - OPEN_INFO_ITEM_DIALOG("open info item dialog"); + OPEN_INFO_ITEM_DIALOG("open info item dialog"), + GETTING_MAIN_SCREEN_TAB("getting main screen tab"); private final String message; diff --git a/app/src/main/java/org/schabi/newpipe/fragments/BlankFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/BlankFragment.java index fe4eef37a..6f879a7e1 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/BlankFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/BlankFragment.java @@ -9,14 +9,52 @@ import androidx.annotation.Nullable; import org.schabi.newpipe.BaseFragment; import org.schabi.newpipe.R; +import org.schabi.newpipe.error.ErrorInfo; +import org.schabi.newpipe.error.ErrorPanelHelper; public class BlankFragment extends BaseFragment { + + @Nullable + final ErrorInfo errorInfo; + @Nullable + ErrorPanelHelper errorPanel = null; + + /** + * Builds a blank fragment that just says the app name and suggests clicking on search. + */ + public BlankFragment() { + this(null); + } + + /** + * @param errorInfo if null acts like {@link BlankFragment}, else shows an error panel. + */ + public BlankFragment(@Nullable final ErrorInfo errorInfo) { + this.errorInfo = errorInfo; + } + @Nullable @Override public View onCreateView(final LayoutInflater inflater, @Nullable final ViewGroup container, final Bundle savedInstanceState) { setTitle("NewPipe"); - return inflater.inflate(R.layout.fragment_blank, container, false); + final View view = inflater.inflate(R.layout.fragment_blank, container, false); + if (errorInfo != null) { + errorPanel = new ErrorPanelHelper(this, view, null); + errorPanel.showError(errorInfo); + view.findViewById(R.id.blank_page_content).setVisibility(View.GONE); + } + return view; + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + + if (errorPanel != null) { + errorPanel.dispose(); + errorPanel = null; + } } @Override diff --git a/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java index 4df905a31..1a5e5aa45 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java @@ -36,7 +36,9 @@ import com.google.android.material.tabs.TabLayout; import org.schabi.newpipe.BaseFragment; import org.schabi.newpipe.R; import org.schabi.newpipe.databinding.FragmentMainBinding; +import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.ErrorUtil; +import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.local.playlist.LocalPlaylistFragment; import org.schabi.newpipe.settings.tabs.Tab; import org.schabi.newpipe.settings.tabs.TabsManager; @@ -302,10 +304,9 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte final Fragment fragment; try { fragment = tab.getFragment(context); - } catch (final Exception e) { - ErrorUtil.showUiErrorSnackbar(context, "Getting fragment item", e); - // TODO: show an error fragment instead - return new BlankFragment(); + } catch (final Throwable t) { + return new BlankFragment(new ErrorInfo(t, UserAction.GETTING_MAIN_SCREEN_TAB, + "Tab " + tab.getClass().getSimpleName() + ":" + tab.getTabName(context))); } if (fragment instanceof BaseFragment) { diff --git a/app/src/main/res/layout/fragment_blank.xml b/app/src/main/res/layout/fragment_blank.xml index 6c2978e95..4d874ebdb 100644 --- a/app/src/main/res/layout/fragment_blank.xml +++ b/app/src/main/res/layout/fragment_blank.xml @@ -4,7 +4,9 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + Date: Sat, 19 Jul 2025 20:34:09 +0200 Subject: [PATCH 114/143] Improve comment --- .../java/org/schabi/newpipe/settings/SettingMigrations.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java b/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java index 88ab3eaeb..d13e73090 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java +++ b/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java @@ -41,8 +41,8 @@ public final class SettingMigrations { private static SharedPreferences sp; /** - * List of UI actions that are performed after the UI is initialized - * to inform the user about changes that were applied by migrations. + * List of UI actions that are performed after the UI is initialized (e.g. showing alert + * dialogs) to inform the user about changes that were applied by migrations. */ private static final List> MIGRATION_INFO = new ArrayList<>(); From 991d9ea3dfcdb4d07e855a14cddc05dcbc97f3f6 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sat, 19 Jul 2025 20:39:55 +0200 Subject: [PATCH 115/143] Fix state not saved --- .../java/org/schabi/newpipe/fragments/BlankFragment.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/BlankFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/BlankFragment.java index 6f879a7e1..66e132aff 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/BlankFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/BlankFragment.java @@ -7,6 +7,8 @@ import android.view.ViewGroup; import androidx.annotation.Nullable; +import com.evernote.android.state.State; + import org.schabi.newpipe.BaseFragment; import org.schabi.newpipe.R; import org.schabi.newpipe.error.ErrorInfo; @@ -14,8 +16,9 @@ import org.schabi.newpipe.error.ErrorPanelHelper; public class BlankFragment extends BaseFragment { + @State @Nullable - final ErrorInfo errorInfo; + ErrorInfo errorInfo; @Nullable ErrorPanelHelper errorPanel = null; From 893a227ab169782a539d86b2bb90602f2d2f281f Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Sat, 19 Jul 2025 19:14:38 +0530 Subject: [PATCH 116/143] Enable per-app language preferences for Android < 13 --- app/src/main/AndroidManifest.xml | 9 ++ app/src/main/java/org/schabi/newpipe/App.java | 2 +- .../java/org/schabi/newpipe/MainActivity.java | 8 +- .../org/schabi/newpipe/RouterActivity.java | 2 - .../org/schabi/newpipe/about/AboutActivity.kt | 2 - .../schabi/newpipe/about/LicenseFragment.kt | 2 - .../newpipe/download/DownloadActivity.java | 3 - .../newpipe/download/DownloadDialog.java | 2 - .../schabi/newpipe/error/ErrorActivity.java | 5 +- .../fragments/detail/DescriptionFragment.java | 2 +- .../list/channel/ChannelAboutFragment.java | 4 +- .../ImportConfirmationDialog.java | 3 - .../newpipe/player/PlayQueueActivity.java | 2 - .../org/schabi/newpipe/player/Player.java | 6 +- .../schabi/newpipe/player/PlayerService.java | 3 - .../helper/PlaybackParameterDialog.java | 2 - .../MediaBrowserPlaybackPreparer.kt | 5 +- .../BackupRestoreSettingsFragment.java | 3 - .../settings/ContentSettingsFragment.java | 49 ++++------ .../settings/DownloadSettingsFragment.java | 4 - .../newpipe/settings/SettingsActivity.java | 4 - .../org/schabi/newpipe/util/ListHelper.java | 10 +- .../org/schabi/newpipe/util/Localization.java | 98 ++++++++----------- 23 files changed, 85 insertions(+), 145 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e52dded5e..e0abd977b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -57,6 +57,15 @@ + + + + = 33) { - requirePreference(R.string.app_language_key).setVisible(false); - final Preference newAppLanguagePref = + appLanguagePref.setVisible(false); + final var newAppLanguagePref = requirePreference(R.string.app_language_android_13_and_up_key); newAppLanguagePref.setSummaryProvider(preference -> { - final Locale customLocale = AppCompatDelegate.getApplicationLocales().get(0); - if (customLocale != null) { - return customLocale.getDisplayName(); - } - return getString(R.string.systems_language); + final Locale loc = AppCompatDelegate.getApplicationLocales().get(0); + return loc != null ? loc.getDisplayName() : getString(R.string.systems_language); }); newAppLanguagePref.setOnPreferenceClickListener(preference -> { final Intent intent = new Intent(Settings.ACTION_APP_LOCALE_SETTINGS) @@ -55,10 +50,16 @@ public class ContentSettingsFragment extends BasePreferenceFragment { return true; }); newAppLanguagePref.setVisible(true); + } else { + appLanguagePref.setOnPreferenceChangeListener((preference, newValue) -> { + final String language = (String) newValue; + final Locale locale = Locale.forLanguageTag(language); + AppCompatDelegate.setApplicationLocales(LocaleListCompat.create(locale)); + return true; + }); } - final Preference imageQualityPreference = requirePreference(R.string.image_quality_key); - imageQualityPreference.setOnPreferenceChangeListener( + requirePreference(R.string.image_quality_key).setOnPreferenceChangeListener( (preference, newValue) -> { ImageStrategy.setPreferredImageQuality(PreferredImageQuality .fromPreferenceKey(requireContext(), (String) newValue)); @@ -92,22 +93,10 @@ public class ContentSettingsFragment extends BasePreferenceFragment { public void onDestroy() { super.onDestroy(); - final String selectedLanguage = - defaultPreferences.getString(getString(R.string.app_language_key), "en"); - - if (!selectedLanguage.equals(initialLanguage)) { - if (Build.VERSION.SDK_INT < 33) { - Toast.makeText( - requireContext(), - R.string.localization_changes_requires_app_restart, - Toast.LENGTH_LONG - ).show(); - } - final Localization selectedLocalization = org.schabi.newpipe.util.Localization - .getPreferredLocalization(requireContext()); - final ContentCountry selectedContentCountry = org.schabi.newpipe.util.Localization - .getPreferredContentCountry(requireContext()); - NewPipe.setupLocalization(selectedLocalization, selectedContentCountry); - } + final Localization selectedLocalization = org.schabi.newpipe.util.Localization + .getPreferredLocalization(requireContext()); + final ContentCountry selectedContentCountry = org.schabi.newpipe.util.Localization + .getPreferredContentCountry(requireContext()); + NewPipe.setupLocalization(selectedLocalization, selectedContentCountry); } } diff --git a/app/src/main/java/org/schabi/newpipe/settings/DownloadSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/DownloadSettingsFragment.java index ff7811af3..356dcd9b2 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/DownloadSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/DownloadSettingsFragment.java @@ -1,7 +1,5 @@ package org.schabi.newpipe.settings; -import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage; - import android.app.Activity; import android.content.ContentResolver; import android.content.Context; @@ -209,8 +207,6 @@ public class DownloadSettingsFragment extends BasePreferenceFragment { } private void requestDownloadPathResult(final ActivityResult result, final String key) { - assureCorrectAppLanguage(getContext()); - if (result.getResultCode() != Activity.RESULT_OK) { return; } diff --git a/app/src/main/java/org/schabi/newpipe/settings/SettingsActivity.java b/app/src/main/java/org/schabi/newpipe/settings/SettingsActivity.java index 0d57ce174..d5089cb7d 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SettingsActivity.java +++ b/app/src/main/java/org/schabi/newpipe/settings/SettingsActivity.java @@ -1,7 +1,5 @@ package org.schabi.newpipe.settings; -import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage; - import android.content.Context; import android.os.Bundle; import android.text.TextUtils; @@ -89,7 +87,6 @@ public class SettingsActivity extends AppCompatActivity implements @Override protected void onCreate(final Bundle savedInstanceBundle) { setTheme(ThemeHelper.getSettingsThemeStyle(this)); - assureCorrectAppLanguage(this); super.onCreate(savedInstanceBundle); Bridge.restoreInstanceState(this, savedInstanceBundle); @@ -228,7 +225,6 @@ public class SettingsActivity extends AppCompatActivity implements // Build search items final Context searchContext = getApplicationContext(); - assureCorrectAppLanguage(searchContext); final PreferenceParser parser = new PreferenceParser(searchContext, config); final PreferenceSearcher searcher = new PreferenceSearcher(config); diff --git a/app/src/main/java/org/schabi/newpipe/util/ListHelper.java b/app/src/main/java/org/schabi/newpipe/util/ListHelper.java index 282a88b1e..ea41f3e81 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ListHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ListHelper.java @@ -322,7 +322,7 @@ public final class ListHelper { } // Sort collected streams by name - return collectedStreams.values().stream().sorted(getAudioTrackNameComparator(context)) + return collectedStreams.values().stream().sorted(getAudioTrackNameComparator()) .collect(Collectors.toList()); } @@ -359,7 +359,7 @@ public final class ListHelper { } // Sort tracks alphabetically, sort track streams by quality - final Comparator nameCmp = getAudioTrackNameComparator(context); + final Comparator nameCmp = getAudioTrackNameComparator(); final Comparator formatCmp = getAudioFormatComparator(context); return collectedStreams.values().stream() @@ -867,12 +867,10 @@ public final class ListHelper { * Get a {@link Comparator} to compare {@link AudioStream}s by their languages and track types * for alphabetical sorting. * - * @param context app context for localization * @return Comparator */ - private static Comparator getAudioTrackNameComparator( - @NonNull final Context context) { - final Locale appLoc = Localization.getAppLocale(context); + private static Comparator getAudioTrackNameComparator() { + final Locale appLoc = Localization.getAppLocale(); return Comparator.comparing(AudioStream::getAudioLocale, Comparator.nullsLast( Comparator.comparing(locale -> locale.getDisplayName(appLoc)))) diff --git a/app/src/main/java/org/schabi/newpipe/util/Localization.java b/app/src/main/java/org/schabi/newpipe/util/Localization.java index 65cfec930..40c7b2a03 100644 --- a/app/src/main/java/org/schabi/newpipe/util/Localization.java +++ b/app/src/main/java/org/schabi/newpipe/util/Localization.java @@ -5,14 +5,12 @@ import static org.schabi.newpipe.MainActivity.DEBUG; import android.annotation.SuppressLint; import android.content.Context; import android.content.SharedPreferences; -import android.content.res.Configuration; import android.content.res.Resources; import android.icu.text.CompactDecimalFormat; import android.os.Build; +import android.text.BidiFormatter; import android.text.TextUtils; import android.text.format.DateUtils; -import android.text.BidiFormatter; -import android.util.DisplayMetrics; import android.util.Log; import androidx.annotation.NonNull; @@ -43,7 +41,6 @@ import java.time.format.FormatStyle; import java.util.Arrays; import java.util.List; import java.util.Locale; -import java.util.Objects; import java.util.stream.Collectors; @@ -120,39 +117,35 @@ public final class Localization { return getLocaleFromPrefs(context, R.string.content_language_key); } - public static Locale getAppLocale(@NonNull final Context context) { - if (Build.VERSION.SDK_INT >= 33) { - final Locale customLocale = AppCompatDelegate.getApplicationLocales().get(0); - return Objects.requireNonNullElseGet(customLocale, Locale::getDefault); - } - return getLocaleFromPrefs(context, R.string.app_language_key); + public static Locale getAppLocale() { + final Locale customLocale = AppCompatDelegate.getApplicationLocales().get(0); + return customLocale != null ? customLocale : Locale.getDefault(); } - public static String localizeNumber(@NonNull final Context context, final long number) { - return localizeNumber(context, (double) number); + public static String localizeNumber(final long number) { + return localizeNumber((double) number); } - public static String localizeNumber(@NonNull final Context context, final double number) { - final NumberFormat nf = NumberFormat.getInstance(getAppLocale(context)); + public static String localizeNumber(final double number) { + final NumberFormat nf = NumberFormat.getInstance(getAppLocale()); return nf.format(number); } - public static String formatDate(@NonNull final Context context, - @NonNull final OffsetDateTime offsetDateTime) { + public static String formatDate(@NonNull final OffsetDateTime offsetDateTime) { return DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM) - .withLocale(getAppLocale(context)).format(offsetDateTime + .withLocale(getAppLocale()).format(offsetDateTime .atZoneSameInstant(ZoneId.systemDefault())); } @SuppressLint("StringFormatInvalid") public static String localizeUploadDate(@NonNull final Context context, @NonNull final OffsetDateTime offsetDateTime) { - return context.getString(R.string.upload_date_text, formatDate(context, offsetDateTime)); + return context.getString(R.string.upload_date_text, formatDate(offsetDateTime)); } public static String localizeViewCount(@NonNull final Context context, final long viewCount) { return getQuantity(context, R.plurals.views, R.string.no_views, viewCount, - localizeNumber(context, viewCount)); + localizeNumber(viewCount)); } public static String localizeStreamCount(@NonNull final Context context, @@ -166,7 +159,7 @@ public final class Localization { return context.getResources().getString(R.string.more_than_100_videos); default: return getQuantity(context, R.plurals.videos, R.string.no_videos, streamCount, - localizeNumber(context, streamCount)); + localizeNumber(streamCount)); } } @@ -187,27 +180,27 @@ public final class Localization { public static String localizeWatchingCount(@NonNull final Context context, final long watchingCount) { return getQuantity(context, R.plurals.watching, R.string.no_one_watching, watchingCount, - localizeNumber(context, watchingCount)); + localizeNumber(watchingCount)); } public static String shortCount(@NonNull final Context context, final long count) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - return CompactDecimalFormat.getInstance(getAppLocale(context), + return CompactDecimalFormat.getInstance(getAppLocale(), CompactDecimalFormat.CompactStyle.SHORT).format(count); } final double value = (double) count; if (count >= 1000000000) { - return localizeNumber(context, round(value / 1000000000)) + return localizeNumber(round(value / 1000000000)) + context.getString(R.string.short_billion); } else if (count >= 1000000) { - return localizeNumber(context, round(value / 1000000)) + return localizeNumber(round(value / 1000000)) + context.getString(R.string.short_million); } else if (count >= 1000) { - return localizeNumber(context, round(value / 1000)) + return localizeNumber(round(value / 1000)) + context.getString(R.string.short_thousand); } else { - return localizeNumber(context, value); + return localizeNumber(value); } } @@ -377,8 +370,8 @@ public final class Localization { prettyTime.removeUnit(Decade.class); } - public static PrettyTime resolvePrettyTime(@NonNull final Context context) { - return new PrettyTime(getAppLocale(context)); + public static PrettyTime resolvePrettyTime() { + return new PrettyTime(getAppLocale()); } public static String relativeTime(@NonNull final OffsetDateTime offsetDateTime) { @@ -410,14 +403,6 @@ public final class Localization { } } - public static void assureCorrectAppLanguage(final Context c) { - final Resources res = c.getResources(); - final DisplayMetrics dm = res.getDisplayMetrics(); - final Configuration conf = res.getConfiguration(); - conf.setLocale(getAppLocale(c)); - res.updateConfiguration(conf, dm); - } - private static Locale getLocaleFromPrefs(@NonNull final Context context, @StringRes final int prefKey) { final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); @@ -453,28 +438,29 @@ public final class Localization { } public static void migrateAppLanguageSettingIfNecessary(@NonNull final Context context) { - // Starting with pull request #12093, NewPipe on Android 13+ exclusively uses Android's + // Starting with pull request #12093, NewPipe exclusively uses Android's // public per-app language APIs to read and set the UI language for NewPipe. - // If running on Android 13+, the following code will migrate any existing custom - // app language in SharedPreferences to use the public per-app language APIs instead. - if (Build.VERSION.SDK_INT >= 33) { - final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); - final String appLanguageKey = context.getString(R.string.app_language_key); - final String appLanguageValue = sp.getString(appLanguageKey, null); - if (appLanguageValue != null) { + // The following code will migrate any existing custom app language in SharedPreferences to + // use the public per-app language APIs instead. + final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); + final String appLanguageKey = context.getString(R.string.app_language_key); + final String appLanguageValue = sp.getString(appLanguageKey, null); + if (appLanguageValue != null) { + // The app language key is used on Android versions < Tiramisu; for more info, see + // ContentSettingsFragment. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { sp.edit().remove(appLanguageKey).apply(); - final String appLanguageDefaultValue = - context.getString(R.string.default_localization_key); - if (!appLanguageValue.equals(appLanguageDefaultValue)) { - try { - AppCompatDelegate.setApplicationLocales( - LocaleListCompat.forLanguageTags(appLanguageValue) - ); - } catch (final RuntimeException e) { - Log.e(TAG, "Failed to migrate previous custom app language " - + "setting to public per-app language APIs" - ); - } + } + final String appLanguageDefaultValue = + context.getString(R.string.default_localization_key); + if (!appLanguageValue.equals(appLanguageDefaultValue)) { + try { + final var locales = LocaleListCompat.forLanguageTags(appLanguageValue); + AppCompatDelegate.setApplicationLocales(locales); + } catch (final RuntimeException e) { + Log.e(TAG, "Failed to migrate previous custom app language " + + "setting to public per-app language APIs" + ); } } } From b8f9c125cd27e83f8c4c86140bb1bb959a63dd67 Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Sun, 20 Jul 2025 05:03:20 +0530 Subject: [PATCH 117/143] Add link for future reference --- .../java/org/schabi/newpipe/util/Localization.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/util/Localization.java b/app/src/main/java/org/schabi/newpipe/util/Localization.java index 40c7b2a03..fccaef8c8 100644 --- a/app/src/main/java/org/schabi/newpipe/util/Localization.java +++ b/app/src/main/java/org/schabi/newpipe/util/Localization.java @@ -437,11 +437,13 @@ public final class Localization { return context.getResources().getQuantityString(pluralId, safeCount, formattedCount); } + // Starting with pull request #12093, NewPipe exclusively uses Android's + // public per-app language APIs to read and set the UI language for NewPipe. + // The following code will migrate any existing custom app language in SharedPreferences to + // use the public per-app language APIs instead. + // For reference, see + // https://android-developers.googleblog.com/2022/11/per-app-language-preferences-part-1.html public static void migrateAppLanguageSettingIfNecessary(@NonNull final Context context) { - // Starting with pull request #12093, NewPipe exclusively uses Android's - // public per-app language APIs to read and set the UI language for NewPipe. - // The following code will migrate any existing custom app language in SharedPreferences to - // use the public per-app language APIs instead. final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); final String appLanguageKey = context.getString(R.string.app_language_key); final String appLanguageValue = sp.getString(appLanguageKey, null); From abd9aade87fab9e28d2c0bdf1ecb418866d6a24c Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Sun, 20 Jul 2025 05:24:56 +0530 Subject: [PATCH 118/143] Update AppCompat --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 094cc7b47..a629f65eb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -225,7 +225,7 @@ dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:${kotlin_version}" /** AndroidX **/ - implementation 'androidx.appcompat:appcompat:1.6.1' + implementation 'androidx.appcompat:appcompat:1.7.1' implementation 'androidx.cardview:cardview:1.0.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.core:core-ktx:1.12.0' From 9e14f93186d40830dd8e0243f2288dffb28b3390 Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Sun, 20 Jul 2025 16:18:46 +0530 Subject: [PATCH 119/143] Properly handle when system language is selected --- .../org/schabi/newpipe/settings/ContentSettingsFragment.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java index b98b8cb6c..ec217db3d 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java @@ -53,8 +53,9 @@ public class ContentSettingsFragment extends BasePreferenceFragment { } else { appLanguagePref.setOnPreferenceChangeListener((preference, newValue) -> { final String language = (String) newValue; - final Locale locale = Locale.forLanguageTag(language); - AppCompatDelegate.setApplicationLocales(LocaleListCompat.create(locale)); + final String systemLang = getString(R.string.default_localization_key); + final String tag = systemLang.equals(language) ? null : language; + AppCompatDelegate.setApplicationLocales(LocaleListCompat.forLanguageTags(tag)); return true; }); } From 99003bab07f6d47d91e467c7e40016577ea81fd5 Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Sun, 20 Jul 2025 16:43:37 +0530 Subject: [PATCH 120/143] Clean up imports --- .../newpipe/settings/ContentSettingsFragment.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java index ec217db3d..404ef4bb6 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java @@ -16,8 +16,7 @@ import androidx.preference.Preference; import org.schabi.newpipe.DownloaderImpl; import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.NewPipe; -import org.schabi.newpipe.extractor.localization.ContentCountry; -import org.schabi.newpipe.extractor.localization.Localization; +import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.image.ImageStrategy; import org.schabi.newpipe.util.image.PicassoHelper; import org.schabi.newpipe.util.image.PreferredImageQuality; @@ -94,10 +93,9 @@ public class ContentSettingsFragment extends BasePreferenceFragment { public void onDestroy() { super.onDestroy(); - final Localization selectedLocalization = org.schabi.newpipe.util.Localization - .getPreferredLocalization(requireContext()); - final ContentCountry selectedContentCountry = org.schabi.newpipe.util.Localization - .getPreferredContentCountry(requireContext()); + final var context = requireContext(); + final var selectedLocalization = Localization.getPreferredLocalization(context); + final var selectedContentCountry = Localization.getPreferredContentCountry(context); NewPipe.setupLocalization(selectedLocalization, selectedContentCountry); } } From f48e73eb2a5f6c1e1708907e887e2467dc951978 Mon Sep 17 00:00:00 2001 From: litetex <40789489+litetex@users.noreply.github.com> Date: Sun, 20 Jul 2025 21:52:07 +0200 Subject: [PATCH 121/143] Cleaned up some code related to app language * Use build constants when possible * Inline variables * Don't use var for normal-sized types (that way it's easier to review) * Split code into methods --- .../settings/ContentSettingsFragment.java | 66 +++++++++++-------- .../org/schabi/newpipe/util/Localization.java | 8 +-- 2 files changed, 42 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java index 404ef4bb6..ffc80e30e 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java @@ -33,10 +33,17 @@ public class ContentSettingsFragment extends BasePreferenceFragment { addPreferencesFromResourceRegistry(); - final var appLanguagePref = requirePreference(R.string.app_language_key); - if (Build.VERSION.SDK_INT >= 33) { + setupAppLanguagePreferences(); + setupImageQualityPref(); + } + + private void setupAppLanguagePreferences() { + final Preference appLanguagePref = requirePreference(R.string.app_language_key); + // Android 13+ allows to set app specific languages + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { appLanguagePref.setVisible(false); - final var newAppLanguagePref = + + final Preference newAppLanguagePref = requirePreference(R.string.app_language_android_13_and_up_key); newAppLanguagePref.setSummaryProvider(preference -> { final Locale loc = AppCompatDelegate.getApplicationLocales().get(0); @@ -49,30 +56,33 @@ public class ContentSettingsFragment extends BasePreferenceFragment { return true; }); newAppLanguagePref.setVisible(true); - } else { - appLanguagePref.setOnPreferenceChangeListener((preference, newValue) -> { - final String language = (String) newValue; - final String systemLang = getString(R.string.default_localization_key); - final String tag = systemLang.equals(language) ? null : language; - AppCompatDelegate.setApplicationLocales(LocaleListCompat.forLanguageTags(tag)); - return true; - }); + return; } + appLanguagePref.setOnPreferenceChangeListener((preference, newValue) -> { + final String language = (String) newValue; + final String systemLang = getString(R.string.default_localization_key); + final String tag = systemLang.equals(language) ? null : language; + AppCompatDelegate.setApplicationLocales(LocaleListCompat.forLanguageTags(tag)); + return true; + }); + } + + private void setupImageQualityPref() { requirePreference(R.string.image_quality_key).setOnPreferenceChangeListener( - (preference, newValue) -> { - ImageStrategy.setPreferredImageQuality(PreferredImageQuality - .fromPreferenceKey(requireContext(), (String) newValue)); - try { - PicassoHelper.clearCache(preference.getContext()); - Toast.makeText(preference.getContext(), - R.string.thumbnail_cache_wipe_complete_notice, Toast.LENGTH_SHORT) - .show(); - } catch (final IOException e) { - Log.e(TAG, "Unable to clear Picasso cache", e); - } - return true; - }); + (preference, newValue) -> { + ImageStrategy.setPreferredImageQuality(PreferredImageQuality + .fromPreferenceKey(requireContext(), (String) newValue)); + try { + PicassoHelper.clearCache(preference.getContext()); + Toast.makeText(preference.getContext(), + R.string.thumbnail_cache_wipe_complete_notice, Toast.LENGTH_SHORT) + .show(); + } catch (final IOException e) { + Log.e(TAG, "Unable to clear Picasso cache", e); + } + return true; + }); } @Override @@ -93,9 +103,9 @@ public class ContentSettingsFragment extends BasePreferenceFragment { public void onDestroy() { super.onDestroy(); - final var context = requireContext(); - final var selectedLocalization = Localization.getPreferredLocalization(context); - final var selectedContentCountry = Localization.getPreferredContentCountry(context); - NewPipe.setupLocalization(selectedLocalization, selectedContentCountry); + final Context context = requireContext(); + NewPipe.setupLocalization( + Localization.getPreferredLocalization(context), + Localization.getPreferredContentCountry(context)); } } diff --git a/app/src/main/java/org/schabi/newpipe/util/Localization.java b/app/src/main/java/org/schabi/newpipe/util/Localization.java index fccaef8c8..2bd4664ae 100644 --- a/app/src/main/java/org/schabi/newpipe/util/Localization.java +++ b/app/src/main/java/org/schabi/newpipe/util/Localization.java @@ -448,8 +448,8 @@ public final class Localization { final String appLanguageKey = context.getString(R.string.app_language_key); final String appLanguageValue = sp.getString(appLanguageKey, null); if (appLanguageValue != null) { - // The app language key is used on Android versions < Tiramisu; for more info, see - // ContentSettingsFragment. + // The app language key is used on Android versions < 33 + // for more info, see ContentSettingsFragment if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { sp.edit().remove(appLanguageKey).apply(); } @@ -457,8 +457,8 @@ public final class Localization { context.getString(R.string.default_localization_key); if (!appLanguageValue.equals(appLanguageDefaultValue)) { try { - final var locales = LocaleListCompat.forLanguageTags(appLanguageValue); - AppCompatDelegate.setApplicationLocales(locales); + AppCompatDelegate.setApplicationLocales( + LocaleListCompat.forLanguageTags(appLanguageValue)); } catch (final RuntimeException e) { Log.e(TAG, "Failed to migrate previous custom app language " + "setting to public per-app language APIs" From 99ae3fdd4ea00d0dc8e492ac3fc2447cba51425e Mon Sep 17 00:00:00 2001 From: litetex <40789489+litetex@users.noreply.github.com> Date: Sun, 20 Jul 2025 22:05:05 +0200 Subject: [PATCH 122/143] Removed no longer needed translation key --- app/src/main/res/values-ar-rLY/strings.xml | 1 - app/src/main/res/values-ar/strings.xml | 1 - app/src/main/res/values-az/strings.xml | 1 - app/src/main/res/values-b+ast/strings.xml | 1 - app/src/main/res/values-b+uz+Latn/strings.xml | 1 - app/src/main/res/values-be/strings.xml | 1 - app/src/main/res/values-bg/strings.xml | 1 - app/src/main/res/values-bn/strings.xml | 1 - app/src/main/res/values-ca/strings.xml | 1 - app/src/main/res/values-ckb/strings.xml | 1 - app/src/main/res/values-cs/strings.xml | 1 - app/src/main/res/values-da/strings.xml | 1 - app/src/main/res/values-de/strings.xml | 1 - app/src/main/res/values-el/strings.xml | 1 - app/src/main/res/values-eo/strings.xml | 1 - app/src/main/res/values-es/strings.xml | 1 - app/src/main/res/values-et/strings.xml | 1 - app/src/main/res/values-eu/strings.xml | 1 - app/src/main/res/values-fa/strings.xml | 1 - app/src/main/res/values-fi/strings.xml | 1 - app/src/main/res/values-fr/strings.xml | 1 - app/src/main/res/values-gl/strings.xml | 1 - app/src/main/res/values-he/strings.xml | 1 - app/src/main/res/values-hi/strings.xml | 1 - app/src/main/res/values-hr/strings.xml | 1 - app/src/main/res/values-hu/strings.xml | 1 - app/src/main/res/values-in/strings.xml | 1 - app/src/main/res/values-is/strings.xml | 1 - app/src/main/res/values-it/strings.xml | 1 - app/src/main/res/values-ja/strings.xml | 1 - app/src/main/res/values-ka/strings.xml | 1 - app/src/main/res/values-kmr/strings.xml | 1 - app/src/main/res/values-ko/strings.xml | 1 - app/src/main/res/values-ku/strings.xml | 1 - app/src/main/res/values-lt/strings.xml | 1 - app/src/main/res/values-lv/strings.xml | 1 - app/src/main/res/values-mk/strings.xml | 1 - app/src/main/res/values-ml/strings.xml | 1 - app/src/main/res/values-nb-rNO/strings.xml | 1 - app/src/main/res/values-ne/strings.xml | 1 - app/src/main/res/values-nl-rBE/strings.xml | 1 - app/src/main/res/values-nl/strings.xml | 1 - app/src/main/res/values-nqo/strings.xml | 1 - app/src/main/res/values-or/strings.xml | 1 - app/src/main/res/values-pa/strings.xml | 1 - app/src/main/res/values-pl/strings.xml | 1 - app/src/main/res/values-pt-rBR/strings.xml | 1 - app/src/main/res/values-pt-rPT/strings.xml | 1 - app/src/main/res/values-pt/strings.xml | 1 - app/src/main/res/values-ro/strings.xml | 1 - app/src/main/res/values-ru/strings.xml | 1 - app/src/main/res/values-ryu/strings.xml | 1 - app/src/main/res/values-sat/strings.xml | 1 - app/src/main/res/values-sc/strings.xml | 1 - app/src/main/res/values-sk/strings.xml | 1 - app/src/main/res/values-sl/strings.xml | 1 - app/src/main/res/values-so/strings.xml | 1 - app/src/main/res/values-sq/strings.xml | 1 - app/src/main/res/values-sr/strings.xml | 1 - app/src/main/res/values-sv/strings.xml | 1 - app/src/main/res/values-ta/strings.xml | 1 - app/src/main/res/values-te/strings.xml | 1 - app/src/main/res/values-tr/strings.xml | 1 - app/src/main/res/values-uk/strings.xml | 1 - app/src/main/res/values-ur/strings.xml | 1 - app/src/main/res/values-vi/strings.xml | 1 - app/src/main/res/values-zh-rCN/strings.xml | 1 - app/src/main/res/values-zh-rHK/strings.xml | 1 - app/src/main/res/values-zh-rTW/strings.xml | 1 - app/src/main/res/values/strings.xml | 1 - 70 files changed, 70 deletions(-) diff --git a/app/src/main/res/values-ar-rLY/strings.xml b/app/src/main/res/values-ar-rLY/strings.xml index fa19afe78..0ab5fe741 100644 --- a/app/src/main/res/values-ar-rLY/strings.xml +++ b/app/src/main/res/values-ar-rLY/strings.xml @@ -227,7 +227,6 @@ المميزة عرض المحتوى الذي يُحتمل أن يكون غير مناسب للأطفال لأن له حدًا عمريًا (مثل 18+) بدأ التشغيل في الخلفية - ستتغير اللغة بمجرد إعادة تشغيل التطبيق القصيرة قوائم التشغيل تنظيف diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index c4eee0835..fff1dd3a9 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -427,7 +427,6 @@ الكشك الافتراضي لا توجد مشاهدة لا أحد يستمع - ستتغير اللغة بمجرد إعادة تشغيل التطبيق %s مشاهدة %s مشاهدة diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml index ee35996a6..682dda98f 100644 --- a/app/src/main/res/values-az/strings.xml +++ b/app/src/main/res/values-az/strings.xml @@ -342,7 +342,6 @@ Etibarlı ZIP faylı yoxdur Xəbərdarlıq: Bütün faylları idxal etmək mümkün olmadı. Tənzimləmələri də idxal etmək istəyirsiniz\? - Tətbiq yenidən başladıldıqdan sonra dil dəyişəcəkdir Ən yaxşı 50 Yeni və populyar Yerli diff --git a/app/src/main/res/values-b+ast/strings.xml b/app/src/main/res/values-b+ast/strings.xml index 454ddd152..51b4fdec0 100644 --- a/app/src/main/res/values-b+ast/strings.xml +++ b/app/src/main/res/values-b+ast/strings.xml @@ -223,7 +223,6 @@ Política de privacidá de NewPipe El ficheru nun pue crease El sirvidor nun unvia datos - La llingua va camudar namás que se reanicie l\'aplicación. Buscar Compartir con Soscribiéstite diff --git a/app/src/main/res/values-b+uz+Latn/strings.xml b/app/src/main/res/values-b+uz+Latn/strings.xml index 780061c73..b556da756 100644 --- a/app/src/main/res/values-b+uz+Latn/strings.xml +++ b/app/src/main/res/values-b+uz+Latn/strings.xml @@ -551,7 +551,6 @@ Yangi va qaynoqlari Top 50 Ommabop - Ilova qayta ishga tushirilgandan so\'ng til o\'zgaradi. Fikrlarni yuklab bo‘lmadi Sozlamalarni ham import qilmoqchimisiz\? Bu sizning joriy sozlamangizni bekor qiladi. diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index f8d4a3670..22f963def 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -537,7 +537,6 @@ %d дзён Ачысціць гісторыю спампоўвання - Мова зменіцца пасля перазапуску праграмы Ніхто не слухае Уключыць Апавяшчэнні пра ход відэахэшавання diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index c38ea7952..c6d4d76ce 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -432,7 +432,6 @@ Най-харесвани Готово Коментари - Езикът ще се смени след рестартиране на приложението Скрит Частен Предложения за отдалечено търсене diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml index e83bbbdb9..715c9146e 100644 --- a/app/src/main/res/values-bn/strings.xml +++ b/app/src/main/res/values-bn/strings.xml @@ -534,7 +534,6 @@ প্রত্যেক ডাউনলোড কোথায় রাখা হবে তা জিজ্ঞেস করা হবে। \nমেমোরি কার্ডে ডাউনলোড করতে সিস্টেম ফোল্ডার পিকার (SAF) এনেবল করুন এই নামের একটি ডাউনলোড চলমান - অ্যাপ আবার শুরু হলে ভাষা পাল্টাবে মিডিয়া সুরঙ্গকরণ অক্ষম দ্রুত ফিড অবস্থা এ বিষয়ে এর বেশি তথ্য দেয় না। কোনো ডাউনলোড ফোল্ডার নির্দিষ্ট করা হয়নি, এখনই একটা সহজাত ডাউনলোড ফোল্ডার নির্বাচন করো diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index a4ed02801..123a5ef67 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -419,7 +419,6 @@ %s escoltants %s escoltants - Es canviarà l\'idioma en reiniciar l\'aplicació Tendències Ensenya el temps passat original sobre els \"items\" Auto-generat (no es troba cap uploader) diff --git a/app/src/main/res/values-ckb/strings.xml b/app/src/main/res/values-ckb/strings.xml index 413f71d85..649e6e73c 100644 --- a/app/src/main/res/values-ckb/strings.xml +++ b/app/src/main/res/values-ckb/strings.xml @@ -107,7 +107,6 @@ ناتوانرێت به‌ژداریكردنه‌كه‌ نوێبكرێته‌وه‌ پشت شاشە بێ ئەنجامه‌ - زمان دەگۆڕدرێت لەدوای داگیرساندنەوەی به‌رنامه‌كه‌ لادانی سەیرکراو پیشاندانی نیشانەکەری شوێنی کارپێکەر لە خشتەکاندا شوێنەکان لە خشتەکاندا diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index a144e996a..ea531408f 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -427,7 +427,6 @@ %s posluchači %s posluchačů - Ke změně jazyka dojde po restartu aplikace Výchozí kiosek Délka přetočení vpřed/zpět Instance PeerTube diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 86be3084a..cecdcc4fe 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -507,7 +507,6 @@ Stryg på elementer for at fjerne dem Vælg en playliste Ingen playliste-bogmærker endnu - Sproget ændres, når appen genstarter Afspillerkø Vis kanalens detaljer Sæt i kø diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 416f9d584..309709f47 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -432,7 +432,6 @@ %s Zuhörer %s Zuhörer - Die Sprache ändert sich, sobald die App neu gestartet wird PeerTube-Instanzen Finde auf %s die Instanzen, die dir gefallen Instanz hinzufügen diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index f871e9146..67a24bd4f 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -422,7 +422,6 @@ %s ακροατής %s ακροατές - Η γλώσσα θα αλλάξει αφού επανεκκινηθεί η εφαρμογή Προεπιλεγμένο περίπτερο Μόνο HTTPS σύνδεσμοι υποστηρίζονται Τοπικά diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml index 66e2c4d10..1da4d536c 100644 --- a/app/src/main/res/values-eo/strings.xml +++ b/app/src/main/res/values-eo/strings.xml @@ -421,7 +421,6 @@ %s aŭskultanto %s aŭskultantoj - La lingvo ŝanĝos kiam la apo restartos Daŭro de rapidpluiga/revolva serĉo Instancoj de PeerTube Elekti viajn preferitajn instancojn de PeerTube diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 43df8dcfd..610d900ec 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -427,7 +427,6 @@ %s oyentes %s oyentes - El idioma cambiará después del reinicio de la aplicación Duración de búsqueda al avanzar y/o retroceder Instancias de PeerTube Selecciona tus instancias favoritas de PeerTube diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index 5e62c98a2..9f9c7207c 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -487,7 +487,6 @@ Lisa esitusjärjekorda Hiljuti lisatud Kohalikud - Keele muutus jõustub rakenduse uuesti käivitamisel Kommentaaride laadimine ei õnnestunud Esitusloendi järjehoidjaid veel pole Vali esitusloend diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index b1c393db7..16054d9ae 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -422,7 +422,6 @@ Erreprodukziorako kokapen guztiak ezabatzen ditu Ezabatu erreprodukziorako kokapen guztiak\? Aktibatu zerbitzua, orain hautatua: - Hizkuntza aldatuko da aplikazioa berrabiarazterakoan Kiosko Lehenetsia Aurreratze/atzeratze bilaketaren iraupena PeerTube instantziak diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index 6fef73fc7..3bba8efb8 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -469,7 +469,6 @@ مورد پسندترین‌ها اخیرا اضافه شده محلی - با آغاز دوبارهٔ کاره، زبان تغییر خواهد کرد کیوسک پیش‌فرض انجام شد وقتی انجام شد، «Done» یا «انجام شد» را بفشارید diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 0bc4f4692..20734dd26 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -337,7 +337,6 @@ Hiljattain lisätyt Paikalliset Pidetyimmät - Kieli vaihtuu, kun sovellus uudelleenkäynnistetään Kommentteja ei voitu ladata Mitkä välilehdet näytetään pääsivulla Valmis diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index cf6c50a76..c3fe5cf58 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -428,7 +428,6 @@ %s auditeurs %s auditeurs - La langue changera une fois que l’application aura redémarré Durée de l’avance et retour rapide Instances PeerTube Veuillez choisir vos instances PeerTube préférées diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 84bbbb338..d345b9385 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -463,7 +463,6 @@ Conferencias O que ten mais gústames Engadiuse recentemente - O idioma cambiará unha vez que se reinicie o aplicativo Non se puideron cargar os comentarios Aínda non hai marcadores nesta lista de reprodución Seleccionar unha lista de reprodución diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index 83c85cc9e..bd560f07b 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -432,7 +432,6 @@ %s מאזינים %s מאזינים - השפה תוחלף עם הפעלת היישומון מחדש קיוסק ברירת מחדל משך קפיצה מהירה קדימה/אחורה מופעים של PeerTube diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 086d200d5..37282a0da 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -423,7 +423,6 @@ %s श्रोता %s श्रोता - ऐप के पुनः आरंभ होने के बाद भाषा बदल जाएगी तेज मोड सक्षम करें तेज मोड अक्षम करें क्या आपको लगता है कि फीड लोडिंग बहुत धीमी है\? यदि ऐसा है, तो तेज़ लोडिंग को सक्षम करने का प्रयास करें (आप इसे सेटिंग्स में या नीचे दिए गए बटन को दबाकर बदल सकते हैं)। diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 3c09a8aca..c4cd60c0b 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -406,7 +406,6 @@ Izbrisati sve pozicije reprodukcije\? Nitko ne gleda Nitko ne sluša - Jezik će se promijeniti nakon ponovnog pokretanja aplikcije Standardni kiosk Podržani su samo HTTP URL-ovi Lokalni diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index e55471d48..14c55b772 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -428,7 +428,6 @@ Senki sem nézi A feliratkozók száma nem érhető el Helyi - A nyelv az alkalmazás újraindításakor fog megváltozni A megjegyzések betöltése sikertelen Válasszon egy lejátszási listát Lejátszás automatikus indítása — %s diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 0bc414a92..19f867d7c 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -417,7 +417,6 @@ %s pendengar - Bahasa yang diubah akan diterapkan setelah aplikasi dimulai ulang Situs PeerTube Pilih situs PeerTube favorit Anda Temukan situs yang Anda suka di %s diff --git a/app/src/main/res/values-is/strings.xml b/app/src/main/res/values-is/strings.xml index 986ae282c..e7ce69e41 100644 --- a/app/src/main/res/values-is/strings.xml +++ b/app/src/main/res/values-is/strings.xml @@ -268,7 +268,6 @@ Nýlega spilað Mest spilað Aðalsíða - Tungumálið breytist þegar forritið er endurræst Flutt út Flutt inn Staðbundið diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 654a4c181..4c087f4de 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -427,7 +427,6 @@ %s ascoltatori %s ascoltatori - La lingua verrà cambiata al riavvio dell\'applicazione Contenuti in evidenza predefiniti Durata avanzamento e riavvolgimento rapidi Istanze PeerTube diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index fda1e2e21..25c1d9fe9 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -418,7 +418,6 @@ %s 人が聴取中 - アプリを再起動すると、言語が変更されます 高速早送り/巻き戻し間隔 PeerTube インスタンス PeerTube インスタンスを選択する diff --git a/app/src/main/res/values-ka/strings.xml b/app/src/main/res/values-ka/strings.xml index 80cbac475..4fc00c0b3 100644 --- a/app/src/main/res/values-ka/strings.xml +++ b/app/src/main/res/values-ka/strings.xml @@ -333,7 +333,6 @@ გაფრთხილება: ყველა ფაილის იმპორტი ვერ მოხერხდა. ეს უგულებელყოფს თქვენს მიმდინარე პარამეტრს. კომენტარების ჩატვირთვა ვერ მოხერხდა - ენა შეიცვლება აპის გადატვირთვის შემდეგ ტრენდული ტოპ 50 ახალი და ცხელი diff --git a/app/src/main/res/values-kmr/strings.xml b/app/src/main/res/values-kmr/strings.xml index 9f19ced10..b5e5235d5 100644 --- a/app/src/main/res/values-kmr/strings.xml +++ b/app/src/main/res/values-kmr/strings.xml @@ -139,7 +139,6 @@ Pel hate jêbirin Betal bike Çareseriya çêtirîn - Gava ku sepanê ji nû ve dest pê kir dê ziman biguhere. Ouldîrove nehat barkirin Ma hûn dixwazin mîhengan jî îthal bikin\? Ev ê sazkirina xweya heyî ji holê rabike. diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 283adc7f2..cfc328a20 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -418,7 +418,6 @@ %s명 청취중 - 앱이 다시 시작되면 언어가 변경됩니다 빠른-감기/되감기 찾는 시간 피어튜브 인스턴스 선호하는 PeerTube 인스턴스 선택 diff --git a/app/src/main/res/values-ku/strings.xml b/app/src/main/res/values-ku/strings.xml index 4b4c6f2c9..2f3934fff 100644 --- a/app/src/main/res/values-ku/strings.xml +++ b/app/src/main/res/values-ku/strings.xml @@ -398,7 +398,6 @@ فایلێک بەهەمان ناو هەیە فایلێکی دابەزێنراو بەم ناوەوە هەیە ناتوانرێ لەسەر ئەو فایلە جێگیربکرێ - زمان دەگۆڕدرێ لەدوای داخستن و پاشان کردنەوەی ئەپ. پەڕەی بنەڕەتی ماوەی خێرا بردنە پێشەوە\\ گێڕانەوە بۆ دواوە دۆخی پێرتووبی diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index 2ff3f1165..feb11a01c 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -494,7 +494,6 @@ Labiausiai patikę Nesenai pridėta Vietinė - Kalba pasikeis paleidus programą iš naujo Komentarų įkelti nepavyko Ar norite importuoti nustatymus\? Kol kas nėra grojaraščio žymų diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml index 9372d3c3f..2d1c60256 100644 --- a/app/src/main/res/values-lv/strings.xml +++ b/app/src/main/res/values-lv/strings.xml @@ -272,7 +272,6 @@ Atrodiet instances, kas jums patīk ar %s Izvēlaties jūsu mīļākās PeerTube instances PeerTube serveri (instances) - Valoda nomainīsies, kad aplikāciju restartēs Neviena lietotne jūsu ierīcē nevar šo atvērt Nodaļas Jaunākie diff --git a/app/src/main/res/values-mk/strings.xml b/app/src/main/res/values-mk/strings.xml index ba41b730b..1d3183b10 100644 --- a/app/src/main/res/values-mk/strings.xml +++ b/app/src/main/res/values-mk/strings.xml @@ -685,7 +685,6 @@ %s нови стримови Ве молиме, проверете дали веќе има дискусија за проблем како овој. Создадените дупликати ни одземаат од времето, коешто можеме да го посветиме на поправање на проблемот. - Јазикот ќе се смени откако апликацијата ќе биде рестартирана Додај го во редослед следното Нема гледачи Готово diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml index e3ba6f488..39ce5e57f 100644 --- a/app/src/main/res/values-ml/strings.xml +++ b/app/src/main/res/values-ml/strings.xml @@ -81,7 +81,6 @@ പുതിയതും ചൂടേറിയതും മികച്ച 50 ട്രെൻഡിങ്ങ് - അപ്ലിക്കേഷൻ പുനരാരംഭിച്ചുകഴിഞ്ഞാൽ ഭാഷ മാറും കമെന്റുകൾ ലോഡുചെയ്യാനായില്ല ക്രമീകരണങ്ങളും ഇമ്പോർട്ടുചെയ്യാൻ നിങ്ങൾ ആഗ്രഹിക്കുന്നുണ്ടോ\? ഇത് നിങ്ങളുടെ നിലവിലെ സജ്ജീകരണത്തെ അസാധുവാക്കും. diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index a9ca6eaed..c2311585a 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -422,7 +422,6 @@ %s lytter %s lyttere - Språket vil endres etter at appen har startet på nytt Standard kiosk PeerTube-instanser Lokal diff --git a/app/src/main/res/values-ne/strings.xml b/app/src/main/res/values-ne/strings.xml index 679b10846..dd570b82e 100644 --- a/app/src/main/res/values-ne/strings.xml +++ b/app/src/main/res/values-ne/strings.xml @@ -416,7 +416,6 @@ %s श्रोता %s श्रोताहरु - भाषा परिवर्तन एप पून:सुरु हुदा लागु हुनेछ। पूर्वनिर्धारित किओस्क (Kiosk) छिटो-अगाडि /-पछाडी खोज्न अवधि PeerTube उदाहरणहरू diff --git a/app/src/main/res/values-nl-rBE/strings.xml b/app/src/main/res/values-nl-rBE/strings.xml index 733689524..a78b96585 100644 --- a/app/src/main/res/values-nl-rBE/strings.xml +++ b/app/src/main/res/values-nl-rBE/strings.xml @@ -486,7 +486,6 @@ Meest leuk gevonden Recent toegevoegd Lokaal - De taal zal veranderen zodra de app opnieuw is opgestart Geen afspeellijst bladwijzers Selecteer een afspeellijst Standaard kiosk diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index e3e49fc72..0c16a5c9b 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -420,7 +420,6 @@ %s luisteraar %s luisteraars - De taal zal veranderen zodra de app opnieuw is opgestart Standaard kiosk Duur voor-/achteruit spoelen PeerTube-instanties diff --git a/app/src/main/res/values-nqo/strings.xml b/app/src/main/res/values-nqo/strings.xml index d2ec63afa..016ce1ba2 100644 --- a/app/src/main/res/values-nqo/strings.xml +++ b/app/src/main/res/values-nqo/strings.xml @@ -408,7 +408,6 @@ ߖߊ߲߬ߕߏ߬ߒߘߐ: ߞߐߕߐ߮ ߟߎ߬ ߓߍ߯ ߕߍ߫ ߛߋ߫ ߟߊߛߣߍ߫ ߟߊ߫. ߕߏߟߏ߲߫ ߛߙߍߘߍ ߘߏ߫ ߛߎߥߊ߲ߘߌ߫ ߕߏߟߏ߲߫ ߛߙߍߘߍ߫ ߟߊߞߎ߲߬ߘߎ߬ߣߍ߲߬ ߕߍ߫ ߝߟߐ߫ - ߞߊ߲ ߘߌߣߊ߬ ߡߊߝߊ߬ߟߋ߲߬ ߣߌ߫ ߟߥߊߟߌߟߊ߲ ߣߊ߬ ߘߊ߫ ߘߐߟߥߌ߬ ߛߊ߲ߞߊߥߟߌ ߟߎ߬ ߞߊ߲߬ߞߎߡߊ ߟߎ߬ ߕߍ߫ ߛߋ߫ ߟߊ߫ ߖߛߐ߫ ߟߊ߫ ߘߌ߲߬ߞߌ߬ߙߊ߬ߡߊ diff --git a/app/src/main/res/values-or/strings.xml b/app/src/main/res/values-or/strings.xml index cae53566e..cf9ebdb97 100644 --- a/app/src/main/res/values-or/strings.xml +++ b/app/src/main/res/values-or/strings.xml @@ -62,7 +62,6 @@ ଇତିହାସ ବିଲୋପ ଦେଖନ୍ତୁ ପ୍ଲେକ୍ ପୋଜିସନ୍ ଡିଲିଟ୍ ହୋଇଛି ସନ୍ଧାନ ଇତିହାସ ବିଲୋପ ହେଲା - ଆପ୍ ପୁନଃଆରମ୍ଭ ହେବା ପରେ ଭାଷା ପରିବର୍ତ୍ତନ ହେବ ପ୍ଲେଲିଷ୍ଟ ଥମ୍ବନେଲ ଭାବରେ ସେଟ୍ କରନ୍ତୁ ଫାଇଲ୍ କୁ ନବଲିଖନ କରିପାରିବ ନାହିଁ ଫାଇଲ୍ ସୃଷ୍ଟି ହୋଇପାରିବ ନାହିଁ diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml index 56cbd6ead..ad14e7d05 100644 --- a/app/src/main/res/values-pa/strings.xml +++ b/app/src/main/res/values-pa/strings.xml @@ -540,7 +540,6 @@ ਵਧੇਰੇ ਪਸੰਦ ਕੀਤੇ ਗਏ ਹਾਲ ਹੀ ਵਿੱਚ ਸ਼ਾਮਿਲ ਸਥਾਨਕ - ਭਾਸ਼ਾ ਐਪ ਨੂੰ ਦੋਬਾਰਾ ਚਲਾਉਣ \'ਤੇ ਬਦਲੇਗੀ ਪਲੇਲਿਸਟ ਚੁਣੋ ਹੋ ਗਿਆ ਹੱਲ ਕਰੋ diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 1a426b8dd..dc3f88cec 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -432,7 +432,6 @@ %s słuchaczy %s słuchaczy - Język zmieni się po ponownym uruchomieniu aplikacji Wielkość skoku przy przewijaniu Serwery PeerTube Wybierz swoje ulubione serwery PeerTube diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 5988038e5..d13cbcfe3 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -428,7 +428,6 @@ %s ouvintes %s ouvintes - O idioma será alterado após reiniciar o aplicativo Duração de avanço/retrocesso rápido Instâncias PeerTube Selecione suas instâncias favoritas do PeerTube diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index 36d3c5e42..6ceec006e 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -527,7 +527,6 @@ Modificar escala de legendas e estilo de fundo. Tem que reiniciar a aplicação para aplicar as alterações Ação recusada pelo sistema Músicas - O idioma será alterado assim que reiniciar a app Adicionar instância Faixas Reproduzir no Kodi diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index b1a27b772..13a536895 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -428,7 +428,6 @@ %s ouvintes %s ouvintes - O idioma será alterado assim que reiniciar a aplicação Duração de avanço/recuo rápido Instâncias PeerTube Defina as suas instâncias PeerTube preferidas diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 42f464d96..eb4e75c28 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -559,7 +559,6 @@ Cele mai apreciate Adăugate recent Local - Limba se va schimba odată ce aplicația este repornită Nu există încă marcaje în playlist Selectați un playlist Chioșc implicit diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index d7fbdeb09..a512b6fa8 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -434,7 +434,6 @@ %s слушателя %s слушателей - Язык будет изменён после перезапуска Шаг перемотки Серверы PeerTube Выберите предпочтительные серверы diff --git a/app/src/main/res/values-ryu/strings.xml b/app/src/main/res/values-ryu/strings.xml index 0396245e1..1bc89420c 100644 --- a/app/src/main/res/values-ryu/strings.xml +++ b/app/src/main/res/values-ryu/strings.xml @@ -423,7 +423,6 @@ %sんかいんがちょうしゅちゅう %sんかいんがちょうしゅちゅう - アプリさいきちゃーしーねー、ぎんぐがへいるかんさりやびーん こうすくはやうくい/まきむどぅしかんかく PeerTubeインスタンス PeerTubeインスタンスさんたくすん diff --git a/app/src/main/res/values-sat/strings.xml b/app/src/main/res/values-sat/strings.xml index 8b44cd5e0..a3ed7c405 100644 --- a/app/src/main/res/values-sat/strings.xml +++ b/app/src/main/res/values-sat/strings.xml @@ -520,7 +520,6 @@ ᱢᱤᱫ ᱯᱷᱟᱤᱞᱤᱥᱴ ᱵᱟᱪᱷᱟᱣ ᱢᱮ ᱤᱢᱯᱳᱨᱴ ᱱᱤᱛ ᱦᱟᱹᱵᱤᱡ playlist bookmarks ᱵᱟᱹᱱᱩᱜᱼᱟ - ᱮᱯ ᱮᱦᱚᱵ ᱞᱮᱠᱷᱟᱱ ᱯᱟᱹᱨᱥᱤ ᱵᱚᱫᱚᱞᱚᱜ-ᱟ ᱮᱥᱯᱟᱨᱴ ᱟᱠᱟᱱᱟ ᱴᱨᱮᱱᱰᱤᱝ ᱚᱰᱤᱭᱳ ᱥᱮᱴᱤᱝ diff --git a/app/src/main/res/values-sc/strings.xml b/app/src/main/res/values-sc/strings.xml index 549e8f88b..0c42f1ef0 100644 --- a/app/src/main/res/values-sc/strings.xml +++ b/app/src/main/res/values-sc/strings.xml @@ -66,7 +66,6 @@ Noos e Populares Sos mègius 50 Tendèntzias - Sa limba at a mudare a pustis chi as a torrare a allùghere s\'aplicatzione Carrigamentu de sos cummentos fallidu Cheres fintzas importare sas impostatziones\? Custu at a subraiscrìere sas impostatziones tuas de como. diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 1e7337311..ad2dacfd6 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -428,7 +428,6 @@ %s poslucháči %s poslucháčov - Zmena jazyka sa prejaví po reštarte aplikácie Dĺžka rýchleho pretáčania Inštancie PeerTube Vyberte si svoje obľúbené inštancie PeerTube diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index b0fcec406..cd41b43ba 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -253,7 +253,6 @@ Najbolj všečkan Dodano nedolgo nazaj Lokalno - Jezik bo spremenjen ob ponovnem zagonu aplikacije Ni mogoče naložiti komentarjev Ni veljavne ZIP datoteke Uvoženo diff --git a/app/src/main/res/values-so/strings.xml b/app/src/main/res/values-so/strings.xml index 0b0b3d06e..6b4de7353 100644 --- a/app/src/main/res/values-so/strings.xml +++ b/app/src/main/res/values-so/strings.xml @@ -139,7 +139,6 @@ Shiddan Cusub oo Shiddan 50ka Sare - Luuqadu waxay isbaddali doontaa marka appka dib loo soo kiciyo Faallooyinka lama soo kicin karo Inaad sidoo kale fadhiga soo galiso ma rabtaa\? Tani waxay baddali fadhiga siduu kuu yahay hadda. diff --git a/app/src/main/res/values-sq/strings.xml b/app/src/main/res/values-sq/strings.xml index 873234e23..162ba5ada 100644 --- a/app/src/main/res/values-sq/strings.xml +++ b/app/src/main/res/values-sq/strings.xml @@ -207,7 +207,6 @@ Të rejat dhe të nxehtat Top 50 E trendit - Gjuha do të ndryshojë sapo aplikacioni të riniset Nuk mundën të ngarkohen komentet A dëshironi që të importoni dhe aranzhimet gjithashtu\? Kjo do të mbishkruajë strukturimin tuaj të tanishëm. diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index 99542e72c..99b9e971f 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -368,7 +368,6 @@ Највише свиђања Недавно додато Локално - Језик ће бити промењен након рестартовања апликације Није могуће учитати коментаре Желите ли да увезете и подешавања\? Ово ће заменити ваше тренутно подешавање. diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 2eff9567c..3beab4181 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -436,7 +436,6 @@ Lokala Klar Slå på YouTubes \"Begränsat läge\" - Språket ändras när appen startas om Det gick inte att läsa in kommentarerna Inaktivera snabbläge Aktivera snabbläge diff --git a/app/src/main/res/values-ta/strings.xml b/app/src/main/res/values-ta/strings.xml index 71771ddae..906249376 100644 --- a/app/src/main/res/values-ta/strings.xml +++ b/app/src/main/res/values-ta/strings.xml @@ -616,7 +616,6 @@ செல்லுபடியாகும் சிப் கோப்பு இல்லை இது உங்கள் தற்போதைய அமைப்பை மேலெழுதும். கருத்துகளை ஏற்ற முடியவில்லை - பயன்பாடு மறுதொடக்கம் செய்யப்பட்டவுடன் மொழி மாறும் அண்மைக் காலத்தில் சேர்க்கப்பட்டது மிகவும் பிடித்தது மாநாடுகள் diff --git a/app/src/main/res/values-te/strings.xml b/app/src/main/res/values-te/strings.xml index 57802f5a1..c537495ba 100644 --- a/app/src/main/res/values-te/strings.xml +++ b/app/src/main/res/values-te/strings.xml @@ -363,7 +363,6 @@ reCAPTCHA సవాలు అభ్యర్థించబడింది ప్లేజాబితాను ఎంచుకోండి డాటాబేసుని ఎగుమతిచేయుము - యాప్ పునఃప్రారంభించబడిన తర్వాత భాష మారుతుంది ఛానెల్ వివరాలను చూపు కంటెంట్‌ని తెరిచేటప్పుడు డిఫాల్ట్ చర్య — %s ప్రాధాన్య \'తెరవండి\' చర్య diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 66a393f6d..a26016f1a 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -422,7 +422,6 @@ %s dinleyici %s dinleyici - Uygulama yeniden başlatıldıktan sonra dil değişecektir Hızlı ileri/geri atlama süresi PeerTube örnekleri Favori PeerTube örneklerinizi seçin diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 5c4034f4b..32e03bea0 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -428,7 +428,6 @@ %s слухача %s слухачів - Мова зміниться після перезапуску застосунку Швидке перемотування Екземпляри PeerTube Виберіть сервер PeerTube diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml index 99839de69..1a434ab63 100644 --- a/app/src/main/res/values-ur/strings.xml +++ b/app/src/main/res/values-ur/strings.xml @@ -417,7 +417,6 @@ %s سننے والا %s سننے والے - جب ایپ دوبارہ شروع ہو گی تو زبان تبدیل ہو جائے گی طے شدہ کیوسک آگے بھگانے /- پیچھے کرنے کی مدت پیر ٹیوب واقعات diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 22bc03c2c..e1073e7af 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -441,7 +441,6 @@ Tắt tiếng Được yêu thích nhất Đã thêm gần đây - Ngôn ngữ sẽ thay đổi khi ứng dụng khởi động lại Bấm \"Xong\" khi hoàn thành Đã hoàn thành ∞ video diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 013669e80..3c9c79457 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -418,7 +418,6 @@ %s 位听众 - 语言更改将在重启应用后生效 PeerTube 服务器 设置自定义 PeerTube 服务器 查找你需要的服务器 %s diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index c804c53c0..6b5529992 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -326,7 +326,6 @@ 頭版要擺放邊啲分頁 打橫掃走啲項目去剷走佢 空白頁 - 重新開過個 app 之後就會轉新語言 時興 頭 50 位 最新同大熱 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index b1443f17f..b9ca2d3ce 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -418,7 +418,6 @@ %s 位聽眾 - 語言將會在重新啟動應用程式後變更 快轉/快退搜尋持續時間 PeerTube 站臺 選取您最愛的 PeerTube 站臺 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5887c65e4..6ab2fc7a5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -413,7 +413,6 @@ This will override your current setup. Do you want to also import settings? Could not load comments - The language will change once the app is restarted Select a feed group No feed group created yet From a4bd82be8a3efc98dea2fe9e7c3913a9ca888db7 Mon Sep 17 00:00:00 2001 From: Kouki Badr <36043466+koukibadr@users.noreply.github.com> Date: Tue, 22 Jul 2025 04:28:56 +0100 Subject: [PATCH 123/143] fix: handle nullable nextPage behavior when searching albums #12401 (#12408) * fix: handle nullable nextPage behavior when searching albums #12401 * feat: add nullable annotation to newPage attribute in SearchFragment * Updated more usages of InfoItemsPage#getNextPage. Nullability is already handled in these areas so no other changes needed --------- Co-authored-by: Siddhesh Naik --- .../schabi/newpipe/fragments/list/BaseListInfoFragment.java | 2 ++ .../schabi/newpipe/fragments/list/search/SearchFragment.java | 3 ++- .../schabi/newpipe/player/playqueue/AbstractInfoPlayQueue.java | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java index 61a361f23..7f594734a 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java @@ -8,6 +8,7 @@ import android.util.Log; import android.view.View; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import com.evernote.android.state.State; @@ -42,6 +43,7 @@ public abstract class BaseListInfoFragment menuItemToFilterName = new SparseArrayCompat<>(); private StreamingService service; + @Nullable private Page nextPage; private boolean showLocalSuggestions = true; private boolean showRemoteSuggestions = true; @@ -1090,7 +1091,7 @@ public class SearchFragment extends BaseListFragment> final int serviceId; final String baseUrl; + @Nullable Page nextPage; private transient Disposable fetchReactor; From 30e33d59e885195bbc67530c937371cfca41bef0 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Tue, 22 Jul 2025 16:03:37 +0200 Subject: [PATCH 124/143] Use correct fix for nextPage being null while creating error report in SearchFragment.handleNextItems() --- .../newpipe/fragments/list/search/SearchFragment.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java index fc95312ea..6916ca826 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java @@ -1089,8 +1089,9 @@ public class SearchFragment extends BaseListFragment result) { showListFooter(false); infoListAdapter.addInfoItemList(result.getItems()); - nextPage = result.getNextPage(); + // nextPage should not be null here because it refers to the page + // which results are handled here, but we check it anyway if (!result.getErrors().isEmpty() && nextPage != null) { showSnackBarError(new ErrorInfo(result.getErrors(), UserAction.SEARCHED, "\"" + searchString + "\" → pageUrl: " + nextPage.getUrl() + ", " @@ -1098,6 +1099,10 @@ public class SearchFragment extends BaseListFragment Date: Thu, 17 Jul 2025 10:32:31 +0200 Subject: [PATCH 125/143] Release v0.28.0 (1005) --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index a629f65eb..54bd86a72 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -23,9 +23,9 @@ android { if (System.properties.containsKey('versionCodeOverride')) { versionCode System.getProperty('versionCodeOverride') as Integer } else { - versionCode 1004 + versionCode 1005 } - versionName "0.27.7" + versionName "0.28.0" if (System.properties.containsKey('versionNameSuffix')) { versionNameSuffix System.getProperty('versionNameSuffix') } From a9ce2e960561ca0687ebf54d21a1c904a8ed3bca Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sun, 27 Jul 2025 09:39:53 +0200 Subject: [PATCH 126/143] Update USER_AGENT to Firefox 140 ESR --- app/src/main/java/org/schabi/newpipe/DownloaderImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/DownloaderImpl.java b/app/src/main/java/org/schabi/newpipe/DownloaderImpl.java index 5159fbfdc..6ccc2437a 100644 --- a/app/src/main/java/org/schabi/newpipe/DownloaderImpl.java +++ b/app/src/main/java/org/schabi/newpipe/DownloaderImpl.java @@ -29,7 +29,7 @@ import okhttp3.ResponseBody; public final class DownloaderImpl extends Downloader { public static final String USER_AGENT = - "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0"; + "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:140.0) Gecko/20100101 Firefox/140.0"; public static final String YOUTUBE_RESTRICTED_MODE_COOKIE_KEY = "youtube_restricted_mode_key"; public static final String YOUTUBE_RESTRICTED_MODE_COOKIE = "PREF=f2=8000000"; From 9ba30887f9f58f8cd545996a14e0117b815b68fc Mon Sep 17 00:00:00 2001 From: Stypox Date: Mon, 28 Jul 2025 14:43:46 +0200 Subject: [PATCH 127/143] Improve null checking further in SearchFragment.handleNextItems --- .../fragments/list/search/SearchFragment.java | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java index 6916ca826..cea06b942 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java @@ -1090,14 +1090,19 @@ public class SearchFragment extends BaseListFragment Date: Sat, 26 Jul 2025 15:43:36 +0200 Subject: [PATCH 128/143] Use regions --- .../newpipe/player/helper/PlayerHelper.java | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java index a110a80d6..791346d66 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java @@ -89,9 +89,7 @@ public final class PlayerHelper { private PlayerHelper() { } - //////////////////////////////////////////////////////////////////////////// - // Exposed helpers - //////////////////////////////////////////////////////////////////////////// + // region Exposed helpers @NonNull public static String getTimeString(final int milliSeconds) { @@ -219,9 +217,8 @@ public final class PlayerHelper { ? null : getAutoQueuedSinglePlayQueue(autoQueueItems.get(0)); } - //////////////////////////////////////////////////////////////////////////// - // Settings Resolution - //////////////////////////////////////////////////////////////////////////// + // endregion + // region Resolution public static boolean isResumeAfterAudioFocusGain(@NonNull final Context context) { return getPreferences(context) @@ -405,9 +402,8 @@ public final class PlayerHelper { return Integer.parseInt(preferredIntervalBytes) * 1024; } - //////////////////////////////////////////////////////////////////////////// - // Private helpers - //////////////////////////////////////////////////////////////////////////// + // endregion + // region Private helpers @NonNull private static SharedPreferences getPreferences(@NonNull final Context context) { @@ -427,9 +423,8 @@ public final class PlayerHelper { } - //////////////////////////////////////////////////////////////////////////// - // Utils used by player - //////////////////////////////////////////////////////////////////////////// + // endregion + // region Utils used by player @RepeatMode public static int nextRepeatMode(@RepeatMode final int repeatMode) { @@ -503,4 +498,6 @@ public final class PlayerHelper { player.getContext().getString(R.string.seek_duration_key), player.getContext().getString(R.string.seek_duration_default_value)))); } + + // endregion } From 70841db92ff1d8208acdd687973c40c9a76b01d6 Mon Sep 17 00:00:00 2001 From: litetex <40789489+litetex@users.noreply.github.com> Date: Sat, 26 Jul 2025 15:43:46 +0200 Subject: [PATCH 129/143] Cleanup ``Localization`` formatting --- .../main/java/org/schabi/newpipe/util/Localization.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/util/Localization.java b/app/src/main/java/org/schabi/newpipe/util/Localization.java index 2bd4664ae..bd5463088 100644 --- a/app/src/main/java/org/schabi/newpipe/util/Localization.java +++ b/app/src/main/java/org/schabi/newpipe/util/Localization.java @@ -127,14 +127,13 @@ public final class Localization { } public static String localizeNumber(final double number) { - final NumberFormat nf = NumberFormat.getInstance(getAppLocale()); - return nf.format(number); + return NumberFormat.getInstance(getAppLocale()).format(number); } public static String formatDate(@NonNull final OffsetDateTime offsetDateTime) { return DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM) - .withLocale(getAppLocale()).format(offsetDateTime - .atZoneSameInstant(ZoneId.systemDefault())); + .withLocale(getAppLocale()) + .format(offsetDateTime.atZoneSameInstant(ZoneId.systemDefault())); } @SuppressLint("StringFormatInvalid") From ebd5e1a3180671ec0c5b2e3b72a67dbf28d8e543 Mon Sep 17 00:00:00 2001 From: litetex <40789489+litetex@users.noreply.github.com> Date: Sat, 26 Jul 2025 16:01:25 +0200 Subject: [PATCH 130/143] Remove unused method --- .../schabi/newpipe/player/helper/PlayerHelper.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java index 791346d66..d3e10da5d 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java @@ -117,18 +117,6 @@ public final class PlayerHelper { return PITCH_FORMATTER.format(pitch); } - @NonNull - public static String subtitleMimeTypesOf(@NonNull final MediaFormat format) { - switch (format) { - case VTT: - return MimeTypes.TEXT_VTT; - case TTML: - return MimeTypes.APPLICATION_TTML; - default: - throw new IllegalArgumentException("Unrecognized mime type: " + format.name()); - } - } - @NonNull public static String captionLanguageOf(@NonNull final Context context, @NonNull final SubtitlesStream subtitles) { From 893a1cb699f2e74af85ab70a57da82111b7b64b8 Mon Sep 17 00:00:00 2001 From: litetex <40789489+litetex@users.noreply.github.com> Date: Sat, 26 Jul 2025 16:06:44 +0200 Subject: [PATCH 131/143] Encapsulate Formatters in PlayerHelper and reset them when the language is changed/changing. This way they will be re-initialized on the next call. Also Remove a bunch of outdated/non-thread safe code (STRING_FORMATTER) --- .../newpipe/player/helper/PlayerHelper.java | 71 ++++++++++++++----- .../settings/ContentSettingsFragment.java | 3 + 2 files changed, 57 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java index d3e10da5d..266d65f36 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java @@ -33,11 +33,9 @@ import com.google.android.exoplayer2.trackselection.ExoTrackSelection; import com.google.android.exoplayer2.ui.AspectRatioFrameLayout; import com.google.android.exoplayer2.ui.AspectRatioFrameLayout.ResizeMode; import com.google.android.exoplayer2.ui.CaptionStyleCompat; -import com.google.android.exoplayer2.util.MimeTypes; import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.InfoItem; -import org.schabi.newpipe.extractor.MediaFormat; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.extractor.stream.SubtitlesStream; @@ -47,13 +45,14 @@ import org.schabi.newpipe.player.playqueue.PlayQueue; import org.schabi.newpipe.player.playqueue.PlayQueueItem; import org.schabi.newpipe.player.playqueue.SinglePlayQueue; import org.schabi.newpipe.util.ListHelper; +import org.schabi.newpipe.util.Localization; import java.lang.annotation.Retention; import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; import java.text.NumberFormat; import java.util.ArrayList; import java.util.Collections; -import java.util.Formatter; import java.util.HashSet; import java.util.List; import java.util.Locale; @@ -62,11 +61,7 @@ import java.util.Set; import java.util.concurrent.TimeUnit; public final class PlayerHelper { - private static final StringBuilder STRING_BUILDER = new StringBuilder(); - private static final Formatter STRING_FORMATTER = - new Formatter(STRING_BUILDER, Locale.getDefault()); - private static final NumberFormat SPEED_FORMATTER = new DecimalFormat("0.##x"); - private static final NumberFormat PITCH_FORMATTER = new DecimalFormat("##%"); + private static final FormattersProvider FORMATTERS_PROVIDER = new FormattersProvider(); @Retention(SOURCE) @IntDef({AUTOPLAY_TYPE_ALWAYS, AUTOPLAY_TYPE_WIFI, @@ -91,6 +86,10 @@ public final class PlayerHelper { // region Exposed helpers + public static void resetFormat() { + FORMATTERS_PROVIDER.reset(); + } + @NonNull public static String getTimeString(final int milliSeconds) { final int seconds = (milliSeconds % 60000) / 1000; @@ -98,23 +97,24 @@ public final class PlayerHelper { final int hours = (milliSeconds % 86400000) / 3600000; final int days = (milliSeconds % (86400000 * 7)) / 86400000; - STRING_BUILDER.setLength(0); - return (days > 0 - ? STRING_FORMATTER.format("%d:%02d:%02d:%02d", days, hours, minutes, seconds) - : hours > 0 - ? STRING_FORMATTER.format("%d:%02d:%02d", hours, minutes, seconds) - : STRING_FORMATTER.format("%02d:%02d", minutes, seconds) - ).toString(); + final Formatters formatters = FORMATTERS_PROVIDER.formatters(); + if (days > 0) { + return formatters.stringFormat("%d:%02d:%02d:%02d", days, hours, minutes, seconds); + } + + return hours > 0 + ? formatters.stringFormat("%d:%02d:%02d", hours, minutes, seconds) + : formatters.stringFormat("%02d:%02d", minutes, seconds); } @NonNull public static String formatSpeed(final double speed) { - return SPEED_FORMATTER.format(speed); + return FORMATTERS_PROVIDER.formatters().speed().format(speed); } @NonNull public static String formatPitch(final double pitch) { - return PITCH_FORMATTER.format(pitch); + return FORMATTERS_PROVIDER.formatters().pitch().format(pitch); } @NonNull @@ -487,5 +487,42 @@ public final class PlayerHelper { player.getContext().getString(R.string.seek_duration_default_value)))); } + // endregion + // region Format + + static class FormattersProvider { + private Formatters formatters; + + public Formatters formatters() { + if (formatters == null) { + formatters = Formatters.create(); + } + return formatters; + } + + public void reset() { + formatters = null; + } + } + + record Formatters( + Locale locale, + NumberFormat speed, + NumberFormat pitch) { + + static Formatters create() { + final Locale locale = Localization.getAppLocale(); + final DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(locale); + return new Formatters( + locale, + new DecimalFormat("0.##x", dfs), + new DecimalFormat("##%", dfs)); + } + + String stringFormat(final String format, final Object... args) { + return String.format(locale, format, args); + } + } + // endregion } diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java index ffc80e30e..e1d0e7be3 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java @@ -16,6 +16,7 @@ import androidx.preference.Preference; import org.schabi.newpipe.DownloaderImpl; import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.NewPipe; +import org.schabi.newpipe.player.helper.PlayerHelper; import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.image.ImageStrategy; import org.schabi.newpipe.util.image.PicassoHelper; @@ -53,6 +54,7 @@ public class ContentSettingsFragment extends BasePreferenceFragment { final Intent intent = new Intent(Settings.ACTION_APP_LOCALE_SETTINGS) .setData(Uri.fromParts("package", requireContext().getPackageName(), null)); startActivity(intent); + PlayerHelper.resetFormat(); return true; }); newAppLanguagePref.setVisible(true); @@ -64,6 +66,7 @@ public class ContentSettingsFragment extends BasePreferenceFragment { final String systemLang = getString(R.string.default_localization_key); final String tag = systemLang.equals(language) ? null : language; AppCompatDelegate.setApplicationLocales(LocaleListCompat.forLanguageTags(tag)); + PlayerHelper.resetFormat(); return true; }); } From eea2b7417efa09d04b6c88aae9d76266d6852297 Mon Sep 17 00:00:00 2001 From: Stypox Date: Mon, 28 Jul 2025 15:29:06 +0200 Subject: [PATCH 132/143] Fix player formatters resetting too early on language change formatters() is called again by the player before the user has a chance to click on the language in the language chooser. So the correct solution would probably be to attach to https://developer.android.com/reference/android/content/Intent#ACTION_LOCALE_CHANGED, but let's keep it simple. I added `PlayerHelper.resetFormat();` in `ContentSettingsFragment.onDestroy()` and it works. It will mean the player formatters will be reset every time the user exits content settings, but whatever. --- .../org/schabi/newpipe/settings/ContentSettingsFragment.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java index e1d0e7be3..b855f7c38 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java @@ -54,7 +54,6 @@ public class ContentSettingsFragment extends BasePreferenceFragment { final Intent intent = new Intent(Settings.ACTION_APP_LOCALE_SETTINGS) .setData(Uri.fromParts("package", requireContext().getPackageName(), null)); startActivity(intent); - PlayerHelper.resetFormat(); return true; }); newAppLanguagePref.setVisible(true); @@ -66,7 +65,6 @@ public class ContentSettingsFragment extends BasePreferenceFragment { final String systemLang = getString(R.string.default_localization_key); final String tag = systemLang.equals(language) ? null : language; AppCompatDelegate.setApplicationLocales(LocaleListCompat.forLanguageTags(tag)); - PlayerHelper.resetFormat(); return true; }); } @@ -110,5 +108,6 @@ public class ContentSettingsFragment extends BasePreferenceFragment { NewPipe.setupLocalization( Localization.getPreferredLocalization(context), Localization.getPreferredContentCountry(context)); + PlayerHelper.resetFormat(); } } From 6516fb96fd345076d6a1ce21759b61323c96eb98 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Mon, 28 Jul 2025 20:39:59 +0200 Subject: [PATCH 133/143] Translated using Weblate (Romanian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (748 of 748 strings) Translated using Weblate (Arabic) Currently translated at 100.0% (86 of 86 strings) Translated using Weblate (Russian) Currently translated at 100.0% (86 of 86 strings) Translated using Weblate (Arabic) Currently translated at 100.0% (748 of 748 strings) Translated using Weblate (Arabic) Currently translated at 100.0% (748 of 748 strings) Translated using Weblate (Russian) Currently translated at 100.0% (748 of 748 strings) Translated using Weblate (Turkish) Currently translated at 100.0% (748 of 748 strings) Translated using Weblate (Indonesian) Currently translated at 100.0% (748 of 748 strings) Translated using Weblate (French) Currently translated at 100.0% (748 of 748 strings) Translated using Weblate (Icelandic) Currently translated at 99.4% (745 of 749 strings) Translated using Weblate (Estonian) Currently translated at 18.6% (16 of 86 strings) Translated using Weblate (Slovak) Currently translated at 100.0% (86 of 86 strings) Translated using Weblate (Portuguese (Portugal)) Currently translated at 99.5% (746 of 749 strings) Translated using Weblate (Belarusian) Currently translated at 99.7% (747 of 749 strings) Translated using Weblate (Estonian) Currently translated at 100.0% (749 of 749 strings) Translated using Weblate (Bulgarian) Currently translated at 100.0% (749 of 749 strings) Translated using Weblate (Hebrew) Currently translated at 99.7% (747 of 749 strings) Translated using Weblate (Chinese (Traditional Han script)) Currently translated at 100.0% (749 of 749 strings) Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (749 of 749 strings) Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (749 of 749 strings) Translated using Weblate (Polish) Currently translated at 100.0% (749 of 749 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (749 of 749 strings) Translated using Weblate (Czech) Currently translated at 100.0% (749 of 749 strings) Translated using Weblate (Slovak) Currently translated at 99.7% (747 of 749 strings) Translated using Weblate (Greek) Currently translated at 100.0% (749 of 749 strings) Translated using Weblate (Portuguese) Currently translated at 99.5% (746 of 749 strings) Translated using Weblate (Italian) Currently translated at 100.0% (749 of 749 strings) Translated using Weblate (Hungarian) Currently translated at 100.0% (749 of 749 strings) Translated using Weblate (German) Currently translated at 100.0% (749 of 749 strings) Translated using Weblate (German) Currently translated at 100.0% (749 of 749 strings) Translated using Weblate (Tamazight (Central Atlas)) Currently translated at 19.2% (144 of 749 strings) Translated using Weblate (Macedonian) Currently translated at 79.3% (594 of 749 strings) Translated using Weblate (Slovenian) Currently translated at 54.6% (409 of 749 strings) Translated using Weblate (Tigrinya) Currently translated at 12.7% (95 of 747 strings) Translated using Weblate (Tigrinya) Currently translated at 3.4% (3 of 86 strings) Translated using Weblate (Icelandic) Currently translated at 99.4% (743 of 747 strings) Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 90.6% (78 of 86 strings) Translated using Weblate (Slovak) Currently translated at 100.0% (86 of 86 strings) Translated using Weblate (French) Currently translated at 100.0% (86 of 86 strings) Translated using Weblate (Italian) Currently translated at 100.0% (86 of 86 strings) Translated using Weblate (Italian) Currently translated at 100.0% (86 of 86 strings) Translated using Weblate (Polish) Currently translated at 58.1% (50 of 86 strings) Translated using Weblate (Hindi) Currently translated at 100.0% (86 of 86 strings) Translated using Weblate (Hungarian) Currently translated at 100.0% (86 of 86 strings) Translated using Weblate (Punjabi) Currently translated at 100.0% (86 of 86 strings) Translated using Weblate (Czech) Currently translated at 100.0% (86 of 86 strings) Translated using Weblate (Ukrainian) Currently translated at 100.0% (86 of 86 strings) Translated using Weblate (German) Currently translated at 100.0% (86 of 86 strings) Translated using Weblate (Belarusian) Currently translated at 100.0% (747 of 747 strings) Translated using Weblate (Punjabi) Currently translated at 100.0% (747 of 747 strings) Translated using Weblate (Hindi) Currently translated at 100.0% (747 of 747 strings) Translated using Weblate (Czech) Currently translated at 100.0% (747 of 747 strings) Translated using Weblate (Slovak) Currently translated at 100.0% (747 of 747 strings) Translated using Weblate (Slovak) Currently translated at 100.0% (747 of 747 strings) Translated using Weblate (German) Currently translated at 100.0% (747 of 747 strings) Co-authored-by: 439JBYL80IGQTF25UXNR0X1BG <439JBYL80IGQTF25UXNR0X1BG@users.noreply.hosted.weblate.org> Co-authored-by: Agnieszka C Co-authored-by: Drugi Sapog Co-authored-by: Dual Natan Co-authored-by: Emin Tufan Çetin Co-authored-by: Fjuro Co-authored-by: Ghost of Sparta Co-authored-by: Hakim Oubouali Co-authored-by: Hosted Weblate Co-authored-by: Igor Rückert Co-authored-by: Igor Sorocean Co-authored-by: Jeff Huang Co-authored-by: Marian Hanzel Co-authored-by: Matej U Co-authored-by: Michael Moroni Co-authored-by: Mickaël Binos Co-authored-by: Milan Co-authored-by: NTFSynergy Co-authored-by: Priit Jõerüüt Co-authored-by: Random Co-authored-by: Rex_sa Co-authored-by: Stypox Co-authored-by: Sveinn í Felli Co-authored-by: Trunars Co-authored-by: Vasilis K Co-authored-by: VfBFan Co-authored-by: Yaron Shahrabani Co-authored-by: Yassin Amir Co-authored-by: erti Co-authored-by: ikanakova Co-authored-by: nautilusx Co-authored-by: ssantos Co-authored-by: whistlingwoods <72640314+whistlingwoods@users.noreply.github.com> Co-authored-by: zmni Co-authored-by: Максим Горпиніч Co-authored-by: 大王叫我来巡山 Co-authored-by: 赖诚俊 Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ar/ 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/et/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/fr/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/hi/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/hu/ 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/pl/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ru/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/sk/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/ti/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/uk/ Translate-URL: https://hosted.weblate.org/projects/newpipe/metadata/zh_Hans/ Translation: NewPipe/Metadata --- app/src/main/res/values-ar/strings.xml | 5 ++ app/src/main/res/values-be/strings.xml | 71 ++++++++++--------- app/src/main/res/values-bg/strings.xml | 4 +- app/src/main/res/values-cs/strings.xml | 22 +++--- app/src/main/res/values-de/strings.xml | 5 ++ app/src/main/res/values-el/strings.xml | 5 ++ app/src/main/res/values-et/strings.xml | 4 +- app/src/main/res/values-fr/strings.xml | 4 +- app/src/main/res/values-he/strings.xml | 6 +- app/src/main/res/values-hi/strings.xml | 8 +++ app/src/main/res/values-hu/strings.xml | 2 + app/src/main/res/values-in/strings.xml | 9 ++- app/src/main/res/values-is/strings.xml | 8 +++ app/src/main/res/values-it/strings.xml | 2 + app/src/main/res/values-mk/strings.xml | 2 +- app/src/main/res/values-pa/strings.xml | 10 ++- app/src/main/res/values-pl/strings.xml | 2 + app/src/main/res/values-pt-rBR/strings.xml | 5 ++ app/src/main/res/values-pt-rPT/strings.xml | 2 + app/src/main/res/values-pt/strings.xml | 2 + app/src/main/res/values-ro/strings.xml | 11 ++- app/src/main/res/values-ru/strings.xml | 5 ++ app/src/main/res/values-sk/strings.xml | 53 +++++++------- app/src/main/res/values-sl/strings.xml | 2 +- app/src/main/res/values-ti/strings.xml | 12 ++-- app/src/main/res/values-tr/strings.xml | 10 ++- app/src/main/res/values-tzm/strings.xml | 2 +- app/src/main/res/values-uk/strings.xml | 8 ++- app/src/main/res/values-zh-rCN/strings.xml | 6 +- app/src/main/res/values-zh-rTW/strings.xml | 4 ++ .../metadata/android/ar/changelogs/1005.txt | 17 +++++ .../metadata/android/cs/changelogs/1005.txt | 17 +++++ .../metadata/android/de/changelogs/1005.txt | 17 +++++ .../metadata/android/et/changelogs/1005.txt | 17 +++++ .../metadata/android/fr/changelogs/1005.txt | 17 +++++ .../metadata/android/hi/changelogs/1005.txt | 17 +++++ .../metadata/android/hu/changelogs/1005.txt | 17 +++++ .../metadata/android/it/changelogs/1005.txt | 17 +++++ .../metadata/android/pa/changelogs/1005.txt | 17 +++++ .../metadata/android/pl/changelogs/1005.txt | 17 +++++ .../metadata/android/ru/changelogs/1005.txt | 17 +++++ .../metadata/android/sk/changelogs/1000.txt | 20 +++--- .../metadata/android/sk/changelogs/1005.txt | 18 +++++ .../metadata/android/sk/full_description.txt | 2 +- .../metadata/android/ti/full_description.txt | 2 +- .../metadata/android/ti/short_description.txt | 2 +- .../metadata/android/uk/changelogs/1002.txt | 5 +- .../metadata/android/uk/changelogs/1003.txt | 7 +- .../metadata/android/uk/changelogs/1004.txt | 4 +- .../metadata/android/uk/changelogs/1005.txt | 17 +++++ .../android/zh-Hans/changelogs/1001.txt | 6 ++ 51 files changed, 448 insertions(+), 113 deletions(-) create mode 100644 fastlane/metadata/android/ar/changelogs/1005.txt create mode 100644 fastlane/metadata/android/cs/changelogs/1005.txt create mode 100644 fastlane/metadata/android/de/changelogs/1005.txt create mode 100644 fastlane/metadata/android/et/changelogs/1005.txt create mode 100644 fastlane/metadata/android/fr/changelogs/1005.txt create mode 100644 fastlane/metadata/android/hi/changelogs/1005.txt create mode 100644 fastlane/metadata/android/hu/changelogs/1005.txt create mode 100644 fastlane/metadata/android/it/changelogs/1005.txt create mode 100644 fastlane/metadata/android/pa/changelogs/1005.txt create mode 100644 fastlane/metadata/android/pl/changelogs/1005.txt create mode 100644 fastlane/metadata/android/ru/changelogs/1005.txt create mode 100644 fastlane/metadata/android/sk/changelogs/1005.txt create mode 100644 fastlane/metadata/android/uk/changelogs/1005.txt create mode 100644 fastlane/metadata/android/zh-Hans/changelogs/1001.txt diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index fff1dd3a9..7e002d88a 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -885,4 +885,9 @@ صفحة مجموعة القناة حدد مجموعة المحتوى لم تنشئ مجموعة محتوى + الإعجابات + البحث %1$s + البحث %1$s (%2$s) + تمت إزالة صفحة أفضل 50 من SoundCloud + أوقفت SoundCloud صفحة أفضل 50 الأصلية. تمت إزالة علامة التبويب المقابلة من صفحتك الرئيسية. diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index 22f963def..9f40ae48f 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -55,7 +55,7 @@ Памятаць апошнія памер і пазіцыю ўсплывальнага акна Хуткі пошук пазіцыі Недакладны пошук дазваляе плэеру знаходзіць пазіцыі хутчэй са зніжанай дакладнасцю. Пошук цягам 5, 15 ці 25 секунд пры гэтым немажлівы - Кэш малюнкаў ачышчаны + Кэш відарысаў ачышчаны Ачысціць кэш метаданых Выдаліць усе даныя вэб-старонак у кэшы Кэш метаданых ачышчаны @@ -71,8 +71,8 @@ Працягваць прайграванне пасля перапынкаў (напрыклад, тэлефонных званкоў) Спампаваць «Наступнае» і «Прапанаванае» відэа - Паказваць падказку «Зацісніце, каб дадаць» - Паказваць падказку пры націсканні «У акне» або «У фоне» на старонцы звестак аб відэа + Паказваць падказку «Утрымлівайце, каб дадаць у чаргу» + Паказваць падказку пры націсканні кнопкі «У акне» або «У фоне» на старонцы відэа URL не падтрымліваецца Прадвызначаная краіна кантэнту Прадвызначаная мова кантэнту @@ -137,7 +137,7 @@ Такой папкі не існуе Такога файла або крыніцы кантэнту не існуе Файл не існуе або няма дазволу на яго чытанне ці запіс - Імя файла не можа быць пустым + Назва файла не можа быць пустой Адбылася памылка: %1$s Няма трансляцый, даступных для спампоўвання Прабачце, гэта не павінна было адбыцца. @@ -154,7 +154,7 @@ Спадабалася Не спадабалася Няма вынікаў - Нічога няма, акрамя цвыркуноў + Нічога няма, хоць сабак ганяй Перацягніце, каб змяніць парадак Відэа Аўдыя @@ -191,7 +191,7 @@ Адхіліць Перайменаваць ОК - Імя файла + Назва файла Патокі Памылка NewPipe спампоўвае @@ -204,7 +204,7 @@ Запыт reCAPTCHA Запытаны ўвод reCAPTCHA Спампоўванне - Дапушчальныя ў назвах файлаў сімвалы + Сімвалы, дапушчальныя ў назвах файлаў Недапушчальныя сімвалы замяняюцца на гэты Сімвал для замены Літары і лічбы @@ -253,7 +253,7 @@ Выдаліць Падрабязнасці Налады аўдыя - Зацісніце, каб дадаць у чаргу + Утрымлівайце, каб дадаць у чаргу Пачаць прайграванне ў фоне Пачаць прайграванне ў акне Адкрыць бакавую панэль @@ -268,7 +268,7 @@ Загрузка запытанага кантэнту Стварыць плэй-ліст Перайменаваць - Імя + Назва Дадаць у плэй-ліст Зрабіць мініяцюрай плэй-ліста Дадаць плэй-ліст у закладкі @@ -327,7 +327,7 @@ Апавяшчэнні пра новыя версіі NewPipe Знешняе сховішча недаступна Спампоўванне на знешнюю SD-карту немагчыма. Скінуць размяшчэнне папкі спампоўвання? - Памылка чытання захаваных укладак. Выкарыстоўваюцца ўкладкі па змаўчанні + Не ўдалося прачытаць захаваныя ўкладкі, таму выкарыстоўваюцца прадвызначаныя Аднавіць прадвызначаныя значэнні Аднавіць прадвызначаныя значэнні? Колькасць падпісчыкаў недаступна @@ -347,9 +347,9 @@ Дадаць у чаргу Дзеянне забаронена сістэмай Памылка спампоўвання - Стварыць унікальнае імя + Стварыць унікальную назву Перазапісаць - Файл з такім імем ужо спампоўваецца + Файл з такой назвай ўжо спампоўваецца Паказаць тэкст памылкі Немагчыма стварыць папку прызначэння Немагчыма стварыць файл @@ -376,14 +376,14 @@ Працягваць прайграванне Аднаўляць апошнюю пазіцыю Пазіцыі ў спісах - Адлюстроўваць індыкатары пазіцый прагляду ў спісах + Паказваць у спісах пазіцыю прайгравання Ачыстка даных Пазіцыі прайгравання выдалены Файл перамешчаны або выдалены - Файл з такім імем ужо існуе - Файл з такім імем ужо існуе + Файл з такой назвай ужо існуе + Спампаваны файл з такой назвай ужо існуе немагчыма перазапісаць файл - Файл з такім імем ужо дададзены ў чаргу спампоўвання + Файл з такой назвай ужо ў чарзе спампоўвання Праграма NewPipe была закрыта падчас працы з файлам На прыладзе скончылася вольнае месца Прагрэс страчаны, бо файл быў выдалены @@ -542,11 +542,11 @@ Апавяшчэнні пра ход відэахэшавання Стварыць паведамленне пра памылку Выберыце падпіскі - Імпарт ці экспарт падпісак з 3-кропкавага меню + Імпартуйце або экспартуйце падпіскі праз меню з трыма кропкамі ⁝ Забарона вылучэння тэксту ў апісанні Хуткі рэжым Калі ў вас узніклі праблемы з выкарыстаннем праграмы, абавязкова азнаёмцеся з адказамі на частыя пытанні! - Адключыць тунэляванне медыя + Адключыць тунэляванне мультымедыя Мініяцюра з перадпраглядам у паласе перамотвання Высокая якасць (больш) Не паказваць @@ -607,15 +607,15 @@ Дублікат дададзены %d раз(ы) LeakCanary недаступны Паказаць уцечкі памяці - Адключыце мультымедыйнае тунэляванне, калі ў вас з\'яўляецца чорны экран або заіканне падчас прайгравання відэа. + Адключыце тунэляванне мультымедыя, калі відэа прайграецца перарывіста або паказваецца чорны экран. Не ўдалося скапіяваць у буфер абмену Папка спампоўвання яшчэ не зададзена, выберыце папку спампоўвання цяпер Частыя пытанні Перайсці на вэб-сайт - Правядзіце пальцам па элементах, каб выдаліць іх + Каб выдаліць элемент, змахніце яго ўбок Прыбраць пастаянную мініяцюру - Паказваць індыкатары выяў - Паказваць каляровыя стужкі Пікаса на выявах, якія пазначаюць іх крыніцу: чырвоная для сеткі, сіняя для дыска і зялёная для памяці + Паказваць на відарысах указальнікі + Паказваць на відарысах каляровыя меткі Picasso, якія абазначаюць яго крыніцу: чырвоная — сетка, сіняя — дыск, зялёная — памяць Апрацоўка стужкі… Пры кожным спампоўванні вам будзе прапанавана выбраць месца захавання Загрузка канала… @@ -641,10 +641,10 @@ %d выбраных %d выбраных - Пустая назва групы - Выдаліць гэту групу? + Назва групы пустая + Выдаліць групу? Новая - Паказаць толькі разгрупаваныя падпіскі + Паказваць толькі не згрупаваныя падпіскі Запланаваныя Паказваць «Збой плэера» Запусціце праверку новых патокаў @@ -715,7 +715,7 @@ Даступна для некаторых сэрвісаў, звычайна значна хутчэй, але можа перадаваць абмежаваную колькасць элементаў і не ўсю інфармацыю (можа адсутнічаць працягласць, тып элемента, паказчык трансляцыі) Узроставае абмежаванне Для гэтага дзеяння не знойдзены прыдатны файлавы менеджар. \nУсталюйце файлавы менеджар, сумяшчальны з Storage Access Framework - Ніякая праграма на вашай прыладзе не можа адкрыць гэта + На прыладзе няма праграмы, каб адкрыць гэты файл Стандартнае значэнне ExoPlayer Прагледжаныя часткова Лічыце, што загрузка каналаў адбываецца занадта павольна? Калі так, паспрабуйце ўключыць хуткую загрузку (можна змяніць у наладах або націснуўшы кнопку ніжэй). \n \nNewPipe прапануе два спосабы загрузкі каналаў: \n• Атрыманне ўсяго канала падпіскі. Павольны, але інфармацыя поўная). \n• Выкарыстанне спецыяльнай канчатковай кропкі абслугоўвання. Хуткі, але звычайна інфармацыя няпоўная). \n \nРозніца паміж імі ў тым, што ў хуткім звычайна адсутнічае частка інфармацыі, напрыклад, працягласць або тып (немагчыма адрозніць трансляцыі ад звычайных відэа), і ён можа вяртаць менш элементаў. \n \nYouTube з\'яўляецца прыкладам сэрвісу, які прапануе гэты хуткі метад праз RSS-канал. \n \nТакім чынам, выбар залежыць ад таго, чаму вы аддаяце перавагу: хуткасці або дакладнасці інфармацыя. @@ -747,8 +747,8 @@ У гэтым патоку ўжо павінна быць гукавая дарожка Уключыце гэту опцыю, калі ў вас ёсць праблемы з ініцыялізацыяй дэкодэра, якая вяртаецца да дэкодэраў з больш нізкім прыярытэтам, калі ініцыялізацыя асноўных дэкодэраў не ўдаецца. Гэта можа прывесці да нізкай прадукцыйнасці прайгравання, чым пры выкарыстанні асноўных дэкодэраў Кіраванне некаторымі наладамі ExoPlayer. Каб гэтыя змены ўступілі ў сілу, патрабуецца перазапуск прайгравальніка - Гэты абыходны шлях вызваляе і паўторна стварае відэакодэкі, калі адбываецца змяненне паверхні, замест таго, каб зажаваць паверхню непасрэдна для кодэка. Ужо выкарыстоўваецца ExoPlayer на некаторых прыладах з такой праблемай, гэты параметр ужываецца толькі на прыладах з Android 6 і вышэй\n\nУключэнне параметра можа прадухіліць памылкі прайгравання пры пераключэнні бягучага відэаплэера або пераключэнні ў поўнаэкранны рэжым - Якасць выяў + Гэты абыходны шлях вызваляе і паўторна стварае відэакодэкі, калі адбываецца змяненне паверхні, замест таго, каб задаваць паверхню непасрэдна для кодэка. Ужо выкарыстоўваецца ExoPlayer на некаторых прыладах з такой праблемай, гэты параметр ужываецца толькі на прыладах з Android 6 і вышэй\n\nУключэнне параметра можа прадухіліць памылкі прайгравання пры пераключэнні бягучага відэаплэера або пераключэнні ў поўнаэкранны рэжым + Якасць відарысаў Відэа \? Падпісчыкі @@ -767,12 +767,12 @@ Атрыманне ўкладак канала Аватары Наступны паток - Прадвызначана на вашай прыладзе адключана медыятунэляванне, бо гэтая мадэль прылады яго не падтрымлівае. + Прадвызначана на вашай прыладзе адключана тунэляванне мультымедыя, бо вядома, што гэта мадэль яго не падтрымлівае. Аватары падканалаў Адкрыць чаргу прайгравання - Не загружаць выявы + Не загружаць відарысы Высокая якасць - Аб канале + Пра канал Абагуліць плэй-ліст Пераматаць наперад Альбомы @@ -786,9 +786,9 @@ - %1$s: %2$s Перамясціць панэль укладак уніз Няма жывых трансляцый - Выберыце якасць выяў і ці трэба спампоўваць выявы ўвогуле, каб паменшыць выкарыстанне даных і памяці. Змены ачышчаюць кэш выяў як у памяці, так і на дыску - %s + Выберыце якасць відарысаў ці ўвогуле не загружаць відарысы, каб паменшыць выкарыстанне даных і памяці. Змены ачышчаюць кэш відарысаў у памяці і на дыску (%s) Прайграць - Іншыя опцыі + Іншыя параметры Мініяцюры Трэкі Працягласць @@ -807,7 +807,7 @@ Каб адрэдагаваць кожнае з дзеянняў у апавяшчэнні, націсніце на яго. Першыя тры дзеянні (прайграванне/паўза, папярэдні і наступны) зададзены сістэмай, іх змяніць немагчыма. Недастаткова вольнага месца на прыладзе Так - NewPipe можа аўтаматычна правяраць наяўнасць абнаўленняў і паведаміць вам, калі яны будуць даступны. \nУключыць гэту функцыю? + NewPipe можа час ад часу аўтаматычна правяраць наяўнасць новай версіі і апавяшчаць, калі яна будзе даступна. \nУключыць гэту функцыю? Налады ў імпартаваным экспарце выкарыстоўваюць уразлівы фармат, які састарэў з версіі NewPipe 0.27.0. Пераканайцеся, што імпартаваны экспарт атрыманы з надзейнай крыніцы, і ў будучыні пераважней выкарыстоўваць толькі экспарт, атрыманы з NewPipe 0.27.0 ці навей. Падтрымка імпарту налад у гэтым уразлівым фармаце хутка будзе цалкам выдаленая, і тады старыя версіі NewPipe больш не змогуць імпартаваць наладкі з экспарту з новых версій. Не Рэзервовае капіяванне і аднаўленне @@ -820,4 +820,7 @@ Выберыце групу каналаў Група каналаў яшчэ не створана Старонка групы каналаў + Пошук %1$s + Пошук %1$s (%2$s) + Спадабалася diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index c6d4d76ce..0d83f6c0c 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -229,7 +229,7 @@ Съдържание на главната страница Празна страница Страница-павилион - Страница на определен канал + Страница на канал Изберете канал За момента нямате абонаменти Изберете павилион @@ -817,4 +817,6 @@ Търсене %1$s Търсене %1$s (%2$s) Харесвания + Страница SoundCloud Top 50 е премахната + SoundCloud преустанови оригиналните класации Топ 50. Съответният раздел е премахнат от главната ви страница. diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index ea531408f..c1f23457d 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -57,7 +57,7 @@ Jméno souboru Vlákna Zastavit - Smazat + Odstranit Start Zkusit znovu Video @@ -234,8 +234,8 @@ Přidat do playlistu Nastavit jako náhled playlistu Přidat playlist do záložek - Smazat záložku - Smazat tento playlist\? + Odstranit záložku + Odstranit tento playlist? Playlist vytvořen V playlistu Náhled playlistu změněn. @@ -411,9 +411,9 @@ Zobrazit pozici přehrávání v seznamech Pozice playbacku smazány Timeout spojení - Smazat pozice playbacku - Smazat všechny pozice playbacku - Smazat všechny pozice playbacku\? + Vymazat pozice přehrávání + Vymaže všechny pozice přehrávání + Vymazat všechny pozice přehrávání? Přepnout službu, právě vybráno: Nikdo nesleduje @@ -444,8 +444,8 @@ obnovuji Toto stahování nelze obnovit Vyberte instanci - Smazat historii stahování - Smazat stažené soubory + Vymazat historii stahování + Odstranit stažené soubory Souhlasit se zobrazením přes jiné aplikace Jazyk aplikace Jazyk systému @@ -488,7 +488,7 @@ %d vybráno Prázdné jméno skupiny - Přejete si smazat tuto skupinu\? + Přejete si odstranit tuto skupinu? Nová Novinky Limit aktualizace novinek @@ -689,7 +689,7 @@ Frekvence kontroly Jakákoli síť Požadované síťové připojení - Smazat všechny stažené soubory z disku\? + Odstranit všechny stažené soubory z disku? Objednali jste si nyní tento kanál Všechny přepnout Nové streamy @@ -846,4 +846,6 @@ Hledat %1$s Hledat %1$s (%2$s) Líbí se + Stránka SoundCloud Top 50 odstraněna + SoundCloud zrušil původní žebříčky Top 50. Příslušná karta byla odstraněna z vaší hlavní stránky. diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 309709f47..1f06121a8 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -829,4 +829,9 @@ Eine Feed-Gruppe auswählen Kanalgruppen-Seite Es wurde noch keine Feed-Gruppe erstellt + Suche %1$s + Suche %1$s (%2$s) + Gefällt mir + SoundCloud-Top-50-Seite entfernt + SoundCloud hat die ursprünglichen Top-50-Charts abgeschafft. Der entsprechende Tab wurde von deiner Hauptseite entfernt. diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 67a24bd4f..84da93a0f 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -829,4 +829,9 @@ Επιλογή ομάδας τροφοδοσίας Δεν δημιουργήθηκε ομάδα τροφοδοσίας ακόμα Σελίδα καναλιού ομάδας + Αναζήτηση %1$s + Αναζήτηση %1$s (%2$s) + Likes + Η σελίδα των SoundCloud Top 50 αφαιρέθηκε + Το SoundCloud έχει καταργήσει τα αρχικά charts με τα Top 50. Η αντίστοιχη καρτέλα έχει αφαιρεθεί από την κύρια σελίδα σας. diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index 9f9c7207c..af8cfde88 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -217,7 +217,7 @@ Enim esitatud Avalehe sisu Tühi leht - Kioski leht + Kioskivaade Kanali leht Vali kanal Kanaleid pole veel tellitud @@ -817,4 +817,6 @@ Otsi: %1$s Otsi: %1$s (%2$s) Meeldimisi + SoundCloudi „Top 50“ leht on eemaldatud + SoundCloud on lõpetanud oma algse „Top 50“ edetabeli pidamise. Seega on ka vastav vahekaart meie rakenduse põhivaatest eemaldatud. diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index c3fe5cf58..9a9590a07 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -164,7 +164,7 @@ Caractères spéciaux Voulez-vous supprimer cet élément de l’historique de recherche \? Contenu de la page principale - Page vide + Page blanche Chaîne Sélectionner une chaîne Tendances @@ -848,4 +848,6 @@ Rechercher %1$s Rechercher %1$s (%2$s) Likes + Page SoundCloud Top 50 supprimée + SoundCloud a abandonné le classement original du Top 50. L\'onglet correspondant a été supprimé de votre page d\'accueil. diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index bd560f07b..a09c0da03 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -179,9 +179,9 @@ היסטוריה למחוק את הפריט הזה מהיסטוריית החיפושים\? תוכן הדף הראשי - דף ריק - דף גישה מזדמנת - דף ערוצים + עמוד ריק + עמוד גישה מזדמנת + עמוד הערוץ נא לבחור ערוץ אין עדיין מינויים לערוצים נא לבחור סוג גישה מזדמנת diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 37282a0da..7d405bcef 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -824,4 +824,12 @@ बैकअप और रिस्टोर आयात किए जा रहे निर्यात में सेटिंग्स एक कमजोर प्रारूप का उपयोग करती हैं जिसे न्यूपाइप 0.27.0 के बाद से हटा दिया गया था। सुनिश्चित करें कि आयात किया जा रहा निर्यात किसी विश्वसनीय स्रोत से है, और भविष्य में केवल न्यूपाइप 0.27.0 या नए से प्राप्त निर्यात का उपयोग करना पसंद करें। इस असुरक्षित प्रारूप में सेटिंग्स आयात करने के लिए समर्थन जल्द ही पूरी तरह से हटा दिया जाएगा, और फिर न्यूपाइप के पुराने संस्करण अब नए संस्करणों से निर्यात की सेटिंग्स आयात नहीं कर पाएंगे। सेकेंडरी + %1$s खोजें + %1$s (%2$s) खोजें + प्लेलिस्ट + कृपया एक फ़ीड समूह चुनें + अभी तक कोई फ़ीड समूह नहीं बनाया गया है + चैनल समूह पेज + पसंद + यूट्यूब अस्थायी प्लेलिस्ट के रूप में साझा करें diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 14c55b772..eb60e377f 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -803,4 +803,6 @@ Keresés %1$s Keresés %1$s (%2$s) Kedvelések + SoundCloud Top 50 oldal eltávolítva + A SoundCloud megszüntette az eredeti Top 50-es listákat. A megfelelő lap el lett távolítva a főoldalról. diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 19f867d7c..b640a1232 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -193,8 +193,8 @@ Terakhir Diputar Sering Diputar Konten halaman utama - Halaman Kosong - Halaman Kedai + Halaman kosong + Halaman kiosk Halaman saluran Pilih saluran Belum ada saluran langganan @@ -815,4 +815,9 @@ Halaman grup saluran Belum ada grup umpan yang dibuat Pilih grup umpan + Cari %1$s + Cari %1$s (%2$s) + Suka + Halaman Top 50 SoundCloud dihapus + SoundCloud telah menghentikan dukungan tangga lagu Top 50. Tab terkait telah dihapus dari halaman utama Anda. diff --git a/app/src/main/res/values-is/strings.xml b/app/src/main/res/values-is/strings.xml index e7ce69e41..bc85f0e06 100644 --- a/app/src/main/res/values-is/strings.xml +++ b/app/src/main/res/values-is/strings.xml @@ -805,4 +805,12 @@ auka Deila sem YouTube-bráðabirgðaspilunarlista Spilunarlistar + Leita í %1$s + Leita í %1$s (%2$s) + Veldu hóp streyma + Enginn hópur streyma útbúinn ennþá + Síða rásahóps + Líkar við + Topp 50 síða SoundCloud fjarlægð + SoundCloud er hætt með Topp 50 vinsældalistann. Viðkomandi flipi hefur verið fjarlægður af aðalsíðunni þinni. diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 4c087f4de..d98875630 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -846,4 +846,6 @@ Cerca %1$s (%2$s) Cerca su %1$s Mi piace + Pagina Top 50 di SoundCloud rimossa + SoundCloud ha dismesso i grafici Top 50 originali. La scheda relativa è stata rimossa dalla pagina principale. diff --git a/app/src/main/res/values-mk/strings.xml b/app/src/main/res/values-mk/strings.xml index 1d3183b10..ff3f9b687 100644 --- a/app/src/main/res/values-mk/strings.xml +++ b/app/src/main/res/values-mk/strings.xml @@ -721,4 +721,4 @@ Изберете гестикулација за десната половина од екранот на плеерот Видеата нема да започнат со емитување во миниплеерот, туку директно ќе се вклучат на цел екран, доколку автоматското ротирање е заклучено. Сѐ уште можете да добиете пристап до миниплеерот, кога ќе излезете од целиот екран URL адресата не може да биде распознаена. Да се отвори со друга апликација? - \ No newline at end of file + diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml index ad14e7d05..757632994 100644 --- a/app/src/main/res/values-pa/strings.xml +++ b/app/src/main/res/values-pa/strings.xml @@ -84,7 +84,7 @@ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲ ਰਿਹਾ ਹੈ ਪੌਪ-ਅਪ ਮੋਡ ਵਿੱਚ ਚੱਲ ਰਿਹਾ ਹੈ ਸਮੱਗਰੀ - ਉਮਰ-ਮੁਤਾਬਕ-ਪਾਬੰਦੀਸ਼ੁਦਾ ਸਮੱਗਰੀ ਵਿਖਾਓ + ਉਮਰ ਮੁਤਾਬਕ ਪਾਬੰਦੀਸ਼ੁਦਾ ਸਮੱਗਰੀ ਵਿਖਾਓ ਲਾਈਵ ਡਾਊਨਲੋਡਸ ਡਾਊਨਲੋਡਸ @@ -824,6 +824,12 @@ ਨਹੀਂ ਇੰਪੋਰਟ ਕੀਤੇ ਜਾ ਰਹੇ ਐਕਸਪੋਰਟ ਵਿੱਚ ਸੈਟਿੰਗਾਂ ਇੱਕ ਕਮਜ਼ੋਰ ਫਾਰਮੈਟ ਦੀ ਵਰਤੋਂ ਕਰਦੀਆਂ ਹਨ ਜੋ ਨਿਊਪਾਈਪ 0.27.0 ਤੋਂ ਬਰਤਰਫ਼ ਕੀਤਾ ਗਿਆ ਸੀ। ਯਕੀਨੀ ਬਣਾਓ ਕਿ ਇੰਪੋਰਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਨਿਰਯਾਤ ਇੱਕ ਭਰੋਸੇਯੋਗ ਸਰੋਤ ਤੋਂ ਹੈ, ਅਤੇ ਸਿਰਫ਼ ਨਿਊਪਾਈਪ 0.27.0 ਜਾਂ ਇਸਤੋਂ ਨਵੇਂ ਤੋਂ ਪ੍ਰਾਪਤ ਕੀਤੇ ਐਕਸਪੋਰਟ ਦੀ ਵਰਤੋਂ ਕਰਨ ਨੂੰ ਤਰਜੀਹ ਦਿਓ। ਇਸ ਕਮਜ਼ੋਰ ਫਾਰਮੈਟ ਵਿੱਚ ਸੈਟਿੰਗਾਂ ਨੂੰ ਆਯਾਤ ਕਰਨ ਲਈ ਸਮਰਥਨ ਜਲਦੀ ਹੀ ਪੂਰੀ ਤਰ੍ਹਾਂ ਹਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ ਅਤੇ ਫਿਰ ਨਿਊਪਾਈਪ ਦੇ ਪੁਰਾਣੇ ਸੰਸਕਰਣ ਹੁਣ ਨਵੇਂ ਸੰਸਕਰਣਾਂ ਤੋਂ ਐਕਸਪੋਰਟ ਦੀਆਂ ਸੈਟਿੰਗਾਂ ਨੂੰ ਇੰਪੋਰਟ ਕਰਨ ਦੇ ਯੋਗ ਨਹੀਂ ਹੋਣਗੇ। ਸੈਕੰਡਰੀ - ਟੈਂਪਰੇਰੀ ਯੂਟਿਊਬ ਪਲੇਲਿਸਟ ਵੱਜੋਂ ਸ਼ੇਅਰ ਕਰੋ + ਅਸਥਾਈ ਯੂਟਿਊਬ ਪਲੇਲਿਸਟ ਵਜੋਂ ਸਾਂਝਾ ਕਰੋ ਪਲੇਲਿਸਟਾਂ + %1$s ਦੀ ਖੋਜ ਕਰੋ + %1$s (%2$s) ٪1$s ਦੀ ਖੋਜ ਕਰੋ + ਫੀਡ ਗਰੁੱਪ ਚੁਣੋ + ਅਜੇ ਤੱਕ ਕੋਈ ਫੀਡ ਗਰੁੱਪ ਨਹੀਂ ਬਣਾਇਆ ਗਿਆ + ਚੈਨਲ ਗਰੁੱਪ ਪੰਨਾ + ਪਸੰਦ diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index dc3f88cec..a0c68f942 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -855,4 +855,6 @@ Szukaj %1$s Szukaj %1$s (%2$s) Polubienia + Usunięto stronę SoundCloud 50 najlepszych + SoundCloud wycofał oryginalną listę 50 najlepszych. Odpowiadająca karta została usunięta ze strony głównej. diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index d13cbcfe3..56731cb06 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -843,4 +843,9 @@ Selecione um grupo de feeds Nenhum grupo de feeds criado ainda Página do grupo do canal + Pesquisar %1$s + Pesquisar %1$s (%2$s) + Curtidas + Página Top 50 do SoundCloud removida + O SoundCloud descontinuou as paradas originais do Top 50. A aba correspondente foi removida da sua página principal. diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index 6ceec006e..f670aa52e 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -843,4 +843,6 @@ Selecione um grupo de feeds Ainda nenhum grupo de feeds criado Página do grupo do canal + Pesquisar %1$s + Pesquisar %1$s (%2$s) diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 13a536895..72c6b62da 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -843,4 +843,6 @@ Selecione um grupo de feeds Ainda nenhum grupo de feeds criado Página do grupo do canal + Pesquisar %1$s + Pesquisar %1$s (%2$s) diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index eb4e75c28..cda82bd25 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -164,9 +164,9 @@ Istoric Doriți să ștergeți acest element din istoricul de căutare? Conținutul pagini principale - Pagină Goală + Pagină goală Pagina de chioșc - Pagină Canale + Pagină canale Alegeți un canal Nu v-ați abonat la niciun canal deocamdată Alegeți un chioșc @@ -841,4 +841,11 @@ Distribuie ca listă de redare temporară YouTube Liste de redare Pagina grupului de canale + Caută: %1$s + Caută %1$s (%2$s) + Selectează un grup de fluxuri + Încă nu a fost creat niciun grup de fluxuri + Aprecieri + Pagina SoundCloud Top 50 a fost eliminată + SoundCloud a eliminat Top 50. Fila corespunzătoare a fost eliminată din pagina principală. diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index a512b6fa8..8b54adaad 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -848,4 +848,9 @@ Страница группы каналов Выберите группу кормов Группа кормов еще не создана + Поиск %1$s + Поиск %1$s (%2$s) + Лайки + Страница SoundCloud Top 50 удалена + SoundCloud прекратил поддерживать оригинальные чарты Top 50. Соответствующая вкладка была удалена с вашей главной страницы. diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index ad2dacfd6..3bae642c7 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -13,12 +13,12 @@ Zdieľať s Použiť externý prehrávač videa Použiť externý prehrávač zvuku - Prevzaté video ukladať do - Prevzaté video súbory sú uložené tu + Adresár stiahnutých videí + Stiahnuté video súbory sú uložené tu Vyberte priečinok pre stiahnuté video Priečinok pre stiahnuté audio Vyberte priečinok pre audio súbory - Prevzaté zvukové súbory sú uložené tu + Stiahnuté zvukové súbory sú uložené tu Štandardné rozlíšenie Prehrať cez Kodi Nainštalovať chýbajúcu aplikáciu Kore\? @@ -74,8 +74,8 @@ Čakajte prosím… Skopírované do schránky Priečinok na sťahovanie zadefinujte prosím neskôr v nastaveniach - Prevzaté - Prevzaté + Sťahované súbory + Stiahnuté Hlásenie o chybe Aplikácia/UP zlyhalo Čo:\\nPožiadavka:\\nJazyk obsahu:\\nKrajina Obsahu:\\nJazyk Aplikácie:\\nSlužba:\\nČas v GMT:\\nBalík:\\nVerzia:\\nOS: @@ -165,7 +165,7 @@ Nebol nájdený žiadny prehrávač pre stream (môžete si nainštalovať napr. VLC). Stiahnuť súbor streamu Zobraziť info - Uložené zoznamy + Uložené playlisty Pridať do Zobrazovať tip \"Pridať podržaním\" Zobrazí tip pri stlačení tlačidiel pozadia alebo vyskakovacieho okna videa \"Podrobnosti:\" @@ -179,8 +179,8 @@ Prepnúť na Video Importovať databázu Exportovať databázu - Prepíše aktuálnu históriu, odbery, zoznamy skladieb a (voliteľne) nastavenia - Exportuje históriu, odbery, zoznamy skladieb a nastavenia + Prepíše aktuálnu históriu, odbery, playlisty a (voliteľne) nastavenia + Exportuje históriu, odbery, playlisty a nastavenia Nepodarilo sa prehrať tento stream Pri prehrávaní došlo k chybe a nemožno pokračovať Zotavovanie po chybe v prehrávaní @@ -200,7 +200,7 @@ Naposledy prehrávané Najprehrávanejšie Obsah na hlavnej stránke - Prázdna strana + Prázdna stránka Kiosk Kanál Vyberte si kanál @@ -228,17 +228,17 @@ Vždy sa opýtať Získavajú sa informácie… Načítanie požadované obsahu - Nový zoznam skladieb + Nový playlist Premenovať Názov - Pridať do zoznamu skladieb - Nastaviť ako miniatúru zoznamu skladieb - Záložka zoznamu skladieb - Odstrániť Záložku - Odstrániť tento zoznam skladieb\? - Zoznam skladieb vytvorený + Pridať do playlistu + Nastaviť ako miniatúru playlistu + Pridať playlist medzi záložky + Odstrániť záložku + Odstrániť tento playlist? + Playlist bol vytvorený V playliste - Miniatúra zoznamu skladieb bola zmenená. + Miniatúra playlistu bola zmenená. Bez titulkov Prispôsobiť Vyplniť @@ -321,7 +321,7 @@ Bez limitu Limitovať rozlíšenie pri použití mobilných dát Kanály - Zoznamy skladieb + Playlisty Skladby Používatelia Pretáčať tiché pasáže @@ -513,8 +513,7 @@ \n \nMožno v budúcnosti sa to zmení. Áno aj čiastočne pozreté videá - Pozreté videá, ktoré ste pozreli pred a po ich pridaní do zoznamu, budú odstránené. -\nSte si istí ich odstránením zo zoznamu\? Táto operácia je nezvratná! + Pozreté videá, ktoré ste pozreli pred a po ich pridaní do playlistu, budú odstránené. \nSte si istí ich odstránením z playlistu? Táto operácia je nezvratná! Odstrániť pozreté videá\? Odstrániť pozreté Pôvodné texty zo služieb budú viditeľné v položkách streamu @@ -534,14 +533,14 @@ Nahlásiť na GitHub-e Kopírovať formátované hlásenie Zobrazujú sa výsledky pre: %s - Zoznamy skladieb + Zoznam playlistov Zobraziť iba nezoskupené odbery Nikdy Iba na WiFi Spustí automatické prehrávanie - %s Prehrať zoznam - Zatiaľ bez záložiek zoznamu - Vyberte zoznam skladieb + Žiadne záložky playlistov + Vyberte playlist Skontrolujte prosím, či rovnaká chyba už nie je nahlásená. Vytváranie duplicitných hlásení komplikuje prácu vývojárov. Nemožno rozpoznať URL. Otvoriť pomocou inej aplikácie\? Automatický rad @@ -722,7 +721,7 @@ Ak máte problémy s používaním aplikácie, určite si prečítajte tieto odpovede na časté otázky! Vypnutie trvalého náhľadu Kopírovanie do schránky zlyhalo - Zoznamy zobrazené šedou farbou už obsahujú danú položku. + Playlisty zobrazené šedou farbou už obsahujú danú položku. Karta Dotykom stiahnite %s Duplikát bol pridaný %d-krát @@ -749,7 +748,7 @@ Preferovať prehrávanie popisu Zvuk: %s Zvuková stopa - Chcete odstrániť všetky duplikátne streamy z tohoto zoznamu\? + Chcete odstrániť všetky duplikátne streamy z tohoto playlistu? Zobrazovať nasledovné streamy V tomto streame by už mala byť prítomná zvuková stopa Výber zvukovej stopy pre externé prehrávače @@ -788,7 +787,7 @@ Dozadu Opäť prehrať Karty, ktoré sa majú načítať pri aktualizácii informačného kanála. Táto možnosť nemá žiadny účinok, ak je kanál aktualizovaný pomocou rýchleho režimu. - Zoznamy skladieb + Playlisty Presunie výber hlavnej karty do spodnej časti Žiadne živé prenosy Prehrať @@ -846,4 +845,6 @@ Hľadať %1$s (%2$s) Hľadať %1$s Páči sa + SoundCloud Top 50 stránka odstránená + SoundCloud prestal používať pôvodnú Top 50. Daná stránka bola odstránená z hlavnej stránky. diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index cd41b43ba..68875fe23 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -459,4 +459,4 @@ Označi kot že ogledano Uporabite hitro nenatančno iskanje Sesuj predvajalnik - \ No newline at end of file + diff --git a/app/src/main/res/values-ti/strings.xml b/app/src/main/res/values-ti/strings.xml index c6edbe4c3..e1f61b7d1 100644 --- a/app/src/main/res/values-ti/strings.xml +++ b/app/src/main/res/values-ti/strings.xml @@ -4,7 +4,7 @@ ኣብ መርበብ-ሓበሬታ ክፉት ውጽኢት ናይ፦ %s ንኽትጅምር ነቲ ምድላይ ምልክት ጠውቆ። - ኣብ %1$s ዝተሓትመ + ዝተሓትመሉ ዕለት %1$s ናይ ዥረት ተጻዋታይ ኣይተረኽበን። VLC ኣውርድ፧ ሐራይ ቅጥዕታት @@ -26,7 +26,7 @@ ሰዓበ ናይ ደገ ቪድዮ ተጠቐም መጻወቲ ምውራድ - ኣይትጽንበሩ + ምስዓብ ኣቋርጽ ነቲ ኣብ\'ቲ ምልክታ ዝተርኣየ ናይ ቪድዮ ምስሊ ካብ 16:9 ናብ 1:1 ርሕቐት ኣቀራርባ ቅረጽ ምስ Kodi ተጻወት ድምር ምስ @@ -43,7 +43,7 @@ ናይ ደገ ድምጺ መጻወቲ ተጠቐም Android ሕብሪ ናይቲ መተሓሳሰቢ ብመሰረት እቲ ኣብቲ ንእሽቶ ስእሊ ዘሎ ቀንዲ ሕብሪ ከም ዝጥዕሞ ግበር (እዚ ኣብ ኩሉ መሳርሒታት ከምዘይርከብ ኣስተውዕል) ትሑዝ ፖፕኣፕ ድንቀት - ነፍሲ ወከፍ መፍለጢ ተግባር ኣብ ታሕቲ ብምጥዋቕ ኣርትዖ። ኣብቲ ውህሉል መተሓሳሰቢ ንኽርአ ክሳብ ሰለስተ ካብኣቶም ምረጽ፡ ኣብ የማናይ ሸነኽ ዘሎ ሳጹናት ብምጥቃም + ነፍሲ ወከፍ መፍለጢ ተግባር ኣብ ታሕቲ ብምጥዋቕ ኣርትዖ። ኣብቲ ውህሉል መተሓሳሰቢ ንኽርአ ክሳብ ሰለስተ ካብኣቶም ምረጽ፡ ኣብ የማናይ ሸነኽ ዘሎ ሳጹናት ብምጥቃም። ፖፕኣፕ ትሑዝ ድንቀት ዝወረዱ ናይ ተንቃሳቀሴ-ምስሌ ፋይላት ኣብዚ ይኽዘኑ @@ -56,7 +56,7 @@ ናይ ድምጺ ፋይል ኣራግፍ ምረጽ ዝጎደለ ኮረ ኣፕፕ ኣውራድ፧ ነባሪ ቅርጺ ድምጺ - ምዝገባ + እትስዕቦም Kodi ሚድያ ማእኸል ቪድዮ ንምጽዋት ዝሕግዝ ኣማራጺ ኣብቲ ውሱን መፍለጢ ንምርኣይ እንተበዝሐ ሰለስተ ተግባራት ክትመርጽ ትኽእል ኢኻ! ተንቃሳቀሴ-ምስሌ ፋይል ኣራግፍ @@ -70,7 +70,7 @@ እወ ኣይፋልን ጸሊም - ቆርበት + ቆርበት ኣርእስቲ ለይታው ቆርበት ናይ ፖፕኣፕ ባህርያት ዘክር ናይ ፖፕኣፕ ዝነበሮ ቦታ ዘክር @@ -88,7 +88,7 @@ ኵሉ መስመርት ዝርዝር-ጸወታ - ቅዳሒት + ቪዶ ተጠቀምቲ ፍጻመታት ደርፍታት diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index a26016f1a..e2774ad39 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -164,9 +164,9 @@ Kurtarılamayan oynatıcı hatası oluştu Oynatıcı hatasından kurtarılıyor Ana sayfanın içeriği - Boş Sayfa - Kiosk Sayfası - Kanal Sayfası + Boş sayfa + Kiosk sayfası + Kanal sayfası Kanal seçin Henüz kanal aboneliği yok Kiosk seçin @@ -830,4 +830,8 @@ Kanal küme sayfası Besleme kümesi oluşturulmadı Beğeni + %1$s İle Ara + %1$s İle Ara (%2$s) + SoundCloud Top 50 sayfası kaldırıldı + SoundCloud, özgün Top 50 listesini artık yayınlamıyor. İlgili sekme ana sayfanızdan kaldırıldı. diff --git a/app/src/main/res/values-tzm/strings.xml b/app/src/main/res/values-tzm/strings.xml index 31d89bdd5..8ef077a9f 100644 --- a/app/src/main/res/values-tzm/strings.xml +++ b/app/src/main/res/values-tzm/strings.xml @@ -178,4 +178,4 @@ Ilbumen Tilgamin n tɣuri Taɣuri tawurmant - \ No newline at end of file + diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 32e03bea0..d548dac3c 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -218,8 +218,8 @@ Відтворювалося найбільше Вміст на головній сторінці Порожня сторінка - Кіоск-сторінка - Канал + Сторінка кіоску + Сторінка каналу Обрати канал Немає підписок на канали Обрати кіоск @@ -849,4 +849,8 @@ Виберіть групу каналів Групу каналів ще не створено Вподобання + Пошук %1$s + Пошук %1$s (%2$s) + Сторінку SoundCloud Top 50 видалено + SoundCloud припинив підтримку оригінальних чартів Топ-50. Відповідну вкладку видалено з вашої головної сторінки. diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 3c9c79457..c63e952f0 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -198,7 +198,7 @@ 是否删除此条搜索历史记录? 主页面的显示内容 空白页 - 『时下流行』页-自定义 + Kiosk 页面 频道页 选择一个频道 尚未订阅频道 @@ -816,4 +816,8 @@ 选择一个订阅源组 尚未创建订阅源组 + 搜索%1$s + 搜索 %1$s (%2$s) + 移除了 SoundCloud Top 50 页面 + SoundCloud 已停止发布原创 Top 50 榜单。相应的标签页已从你的主页移除。 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index b9ca2d3ce..1427ce483 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -816,4 +816,8 @@ 選取 feed 群組 尚未建立 feed 群組 喜歡 + 搜尋 %1$s + 搜尋 %1$s (%2$s) + 已移除 SoundCloud Top 50 頁面 + SoundCloud 已停止原有的 Top 50 排行榜。對應的標籤已從您的首頁移除。 diff --git a/fastlane/metadata/android/ar/changelogs/1005.txt b/fastlane/metadata/android/ar/changelogs/1005.txt new file mode 100644 index 000000000..933c7286a --- /dev/null +++ b/fastlane/metadata/android/ar/changelogs/1005.txt @@ -0,0 +1,17 @@ +جديد +• أضف دعمًا لنظام Android Auto +• السماح لإعداد مجموعات التغذية كعلامات شاشة رئيسية +• [يوتيوب] شارك كقائمة تشغيل مؤقتة +• [SoundCloud] Leges Table Tab + +تحسن +• تلميحات شريط بحث أفضل +• عرض تاريخ التنزيل في التنزيلات +• استخدام Android 13 لكل لغة + +مُثَبَّت +• إصلاح ألوان النص المكسورة في الوضع المظلم +• [youtube] إصلاح قوائم التشغيل لا تحميل أكثر من 100 عنصر +• [youtube] إصلاح مقاطع الفيديو الموصى بها مفقودة +• إصلاح حوادث في عرض قائمة التاريخ +• إصلاح الطوابع الزمنية في ردود التعليقات diff --git a/fastlane/metadata/android/cs/changelogs/1005.txt b/fastlane/metadata/android/cs/changelogs/1005.txt new file mode 100644 index 000000000..2059e43de --- /dev/null +++ b/fastlane/metadata/android/cs/changelogs/1005.txt @@ -0,0 +1,17 @@ +Novinky +• Přidána podpora pro Android Auto. +• Možnost nastavit skupiny kanálů jako záložky na hlavní obrazovce. +• [YouTube] Sdílení jako dočasný seznam skladeb. +• [SoundCloud] Záložka Oblíbené kanály + +Vylepšeno +• Lepší nápověda pro vyhledávací lištu +• Zobrazení data stažení v sekci Stažené soubory +• Použití jazyka Android 13 pro jednotlivé aplikace + +Opraveno +• Oprava chybných barev textu v tmavém režimu +• [YouTube] Oprava seznamů skladeb, které nenačtou více než 100 položek +• [YouTube] Oprava chybějících doporučených videí +• Oprava pádů v zobrazení seznamu historie +• Oprava časových značek v odpovědích na komentáře diff --git a/fastlane/metadata/android/de/changelogs/1005.txt b/fastlane/metadata/android/de/changelogs/1005.txt new file mode 100644 index 000000000..ac9000b65 --- /dev/null +++ b/fastlane/metadata/android/de/changelogs/1005.txt @@ -0,0 +1,17 @@ +Neu +• Android Auto +• Feed-Gruppen als Hauptbildschirm-Tabs +• [YouTube] Teilen als temporäre Wiedergabeliste +• [SoundCloud] Gefällt-Kanal-Tab + +Verbessert +• Bessere Suchleisten-Hinweise +• Anzeige des Downloaddatums +• App-spezifische Spracheinstellungen (Android 13) + +Behoben +• Fehlerhafte Textfarben im dunklen Modus +• [YouTube] Wiedergabelisten laden nicht mehr als 100 Einträge +• [YouTube] Fehlende empfohlene Videos +• Abstürze in der Verlaufslisten-Ansicht +• Zeitstempel in Kommentarantworten diff --git a/fastlane/metadata/android/et/changelogs/1005.txt b/fastlane/metadata/android/et/changelogs/1005.txt new file mode 100644 index 000000000..685803416 --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/1005.txt @@ -0,0 +1,17 @@ +Uus +• Android Auto tugi +• Meedivoogude grupid põhivaates +• [YouTube] Jagamine ajutise esitusloendina +• [SoundCloud] Meeldimiste kanali vahekaart + +Täiendatud +• Paremad otsinguvihjed +• Allalaadimise kuupäev vastavas vaates +• Android 13 puhul rakendusekohane keel + +Parandatud +• Tekstivärvid tumedas kujundused +• [YouTube] Esitusloend ei laadinud üle 100 kirje +• [YouTube] Puuduvad videosoovitused +• Ajaloovaate kookujooksmine +• Ajatemplid kommentaaride vastustes diff --git a/fastlane/metadata/android/fr/changelogs/1005.txt b/fastlane/metadata/android/fr/changelogs/1005.txt new file mode 100644 index 000000000..b7e5ff49f --- /dev/null +++ b/fastlane/metadata/android/fr/changelogs/1005.txt @@ -0,0 +1,17 @@ +Nouveau +• Prise en charge d'Android Auto +• Possibilité de définir des groupes de flux comme onglets de l'écran principal +• [YouTube] Partager comme playlist temporaire +• [SoundCloud] Onglet « J'aime » + +Amélioration +• Amélioration des astuces de la barre de recherche +• Affichage de la date de téléchargement dans Téléchargements +• Utilisation de la langue par application d'Android 13 + +Corrigé +• Correction des couleurs de texte défectueuses en mode sombre +• [YouTube] Correction des playlists ne chargeant pas plus de 100 éléments +• [YouTube] Correction des vidéos recommandées manquantes +• Correction des plantages dans la vue Historique +• Correction des horodatages dans les réponses aux commentaires diff --git a/fastlane/metadata/android/hi/changelogs/1005.txt b/fastlane/metadata/android/hi/changelogs/1005.txt new file mode 100644 index 000000000..495894e76 --- /dev/null +++ b/fastlane/metadata/android/hi/changelogs/1005.txt @@ -0,0 +1,17 @@ +नया ++ • Android Auto के लिए समर्थन जोड़ें ++ • फ़ीड समूहों को मुख्य स्क्रीन टैब के रूप में सेट करने की अनुमति दें ++ • [YouTube] अस्थायी प्लेलिस्ट के रूप में साझा करें ++ • [SoundCloud] "पसंद" चैनल टैब जोङी गई + +बेहतर किए ++ • खोज बार संकेत ++ • डाउनलोडस स्क्रीन में डाउनलोड की तारीख दिखाएं ++ • Android 13+ पर प्रति-ऐप भाषा का उपयोग करें + +फिक्स किए ++ • डार्क मोड में पाठ के रंग ठीक करें ++ • [YouTube] 100 से अधिक आइटम लोड नहीं करने वाली प्लेलिस्ट को ठीक करें ++ • [YouTube] अनुपलब्ध अनुशंसित वीडियो को ठीक करें ++ • इतिहास सूची दृश्य में क्रैश ठीक करें ++ • टिप्पणी के उत्तरों में टाइमस्टैम्प को ठीक करें diff --git a/fastlane/metadata/android/hu/changelogs/1005.txt b/fastlane/metadata/android/hu/changelogs/1005.txt new file mode 100644 index 000000000..6d6974391 --- /dev/null +++ b/fastlane/metadata/android/hu/changelogs/1005.txt @@ -0,0 +1,17 @@ +Újdonság +- Android Auto támogatás hozzáadása +- A hírfolyamcsoportok főképernyőfülekként való beállítása +- [YouTube] Megosztás ideiglenes lejátszási listaként +- [SoundCloud] „Kedvelések” csatorna lap + +Továbbfejlesztve +- Jobb keresősáv-súgók +- Letöltési dátum megjelenítése a letöltések között +- Android 13 alkalmazásonkénti nyelv használata + +Javítva +- Törött szövegszínek javítása sötét módban +- [YouTube] A lejátszási listák 100-nál több elemet nem töltöttek be. +- [YouTube] Az ajánlott videók hiányának javítása +- Az előzmények listanézetben bekövetkező összeomlások javítása +- A hozzászólásválaszok időbélyegeinek javítása diff --git a/fastlane/metadata/android/it/changelogs/1005.txt b/fastlane/metadata/android/it/changelogs/1005.txt new file mode 100644 index 000000000..e70610077 --- /dev/null +++ b/fastlane/metadata/android/it/changelogs/1005.txt @@ -0,0 +1,17 @@ +Novità +• Ora NewPipe funziona su Android Auto +• Aggiungi feed di gruppi di canali nella schermata principale +• [YouTube] Condividi come playlist temporanea +• [SoundCloud] Mi piace nei canali + +Migliorie +• Indizi nella barra di ricerca +• Mostrata la data di scaricamento nella relativa sezione +• Uso della possibilità di scegliere la lingua dell'app, funzione nativa di Android 13 + +Correzioni +• Sistemati i colori del testo col tema scuro +• [YouTube] Ora si caricano più di 100 video nelle playlist +• [YouTube] Ripristinati i video consigliati +• Sistemati i crash nella cronologia +* Sistemato un errore nell'orario di inserimento di una risposta nei commenti diff --git a/fastlane/metadata/android/pa/changelogs/1005.txt b/fastlane/metadata/android/pa/changelogs/1005.txt new file mode 100644 index 000000000..f1492a1ac --- /dev/null +++ b/fastlane/metadata/android/pa/changelogs/1005.txt @@ -0,0 +1,17 @@ +ਨਵਾਂ ++ • Android Auto ਲਈ ਸਮਰਥਨ ਸ਼ਾਮਿਲ ਕਰੋ ++ • ਫੀਡ ਗਰੁੱਪਾਂ ਨੂੰ ਮੁੱਖ ਸਕ੍ਰੀਨ ਟੈਬਾਂ ਵਜੋਂ ਸੈੱਟ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ ++ • [YouTube] ਅਸਥਾਈ ਪਲੇਲਿਸਟ ਦੇ ਵਜੋਂ ਸਾਂਝਾ ਕਰੋ ++ • [SoundCloud] "ਪਸੰਦ" ਚੈਨਲ ਟੈਬ ਜੋੜੀ ਗਈ + +ਬਿਹਤਰ ਕੀਤੇ ++ • ਖੋਜ ਬਾਰ ਸੰਕੇਤ ++ • ਡਾਊਨਲੋਡਸ ਸੂਚੀ ਵਿੱਚ ਡਾਊਨਲੋਡ ਤਾਰੀਖ ਦਿਖਾਓ ++ • ਐਂਡਰਾਇਡ 13+ 'ਤੇ ਪ੍ਰਤੀ ਐਪ ਭਾਸ਼ਾ ਦੀ ਵਰਤੋਂ ਕਰੋ + +ਦਰੁਸਤ ਕੀਤੇ ++ • ਡਾਰਕ ਥੀਮਾਂ 'ਤੇ ਟੈਕਸਟ ਰੰਗਾਂ ਨੂੰ ਠੀਕ ਕਰੋ ++ • [YouTube] ਪਲੇਲਿਸਟਾਂ ਨੂੰ ਠੀਕ ਕਰੋ ਜੋ 100 ਤੋਂ ਵੱਧ ਆਈਟਮਾਂ ਲੋਡ ਨਹੀਂ ਕਰਦੀਆਂ ++ • [YouTube] ਸਿਫਾਰਸ਼ ਕੀਤੀਆਂ ਵੀਡੀਓਜ਼ ਦੀ ਅਣਉਪਲੱਬਧਤਾ ਨੂੰ ਠੀਕ ਕਰੋ ++ • ਇਤਿਹਾਸ ਸੂਚੀ ਦ੍ਰਿਸ਼ ਵਿੱਚ ਕ੍ਰੈਸ਼ ਨੂੰ ਠੀਕ ਕਰੋ ++ • ਟਿੱਪਣੀਆਂ ਦੇ ਜਵਾਬ ਵਿੱਚ ਟਾਈਮਸਟੈਂਪਾਂ ਨੂੰ ਠੀਕ ਕਰੋ diff --git a/fastlane/metadata/android/pl/changelogs/1005.txt b/fastlane/metadata/android/pl/changelogs/1005.txt new file mode 100644 index 000000000..336aa1fa6 --- /dev/null +++ b/fastlane/metadata/android/pl/changelogs/1005.txt @@ -0,0 +1,17 @@ +Nowe +- Obsł. Android Auto +- Opcja ustawiania grup kanałów jako kart ekranu głównego +- [YouTube] Udostęp. jako tymczasowa playlista +- [SoundCloud] Karta kanału polubień + +Ulepszone +- Lepsze podpow. paska wysz. +- Wyśw. daty pobrania w Pobranych +- Używanie języka aplikacji w Androidzie 13 + +Naprawione +- Uszkodzone kolory tekstu w trybie ciemnym +- [YouTube] Playlisty ładujące maks. 100 pozycji +- [YouTube] Brakujące polecane wideo +- Awarie w widoku listy Historii +- Znaczniki czasu w odp. na komentarze diff --git a/fastlane/metadata/android/ru/changelogs/1005.txt b/fastlane/metadata/android/ru/changelogs/1005.txt new file mode 100644 index 000000000..3dead0f05 --- /dev/null +++ b/fastlane/metadata/android/ru/changelogs/1005.txt @@ -0,0 +1,17 @@ +Новое +• Поддержка Android Auto +• Использование групп лент как вкладок главного экрана +• [YouTube] Возможность поделиться временным плейлистом +• [SoundCloud] Вкладка канала "Лайки" + +Улучшено +• Поисковые подсказки +• Показ даты загрузки в Загрузках +• Установка языка для каждого приложения + +Исправлено +• Цвета текста в тёмном режиме +• [YouTube] Плейлисты не загружали более чем 100 элементов +• [YouTube] Отсутствующие рекомендованные видео +• Вылеты в Истории +• Временные метки в ответах на комментарии diff --git a/fastlane/metadata/android/sk/changelogs/1000.txt b/fastlane/metadata/android/sk/changelogs/1000.txt index 61cabd89d..29e2182f4 100644 --- a/fastlane/metadata/android/sk/changelogs/1000.txt +++ b/fastlane/metadata/android/sk/changelogs/1000.txt @@ -1,13 +1,13 @@ Vylepšené -- Umožnené kliknutie na popis playlistu, aby sa zobrazilo viac/menej obsahu -- [PeerTube] Automatické spracovanie odkazov inštancie `subscribeto.me` -- Spustenie prehrávania iba jednej položky v histórii +- Kliknutím na playlist sa zobrazí viac/menej obsahu +- [PeerTube] Automatické spracovanie odkazov z `subscribeto.me` +- Spustiť prehrávanie iba jednej položky v histórii Opravené -- Oprava viditeľnosti tlačidla RSS -- Oprava pádov náhľadu na paneli vyhľadávania -- Oprava pridania položky bez miniatúry do playlistu -- Oprava ukončenia okna sťahovania pred jeho zobrazením -- Oprava vyskakovacieho okna zoznamu súvisiacich položiek -- Oprava poradia v okne pridania do playlistu -- Úprava rozloženia položiek záložiek playlistu +- Viditeľnosť tlačidla RSS +- Pády pri náhľadoch +- Pridanie položky bez miniatúry do playlistu +- Zatváranie okna sťahovania pred jeho zobrazením +- Vyskakovacie okno zoznamu súvisiacich položiek +- Poradie v okne pridania do playlistu +- Rozloženie položiek záložiek playlistu diff --git a/fastlane/metadata/android/sk/changelogs/1005.txt b/fastlane/metadata/android/sk/changelogs/1005.txt new file mode 100644 index 000000000..8f2bfbfab --- /dev/null +++ b/fastlane/metadata/android/sk/changelogs/1005.txt @@ -0,0 +1,18 @@ +Novinky +• Pridaná podpora pre Android Auto +• Možnosť nastaviť skupiny kanálov ako hlavné karty na obrazovke +• [YouTube] Zdieľanie ako dočasný playlist + +• [SoundCloud] Karta „Páči sa“ kanál. + +Vylepšenia +• Lepšia nápoveda v paneli vyhľadávania +• Zobrazenie dátumu stiahnutia v sekcii „Stiahnuté” +• Použitie jazyka Android 13 pre jednotlivé aplikácie + +Opravy +• Oprava chybných farieb textu v tmavom režime +• [YouTube] Oprava playlistov, ktoré nenačítavajú viac ako 100 položiek +• [YouTube] Oprava chýbajúcich odporúčaných videí +• Oprava pádov v zobrazení zoznamu histórie +• Oprava časových značiek v odpovediach na komentáre. diff --git a/fastlane/metadata/android/sk/full_description.txt b/fastlane/metadata/android/sk/full_description.txt index 9de86c677..e1483d4fd 100644 --- a/fastlane/metadata/android/sk/full_description.txt +++ b/fastlane/metadata/android/sk/full_description.txt @@ -1 +1 @@ -NewPipe nepoužíva žiadne Google framework knižnice, ani YouTube API rozhranie. Len analyzuje web, aby získal potrebné informácie. Preto je možné túto aplikáciu používať na zariadeniach bez nainštalovaných Google služieb. Taktiež nepotrebujete účet na YouTube. Appka je FLOSS. +NewPipe nepoužíva Google framework knižnice, ani YouTube API rozhranie. Iba spracováva YouTube stránku aby získal potrebné informácie. Túto aplikáciu je teda možné používať na zariadeniach bez nainštalovaných Google služieb. Taktiež nepotrebujete účet na YouTube. Aplikácia je FLOSS. diff --git a/fastlane/metadata/android/ti/full_description.txt b/fastlane/metadata/android/ti/full_description.txt index f0afa90ab..f58ede5da 100644 --- a/fastlane/metadata/android/ti/full_description.txt +++ b/fastlane/metadata/android/ti/full_description.txt @@ -1 +1 @@ -ኒውፓይፕ ዝዀነ ይኹን ናይ ጎልጋል ቤተ-መጻሕፍቲ ወይ ናይ ዩቱብ ኤፒኢ ኣይጥቀምን ኢዩ። ነቲ ወብ ሳይት ዜድልዮ ሓበሬታ ንምርካብ ጥራይ እዩ ዚምርምሮ ። ስለዚ እዚ ኣፕሊኬሽን እዚ ብዘይ ናይ ጎልጋል ሰርቪስ ኣብ ኤለክትሮኒካዊ መሳርሒታት ክትጥቀመሉ ትኽእል ኢኻ ። ኒውፓይፕ ንምጥቃም እውን ናይ ዩቱብ ሕሳብ ኣየድልየካን ኢዩ እዚ ኸኣ FLOSS ኢዩ። +ኒውፓይፕ ዝዀነ ናይ ጉግል ቤተ-ምስሊታት ወይ ናይ ዩቱብ ኤፒኢይ ኣይጥቀምን ኢዩ። ነቲ መርበብ- ስፍራ ዜድልዮ ሓበሬታ ንምርካብ ጥራይ እዩ ዚምርምሮ። ስለዚ እዚ ኣፕሊኬሽን እዚ ብዘይ ናይ ጉግል ኣገልግሎት ኣብ ኤለክትሮኒካዊ-መሳርሒታት ክትጥቀመሉ ትኽእል ኢኻ። ኒውፓይፕ ንምጥቃም ናይ ዩቱብ ሕሳብ ኣየድልየካን ኢዩ፣ ኒውፓይፕ FLOSS ኢዩ። diff --git a/fastlane/metadata/android/ti/short_description.txt b/fastlane/metadata/android/ti/short_description.txt index f7f2099a1..107cabea0 100644 --- a/fastlane/metadata/android/ti/short_description.txt +++ b/fastlane/metadata/android/ti/short_description.txt @@ -1 +1 @@ -ብናጻ ፈኲስ ናይ ዩቱብ ግንባር ንኣንድሮይድ ። +ነጻ ናይ ዩቱብ ግንባር ንኣንድሮይድ። diff --git a/fastlane/metadata/android/uk/changelogs/1002.txt b/fastlane/metadata/android/uk/changelogs/1002.txt index a90cfff6b..f52bf43af 100644 --- a/fastlane/metadata/android/uk/changelogs/1002.txt +++ b/fastlane/metadata/android/uk/changelogs/1002.txt @@ -1 +1,4 @@ -Виправлено проблему невідтворюваності трансляцій YouTube +Виправлено помилку, через яку YouTube не відтворював жодної трансляції. + +У цьому випуску вирішено лише найактуальнішу помилку, яка перешкоджала завантаженню деталей відео YouTube. +Ми знаємо про інші проблеми, і незабаром випустимо окремий випуск для їх вирішення. diff --git a/fastlane/metadata/android/uk/changelogs/1003.txt b/fastlane/metadata/android/uk/changelogs/1003.txt index a90cfff6b..b969e091c 100644 --- a/fastlane/metadata/android/uk/changelogs/1003.txt +++ b/fastlane/metadata/android/uk/changelogs/1003.txt @@ -1 +1,6 @@ -Виправлено проблему невідтворюваності трансляцій YouTube +Це виправлення, яке виправляє помилки YouTube: +• [YouTube] Виправлено не завантаження інформації про відео, виправлено помилки HTTP 403 під час відтворення відео та відновлено відтворення деяких відео з віковими обмеженнями +• Виправлено незмінні розміри субтитрів +• Виправлено подвійне завантаження інформації під час відкриття потоку +• [Soundcloud] Видалено невідтворювані потоки, захищені DRM +• Оновлені переклади diff --git a/fastlane/metadata/android/uk/changelogs/1004.txt b/fastlane/metadata/android/uk/changelogs/1004.txt index a90cfff6b..1c2ec5d7f 100644 --- a/fastlane/metadata/android/uk/changelogs/1004.txt +++ b/fastlane/metadata/android/uk/changelogs/1004.txt @@ -1 +1,3 @@ -Виправлено проблему невідтворюваності трансляцій YouTube +У цьому випуску виправлено помилку, через яку YouTube відтворював лише 360p-потік. + +Зверніть увагу, що рішення, що використовується в цій версії, ймовірно, тимчасове, і в довгостроковій перспективі потрібно буде впровадити відеопротокол SABR, але учасники TeamNewPipe зараз зайняті, тому будь-яка допомога буде дуже вдячна! https://github.com/TeamNewPipe/NewPipe/issues/12248 diff --git a/fastlane/metadata/android/uk/changelogs/1005.txt b/fastlane/metadata/android/uk/changelogs/1005.txt new file mode 100644 index 000000000..474127f95 --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/1005.txt @@ -0,0 +1,17 @@ +Нове +• Додано підтримку Android Auto +• Дозволено налаштування груп стрічок як вкладок головного екрана +• [YouTube] Поділитися як тимчасовий список відтворення +• [SoundCloud] Вкладка каналу «Вподобання» + +Покращено +• Кращі підказки в рядку пошуку +• Показувати дату завантаження в розділі «Завантаження» +• Використовувати мову Android 13 для кожної програми + +Виправлено +• Виправлено пошкоджені кольори тексту в темному режимі +• [YouTube] Виправлено списки відтворення, які не завантажували більше 100 елементів +• [YouTube] Виправлено відсутні рекомендовані відео +• Виправлено збої в перегляді історії +• Виправлено позначки часу у відповідях на коментарі diff --git a/fastlane/metadata/android/zh-Hans/changelogs/1001.txt b/fastlane/metadata/android/zh-Hans/changelogs/1001.txt new file mode 100644 index 000000000..cdebebf55 --- /dev/null +++ b/fastlane/metadata/android/zh-Hans/changelogs/1001.txt @@ -0,0 +1,6 @@ +改进 +- 始终允许在 Android 13以上系统上更改播放器通知首选项 + +修复 +- 修复了导出数据库/订阅时不会截断已存在的文件,从而可能导致导出损坏的问题 +- 修复了点击时间戳时,播放器从头开始恢复的问题 From e08d2d8726d6eadca78dc7ef06d537598daad6ca Mon Sep 17 00:00:00 2001 From: tobigr Date: Mon, 28 Jul 2025 22:02:16 +0200 Subject: [PATCH 134/143] Add new locals to the in-app language chooser --- app/src/main/res/values/settings_keys.xml | 32 +++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index f98639e04..01a812532 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -1192,6 +1192,8 @@ bn bn-bd bn-in + br + bs ca ckb cs @@ -1207,7 +1209,9 @@ fi fil fr + frc gl + gu he hi hr @@ -1219,23 +1223,31 @@ it ja jv + ka kab kmr + kn ko ku + la lt lv mk ml + mn + mr ms nb-no + nn ne nl nl-be + nqo oc or pa + pa-pk pl pt pt-br @@ -1254,7 +1266,11 @@ ta te th + ti + tl + tok tr + tt tzm uk ur @@ -1277,6 +1293,8 @@ বাংলা বাংলা (বাংলাদেশ) বাংলা (भारत) + Brezhoneg + Босански Català کوردیی سۆرانی Čeština @@ -1292,7 +1310,9 @@ Suomen kieli Wikang Filipino Français + Français (Louisiana) Galego + ગુજરાતી עברית हिन्दी Hrvatski @@ -1304,23 +1324,31 @@ Italiano 日本語 ꦧꦱꦗꦮ + ქართული Taqbaylit Kurmancî + ಕನ್ನಡ 한국어 کوردی + Latina Lietuvių kalba latviski македонски јазик മലയാളം + Монгол хэл + मराठी Bahasa Melayu Norsk bokmål + Norsk Nynorsk Nनेपाली Nederlands (NL) Nederlands (BE) + ߒߞߏ Occitan ଓଡ଼ିଆ ਪੰਜਾਬੀ + ਪੰਜਾਬੀ (PK) Polski Português Português (BR) @@ -1339,7 +1367,11 @@ தமிழ் తెలుగు ไทย + ትግርኛ + Wikang Tagalog + Toki Pona Türkçe + Татар теле Tamaziɣt українська мова اردو From 7130adb4eceaa43d60775190010a81db53ffb264 Mon Sep 17 00:00:00 2001 From: tobigr Date: Mon, 28 Jul 2025 22:02:29 +0200 Subject: [PATCH 135/143] Clean strings --- app/src/main/res/values-tl/strings.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/res/values-tl/strings.xml b/app/src/main/res/values-tl/strings.xml index 02794a620..d41b317e8 100644 --- a/app/src/main/res/values-tl/strings.xml +++ b/app/src/main/res/values-tl/strings.xml @@ -66,5 +66,4 @@ \nBuksan ang \"%1$s\" sa ayos ng app kung gusto mong makita ito. Mga Artista Nakalutang - \ No newline at end of file From ca9fc14c2aab2a49a4cd052136a0009a5a51a19b Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 29 Jul 2025 20:18:31 +0200 Subject: [PATCH 136/143] Fix name of nepali language (there was a leftover N) --- app/src/main/res/values/settings_keys.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index 01a812532..352e4cec1 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -1340,7 +1340,7 @@ Bahasa Melayu Norsk bokmål Norsk Nynorsk - Nनेपाली + नेपाली Nederlands (NL) Nederlands (BE) From ed93603815df0e58dcff19c72d412abd52444741 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Tue, 22 Jul 2025 00:01:40 +0200 Subject: [PATCH 137/143] WIP: Add SettingsMigration to change YouTube trending kiosk tab --- .../java/org/schabi/newpipe/MainActivity.java | 4 +- .../newpipe/settings/NewPipeSettings.java | 3 +- .../settings/migration/MigrationManager.java | 103 ++++++++++++++ .../{ => migration}/SettingMigrations.java | 128 ++++++++++++------ app/src/main/res/values/strings.xml | 2 + 5 files changed, 192 insertions(+), 48 deletions(-) create mode 100644 app/src/main/java/org/schabi/newpipe/settings/migration/MigrationManager.java rename app/src/main/java/org/schabi/newpipe/settings/{ => migration}/SettingMigrations.java (69%) diff --git a/app/src/main/java/org/schabi/newpipe/MainActivity.java b/app/src/main/java/org/schabi/newpipe/MainActivity.java index 21f4f97a1..1aae7fa86 100644 --- a/app/src/main/java/org/schabi/newpipe/MainActivity.java +++ b/app/src/main/java/org/schabi/newpipe/MainActivity.java @@ -78,8 +78,8 @@ import org.schabi.newpipe.player.Player; import org.schabi.newpipe.player.event.OnKeyDownListener; import org.schabi.newpipe.player.helper.PlayerHolder; import org.schabi.newpipe.player.playqueue.PlayQueue; -import org.schabi.newpipe.settings.SettingMigrations; import org.schabi.newpipe.settings.UpdateSettingsFragment; +import org.schabi.newpipe.settings.migration.MigrationManager; import org.schabi.newpipe.util.Constants; import org.schabi.newpipe.util.DeviceUtils; import org.schabi.newpipe.util.KioskTranslator; @@ -195,7 +195,7 @@ public class MainActivity extends AppCompatActivity { UpdateSettingsFragment.askForConsentToUpdateChecks(this); } - SettingMigrations.showUserInfoIfPresent(this); + MigrationManager.showUserInfoIfPresent(this); } @Override diff --git a/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java b/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java index 421440ea7..0a5512c69 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java +++ b/app/src/main/java/org/schabi/newpipe/settings/NewPipeSettings.java @@ -13,6 +13,7 @@ import androidx.preference.PreferenceManager; import org.schabi.newpipe.App; import org.schabi.newpipe.R; +import org.schabi.newpipe.settings.migration.MigrationManager; import org.schabi.newpipe.util.DeviceUtils; import java.io.File; @@ -46,7 +47,7 @@ public final class NewPipeSettings { public static void initSettings(final Context context) { // first run migrations, then setDefaultValues, since the latter requires the correct types - SettingMigrations.runMigrationsIfNeeded(context); + MigrationManager.runMigrationsIfNeeded(context); // readAgain is true so that if new settings are added their default value is set PreferenceManager.setDefaultValues(context, R.xml.main_settings, true); diff --git a/app/src/main/java/org/schabi/newpipe/settings/migration/MigrationManager.java b/app/src/main/java/org/schabi/newpipe/settings/migration/MigrationManager.java new file mode 100644 index 000000000..d5b0e783d --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/settings/migration/MigrationManager.java @@ -0,0 +1,103 @@ +package org.schabi.newpipe.settings.migration; + +import android.content.Context; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; +import androidx.core.util.Consumer; + +import org.schabi.newpipe.R; +import org.schabi.newpipe.error.ErrorUtil; + +import java.util.ArrayList; +import java.util.List; + +/** + * MigrationManager is responsible for running migrations and showing the user information about + * the migrations that were applied. + */ +public final class MigrationManager { + + private static final String TAG = MigrationManager.class.getSimpleName(); + /** + * List of UI actions that are performed after the UI is initialized (e.g. showing alert + * dialogs) to inform the user about changes that were applied by migrations. + */ + private static final List> MIGRATION_INFO = new ArrayList<>(); + + private MigrationManager() { + // MigrationManager is a utility class that is completely static + } + + /** + * Run all migrations that are needed for the current version of NewPipe. + * This method should be called at the start of the application, before any other operations + * that depend on the settings. + * + * @param context Context that can be used to run migrations + */ + public static void runMigrationsIfNeeded(@NonNull final Context context) { + SettingMigrations.runMigrationsIfNeeded(context); + } + + /** + * Perform UI actions informing about migrations that took place if they are present. + * @param context Context that can be used to show dialogs/snackbars/toasts + */ + public static void showUserInfoIfPresent(@NonNull final Context context) { + if (MIGRATION_INFO.isEmpty()) { + return; + } + + try { + MIGRATION_INFO.get(0).accept(context); + } catch (final Exception e) { + ErrorUtil.showUiErrorSnackbar(context, "Showing migration info to the user", e); + // Remove the migration that caused the error and continue with the next one + MIGRATION_INFO.remove(0); + showUserInfoIfPresent(context); + } + } + + /** + * Add a migration info action that will be executed after the UI is initialized. + * This can be used to show dialogs/snackbars/toasts to inform the user about changes that + * were applied by migrations. + * + * @param info the action to be executed + */ + public static void addMigrationInfo(final Consumer info) { + MIGRATION_INFO.add(info); + } + + /** + * This method should be called when the user dismisses the migration info + * to check if there are any more migration info actions to be shown. + * @param context Context that can be used to show dialogs/snackbars/toasts + */ + public static void onMigrationInfoDismissed(@NonNull final Context context) { + MIGRATION_INFO.remove(0); + showUserInfoIfPresent(context); + } + + /** + * Creates a dialog to inform the user about the migration. + * @param uiContext Context that can be used to show dialogs/snackbars/toasts + * @param title the title of the dialog + * @param message the message of the dialog + * @return the dialog that can be shown to the user with a custom dismiss listener + */ + static AlertDialog createMigrationInfoDialog(@NonNull final Context uiContext, + @NonNull final String title, + @NonNull final String message) { + return new AlertDialog.Builder(uiContext) + .setTitle(title) + .setMessage(message) + .setPositiveButton(R.string.ok, null) + .setOnDismissListener(dialog -> + MigrationManager.onMigrationInfoDismissed(uiContext)) + .setCancelable(false) // prevents the dialog from being dismissed accidentally + .create(); + } + +} diff --git a/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java b/app/src/main/java/org/schabi/newpipe/settings/migration/SettingMigrations.java similarity index 69% rename from app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java rename to app/src/main/java/org/schabi/newpipe/settings/migration/SettingMigrations.java index d13e73090..99af27766 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SettingMigrations.java +++ b/app/src/main/java/org/schabi/newpipe/settings/migration/SettingMigrations.java @@ -1,11 +1,14 @@ -package org.schabi.newpipe.settings; +package org.schabi.newpipe.settings.migration; + +import static org.schabi.newpipe.MainActivity.DEBUG; +import static org.schabi.newpipe.extractor.ServiceList.SoundCloud; +import static org.schabi.newpipe.extractor.ServiceList.YouTube; import android.content.Context; import android.content.SharedPreferences; import android.util.Log; import androidx.annotation.NonNull; -import androidx.appcompat.app.AlertDialog; import androidx.core.util.Consumer; import androidx.preference.PreferenceManager; @@ -25,27 +28,28 @@ import java.util.List; import java.util.Set; import java.util.stream.Collectors; -import static org.schabi.newpipe.MainActivity.DEBUG; -import static org.schabi.newpipe.extractor.ServiceList.SoundCloud; - /** - * In order to add a migration, follow these steps, given P is the previous version:
    - * - in the class body add a new {@code MIGRATION_P_P+1 = new Migration(P, P+1) { ... }} and put in - * the {@code migrate()} method the code that need to be run when migrating from P to P+1
    - * - add {@code MIGRATION_P_P+1} at the end of {@link SettingMigrations#SETTING_MIGRATIONS}
    - * - increment {@link SettingMigrations#VERSION}'s value by 1 (so it should become P+1) + * This class contains the code to migrate the settings from one version to another. + * Migrations are run automatically when the app is started and the settings version changed. + *
    + * In order to add a migration, follow these steps, given {@code P} is the previous version: + *

      + *
    • in the class body add a new {@code MIGRATION_P_P+1 = new Migration(P, P+1) { ... }} and put + * in the {@code migrate()} method the code that need to be run + * when migrating from {@code P} to {@code P+1}
    • + *
    • add {@code MIGRATION_P_P+1} at the end of {@link SettingMigrations#SETTING_MIGRATIONS}
    • + *
    • increment {@link SettingMigrations#VERSION}'s value by 1 + * (so it becomes {@code P+1})
    • + *
    + * Migrations can register UI actions using {@link MigrationManager#addMigrationInfo(Consumer)} + * that will be performed after the UI is initialized to inform the user about changes + * that were applied by migrations. */ public final class SettingMigrations { private static final String TAG = SettingMigrations.class.toString(); private static SharedPreferences sp; - /** - * List of UI actions that are performed after the UI is initialized (e.g. showing alert - * dialogs) to inform the user about changes that were applied by migrations. - */ - private static final List> MIGRATION_INFO = new ArrayList<>(); - private static final Migration MIGRATION_0_1 = new Migration(0, 1) { @Override public void migrate(@NonNull final Context context) { @@ -169,16 +173,63 @@ public final class SettingMigrations { && kioskTab.getKioskServiceId() == SoundCloud.getServiceId() && kioskTab.getKioskId().equals("Top 50"))) .collect(Collectors.toUnmodifiableList()); - if (tabs.size() != cleanedTabs.size()) { + if (tabs.size() != cleanedTabs.size() || DEBUG) { // TODO: remove debug condition tabsManager.saveTabs(cleanedTabs); // create an AlertDialog to inform the user about the change - MIGRATION_INFO.add((Context uiContext) -> new AlertDialog.Builder(uiContext) - .setTitle(R.string.migration_info_6_7_title) - .setMessage(R.string.migration_info_6_7_message) - .setPositiveButton(R.string.ok, null) - .setCancelable(false) - .create() - .show()); + MigrationManager.addMigrationInfo(uiContext -> + MigrationManager.createMigrationInfoDialog( + uiContext, + uiContext.getString(R.string.migration_info_6_7_title), + uiContext.getString(R.string.migration_info_6_7_message)) + .show()); + } + } + }; + + private static final Migration MIGRATION_7_8 = new Migration(7, 8) { + @Override + protected void migrate(@NonNull final Context context) { + // YouTube remove the combined Trending kiosk, see + // https://github.com/TeamNewPipe/NewPipe/discussions/12445 for more information. + // If the user has a dedicated YouTube/Trending kiosk tab, + // it is removed and replaced with the new live kiosk tab. + // The default trending kiosk tab is not touched + // because it uses the default kiosk provided by the extractor + // and is thus updated automatically. + final TabsManager tabsManager = TabsManager.getManager(context); + final List tabs = tabsManager.getTabs(); + final boolean hadYtTrendingTab = tabs.stream() + .anyMatch(tab -> !(tab instanceof Tab.KioskTab kioskTab + && kioskTab.getKioskServiceId() == YouTube.getServiceId() + && kioskTab.getKioskId().equals("Trending"))); + if (hadYtTrendingTab) { + final List cleanedTabs = new ArrayList<>(); + for (final Tab tab : tabs) { + if (tab instanceof Tab.KioskTab kioskTab + && kioskTab.getKioskServiceId() == YouTube.getServiceId() + && kioskTab.getKioskId().equals("Trending")) { + // replace the YouTube Trending tab with the new live kiosk tab + // TODO: use the correct kiosk ID for the live kiosk tab + cleanedTabs.add(new Tab.KioskTab(YouTube.getServiceId(), "Live")); + } else { + cleanedTabs.add(tab); + } + } + tabsManager.saveTabs(cleanedTabs); + } + + final boolean hasDefaultTrendingTab = tabs.stream() + .anyMatch(tab -> tab instanceof Tab.DefaultKioskTab); + + // TODO: remove debugging code + if (hadYtTrendingTab || hasDefaultTrendingTab || newVersion == VERSION) { + // User is informed about the change + MigrationManager.addMigrationInfo(uiContext -> + MigrationManager.createMigrationInfoDialog( + uiContext, + uiContext.getString(R.string.migration_info_7_8_title), + uiContext.getString(R.string.migration_info_7_8_message)) + .show()); } } }; @@ -196,26 +247,28 @@ public final class SettingMigrations { MIGRATION_3_4, MIGRATION_4_5, MIGRATION_5_6, - MIGRATION_6_7 + MIGRATION_6_7, + MIGRATION_7_8, }; /** * Version number for preferences. Must be incremented every time a migration is necessary. */ - private static final int VERSION = 7; + private static final int VERSION = 8; - public static void runMigrationsIfNeeded(@NonNull final Context context) { + static void runMigrationsIfNeeded(@NonNull final Context context) { // setup migrations and check if there is something to do sp = PreferenceManager.getDefaultSharedPreferences(context); final String lastPrefVersionKey = context.getString(R.string.last_used_preferences_version); - final int lastPrefVersion = sp.getInt(lastPrefVersionKey, 0); + //final int lastPrefVersion = sp.getInt(lastPrefVersionKey, 0); + final int lastPrefVersion = 6; // TODO: remove this line after testing // no migration to run, already up to date if (App.getApp().isFirstRun()) { sp.edit().putInt(lastPrefVersionKey, VERSION).apply(); return; - } else if (lastPrefVersion == VERSION) { + } else if (lastPrefVersion == VERSION && !DEBUG) { // TODO: remove DEBUG check return; } @@ -249,21 +302,6 @@ public final class SettingMigrations { sp.edit().putInt(lastPrefVersionKey, currentVersion).apply(); } - /** - * Perform UI actions informing about migrations that took place if they are present. - * @param context Context that can be used to show dialogs/snackbars/toasts - */ - public static void showUserInfoIfPresent(@NonNull final Context context) { - for (final Consumer consumer : MIGRATION_INFO) { - try { - consumer.accept(context); - } catch (final Exception e) { - ErrorUtil.showUiErrorSnackbar(context, "Showing migration info to the user", e); - } - } - MIGRATION_INFO.clear(); - } - private SettingMigrations() { } abstract static class Migration { @@ -282,7 +320,7 @@ public final class SettingMigrations { * the current settings version. */ private boolean shouldMigrate(final int currentVersion) { - return oldVersion >= currentVersion; + return oldVersion >= currentVersion || newVersion == VERSION; } protected abstract void migrate(@NonNull Context context); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6ab2fc7a5..cfc51f4e9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -866,4 +866,6 @@ The settings in the export being imported use a vulnerable format that was deprecated since NewPipe 0.27.0. Make sure the export being imported is from a trusted source, and prefer using only exports obtained from NewPipe 0.27.0 or newer in the future. Support for importing settings in this vulnerable format will soon be removed completely, and then old versions of NewPipe will not be able to import settings of exports from new versions anymore. SoundCloud Top 50 page removed SoundCloud has discontinued the original Top 50 charts. The corresponding tab has been removed from your main page. + YouTube combined trending removed + YouTube has discontinued the combined trending page as of 21st July 2025. NewPipe replaced the default trending page with the trending livestreams.\n\nYou can also select different ones in the content settings. From 7cecd11f721d49c8da357a63ef193dc19a42b3b0 Mon Sep 17 00:00:00 2001 From: Stypox Date: Mon, 28 Jul 2025 19:24:18 +0200 Subject: [PATCH 138/143] [YouTube] Add icons and strings for new trending pages --- .../org/schabi/newpipe/util/KioskTranslator.java | 16 ++++++++++++++++ app/src/main/res/drawable/ic_podcasts.xml | 5 +++++ app/src/main/res/values/strings.xml | 4 ++++ 3 files changed, 25 insertions(+) create mode 100644 app/src/main/res/drawable/ic_podcasts.xml diff --git a/app/src/main/java/org/schabi/newpipe/util/KioskTranslator.java b/app/src/main/java/org/schabi/newpipe/util/KioskTranslator.java index b8c2ff236..69cf17639 100644 --- a/app/src/main/java/org/schabi/newpipe/util/KioskTranslator.java +++ b/app/src/main/java/org/schabi/newpipe/util/KioskTranslator.java @@ -52,6 +52,14 @@ public final class KioskTranslator { return c.getString(R.string.featured); case "Radio": return c.getString(R.string.radio); + case "trending_gaming": + return c.getString(R.string.gaming); + case "trending_music": + return c.getString(R.string.music); + case "trending_movies_and_shows": + return c.getString(R.string.movies); + case "trending_podcasts_episodes": + return c.getString(R.string.podcasts); default: return kioskId; } @@ -77,6 +85,14 @@ public final class KioskTranslator { return R.drawable.ic_stars; case "Radio": return R.drawable.ic_radio; + case "trending_gaming": + return R.drawable.ic_videogame_asset; + case "trending_music": + return R.drawable.ic_music_note; + case "trending_movies_and_shows": + return R.drawable.ic_movie; + case "trending_podcasts_episodes": + return R.drawable.ic_podcasts; default: return 0; } diff --git a/app/src/main/res/drawable/ic_podcasts.xml b/app/src/main/res/drawable/ic_podcasts.xml new file mode 100644 index 000000000..c297e8fd3 --- /dev/null +++ b/app/src/main/res/drawable/ic_podcasts.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index cfc51f4e9..a8c8694ca 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -868,4 +868,8 @@ SoundCloud has discontinued the original Top 50 charts. The corresponding tab has been removed from your main page. YouTube combined trending removed YouTube has discontinued the combined trending page as of 21st July 2025. NewPipe replaced the default trending page with the trending livestreams.\n\nYou can also select different ones in the content settings. + Gaming + Music + Movies + Podcasts From 8400a9ae8ec7a4361b9398f7e20177531d751119 Mon Sep 17 00:00:00 2001 From: Stypox Date: Mon, 28 Jul 2025 21:47:26 +0200 Subject: [PATCH 139/143] Remove DEBUG statements and don't replace yt trending with live You can use this command to test instead: adb shell run-as org.schabi.newpipe.debug.pr12450 'sed -i '"'"'s###'"'"' shared_prefs/org.schabi.newpipe.debug.pr12450_preferences.xml' && adb shell run-as org.schabi.newpipe.debug.pr12450 'sed -i '"'"'s#\]}#,{\"tab_id\":5,\"service_id\":0,\"kiosk_id\":\"Trending\"},{\"tab_id\":5,\"service_id\":1,\"kiosk_id\":\"Top 50\"}]}#'"'"' shared_prefs/org.schabi.newpipe.debug.pr12450_preferences.xml' --- .../settings/migration/SettingMigrations.java | 34 ++++++------------- app/src/main/res/values/strings.xml | 2 +- 2 files changed, 11 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/migration/SettingMigrations.java b/app/src/main/java/org/schabi/newpipe/settings/migration/SettingMigrations.java index 99af27766..67944075d 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/migration/SettingMigrations.java +++ b/app/src/main/java/org/schabi/newpipe/settings/migration/SettingMigrations.java @@ -21,7 +21,6 @@ import org.schabi.newpipe.settings.tabs.Tab; import org.schabi.newpipe.settings.tabs.TabsManager; import org.schabi.newpipe.util.DeviceUtils; -import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -173,7 +172,7 @@ public final class SettingMigrations { && kioskTab.getKioskServiceId() == SoundCloud.getServiceId() && kioskTab.getKioskId().equals("Top 50"))) .collect(Collectors.toUnmodifiableList()); - if (tabs.size() != cleanedTabs.size() || DEBUG) { // TODO: remove debug condition + if (tabs.size() != cleanedTabs.size()) { tabsManager.saveTabs(cleanedTabs); // create an AlertDialog to inform the user about the change MigrationManager.addMigrationInfo(uiContext -> @@ -198,31 +197,19 @@ public final class SettingMigrations { // and is thus updated automatically. final TabsManager tabsManager = TabsManager.getManager(context); final List tabs = tabsManager.getTabs(); - final boolean hadYtTrendingTab = tabs.stream() - .anyMatch(tab -> !(tab instanceof Tab.KioskTab kioskTab + final List cleanedTabs = tabs.stream() + .filter(tab -> !(tab instanceof Tab.KioskTab kioskTab && kioskTab.getKioskServiceId() == YouTube.getServiceId() - && kioskTab.getKioskId().equals("Trending"))); - if (hadYtTrendingTab) { - final List cleanedTabs = new ArrayList<>(); - for (final Tab tab : tabs) { - if (tab instanceof Tab.KioskTab kioskTab - && kioskTab.getKioskServiceId() == YouTube.getServiceId() - && kioskTab.getKioskId().equals("Trending")) { - // replace the YouTube Trending tab with the new live kiosk tab - // TODO: use the correct kiosk ID for the live kiosk tab - cleanedTabs.add(new Tab.KioskTab(YouTube.getServiceId(), "Live")); - } else { - cleanedTabs.add(tab); - } - } + && kioskTab.getKioskId().equals("Trending"))) + .collect(Collectors.toUnmodifiableList()); + if (tabs.size() != cleanedTabs.size()) { tabsManager.saveTabs(cleanedTabs); } final boolean hasDefaultTrendingTab = tabs.stream() .anyMatch(tab -> tab instanceof Tab.DefaultKioskTab); - // TODO: remove debugging code - if (hadYtTrendingTab || hasDefaultTrendingTab || newVersion == VERSION) { + if (tabs.size() != cleanedTabs.size() || hasDefaultTrendingTab) { // User is informed about the change MigrationManager.addMigrationInfo(uiContext -> MigrationManager.createMigrationInfoDialog( @@ -261,14 +248,13 @@ public final class SettingMigrations { // setup migrations and check if there is something to do sp = PreferenceManager.getDefaultSharedPreferences(context); final String lastPrefVersionKey = context.getString(R.string.last_used_preferences_version); - //final int lastPrefVersion = sp.getInt(lastPrefVersionKey, 0); - final int lastPrefVersion = 6; // TODO: remove this line after testing + final int lastPrefVersion = sp.getInt(lastPrefVersionKey, 0); // no migration to run, already up to date if (App.getApp().isFirstRun()) { sp.edit().putInt(lastPrefVersionKey, VERSION).apply(); return; - } else if (lastPrefVersion == VERSION && !DEBUG) { // TODO: remove DEBUG check + } else if (lastPrefVersion == VERSION) { return; } @@ -320,7 +306,7 @@ public final class SettingMigrations { * the current settings version. */ private boolean shouldMigrate(final int currentVersion) { - return oldVersion >= currentVersion || newVersion == VERSION; + return oldVersion >= currentVersion; } protected abstract void migrate(@NonNull Context context); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a8c8694ca..c78845472 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -867,7 +867,7 @@ SoundCloud Top 50 page removed SoundCloud has discontinued the original Top 50 charts. The corresponding tab has been removed from your main page. YouTube combined trending removed - YouTube has discontinued the combined trending page as of 21st July 2025. NewPipe replaced the default trending page with the trending livestreams.\n\nYou can also select different ones in the content settings. + YouTube has discontinued the combined trending page as of 21st July 2025. NewPipe replaced the default trending page with the trending livestreams.\n\nYou can also select different trending pages in \"Settings > Content > Content of main page\". Gaming Music Movies From d96c0aebb1c2a893fb28e6cf40aa9af772ecb002 Mon Sep 17 00:00:00 2001 From: Stypox Date: Thu, 31 Jul 2025 22:48:13 +0200 Subject: [PATCH 140/143] Show tabs above kiosks in drawer --- .../java/org/schabi/newpipe/MainActivity.java | 60 ++++++++++--------- app/src/main/res/menu/drawer_items.xml | 1 + 2 files changed, 34 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/MainActivity.java b/app/src/main/java/org/schabi/newpipe/MainActivity.java index 1aae7fa86..4fbd562b4 100644 --- a/app/src/main/java/org/schabi/newpipe/MainActivity.java +++ b/app/src/main/java/org/schabi/newpipe/MainActivity.java @@ -263,19 +263,6 @@ public class MainActivity extends AppCompatActivity { */ private void addDrawerMenuForCurrentService() throws ExtractionException { //Tabs - final int currentServiceId = ServiceHelper.getSelectedServiceId(this); - final StreamingService service = NewPipe.getService(currentServiceId); - - int kioskMenuItemId = 0; - - for (final String ks : service.getKioskList().getAvailableKiosks()) { - drawerLayoutBinding.navigation.getMenu() - .add(R.id.menu_tabs_group, kioskMenuItemId, 0, KioskTranslator - .getTranslatedKioskName(ks, this)) - .setIcon(KioskTranslator.getKioskIcon(ks)); - kioskMenuItemId++; - } - drawerLayoutBinding.navigation.getMenu() .add(R.id.menu_tabs_group, ITEM_ID_SUBSCRIPTIONS, ORDER, R.string.tab_subscriptions) @@ -293,6 +280,20 @@ public class MainActivity extends AppCompatActivity { .add(R.id.menu_tabs_group, ITEM_ID_HISTORY, ORDER, R.string.action_history) .setIcon(R.drawable.ic_history); + //Kiosks + final int currentServiceId = ServiceHelper.getSelectedServiceId(this); + final StreamingService service = NewPipe.getService(currentServiceId); + + int kioskMenuItemId = 0; + + for (final String ks : service.getKioskList().getAvailableKiosks()) { + drawerLayoutBinding.navigation.getMenu() + .add(R.id.menu_kiosks_group, kioskMenuItemId, 0, KioskTranslator + .getTranslatedKioskName(ks, this)) + .setIcon(KioskTranslator.getKioskIcon(ks)); + kioskMenuItemId++; + } + //Settings and About drawerLayoutBinding.navigation.getMenu() .add(R.id.menu_options_about_group, ITEM_ID_SETTINGS, ORDER, R.string.settings) @@ -312,10 +313,13 @@ public class MainActivity extends AppCompatActivity { changeService(item); break; case R.id.menu_tabs_group: + tabSelected(item); + break; + case R.id.menu_kiosks_group: try { - tabSelected(item); + kioskSelected(item); } catch (final Exception e) { - ErrorUtil.showUiErrorSnackbar(this, "Selecting main page tab", e); + ErrorUtil.showUiErrorSnackbar(this, "Selecting drawer kiosk", e); } break; case R.id.menu_options_about_group: @@ -339,7 +343,7 @@ public class MainActivity extends AppCompatActivity { .setChecked(true); } - private void tabSelected(final MenuItem item) throws ExtractionException { + private void tabSelected(final MenuItem item) { switch (item.getItemId()) { case ITEM_ID_SUBSCRIPTIONS: NavigationHelper.openSubscriptionFragment(getSupportFragmentManager()); @@ -356,18 +360,19 @@ public class MainActivity extends AppCompatActivity { case ITEM_ID_HISTORY: NavigationHelper.openStatisticFragment(getSupportFragmentManager()); break; - default: - final StreamingService currentService = ServiceHelper.getSelectedService(this); - int kioskMenuItemId = 0; - for (final String kioskId : currentService.getKioskList().getAvailableKiosks()) { - if (kioskMenuItemId == item.getItemId()) { - NavigationHelper.openKioskFragment(getSupportFragmentManager(), - currentService.getServiceId(), kioskId); - break; - } - kioskMenuItemId++; - } + } + } + + private void kioskSelected(final MenuItem item) throws ExtractionException { + final StreamingService currentService = ServiceHelper.getSelectedService(this); + int kioskMenuItemId = 0; + for (final String kioskId : currentService.getKioskList().getAvailableKiosks()) { + if (kioskMenuItemId == item.getItemId()) { + NavigationHelper.openKioskFragment(getSupportFragmentManager(), + currentService.getServiceId(), kioskId); break; + } + kioskMenuItemId++; } } @@ -408,6 +413,7 @@ public class MainActivity extends AppCompatActivity { drawerLayoutBinding.navigation.getMenu().removeGroup(R.id.menu_services_group); drawerLayoutBinding.navigation.getMenu().removeGroup(R.id.menu_tabs_group); + drawerLayoutBinding.navigation.getMenu().removeGroup(R.id.menu_kiosks_group); drawerLayoutBinding.navigation.getMenu().removeGroup(R.id.menu_options_about_group); // Show up or down arrow diff --git a/app/src/main/res/menu/drawer_items.xml b/app/src/main/res/menu/drawer_items.xml index 24c321b8a..8214f3f02 100644 --- a/app/src/main/res/menu/drawer_items.xml +++ b/app/src/main/res/menu/drawer_items.xml @@ -2,5 +2,6 @@ + From b7b836e941a87a44a149775dc33c23a4f001055c Mon Sep 17 00:00:00 2001 From: Stypox Date: Thu, 31 Jul 2025 23:10:47 +0200 Subject: [PATCH 141/143] Update the names of YT kiosks --- .../java/org/schabi/newpipe/util/KioskTranslator.java | 8 ++++---- .../main/java/org/schabi/newpipe/util/Localization.java | 3 ++- app/src/main/res/values/strings.xml | 8 ++++---- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/util/KioskTranslator.java b/app/src/main/java/org/schabi/newpipe/util/KioskTranslator.java index 69cf17639..5aa332159 100644 --- a/app/src/main/java/org/schabi/newpipe/util/KioskTranslator.java +++ b/app/src/main/java/org/schabi/newpipe/util/KioskTranslator.java @@ -53,13 +53,13 @@ public final class KioskTranslator { case "Radio": return c.getString(R.string.radio); case "trending_gaming": - return c.getString(R.string.gaming); + return c.getString(R.string.trending_gaming); case "trending_music": - return c.getString(R.string.music); + return c.getString(R.string.trending_music); case "trending_movies_and_shows": - return c.getString(R.string.movies); + return c.getString(R.string.trending_movies); case "trending_podcasts_episodes": - return c.getString(R.string.podcasts); + return c.getString(R.string.trending_podcasts); default: return kioskId; } diff --git a/app/src/main/java/org/schabi/newpipe/util/Localization.java b/app/src/main/java/org/schabi/newpipe/util/Localization.java index bd5463088..1073afffd 100644 --- a/app/src/main/java/org/schabi/newpipe/util/Localization.java +++ b/app/src/main/java/org/schabi/newpipe/util/Localization.java @@ -388,9 +388,10 @@ public final class Localization { * {@code parsed != null} and the relevant setting is enabled, {@code textual} will * be appended to the returned string for debugging purposes. */ + @Nullable public static String relativeTimeOrTextual(@Nullable final Context context, @Nullable final DateWrapper parsed, - final String textual) { + @Nullable final String textual) { if (parsed == null) { return textual; } else if (DEBUG && context != null && PreferenceManager diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c78845472..57f78c221 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -868,8 +868,8 @@ SoundCloud has discontinued the original Top 50 charts. The corresponding tab has been removed from your main page. YouTube combined trending removed YouTube has discontinued the combined trending page as of 21st July 2025. NewPipe replaced the default trending page with the trending livestreams.\n\nYou can also select different trending pages in \"Settings > Content > Content of main page\". - Gaming - Music - Movies - Podcasts + Gaming trends + Trending podcasts + Trending movies and shows + Trending music From b846746119fb037b39425775acbea53d92472673 Mon Sep 17 00:00:00 2001 From: Stypox Date: Thu, 31 Jul 2025 23:32:04 +0200 Subject: [PATCH 142/143] Update NewPipeExtractor to v0.24.8 --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 54bd86a72..d6c93c1f7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -214,7 +214,7 @@ dependencies { // the corresponding commit hash, since JitPack sometimes deletes artifacts. // If there’s already a git hash, just add more of it to the end (or remove a letter) // to cause jitpack to regenerate the artifact. - implementation 'com.github.TeamNewPipe:NewPipeExtractor:7adbc48a0aa872c016b8ec089e278d5e12772054' + implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.24.8' implementation 'com.github.TeamNewPipe:NoNonsense-FilePicker:5.0.0' /** Checkstyle **/ From 5aefa4aff258487df72343ea5edcfbe43e1b3f2e Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Thu, 31 Jul 2025 23:42:34 +0200 Subject: [PATCH 143/143] Translated using Weblate (Tigrinya) Currently translated at 12.7% (95 of 748 strings) Co-authored-by: fool --- app/src/main/res/values-ti/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-ti/strings.xml b/app/src/main/res/values-ti/strings.xml index e1f61b7d1..f25b86cc1 100644 --- a/app/src/main/res/values-ti/strings.xml +++ b/app/src/main/res/values-ti/strings.xml @@ -5,7 +5,7 @@ ውጽኢት ናይ፦ %s ንኽትጅምር ነቲ ምድላይ ምልክት ጠውቆ። ዝተሓትመሉ ዕለት %1$s - ናይ ዥረት ተጻዋታይ ኣይተረኽበን። VLC ኣውርድ፧ + ናይ ዥረት ተጻዋታይ ኣይተረኽበን። VLC ይውርድ፧ ሐራይ ቅጥዕታት \"%1$s\" ማለቱ ድዩ፧