From c9ef089199116def2191123c8073695116061568 Mon Sep 17 00:00:00 2001 From: Bernd N Date: Tue, 28 Jul 2020 14:03:38 +0000 Subject: [PATCH 001/137] Translated using Weblate (German) Currently translated at 100.0% (584 of 584 strings) --- app/src/main/res/values-de/strings.xml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 20c4e3286..1902fff85 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -33,8 +33,8 @@ Video-Vorschaubild Video abspielen, Dauer: Avatarbild des Uploaders - Gefällt nicht - Gefällt + Gefällt mir nicht + Gefällt mir Externen Video-Player verwenden Externen Audio-Player verwenden Im Hintergrund abspielen @@ -581,7 +581,7 @@ Abos zuletzt aktualisiert: %s Grenzwert für Feed-Aktualisierung Aus fest zugeordnetem Feed abholen wenn verfügbar - Steht in manchen Diensten zur Verfügung, ist meist viel schneller, liefert aber eventuell eine eingeschränkte Anzahl an Elementen und oft inkomplette Informationen (z. B. keine Videolänge, keinen Elementtyp, keinen Live-Status). + Steht in manchen Diensten zur Verfügung, ist meist viel schneller, liefert aber eventuell eine eingeschränkte Anzahl an Elementen und oft unvollständige Informationen (z. B. keine Videolänge, keinen Elementtyp, keinen Live-Status). Glaubst du, dass das Laden von Feeds zu langsam ist\? Wenn ja, versuche den Schnelllademodus einzuschalten (du kannst ihn in den Einstellungen oder über die Schaltfläche unten ändern). \n \nNewPipe bietet zwei Feed-Ladestrategien: @@ -616,4 +616,9 @@ Erstellt von %s Von %s Nur nicht gruppierte Abonnements anzeigen + Playlist-Seite + Keine Playlist Bookmarks bis jetzt + Playlist auswählen + Bitte überprüfen Sie, ob es schon Fragen zu diesem Thema gibt. Doppelt erstellte Tickets kosten uns Zeit, die wir nutzen könnten, um diesen Fehler zu beheben. + Zeige Ergebnisse für: %s \ No newline at end of file From 4a50fcab2c336ccf2de5f29d615f1a007bbd4607 Mon Sep 17 00:00:00 2001 From: ssantos Date: Tue, 28 Jul 2020 14:48:08 +0000 Subject: [PATCH 002/137] Translated using Weblate (Portuguese) Currently translated at 100.0% (584 of 584 strings) --- app/src/main/res/values-pt/strings.xml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index a52946dbd..8a3fb139f 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -105,7 +105,7 @@ Transferência do NewPipe Não foi possível carregar a imagem Aplicação/IU terminou em erro - O quê:\\nPedido:\\nIdioma do conteúdo:\\nServiço:\\nHora GMT:\\nPacote:\\nVersão:\\nVersão do SO: + O quê:\\nPedido:\\nIdioma do conteúdo:\\nPaís do conteúdo\\nIdioma da app\\nServiço:\\nHora GMT:\\nPacote:\\nVersão:\\nVersão do SO: Abrir em modo popup Preto Tudo @@ -614,4 +614,11 @@ Criado por %s Miniatura do avatar do canal Mostrar apenas assinaturas não agrupadas + Página da lista de reprodução + Ainda não há marcadores de listas de reprodução + Selecione uma lista de reprodução + Por favor, verifique se já existe um assunto a discutir o seu acidente. Criar bilhetes duplicados tirará-nos tempo que poderíamos gastar com a reparação do bug real. + Reportar erro no GitHub + Copiar relatório formatado + Mostrando resultados para: %s \ No newline at end of file From b4a34d58db4d32c4f84bef88d0af09e191b881f1 Mon Sep 17 00:00:00 2001 From: zmni Date: Tue, 28 Jul 2020 12:07:09 +0000 Subject: [PATCH 003/137] Translated using Weblate (Indonesian) Currently translated at 100.0% (584 of 584 strings) --- app/src/main/res/values-in/strings.xml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index cc976ecff..2f6520372 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -102,7 +102,7 @@ Tidak bisa dekripsi tanda tangan URL video App/UI rusak Tidak bisa mendapatkan stream apapun - Apa:\\nPermintaan:\\nBahasa Konten:\\nLayanan:\\nWaktu GMT:\\nPaket:\\nVersi:\\nVersi OS: + Apa:\\nPermintaan:\\nBahasa Konten:\\nNegara Konten:\\nBahasa Apl:\\nLayanan:\\nWaktu GMT:\\nPaket:\\nVersi:\\nVersi OS: Laporan pengguna Thread Tantangan reCAPTCHA @@ -603,4 +603,12 @@ Oleh %s Dibuat oleh %s Thumbnail avatar channel + Harap periksa apakah masalah yang sama sudah ada atau belum. Ketika laporan anda ternyata sudah ada, anda membuat kami menghabiskan waktu yang seharusnya bisa kami gunakan untuk meningkatkan aplikasi menjadi lebih baik. + Laporkan kesalahan pada GitHub + Salin laporan dengan format + Menampilkan hasil untuk: %s + Halaman daftar putar + Hanya tampilkan langganan tanpa grup + Belum ada markah daftar putar + Pilih daftar putar \ No newline at end of file From 7f1749d8532cbad175b37335db2c70bf88741289 Mon Sep 17 00:00:00 2001 From: WaldiS Date: Tue, 28 Jul 2020 14:20:19 +0000 Subject: [PATCH 004/137] Translated using Weblate (Polish) Currently translated at 100.0% (584 of 584 strings) --- app/src/main/res/values-pl/strings.xml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index deef7afbd..461bcfe2c 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -68,7 +68,7 @@ Zgłoś Informacje: Co się stało: - Co:\\nRequest:\\nJęzyk treści:\\nUsługa:\\nCzas GMT:\\nPakiet:\\nWersja:\\nWersja systemu: + Co:\\nŻądanie:\\nJęzyk treści:\\nKraj treści:\\nJęzyk aplikacji:\\nUsługa:\\nCzas GMT:\\nPakiet:\\nWersja:\\nWersja systemu operacyjnego: Twój komentarz (po angielsku): Szczegóły: Miniatura filmu @@ -624,4 +624,11 @@ Utworzone przez %s Miniatura awatara kanału Pokaż tylko niezgrupowane subskrypcje + Strona playlisty + Nie ma jeszcze zakładek list odtwarzania + Wybierz playlistę + Sprawdź, czy problem dotyczący Twojej awarii już istnieje. Tworząc zduplikowane wpisy, zajmujesz nam czas, który możemy poświęcić na naprawienie rzeczywistego błędu. + Zgłoś błąd na GitHub + Skopiuj sformatowany raport + Wyświetlono wyniki dla: %s \ No newline at end of file From a7dc0c2d55f0f526e5ad00e06e73d8d851c07696 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Gon=C3=A7alves?= Date: Tue, 28 Jul 2020 13:20:51 +0000 Subject: [PATCH 005/137] Translated using Weblate (Portuguese (Brazil)) Currently translated at 98.8% (577 of 584 strings) --- app/src/main/res/values-pt-rBR/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index a0a62ca91..bda8dd452 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -614,4 +614,5 @@ Criado por %s Capa do avatar do canal Mostrar apenas inscrições não agrupadas + Mostrando resultados para\? %s \ No newline at end of file From 2e1029e1578982426b6c4c3422e44aca94a8f839 Mon Sep 17 00:00:00 2001 From: chr56 Date: Tue, 28 Jul 2020 13:38:33 +0000 Subject: [PATCH 006/137] Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (584 of 584 strings) --- app/src/main/res/values-b+zh+HANS+CN/strings.xml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-b+zh+HANS+CN/strings.xml b/app/src/main/res/values-b+zh+HANS+CN/strings.xml index 40712041e..749540eb6 100644 --- a/app/src/main/res/values-b+zh+HANS+CN/strings.xml +++ b/app/src/main/res/values-b+zh+HANS+CN/strings.xml @@ -71,7 +71,7 @@ 无法得知订阅人数 发布新版本时,通知我升级应用 网格 - NewPipe有更新! + NewPipe可更新! 服务器不接受 接收 multi-threaded 下载, 以 @string/msg_threads = 1 重试 自动播放 清除数据 @@ -191,7 +191,7 @@ 报告 信息: 发生了什么: - 详情:\\n请求:\\n内容语言:\\n服务:\\nGMT时间:\\n包:\\n版本:\\n操作系统版本: + 详情:\\n请求:\\n内容语言:\\n内容国家:\\n客户端语言:\\n服务:\\nGMT时间:\\n包名:\\n版本:\\n操作系统版本: 您的附近说明(请用英文): 详细信息: 视频预览缩略图 @@ -604,4 +604,11 @@ 在项目上显示原始时间 YouTube受限模式 仅显示未分组订阅 + 播放列表页 + 尚无播放列表书签 + 选择播放列表 + 请检查您的问题是否已经存在。创建重复票证时,您需要从我们那里花些时间来让我们修复真正的bug。 + 去GitHub上报告错误 + 复制格式报告 + 显示结果为:%s \ No newline at end of file From 8827ae4d2c405b85265669a1b605138b7ab01321 Mon Sep 17 00:00:00 2001 From: Ville Rantanen Date: Tue, 28 Jul 2020 13:57:44 +0000 Subject: [PATCH 007/137] Translated using Weblate (Finnish) Currently translated at 100.0% (584 of 584 strings) --- app/src/main/res/values-fi/strings.xml | 52 +++++++++++++++----------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index d325f7ee4..d90aeb80a 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -17,14 +17,14 @@ Valitse selain kierto Käytä ulkoista videosoitinta - Poistaa äänen joillakin resoluutioilla + Ääni saattaa lakata toimimasta joillakin resoluutioilla Käytä ulkoista äänisoitinta Ponnahdusikkunatila Tilaa Tilattu Kanavan tilaus peruttu Tilauksen vaihtaminen epäonnistui - Ei pystytty päivittämään tilausta + Tilausta ei voitu päivittää Päävalikko Tilaukset Uudet @@ -40,12 +40,12 @@ Toistaa videon automaattisesti, kun NewPipe avataan toisesta ohjelmasta Oletusresoluutio Ponnahdusikkunan oletusresoluutio - Näytä korkeampia resoluutioita - Vain jotkin laitteet voivat toistaa 2K/4K-videoa - Toista Kodi:ssa + Näytä korkeammat resoluutiot + Vain jotkin laitteet voivat toistaa 2K/4K-videota + Toista Kodissa Asennetaanko puuttuva Kore-sovellus\? - Näytä \"Toista Kodi:ssa\" vaihtoehto - Näyttää painikkeen, jolla voi toistaa videon Kodi media center:llä + Näytä \"Toista Kodissa\"-vaihtoehto + Näyttää vaihtoehdon videon toistamiseen Kodi-mediasoittimessa Ääni Oletusääniformaatti Oletusvideoformaatti @@ -68,7 +68,7 @@ Seuraava Näytä seuraavia ja samankaltaisia videoita URL ei tuettu - Oletus-sisällon kieli + Sisällon oletuskieli Soitin Käyttäytyminen Video & ääni @@ -102,12 +102,12 @@ Ilmoitukset NewPipen tausta- ja ponnahdusikkunasoittimille Virhe Verkkovirhe - Ei pystytty lataamaan kaikkia esikatselukuvia - Ei pystytty purkamaan salausta videon URL allekirjoitukselle - Ei pystytty jäsentämään websivua - Ei pystytty jäsentämään websivua kokonaan + Kaikkia esikatselukuvia ei voitu ladata + Videon URL-allekirjoituksen salausta ei voitu purkaa + Verkkosivua ei voitu jäsentää + Verkkosivua ei voitu täysin jäsentää Sisältö ei ole saatavilla - Ei pystytty asettamaan latausvalikkoa + Latausvalikkoa ei voitu asettaa Live-suoratoistoa ei vielä tueta Suoratoistosisältöä ei saatu Kuvan lataus epäonnistui @@ -178,9 +178,9 @@ reCAPTCHA-haaste pyydetty Lataus Sallitut merkit tiedostonimissä - Epäkelvot merkit korvataan tällä arvolla + Kielletyt merkit korvataan tällä arvolla Korvaava merkki - Kirjaimia ja numeroita + Kirjaimet ja numerot Suurin osa erikoismerkeistä Tietoja NewPipe Asetukset @@ -208,7 +208,7 @@ Haluatko poistaa tämän hakuhistoriasta? Jatka toistoa Info: - Mikä:\\nPyyntö:\\nSisällön kieli:\\nPalvelu:\\nGMT Aika:\\nPaketti:\\nVersio:\\nOS versio: + Mikä:\\nPyyntö:\\nSisällön kieli:\\nSisällön maa:\\n:Sovelluksen kieli:\\nPalvelu:\\nGMT Aika:\\nPaketti:\\nVersio:\\nOS versio: © %1$s %2$s %3$s alla Pääsivun sisältö Tyhjä sivu @@ -251,7 +251,7 @@ Suoratoistosoitinta ei löytynyt (voit asentaa VLC:n toistaaksesi). Lataa suoratoistotiedosto Näytä lisätietoja - Kirjanmerkityt soittolistat + Soittolistakirjanmerkit Lisää soittolistaan Käytä nopeampaa epätarkkaa pikakelausta Epätarkka kelaus mahdollistaa videon kelauksen nopeammin huonommalla tarkkuudella. Kelaaminen 5, 15 tai 25 sekuntia ei toimi tämän kanssa. @@ -394,7 +394,7 @@ Hyväksy Hylkää Ei rajaa - Rajoita resoluutiota kun mobiilidata on käytössä + Rajoita resoluutiota mobiilidataa käytettäessä Pienennä vaihdettaessa ohjelmaa Toiminto vaihdettaessa toiseen ohjelmaan päävideosoittimesta — %s Ei koskaan @@ -512,7 +512,7 @@ Hae erityisestä syötteestä, kun sellainen on saatavilla Päivitä aina Edellisestä päivityksestä kulunut aika, jonka jälkeen tilaus katsotaan vanhentuneeksi - Syötteen päivitysvälin kynnysarvo + Syötteen päivitysväli Syöte Uusi Haluatko poistaa tämän ryhmän\? @@ -552,13 +552,13 @@ Valitse instanssi \'Storage Access Framework\' sallii lataukset ulkoiselle SD-kortille. \nJotkin laitteet eivät ole yhteensopivia - Käytä SAF:ää + Ota SAF käyttöön Jokaisen latauksen kohde kysytään. \nValitse SAF, jos haluat ladata ulkoiselle SD-kortille Jokaisen latauksen kohde kysytään Kysy mihin ladataan Aloita lataukset - Yksi lataus kerrallaan on käynnissä + Salli vain yksi lataus kerrallaan Rajoita latausjonon kokoa Suurin määrä yrityksiä ennen kuin lataus perutaan Uudelleenyritysten maksimimäärä @@ -598,7 +598,7 @@ Näytä alkuperäinen aika sisällölle Tauota lataukset Hyödyllinen vaihdettaessa mobiilidataan, vaikka joitakin latauksia ei voi pysäyttää - Keskeytä käytön mukaan laskutettavilla yhteyksillä + Keskeytä, kun yhteys on käytön mukaan laskutettava tauotettu Napauta ladataksesi NewPipe-päivitys on saatavilla! @@ -613,4 +613,12 @@ Poista mykistys Mykistä Konferenssit + Soittolistasivu + Näytä vain ryhmittelemättömät tilaukset + Ei soittolistakirjanmerkkejä vielä + Valitse soittolista + Ole hyvä ja tarkasta onko kaatumiseen liittyvä ongelma jo raportoitu. Tikettien kaksoiskappaleiden selvittely vie aikaa varsinaisten ohjelmavirheiden korjaamiselta. + Raportoi virhe GitHubissa + Kopioi muotoiltu raportti + Näytetään tulokset haulle: %s \ No newline at end of file From c841d7a32bc15f6e25d83a5da3704c8a138a1633 Mon Sep 17 00:00:00 2001 From: Anxhelo Lushka Date: Tue, 28 Jul 2020 12:31:34 +0000 Subject: [PATCH 008/137] Translated using Weblate (Albanian) Currently translated at 100.0% (584 of 584 strings) --- app/src/main/res/values-sq/strings.xml | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/app/src/main/res/values-sq/strings.xml b/app/src/main/res/values-sq/strings.xml index 278e27371..bd016cf67 100644 --- a/app/src/main/res/values-sq/strings.xml +++ b/app/src/main/res/values-sq/strings.xml @@ -283,7 +283,7 @@ Shikoje në GitHub Nëse keni ide rreth; përkthimeve, ndryshimeve në dizajn, pastrimit të kodit, apo ndryshime rrënjësore të kodit—ndihma është gjithnjë e mirëpritur. Sa më shumë të bëhet aq më mirë do jetë! Kontribuo - Streaming i lirë dhe i lehtë në Android. + Luajtës i lehtë dhe libre në Android. Licensat Kontribuesit Rreth @@ -372,7 +372,7 @@ Pamjet statike të parapamjes së videove Detajet: Komenti juaj (në Anglisht): - Çfarë:\\nKërkesa:\\nGjuha e përmbajtjes:\\nShërbimi:\\nKoha në GMT:\\nPaketa:\\nVersioni:\\nVersioni i sistemit operativ: + Çfarë:\\nKërkesa:\\nGjuha e përmbajtjes:\\nShteti i pëmbajtjes:\\nGjuha e aplikacionit:\\nShërbimi:\\nKoha në GMT:\\nPaketa:\\nVersioni:\\nVersioni i sistemit operativ: Çfarë ndodhi: Informacion: Raporto @@ -405,7 +405,7 @@ I abonuar Modaliteti popup Përdor lexues të jashtëm audio - Heq audio në disa rezolucione + Heq audio për disa rezolucione Përdorni lexues video të jashtëm rrotullimi Zgjidhni shfletuesin @@ -587,7 +587,7 @@ Formati i parazgjedhur video Formati i parazgjedhur audio Një pamje statike video shfaqet në ekranin e kyçur kur përdoret luajtësi në sfond - Shfaq një opsion për të luajtur një video përmes qendrës mediatike Kodi + Shfaq një opsion për të luajtur videot përmes Kodi Pamja video në ekranin e kyçur Shfaq opsionin \"Luaj me Kodi\" Instaloni aplikacionin Kore që mungon\? @@ -603,14 +603,22 @@ Skedarët video të shkarkuara ruhen këtu Nuk u gjend lexues për stream (ju mund të instaloni VLC për ta lexuar). Po, dhe videot e shikuara pjesërisht - Videot që janë shikuar më parë dhe dhe pasi janë shtuar në listën e luajtjes do të hiqen. + Videot që janë shikuar më parë dhe pasi janë shtuar në listën e luajtjes do të hiqen. \nA jeni të sigurt\? Kjo nuk mund të zhbëhet! Dëshironi t\'i hiqni videot e para\? Hiq të parat - Tekstet origjinale nga shërbimet do të jenë të dukshme në objektet e stream + Tekstet origjinale nga shërbimet do shihen në produktet e luajtshme Shfaq titullin origjinal \"kohë më parë\" në objekte - Modaliteti i kufizuar i NewPipe + Modaliteti i censuruar i NewPipe Pamja statike e avatarit të kanalit Nga %s Krijuar nga %s + Faqja e listës së luajtjes + Shfaq vetëm abonimet e pagrupuara + Nuk ka ende shënjues të listave të luajtjes + Zgjidhni një listë luajtjeje + Ju lutemi kontrolloni nëse një raport ku diskutohet problemi ekziston tashmë. Kur krijoni raporte të duplikuara, ju merrni më tepër kohë nga ne, kohë të cilën mund ta shpenzonim mbi rregullimin e problemit aktual. + Raporto problemin në GitHub + Kopjo raportin e formatuar + Duke shfaqur rezultatet për: %s \ No newline at end of file From 89f3fca6b110869b1e9d4797abedf3b461746321 Mon Sep 17 00:00:00 2001 From: sudoLife Date: Wed, 29 Jul 2020 10:03:31 +0000 Subject: [PATCH 009/137] Translated using Weblate (English) Currently translated at 99.8% (583 of 584 strings) --- app/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3625e67f4..54b0fde1d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -404,7 +404,7 @@ Select a channel No channel subscriptions yet Select a playlist - No playlists bookmarks yet + No playlist bookmarks yet Select a kiosk Exported Imported From 79487adbecb842dd28ec7f23455dbd62258f9ec1 Mon Sep 17 00:00:00 2001 From: Artyom Date: Wed, 29 Jul 2020 20:18:50 +0000 Subject: [PATCH 010/137] Translated using Weblate (Russian) Currently translated at 100.0% (584 of 584 strings) --- app/src/main/res/values-ru/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 913475d8e..ae10c959f 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -625,4 +625,5 @@ Создано %s Миниатюра значка канала Показывать только несгруппированные подписки + Вы ещё не добавили ни одного плейлиста в закладки \ No newline at end of file From 20b9748a8ca44b94cd0f56b758b38307ac7374b5 Mon Sep 17 00:00:00 2001 From: sudoLife Date: Wed, 29 Jul 2020 10:03:17 +0000 Subject: [PATCH 011/137] Translated using Weblate (Russian) Currently translated at 100.0% (584 of 584 strings) --- app/src/main/res/values-ru/strings.xml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index ae10c959f..9d06e455d 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -121,7 +121,7 @@ Всё Фильтр Новая цель - Что:\\nЗапрос:\\nЯзык контента:\\nСервис:\\nВремя по Гринвичу:\\nПакет:\\nВерсия:\\nВерсия ОС: + Что:\\nЗапрос:\\nЯзык содержимого:\\nСтрана содержимого:\\nЯзык приложения:\\nСервис:\\nВремя по Гринвичу:\\nПакет:\\nВерсия:\\nВерсия ОС: Это разрешение нужно для \nвоспроизведения в окне Открыть во всплывающем окне @@ -626,4 +626,10 @@ Миниатюра значка канала Показывать только несгруппированные подписки Вы ещё не добавили ни одного плейлиста в закладки + Пожалуйста, проверьте, существует ли вопрос по вашей ошибке. Создавая дубликаты, вы отнимаете у нас время, которое мы могли бы использовать на решение проблемы. + Результаты для: %s + Страница плейлиста + Выберите плейлист + Сообщить об ошибке на Github + Копировать отформатированный отчет \ No newline at end of file From 3ea5278b126797108edc706864e4f239035c2b16 Mon Sep 17 00:00:00 2001 From: AioiLight Date: Tue, 28 Jul 2020 23:07:11 +0000 Subject: [PATCH 012/137] Translated using Weblate (Japanese) Currently translated at 99.8% (583 of 584 strings) --- app/src/main/res/values-ja/strings.xml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index f66930a0c..66e4a18b3 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -105,7 +105,7 @@ 不具合報告 画像を読み込みできません アプリ/UI がクラッシュしました - 何:\\\\n提案:\\\\nコンテンツ言語:\\\\nサービス:\\\\nGMT 時間:\\\\nパッケージ:\\\\nバージョン:\\\\nOSバージョン: + どんな問題:\\nリクエスト:\\nコンテンツ言語:\\nコンテンツ国:\\nアプリ言語:\\nサービス:\\nGMT 時間:\\nパッケージ:\\nバージョン:\\nOSバージョン: reCAPTCHA の要求 reCAPTCHA を要求しました ブラック @@ -604,4 +604,11 @@ %s により作成 チャンネルのサムネイル グループ化されていない登録チャンネルのみ表示 + まだプレイリスト ブックマークはありません + クラッシュを説明する問題がすでに存在しているかどうかを確認してください。重複したチケットを作成する場合、あなたは私たちから実際のバグを修正する時間を奪うことになります。 + 次の検索結果を表示しています: %s + GitHub でエラーを報告する + 整形済みリポートをコピー + プレイリスト ページ + プレイリストを選択してください \ No newline at end of file From 458b3daac3f04fb6442ad629c7c8da4d5e6eab1d Mon Sep 17 00:00:00 2001 From: pjammo Date: Wed, 29 Jul 2020 09:37:23 +0000 Subject: [PATCH 013/137] Translated using Weblate (Italian) Currently translated at 99.8% (583 of 584 strings) --- app/src/main/res/values-it/strings.xml | 44 +++++++++++++++----------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 0b2b3b44b..d7bbc9e5a 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -10,7 +10,7 @@ Scarica Cerca Impostazioni - Intendevi: %1$s\? + Forse cercavi: %1$s\? Condividi con Scegli Browser rotazione @@ -60,8 +60,8 @@ Impossibile impostare il menu di download I contenuti in diretta non sono ancora supportati Contenuti - Contenuti Vietati ai Minori - Mostra video riservati a un pubblico maggiorenne. Si possono abilitare nelle Impostazioni. + Contenuti con Restrizioni di Età + Mostra video con restrizioni di età. È possibile modificare questa opzione nelle Impostazioni. Tocca \"Cerca\" per iniziare Riproduzione Automatica Riproduci i video quando NewPipe viene aperto da un\'altra app @@ -105,7 +105,7 @@ Seleziona una cartella per i download Impossibile caricare l\'immagine L\'app/UI si è interrotta - Cosa:\\nRichiesta:\\nLingua contenuto:\\nServizio:\\nOrario GMT:\\nPacchetto:\\nVersione:\\nVersione SO: + Cosa:\\nRichiesta:\\nLingua Contenuti:\\nPaese Contenuti\\nLingua App:\\nServizio:\\nOrario GMT:\\nPacchetto:\\nVersione:\\nVersione SO: Risoluzione reCAPTCHA Nero Tutto @@ -229,7 +229,7 @@ Accodato in Popup Riproduci Tutto Impossibile riprodurre questo flusso - Si è verificato un errore irreversibile + Si è verificato un errore irreversibile del lettore multimediale Ripristino dell\'errore del lettore multimediale Riproduzione in Sottofondo Lettore Popup @@ -322,8 +322,8 @@ Riproduzione continua (non ripetititva) quando si accoda un contenuto consigliato File Nessuna cartella - Nessun file o cartella che contiene sorgenti - Il file non esiste o non si hanno i permessi sufficienti di scrittura o lettura + Nessun file/contenuto sorgente + Il file non esiste o non si hanno i permessi di scrittura o lettura Il nome del file non può essere vuoto Si è verificato un errore: %1$s Importa/esporta @@ -368,8 +368,8 @@ Modifica dimensione e stile dei sottotitoli. Riavviare per applicare le modifiche. Nessuna app installata per riprodurre questo file Pulisci Cronologia Visualizzazioni - Elimina la cronologia degli elementi riprodotti e la posizione di riproduzione - Elimina la cronologia delle visualizzazioni\? + Elimina la cronologia degli elementi riprodotti e le posizioni di riproduzione + Eliminare la cronologia delle visualizzazioni\? Cronologia visualizzazioni eliminata. Pulisci Cronologia Ricerche Elimina la cronologia dei termini di ricerca @@ -412,7 +412,7 @@ Notifiche di aggiornamenti dell\'applicazione Notifiche per una nuova versione di NewPipe Archiviazione esterna non disponibile - Impossibile scaricare sulla scheda SD esterna. Ripristinare la cartella dei download\? + Impossibile scaricare sulla scheda SD esterna. Ripristinare la posizione della cartella dei download\? Impossibile leggere le schede salvate, verranno usate quelle predefinite Ripristina predefiniti Ripristinare valori predefiniti\? @@ -458,7 +458,7 @@ Numero Massimo Tentativi Quante volte provare prima di annullare il download Interrompi con Connessioni a Consumo - Utile quando si passa alla connessione dati mobile, altrimenti alcuni download potrebbero essere sospesi + Utile quando si passa alla connessione dati mobile, tuttavia alcuni download non possono essere sospesi Eventi Conferenze Connesione finita @@ -591,26 +591,34 @@ \n \nLa scelta va fatta in base alle proprie preferenze: velocità o informazioni precise. Gruppo senza nome - Questo contenuto non è ancora supportato da NewPipe. -\n -\nSi spera che sarà supportato in una versione futura. + Questo contenuto non è supportato da NewPipe. +\n +\nSi spera che possa essere supportato in una versione futura. ∞ video 100+ video Artisti Album Canzoni - Questo video ha limiti sull\'età. -\n -\nSe vuoi guardarlo, attiva «Contenuti vietati ai minori» nelle impostazioni. + Questo video ha restrizioni di età. +\n +\nPer vederlo, attivare \"Contenuti con Restrizioni di Età\" nelle Impostazioni. Sì, anche quelli visaualizzati parzialmente Saranno rimossi gli elementi della playlist già visualizzati, sia precedenti che successivi. \nSei sicuro\? L\'azione è irreversibile! Rimuovere i gli elementi già visti\? Rimuovi Elementi Visti - Modalità limitata di YouTube + Modalità con Restrizioni (YouTube) I testi originali dei servizi saranno visibili negli elementi video Mostra i tempi originali degli elementi Immagine del Canale Da %s Creato da %s + Non è ancora stata salvata alcuna playlist + Mostra Solo Iscrizioni Non Raggruppate + Seleziona una Playlist + Risultati per: %s + Playlist + Prima di segnalare un problema, verificare che non sia già stato riportato da qualcun altro. Il tempo che gli sviluppatori utilizzerebbero per creare un ulteriore ticket potrebbe essere invece impiegato per correggere il problema stesso. + Segnala Errore su GitHub + Copia Segnalazione Formattata \ No newline at end of file From 847368718ba6c79f38acc5b718c42891160103d9 Mon Sep 17 00:00:00 2001 From: thami simo Date: Wed, 29 Jul 2020 10:34:44 +0000 Subject: [PATCH 014/137] Translated using Weblate (Arabic) Currently translated at 100.0% (584 of 584 strings) --- app/src/main/res/values-ar/strings.xml | 37 ++++++++++++++++---------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 2d007a043..27214d0fb 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -143,7 +143,7 @@ أبلِغ معلومات: ماذا حدث: - ماذا:\\nطلب:\\nيحتوى اللغة:\\nSالخدمات:\\nتوقيت غرينتش:\\nحزمة:\\nالإصدار:\\nOS إصدار نظام التشغيل: + ماذا:\\nطلب:\\nلغة المحتوى:\\nبلد المحتوى:\\nلغة التطبيق:\\nالخدمات:\\nتوقيت غرينتش:\\nالحزمة:\\nالإصدار:\\nOS الإصدار: تعليقك (باللغة الإنجليزية): التفاصيل: الإبلاغ عن خطأ @@ -155,15 +155,15 @@ ترخيص الوصول إلى التخزين أوّلا ألف مليون - B + بليون ليس هناك مشترِكون %s لا يوجد مشترك %s مشترك - %s المشتركين - %s المشتركين - %s المشتركين - %s المشتركين + %s مشتركين + %s مشتركين + %s مشتركين + %s مشتركين دون مشاهدات لاتوجد فيديوهات @@ -274,7 +274,7 @@ لم يتم العثور على مشغل دفق (يمكنك تثبيت VLC لتشغيله). استيراد قاعدة البيانات تصدير قاعدة البيانات - "الكتابة فوق سجل التاريخ والاشتراكات الحالية " + يتجاوز السجل والاشتراكات الحالية تصدير السجل، الإشتراكات وقوائم التشغيل عرض المعلومات إضافة إلى @@ -297,7 +297,7 @@ تحميل المحتوى المطلوب إنشاء قائمة تشغيل جديدة حذف قائمة التشغيل - "إعادة تسمية قائمة التشغيل " + إعادة تسمية التسمية إضافة إلى قائمة تشغيل هل تريد حذف قائمة التشغيل هذه ؟ @@ -327,7 +327,7 @@ عملية الإستعادة جارية … عملية التصدير جارية … إستيراد ملف - "معرفك , soundcloud.com/ الخاص بك " + معرفك, soundcloud.com/هويتك عند إيقاف تحميل أي صور مصغرة ، وتوفير البيانات واستخدام الذاكرة. تعمل التغييرات على محو ذاكرة التخزين المؤقت للصورة الموجودة على الذاكرة أو على القرص. امسح البيانات الوصفية المخزنة مؤقتًا إزالة جميع بيانات صفحات الويب المخزنة مؤقتًا @@ -365,7 +365,7 @@ الأكثر تشغيلا هذا سوف يُزيل إعداداتك الحالية. طريقة \'التشغيل\' المفضلة - "الإجراء الافتراضي عند فتح المحتوى — %s" + الإجراء الافتراضي عند فتح المحتوى — %s مشغل الخلفية المشغل المنبثق نسخة احتياطية @@ -390,7 +390,7 @@ تردد الصوت حل (قد يسبب تشويه) هل تريد أيضا استيراد الإعدادات؟ - "سياسة الخصوصية في NewPipe " + سياسة خصوصية NewPipe يأخذ مشروع NewPipe خصوصيتك على محمل الجد. لذلك ، لا يجمع التطبيق أي بيانات دون موافقتك. \nتوضح سياسة خصوصية NewPipe بالتفصيل البيانات التي يتم إرسالها وتخزينها عند إرسال تقرير الأعطال. الإطلاع على سياسة الخصوصية @@ -425,7 +425,7 @@ الأحداث الإخطارات لإصدار NewPipe الجديد وحدة التخزين الخارجية غير متوفرة - "التنزيل على بطاقة SD الخارجية غير ممكن. إعادة تعيين موقع مجلد التحميل؟" + لا يمكن التنزيل على بطاقة SD الخارجية. هل تريد إعادة تعيين موقع مجلد التنزيل؟ تعذرت قراءة علامات التبويب المحفوظة, لذا استخدم علامات التبويب الافتراضية استعادة الضبط الافتراضي هل تريد استعادة الإعدادات الافتراضية؟ @@ -471,7 +471,7 @@ توقف أقصى عدد للمحاولات الحد الأقصى لعدد محاولات قبل إلغاء التحميل - "إنقطع الإتصال بالشبكة عند التحويل إلى البيانات المتنقلة" + المقاطعة على الشبكات المقيسة مفيد عند التبديل إلى بيانات الجوال ، على الرغم من أنه لا يمكن تعليق بعض التنزيلات إظهار التعليقات عطّله لإخفاء التعليقات @@ -500,7 +500,8 @@ إيقاف التحميل مؤقتا اسأل عن مكان التنزيل سيُطلب منك مكان حفظ كل تنزيل - سيُطلب منك مكان حفظ كل تنزيل. اختر SAF إذا كنت تريد التنزيل على بطاقة SD خارجية + سيطلب منك مكان حفظ كل تنزيل. +\nاختر SAF إذا كنت تريد التنزيل على بطاقة SD خارجية استخدام آمن يسمح \"إطار الوصول إلى التخزين\" بالتنزيل على بطاقة SD خارجية. \nبعض الأجهزة غير متوافقة @@ -652,4 +653,12 @@ لـ %s أنشأها %s الصورة الرمزية للقناة + صفحة قائمة التشغيل + إظهار الاشتراكات غير المجمعة فقط + لا توجد إشارات مرجعية لقائمة التشغيل حتى الآن + حدد قائمة تشغيل + يرجى التحقق مما إذا كانت هناك مشكلة في مناقشة تعطلك بالفعل. عند إنشاء تذاكر مكررة ، ستأخذ وقتًا منا يمكن أن نقضيه في إصلاح الخطأ الفعلي. + أبلغ عن خطأ على GitHub + نسخ تقرير منسق + عرض النتائج ل : %s \ No newline at end of file From c38767821775942750a6b94af3c83b7b17511a2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20Carvalho=20de=20Ara=C3=BAjo?= Date: Tue, 28 Jul 2020 17:38:43 +0000 Subject: [PATCH 015/137] Translated using Weblate (Portuguese (Brazil)) Currently translated at 99.8% (583 of 584 strings) --- app/src/main/res/values-pt-rBR/strings.xml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index bda8dd452..e96e61c75 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -108,7 +108,7 @@ Usar tor Relatório do usuário Exibir opção \"Ver com Kodi\" - Ocorrido:\\nPedido:\\nIdioma do conteúdo:\\nServiço:\\nHora GMT:\\nPacote:\\nVersão:\\nVersão SO: + Ocorrido:\\nPedido:\\nIdioma do conteúdo:\\nPaís do conteúdo:\\nIdioma do app:\\nServiço:\\nHora GMT:\\nPacote:\\nVersão:\\nVersão SO: Abrir no modo popup Resolução padrão de popup Mostrar resoluções maiores @@ -615,4 +615,10 @@ Capa do avatar do canal Mostrar apenas inscrições não agrupadas Mostrando resultados para\? %s + Ainda não há playlists favoritas + Página da playlist + Selecione uma playlist + Verifique se já existe um assunto discutindo essa falha. Criar duplicatas tirará um tempo que poderíamos gastar corrigindo o bug real. + Reportar erro no GitHub + Copiar relatório formatado \ No newline at end of file From 771513d287a03340259e2a3095ed222f9370277f Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Wed, 29 Jul 2020 02:12:41 +0000 Subject: [PATCH 016/137] Translated using Weblate (Chinese (Traditional)) Currently translated at 99.8% (583 of 584 strings) --- app/src/main/res/values-zh-rTW/strings.xml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index b71d64a1f..06a32eebc 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -105,7 +105,7 @@ 回報 資訊: 發生了什麼事: - 發生了什麼:\\n請求:\\n內容語言:\\n服務:\\nGMT 時間:\\n套件:\\n版本:\\n系統版本: + 發生了什麼:\\n請求:\\n內容語言:\\n內容國家:\\n應用程式語言:\\n服務:\\nGMT 時間:\\n套件:\\n版本:\\n系統版本: 您的留言(請用英文): 詳細資訊: 回報錯誤 @@ -604,4 +604,11 @@ 由 %s 建立 頻道大頭貼縮圖 僅顯示未分組的訂閱 + 尚無播放清單書籤 + 播放清單頁面 + 選取播放清單 + 請檢查是否已有與您的應用程式當機相關的討論議題。當建立重複的工單時,您就是在耗費我們本來可以用來修復臭蟲的時間。 + 在 GitHub 上回報錯誤 + 複製格式化過的報告 + 正在顯示結果:%s \ No newline at end of file From d43cc089fdab38bbf63a2f8d7b2eb7f253dc777f Mon Sep 17 00:00:00 2001 From: sudoLife Date: Wed, 29 Jul 2020 10:18:44 +0000 Subject: [PATCH 017/137] Translated using Weblate (Lithuanian) Currently translated at 42.9% (251 of 584 strings) --- app/src/main/res/values-lt/strings.xml | 89 +++++++------------------- 1 file changed, 22 insertions(+), 67 deletions(-) diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index fb05da09c..510bfb2ea 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -1,5 +1,6 @@ - -Palieskite paiešką, kad pradėtumėte + + + Palieskite paiešką, kad pradėtumėte %1$s peržiūrų Publikuota %1$s Nerastas srauto grotuvas. Ar norite įdiegti VLC? @@ -21,15 +22,12 @@ NewPipe iššokančiojo lango rėžimas Fonas Išokantis langelis - Vaizdo įrašų parsiuntimo kelias Vieta parsisiųstų vaizdo įrašų laikymui Įvesti parsiuntimo kelią vaizdo įrašams - Garso įrašų parsiuntimo kelias Vieta laikyti parsisiųstus garso įrašus Įveskite atsisiuntimų kelią garso įrašams - Automatinis paleidimas Automatiškai groti vaizdo įrašą, kai NewPipe iškvečiama per kitą programėlę Numatytoji raiška @@ -102,8 +100,6 @@ Kas:\\nUžklausa:\\nTurinys Kalba:\\nPaslauga:\\nGMT Time:\\nPaketas:\\nVersija:\\nOperacinė Sistema versija: Jūsų komentaras (anglų kalba): Detalės: - - Vaizdo įrašo peržiūros miniatiūra Vaizdo įrašo peržiūros miniatiūra Įkėlėjo naudotojo paveikslėlio miniatiūra @@ -115,31 +111,25 @@ Naudoti raportavimą Negalima sukurti atsisiuntimų aplanko \'%1$s\' Sukurtas atsisiuntimų aplankas \'%1$s\' - Vaizdas Muzika Bandyti iš naujo - - %s prenumeratorius - %s prenumeratoriai - %s prenumeratorių - - + %s prenumeratorius + %s prenumeratoriai + %s prenumeratorių + - %s vaizdo įrašas - %s vaizdo įrašai - %s vaizdo įrašų - - + %s vaizdo įrašas + %s vaizdo įrašai + %s vaizdo įrašų + Pradėti Pauzė Ištrinti Kontrolinė suma - Nauja užduotis Gerai - Bylos pavadinimas Gijos Klaida @@ -152,21 +142,16 @@ Nukopijuota į iškarpinę Prašome pasirinkti galimą atsisiuntimų aplankalą Šis leidimas nereikalingas, kad atidarytiviššokančio lango rėžime - reCAPTCHA iššūkis reCAPTCHA prašomas iššūkis - Prenumeruoti Užprenumeruota Kanalas Nebeprenumeruojamas Negalima keisti prenumeratos Negalima atnaujinti prenumeratos - Pagrindinis Prenumeratos - Kas Naujo - Ieškoti istorijoje Saugoti paieškos užklausas vietinėje atmintyje Istorija @@ -184,42 +169,33 @@ Grojaraštis Atgal Groti viską - NewPipe pranešimai Foninio ir langelio rėžimo grotuvų pranešimai - [Nežinoma] - Nepavyko groti šio srauto Įvyko nepataisoma grotuvo klaida Atstatoma po grotuvo klaidos - Nėra rezultatų Čia nieko nėra išskyrus svirplius - Saugyklos prieiga uždrausta Tūkst. Mln. Mlrd. - Nėra prenumeratorių Nėra peržiūrų - %s peržiūra - %s peržiūros - %s peržiūrų - - + %s peržiūra + %s peržiūros + %s peržiūrų + Nėra vaizdo įrašų Groti Parsisiųsti Leidžiami simboliai bylų varduose Neleistini simboliai yra pakeičiami šia reikšme Pakaitinis simbolis - Raidės ir skaičiai Ypatingieji simboliai - Apie NewPipe Nustatymai Apie @@ -241,8 +217,6 @@ Kad sužinotumėte daugiau apie NewPipe apsilankykite mūsų interneto puslapyje. NewPipe Leidimas Skaityti leidimą - - Istorija Ieškota Peržiūrėta @@ -252,7 +226,6 @@ Istorija išvalyta Elementas ištrintas Ar norite ištrinti šį elementą iš paieškos istorijos? - Pagrindinio puslapio turinys Tuščias puslapis Kiosko puslapis @@ -262,7 +235,6 @@ Pasirinkite kanalą Nė vienas kanalas dar neužprenumeruotas Pasirinkite kioską - Kioskas Tendencijos Top 50 @@ -278,25 +250,20 @@ Pradėti groti čia Pradėti groti čia foniniame rėžime Pradėti groti čia langelio grotuvo rėžime -Nerastas srauto grotuvas (galite įdiegti VLC kad grotumėte) + Nerastas srauto grotuvas (galite įdiegti VLC kad grotumėte) Parsisiųsti srauto failą. Rodyti informaciją - Adresynas - Pridėti į - Numatyta tūrinio šalis Paslauga Šalinti riktus Visada Tik kartą - Perjungti orentaciją Perjungti į foną Perjungti į iššokantį langą Perjungti į pagrindinį - Importuoti duomenų bazę Eksportuoti duomenų bazę Bus perrašyta dabartinė istorija ir prenumeratos @@ -305,67 +272,55 @@ Negalimas URL Nerasta video srautų Nerasta audio srautų - Tempti kad perrūšiuoti - Sukurti Ištrinti vieną Ištrinti visus Nutraukti Pervadinti - Ar norite ištrinti šią nuorodą iš peržiūrų istorijos? Ar tikrai norite ištrinti visas nuorodas iš peržiūrų istorijos? Paskutinis grotas Daugiausiai grotas - Eksportavimas baigtas Importavimas baigtas Netinkamas ZIP failas Perspėjimas: Nepavyko importuoti visų failų. Tai perrašys dabartinius nustatymus. - Stalčius Uždaryti stalčių Kai kas čia greit atsiras ;D - - Video grotuvas Foninis grotuvas Iššokantis grotuvas Visada klausti - Gauname informaciją… Įkeliamas pasirinktas turinys - Sukurti naują grojaraštį Ištrinti grojaraštį Pervadinti grajaraštį Pavadinimas Pridėti į grojaraštį Nustatyti kaip grojaraščio paveikslėlį - Pridėti grojaraštį į žymes Pašalinti žymes - Ar norite ištrinti šį grojaraštį? Grojaraštis sėkmingai sukurtas Pridėta į grojaraštį Grojaraščio paveikslėlis pakeistas Nepavyko ištrinti grojaraščio - Nėra antraštės - Pritaikyti Užpildyti Priartinti - Automatiškai sugeneruotas - Įjungti LeakCanary Atminties nutekėjimo stebėjimas gali padaryti programėlę nestabilią - Pranešti apie Out-of-Lifecycle klaidas Priverstinai pranešti apie \"undeliverable Rx exceptions occurring outside of fragment or activity lifecycle after dispose\" - - + Išjungti, kad paslėptų komentarai + Rodyti komentarus + Pasirinkti skirtuką + Naujas skirtukas + Atsisakyti prenumeratos + \ No newline at end of file From a56b128a4bc41e567e398ef31be39217ac1dbab9 Mon Sep 17 00:00:00 2001 From: MohammedSR Vevo Date: Wed, 29 Jul 2020 09:16:25 +0000 Subject: [PATCH 018/137] Translated using Weblate (Kurdish) Currently translated at 99.3% (580 of 584 strings) --- app/src/main/res/values-ku/strings.xml | 92 ++++++++++++++------------ 1 file changed, 48 insertions(+), 44 deletions(-) diff --git a/app/src/main/res/values-ku/strings.xml b/app/src/main/res/values-ku/strings.xml index 47c46cc49..6aff9f31e 100644 --- a/app/src/main/res/values-ku/strings.xml +++ b/app/src/main/res/values-ku/strings.xml @@ -1,7 +1,7 @@ گرته‌ له‌ ”گه‌ڕان” بكه‌ بۆ ده‌ستپێكردن - %1$s بینراو + %1$s بینەر بڵاوكراوه‌ته‌وه‌ له‌ %1$s هیچ كارپێكه‌رێكی ڤیدیۆیی نه‌دۆزرایه‌وه‌. ده‌ته‌وێت VLC دابمەزرێنیت؟ هیچ کارپێکەرێکی ڤیدیۆیی نەدۆزرایەوە (دەتوانی کارپێکەری VLC دامەزرێنی) . @@ -9,20 +9,20 @@ پاشگه‌زبوونه‌وه‌ كردنه‌وه‌ له‌ وێبگه‌ر كردنه‌وه‌ له‌ په‌نجه‌ره‌ی بچووک - هاوبه‌شپێكردن + هاوبه‌شیکردن داگرتن داگرتنی پەڕگەی پەخش گه‌ڕان ڕێكخستنه‌كان مەبەستت ئەمەیە: \n%1$s\? - هاوبه‌شپێكردن له‌گه‌ڵ - هه‌ڵبژاردنی وێبگه‌ر + هاوبه‌شكردن له‌گه‌ڵ + وێبگەرێک هەڵبژێرە لاربوونەوە به‌كارهێنانی كارپێكه‌ری ڤیدیۆی ده‌ره‌كی - هه‌نێ له‌ قه‌باره‌كان ده‌نگیان تێدا نابێت + دەنگ نامێنێت لەهەنێ قەبارەدا به‌كارهێنانی كارپێكه‌ری ده‌نگی ده‌ره‌كی - دۆخی په‌نجه‌ره‌ی بچووک + دۆخی په‌نجه‌ره‌ به‌شداربوون به‌شداربوویت به‌شداریت نەما له‌ كه‌ناڵ @@ -31,10 +31,10 @@ پیشاندانی زانیاری سه‌ره‌كی به‌شدارییه‌كان - خشتەی کارپێکردنەکان نیشانەکران + لیستی تراکە نیشانەکراوەکان چی نوێ هه‌یه‌ - لە پاشبنەما - په‌نجه‌ره‌ی بچووک + پاشبنەما + په‌نجه‌ره‌ زیادکردن بۆ فۆڵدەری داگرتنی ڤیدیۆ پەڕگەی ڤیدیۆ داگیراوەکان لێرەدا هەڵدەگیرێن @@ -42,30 +42,30 @@ فۆڵدەری داگرتنی ده‌نگ پەڕگەی دەنگە داگیراوەکان لێرەدا هەڵدەگیرێن فۆڵدەری داگرتنی پەڕگە دەنگییەکان هەڵبژێرە - كاركردنی خۆكارانه‌ + لێدانی خۆکار وردی بنەڕەتی - قه‌باره‌ی بنەڕەتی په‌نجه‌ره‌ی بچووک - پیشاندانی وردی به‌رزتر + ووردی بنەڕەتی په‌نجه‌ره‌ + پیشاندانی ووردی به‌رزتر تەنها چەند مۆبایلێک پشتگیری کارپێکردنی ڤیدیۆی 2K/4K دەکەن كارپێكردن به‌ Kodi ئەپەکە نه‌دۆزرایه‌وه‌. دابمه‌زرێت؟ بژاردەی ”کارپێکردن بە Kodi“ پیشانبدرێت پیشاندانی بژارده‌ی كارپێكردنی ڤیدیۆ به‌ Kodi ده‌نگ - جۆری بنەڕەتی ده‌نگ - جۆری بنەڕەتی ڤیدیۆ + چەشنی بنەڕەتی ده‌نگ + چەشنی بنەڕەتی ڤیدیۆ ڕووكار - سپی + ڕۆشن تاریک ڕه‌ش - بیرهاتنه‌وه‌ی شوێن و قه‌باره‌ی په‌نجه‌ره‌ی بچووک + بیرهاتنه‌وه‌ی شوێن و قه‌باره‌ی په‌نجه‌ره‌ بیرهاتنه‌وه‌ی كۆتا قه‌باره‌ و شوێنی په‌نجه‌ره‌ی بچووك باركردنی وێنۆچكه‌كان ناچالاكی بكه‌ بۆ ڕاگرتنی وێنۆچكه‌كان له‌ باركردن و پاشه‌كه‌وتبوون له‌سه‌ر بیرگه‌ی ئامێره‌كه‌ت. \nگۆڕینی ئه‌مه‌ ده‌بێته‌ هۆی سڕینه‌وه‌یان له‌سه‌ر بیرگه‌ی مۆبایله‌كه‌ت. پاشماوه‌ی وێنۆچكه‌كان سڕایه‌وه‌ - ڤیدیۆ کارپێبکرێ کاتێ ئەپەکە لە ئەپێکیتر کرایەوە - بەکارهێنانی بردنەپێشی ناتەواوی خێرا + ڤیدیۆیەک کارپێئەکرێ کاتێ نیوپایپ لە ئەپێکیتر کرایەوە + بەکارهێنانی بردنەپێشی ناوردی خێرا خاوێنکردنەوەی پاشماوەی داتا سڕینەوەی پاشماوەی هەموو داتاکان پاشماوەی داتاکان سڕانەوە @@ -82,20 +82,20 @@ دواتر پیشاندانی ’دواتر’ و ڤیدیۆ ’هاوشێوەکان’ بەستەرەکە پشتگیری نەکراوە - وڵاتی بنەڕەتی + ناوەڕۆکی وڵاتی بنەڕەتی خزمەتگوزاری کارپێکەر ڤیدیۆ & دەنگ مێژوو & پاشماوە - پەنجەرەی بچووک + پەنجەرە ڕووکار هیتر ڕاستکردنەوە کارپێکردن لە پاشبنەما - کارپێکردن لە پەنجەرەی بچووک + کارپێکردن لە پەنجەرە ڕیزکرا لە کارپێکردن لە پاشبنەما - ڕیزکرا لە کارپێکردن لە پەنجەرەی بچووک - کارپێکردن + ڕیزکرا لە کارپێکردن لە پەنجەرە + لێدان ناوەڕۆک سنوردانانی تەمەن زیندوو @@ -104,37 +104,37 @@ ناتوانرێ سکاڵابکرێ گشتی کەناڵ - لیستی کارپێکردن + لیستی تراک بەڵێ دواتر ناچالاککراوە - فلتەر - نوێکردنەوە - سڕینەوە + پاڵاوتن + تازەکردنەوە + پاککردنەوە قەبارە دانانەوە - باشترین قەبارە + باشترین ووردی گەڕانەوە - کارپێکردنی گشتی + لێدانی هەمووی هەمیشە تەنها ئێستا پەڕگە ئاگانامەکانی ئەپ - ئاگانامەکانی ئەپ بۆ پاشبنەما و کارپێکردنەکانی پەنجەرەی بچووک + ئاگانامەکانی ئەپ بۆ پاشبنەما و کارپێکردنەکانی پەنجەرە (نەزانراو) چەسپاندنی لاربوونەوە گۆڕین بۆ پاشبنەما - گۆڕین بۆ پەنجەرەی بچووک + گۆڕین بۆ پەنجەرە گۆڕین بۆ سەرەکی هێنانەوەی بنکەی زانیاریەکان دەرکردنی بنکەی زانیارییەکان لەسەر مێژوو و بەشداربووەکانی ئێستات جێگیردەبێت خەزنکردنی مێژوو و بەشداربوون و لیستەکان - هەڵەیەک ڕوویدا + هەڵە کێشە لە هێڵەکەتدا هەیە ناتوانرێ هەموو وێنۆچکەکان باربکرێن ناتوانرێ ماڵپەڕ شیبکرێتەوە ناتوانرێ ماڵپەڕ بەتەواوی شیبکرێتەوە - ناوەڕۆک بوونی نییە + ناوەڕۆک بەردەست نییە ناتوانرێ لیستی داگرتن دابنرێ پەخشی ڕاستەوخۆ پشتگیری ناکرێ لەئێستادا هیچ پەخشێ نەدۆزرایەوە @@ -335,11 +335,11 @@ \nسیاسەتی تایبەتی ئەپ بەوردەکاری ڕوونکردنەوەت دەداتێ لەسەر ئەو داتایانەی وەریاندەگرێ و بەکاریاندەبات. خوێندنەوەی سیاسەتی تایبەتی کەناڵەکان - لیستی کارپێکردنەکان + لیستی تراکەکان تراکەکان بەکاربەرەکان بەشدارنەبوون - پەڕەیەکی نوێ + پەڕەی نوێ هەڵبژاردنی پەڕە کۆنترۆڵی دەنگ بەجوڵەی پەنجە جوڵەی پەنجەت لەسەر ڕوونما بەکاربهێنە بۆ گۆڕینی ئاستی دەنگ @@ -369,11 +369,11 @@ ئەم ڕاژەیە ناتوانێ چەندین داگرتن لەیەک کاتدا بکات ڕووداوەکان پیشاندانی لێدوانەکان - ناچالاککردن بۆ پیشان نەدانی لێدوانەکان - کارپێکردنی خۆکاری + ناکارایکە بۆ پیشان نەدانی لێدوانەکان + لێدانی خۆکار هیچ لێدوانێک نییە - کارپێکردنەوەی لیست - گێڕانەوەی لیست بۆ شوێنی پێشووتر + دەسپێکردنەوەی کارپێکەر + گێڕانەوەی کارپێکەر بۆ کۆتا شوێن شوێنەکان لە لیستدا سڕینەوەی داتا مێژووی تەماشاکردن سڕایەوە. @@ -398,9 +398,9 @@ بردنەپێشی ناتەواوی خێرا وا لە کارپێکەرەکە داکات کە بەخێرایی شوێنەکە بگۆڕێت. بردنەپێشی ٥ یان ١٥ یان ٢٥ چرکەیی لەگەڵ ئەمەدا کارناکات. پاشکۆی خۆکاری پەخشێکی بەستراوە لەکاتی کارپێکردنی کۆتا پەخشدا کۆگای گەڕانی نێوخۆیی - گێڕانەوە لەدۆخی سەرنج + دەسپێکردنەوەی کارپێکراو پیشاندانی ڕێنمایی ”داگرتن تا پاشکۆ” - پیشاندانی ڕێنمایی کاتێ لە پاشبنەما یاخوود پەنجەرەی بچووکدا گرتە دەکرێ لەسەر وردەکاری ڤیدیۆیەک + پیشاندانی ڕێنمایی کاتێ لە پاشبنەما یاخوود پەنجەرەدا گرتە دەکرێ لەسەر وردەکاری ڤیدیۆیەک ڕەفتار پیشاندانی ئەو ڤیدیۆیانەی سنوری تەمەنیان بۆ دانراوە. لە ڕێکخستنەکانەوە ڕێگەی پێدەدرێت. ناتوانرێ واژووی بەستەری ڤیدیۆ بخوێنرێتەوە @@ -492,7 +492,7 @@ کیۆسکی بنەڕەتی ماوەی خێرا بردنە پێشەوە\\ گێڕانەوە بۆ دواوە دۆخی پێرتووبی - ئارەزوومەندییەکانی دۆخی پێرتووبی ڕێکبخە + دۆخە دڵخوازەکانی پێرتووبی دیاریبکە ئەو دۆخانە بدۆزەرەوە کە لەگەڵ خۆتدا دەگونجێن لە %s زیادکردنی دۆخ بەستەری دۆخ دابنێ @@ -530,8 +530,8 @@ دەگەڕێنرێتەوە ناتوانرێ ئەم داگرتنە بهێنرێتەوە دۆخێک هەڵبژێرە - چالاککردنی وێنۆچکەی ڤیدیۆی داخستنی ڕوونما - کاتێ کارپێکەری پاشبنەما کاردەکات ئەوا وێنۆچکەی ڤیدیۆکە لە ڕوونما داخراوەکەدا نیشاندەدرێت + وێنۆچکەی ڤیدیۆی ڕوونماداخراو + وێنۆچکەی ڤیدیۆیەک نیشان ئەدرێ لە ڕوونماداخراودا لەکاتی بەکارهێنانی کارپێکەری پاشبنەما سڕینەوەی مێژووی داگرتن سڕینەوەی فایلە داگیراوەکان %1$d لە داگرتنەکان سڕانەوە @@ -611,4 +611,8 @@ لەلایەن %s دروستکراو لەلایەن %s وێنۆچکەی کەناڵ + لیستی تراک دیاربکە + هەڵە لە سکاڵا لەسەر GitHub + لەبەرگرتنەوەی سکاڵا + پیشاندانی ئەنجامەکان بۆ: %s \ No newline at end of file From b9b4762fafd07d173676971155b7423872c49610 Mon Sep 17 00:00:00 2001 From: Digiwizkid Date: Wed, 29 Jul 2020 07:49:30 +0000 Subject: [PATCH 019/137] Translated using Weblate (Bengali (India)) Currently translated at 61.6% (360 of 584 strings) --- app/src/main/res/values-bn-rIN/strings.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/src/main/res/values-bn-rIN/strings.xml b/app/src/main/res/values-bn-rIN/strings.xml index 49993d209..e3118d55c 100644 --- a/app/src/main/res/values-bn-rIN/strings.xml +++ b/app/src/main/res/values-bn-rIN/strings.xml @@ -329,4 +329,13 @@ সার্চ গুলি স্থানীয় ভাবে জমা করুন সার্চ এর সময় সাজেশন দেখান সার্চ সাজেশন + ফিড লোড হচ্ছে… + এরর দেখান + একটি প্লে লিস্ট পছন্দ করুন + সম্পর্কিত + থার্ড-পার্টি লাইসেন্স সমূহ + সম্পর্কিত + গিটহাব এ এরর রিপোর্ট করুন + ডিফল্ট এ ফিরে যান + রেজাল্ট দেখান হচ্ছেঃ %s \ No newline at end of file From 465963a8c229f3fdd7719636528237eb81799700 Mon Sep 17 00:00:00 2001 From: Ajeje Brazorf Date: Tue, 28 Jul 2020 18:00:33 +0000 Subject: [PATCH 020/137] Translated using Weblate (Sardinian) Currently translated at 99.4% (581 of 584 strings) --- app/src/main/res/values-sc/strings.xml | 623 ++++++++++++++++++++++++- 1 file changed, 622 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-sc/strings.xml b/app/src/main/res/values-sc/strings.xml index a6b3daec9..c2dd87c2f 100644 --- a/app/src/main/res/values-sc/strings.xml +++ b/app/src/main/res/values-sc/strings.xml @@ -1,2 +1,623 @@ - \ No newline at end of file + + Importa sas iscritziones iscarrighende su documentu de esportatzione: +\n +\n 1. Bae a custu URL: %1$s +\n 2. Intra cando ti l\'ant a pedire +\n 3. Diat dèpere incumintzare un\'iscarrigamentu (cussu est su documentu de esportatzione) + Esportatzione de s\'iscritzione fallida + Importatzione de s\'iscritzione fallida + Esportatzione anteposta + Importa su documentu + Importende… + Esporta in + Importa dae + Importa + Importa/esporta + Su testu originale dae sos servìtzios at a èssere visìbile in sos elementos de flussu + Ammustra sa data originale in sos elementos + Fortzat sinnalatziones de etzetziones Rx non cunsinnàbiles in foras de su tziclu de bida de sos framnentos o de sas atividades a pustis de s\'ismaltimentu + Sinnala sos errores in foras de su tziclu de bida + Sa compidada de sa pèrdida de memòria diat pòdere causare blocos de s\'aplicatzione durante d\'iscarrigamentu de sa memòria (heap dumping) + LeakCanary + Muda sa mannària e sos istiles de isfundu de su testu de sos suta-tìtulos. Depes torrare a allùghere s\'aplicatzione pro chi tèngiat efetu. + Suta-tìtulos + Ingendradu automaticamente + Ismànnia + Prenu + Adata + Perunu suta-titulu + Ingendradu automaticamente (perunu carrigadore agatadu) + Iscantzellamentu de s\'iscalita fallidu. + Miniadura de s\'iscalita mudada. + Postu in s\'iscalita + Iscalita creada + Iscantzellare custa iscalita\\\? + Boga su sinnalibru + Annanghe s\'iscalita a sos preferidos + Imposta che a miniadura de s\'iscalita + Allughe su sonu + Pone a sa muda + Annanghe a s\'iscalita + Nùmene + Càmbia de nùmene + Iscantzella + Iscalita noa + Carrighende su cuntenutu pedidu + Otenende informatziones… + Pedi semper + Riproduidore a ventanedda + Riproduidore in s\'isfundu + Riproduidore de vìdeos + Atzione predefinida cando aberis unu cuntenutu — %s + Atzione de abertura predefinida + Luego, inoghe, at a apàrrere una cosa ;D + Serra su pannellu + Aberi su pannellu + Incumintza a riproduire in una ventanedda + Incumintza a riproduire in s\'isfundu + Incumintza a riproduire inoghe + Pone in s\'elencu in una ventanedda + Pone in s\'elencu in s\'isfundu + Mantene incarcadu pro pònnere in s\'elencu + Impostatziones àudio + Detàllios + Boga + Riproduidore a ventanedda + Riproduidore in s\'isfundu + Cunferèntzias + Prus agradèssidos + Annànghidos dae pagu + Locale + Noos e Populares + Sos mègius 50 + Tendèntzias + In evidèntzia + 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. + Avisu: no est istadu possìbile importare totu sos documentos. + Perunu documentu ZIP vàlidu + Importatzione acabada + Esportatzione acabada + Ischerta una pàgina de cuntenutos in evidèntzia personalizados + Galu peruna iscritzione a sos canales + Ischerta unu canale + Pàgina de su canale + Pàgina de sa fonte de cuntenutos + Pàgina de iscritzione + Cuntenutos in evidèntzia predefinidos + Cuntenutos in evidèntzia personalizados + Pàgina bòida + Seletzione + Ischedas benint ammustradas in sa pàgina printzipale + Cuntenutu de sa pàgina printzipale + Prus riproduidos + Ùrtima riprodutzione + Ses seguru de chèrrere iscantzellare totu sos elementos dae sa cronologia\? + Cheres iscantzellare custu elementu dae sa cronologia de sos pompiados\? + Cheres iscantzellare custu elementu dae sa cronologia de chirca\? + Elementu iscantzelladu + Cronologia isboidada + Sa cronologia est bòida + Cronologia + Sa cronologia est istudada + Pompiados + Chircas fatas + Cronologia + Leghe sa litzèntzia + NewPipe est unu programma lìberu cun litzèntzia copyleft: lu podes impreare, cumpartzire e megiorare comente cheres. Pro èssere prus craros, lu podes torrare a intregare in suta de sos tèrmines de sa Litzèntzia Generale Pùblica GNU publicada dae sa Free Software Foundation, sa versione 3 de sa litzèntzia o, si preferis, una prus noa. + Litzèntzia de NewPipe + Leghe sa polìtica de riservadesa + Su progetu NewPipe pigat sa riservadesa tua in manera sèria a beru. Pro custa resone s\'aplicatzione non collit perunu datu chene su cunsensu tuo. +\n Sa polìtica de riservadesa de NewPipe ispiegat a sa minuda ite genia de datos benint imbiados cando imbias unu raportu de errore. + Polìtica de riservadesa de NewPipe + Bìsita su situ web de NewPipe pro àteras informatziones e noas. + Situ web + Retribui + NewPipe benit isvilupadu dae voluntàrios chi impreant su tempus lìberu issoro batende·ti sa mègius esperièntzia de impreadore. Torra·li su favore pro agiudare sos isvilupadores a megiorare NewPipe galu de prus, in su mentres chi si gosant una tzìchera de cafè. + Dona + Pòmpia in GitHub + Si tenes ideas pro sa tradutzione, modìficas de su progetu, pro s\'innetadura de su còdighe o pro modìficas de su còdighe mannas, s\'agiudu est semper benebènnidu. Prus si faghet e mègius est! + Contribui + Riprodutzione lìbera e lèbia de trasmissiones (streaming) in Android. + Litzèntzias + Contribuidores + Informatziones + Aberi su situ web + Carrigamentu de sa litzèntzia fallidu + © %1$s de %2$s cun litzèntzia %3$s + Litzèntzias de tertzas partes + Informatziones + Impostatziones + In subra de NewPipe + Peruna aplicatzione installada pro pòdere riproduire custu documentu + Majoria de sos caràteres ispetziales + Lìteras e tzifras + Caràtere de remplasamentu + Sos caràteres non vàlidos benint remplasados cun custu valore + Caràteres permìtidos in sos nùmenes de sos documentos + Iscàrriga + Fatu + B\'at bisòngiu de risòlvere unu reCAPTCHA + Incarca \"Fatu\" cando est risoltu + Disafiu reCAPTCHA + 1 elementu iscantzelladu. + Issèbera una cartella de iscarrigamentu prus a tardu in sas impostatziones + Copiadu in punta de billete + Iseta… + Toca pro detàllios + NewPipe est iscarrighende + S\'URL non tenet unu formadu vàlidu o ìnternet no est a disponimentu + Su documentu esistit giai + Serbidore non suportadu + Errore + Connessiones simultàneas + Nùmene de su documentu + AB + Missione noa + Càmbia de nùmene + Ignora + Summa de verìfica + Iscantzella totu + Iscantzella unu + Iscantzella + Crea + Riprodui + Pàusa + Incumintza + Perunu cummentu + + %s vìdeos + %s vìdeu + + ∞ vìdeos + 100+ vìdeos + Perunu vìdeu + + %s ascurtadore + %s ascurtadores + + Nemos est ascurtende + + %s est pompiende + %s sunt pompiende + + Nemos est pompiende + + %s visualizatzione + %s visualizatziones + + Peruna visualizatzione + Contadore de sos iscritos non disponìbile + + %s iscritos + %s iscritu + + Perunu iscritu + Allughe/istuda su servìtziu. Ischertadu como: + Mrd + Mlln + mil + In antis fruni s\'atzessu a sa memòria + Torra a proare + Àudio + Vìdeu + Cartella de iscarrigamentu \'%1$s\' creada + Impossìbile creare sa cartella de iscarrigamentu \'%1$s\' + Traga pro torrare a ordinare + Non b\'at nudda inoghe + Perunu resurtadu + Raportu de s\'impreadore + Sinnala un\'errore + (Isperimentale) Fortza su tràficu de iscarrigamentu tràmite Tor pro una riservadesa prus manna (sa trasmissione de vìdeos no est galu suportada). + Imprea Tor + Disagradessimentos + Agradessimentos + Miniadura de s\'avatar de su carrigadore + Riprodui su vìdeu, longària: + Miniadura de anteprima de su vìdeu + Detàllios: + Su cummentu tuo (in inglesu): + Ite est acontèssidu: + Informatziones: + Sinnala + Sinnala custu errore pro mèdiu de posta eletrònica + Iscusa, custu non diat dèpere èssere acontèssidu. + Fruni su permissu pro l\'ammustrare in subra de àteras aplicatziones + Cheres ripristinare sos valores predefinidos\? + Riprìstina sos predefinidos + No est istadu possìbile lèghere sas ischedas sarbadas. S\'ant a impreare sas predefinidas + Perunu flussu a disponimentu pro s\'iscarrigamentu + B\'at àpidu un\'errore: %1$s + Su nùmene de su documentu non podet èssere bòidu + Su documentu no esistit o mancat su permissu pro lèghere e pro b\'iscrìere cosa + Custa fonte de documentos o cuntenutos no esistit + Sa cartella no esistit + Documentu iscostiadu o iscantzelladu + Peruna trasmissione àudio agatada + Perunu flussu de vìdeu agatadu + URL non vàlidu + Sos riproduidores esternos non suportant custas castas de ligàmenes + Riprìstinu a pustis de s\'errore de su riproduidore + B\'at àpidu un\'errore de su riproduidore non recuperàbile + Riprodutzione de custu flussu fallida + S\'apl./s\'IU s\'est serrada + Galu perunu sinnalibru de iscalitas + Pensas chi su carrigamentu de sa fonte de cuntenutos (su feed) siat tropu lentu\? Si est gasi, proa a abilitare su carrigamentu lestru (lu podes mudare in sas impostatziones o incarchende su butone inoghe in suta). +\n +\nNewPipe oferit duas istrategias de carrigamentu de sas fontes de cuntenutos: +\n • Recuperende totu su canale de iscritzione, cosa chi est lenta ma prus cumprida. +\n • Impreende unu puntu de essida de unu servìtziu dedicadu, cosa chi est lestra ma, de sòlitu, non cumprida. +\n +\nSa diferèntzia printzipale intre sas duas est su fatu chi cun sa lestra, de sòlitu, unas cantas informatziones mancant, che a sa longària de s\'elementu o sa casta sua (non podet bìdere sa diferèntzia intre sos vìdeos indireta e sos chi sunt normales) diat pòdere frunire prus pagos elementos. +\n +\nYouTube est un\'esèmpiu de unu servìtziu chi frunit custu mètodu lestru cun sa fonte de cuntenutos RSS sua. +\n +\nDuncas s\'issèberu dipendet dae su chi preferis tue: sa lestresa o sas informatziones a sa minuda. + Sa \'Storage Access Framework\' (Istrutura de Atzessu a s\'Archiviatzione) permitet sos iscarrigamentos in un\'ischeda SD esterna. +\nUnos cantos dispositivos non sunt cumpatìbiles + postu in lista + Ammustra una notìfica pro cussigiare un\'agiornamentu de s\'aplicatzione cando b\'est una versione noa a disponimentu + Importa unu profilu de SoundCloud iscriende o s\'URL o su còdighe identificativu (ID) tuo: +\n +\n 1. Abìlita sa modalidade \"pro elaboradores de iscrivania\" in unu navigadore web (custu situ no est a disponimentu pro dispositivos mòbiles) +\n 2. Bae a custu URL: %1$s +\n 3. Intra in su contu tuo cando ti lu benit pedidu +\n 4. Còpia s\'URL de su profilu a ue ses istadu mandadu. + Esportende… + B\'at bisòngiu de custu permissu pro +\nabèrrere sa modalidade ventanedda + Ite:\\nRechesta:\\nLimba de su cuntenutu\\nIstadu de su cuntenutu:\\nLimba de s\'aplicatzione:\\nServìtziu:\\nOràriu GMT:\\nPachete:\\nVersione:\\nVersione SO: + B\'at àpidu unos cantos errores. + Cronologia de chirca iscantzellada. + Custu vìdeu tenet unu lìmite de edade. +\n +\n Si lu cheres bìdere, abìlita \"Cuntenutos limitados pro edade\" in sas impostatziones. + Perunu riproduidore de flussos agatadu (pro lu riproduire podes installare VLC). + Pàgina de s\'iscalita + Ammustra petzi sas iscritziones no agrupadas + Ischerta un\'iscalita + Pro praghere verìfica si esistit giai una sinnalatzione chi chistionat de s\'arrestu anòmalu tuo. Creende sinnalatziones dòpias nos pigas tempus chi diamus pòdere impreare pro acontzare su problema. + Sinnala s\'errore in GitHub + Còpia su raportu formatadu + Ammustrende sos resurtados pro: %s + De %s + Creadu dae %s + Miniadura de avatar de su canale + Custu cuntenutu no est galu suportadu dae NewPipe. +\n +\n Isperamus chi at a èssere suportadu in una versione benidora. + Disabìlita sa modalidade lestra + Abìlita sa modalidade lestra + A disponimentu in unos cantos servìtzios, de sòlitu est meda prus lestru ma diat pòdere frunire unu nùmeru limitadu de elementos e, fatu-fatu, informatziones no intreas (es. peruna longària, casta de elementu, indicadore de istadu in direta). + Recùperu dae una fonte de cuntenutos dedicada, cando est a disponimentu + Agiorna semper + Tempus chi depet colare a pustis de s\'ùrtimu agiornamentu, in antis chi un\'abbonamebèngiat cunsiderada tropu betza — %s + Lìmite de agiornamentu de sa fonte de cuntenutos + Fonte de cuntenutos + Nou + Cheres iscantzellare custu grupu\? + Nùmene + Su nùmene de su grupu est bòidu + + %d ischertadu + %d ischertados + + Perunu abbonamentu ischertadu + Ischerta sas iscritziones + Protzessende sa fonte de cuntenutos… + Carrighende sa fonte de cuntenutos… + Non carrigadas: %d + Ùrtimu agiornamentu de sa fonte (feed): %s + Grupos de canales + Ite b\'at de nou + + %d dies + %d die + + + %d ora + %d oras + + + %d minutu + %d minutos + + + %d segundos + %d segundu + + Pro more de sos lìmites de ExoPlayer sa longària de s\'iscostiamentu lestru est istada impostada a %s segundos + Eja, e fintzas sos vìdeos pompiados in parte + Sos vìdeos pompiados in antis e a pustis de los àere annànghidos a s\'iscalita ant a èssere bogados. +\n Seguru ses\? Custu no est reversìbile! + Bogare sos elementos pompiados\? + Boga sos elementos pompiados + Predefinida de su sistema + Limba de s\'aplicatzione + Issèbera un\'istàntzia + Imprea sa SAF + T\'at a bènnere pedidu in ue sarvare cada documentu. +\n Issèbera SAF si cheres iscarrigare in un\'ischeda SD esterna + T\'at a bènnere pedidu in ue sarvare cada documentu + Pedi in ue iscarrigare + Pone in pàusa sos iscarrigamentos + Faghe incumintzare sos iscarrigamentos + B\'at a èssere petzi un\'iscarrigamentu a sa borta + Lìmita s\'elencu de iscarrigamentu + Serra + Discansosu cando colas a sos datos mòbiles, fintzas si unoscantos iscarrigamentos non podent èssere postos in pàusa + Firma cun sas connessiones a consumu + Nùmeru màssimu de tentativos in antis chi s\'annullet s\'iscarrigamentu + Tentativos màssimos + Firma + %1$s iscarrigamentos iscantzellados + Iscantzella sos documentos iscarrigados + Cheres isboidare sa cronologia de sos iscarrigamentos tuos o iscantzellare totu sos documentos iscarrigados\? + Isbòida sa cronologia de sos iscarrigamentos + Impossìbile recuperare custu iscarrigamentu + Connessione iscadida + Su progressu s\'est pèrdidu, ca su documentu est istadu iscantzelladu + Perunu ispàtziu abarradu in su dispositivu + NewPipe est istadu serradu in su mentres chi fiat traballende a su documentu + Post-protzessamentu fallidu + No agatadu + Custu serbidore no atzetat iscarrigamentos a filos mùltiplos, torra a proare cun @string/msg_threads = 1 + Su serbidore no imbiat datos + Connessione a su serbidore impossìbile + No est istadu possìbile agatare su serbidore + No est istadu possìbile istabilire una connessione segura + Permissu dennegadu dae su sistema + Sa cartella de destinatzione non podet èssere creada + Su documentu non podet èssere creadu + Còdighe + Ammustra s\'errore + B\'est un\'iscarrigamentu in isetu cun custu nùmene + B\'est un\'iscarrigamentu in cursu cun custu nùmene + impossìbile subraiscrìere su documentu + B\'est giai unu documentu iscarrigadu cun custu nùmene + B\'est giai unu documentu cun custu nùmene + Subraiscrie + Ingendra unu nùmene ùnivocu + %s iscarrigamentos acabados + Iscarrigamentu acabadu + Iscarrigamentu fallidu + Atzione vietada dae su sistema + Elencu + recuperende + post-protzessamentu + in pàusa + In isetu + Acabadu + Toca pro iscarrigare + B\'est un\'agiornamentu de NewPipe disponìbile! + Càmbia sa vista + Automàtica + Grìllia + Lista + Modalidade de vista de sa lista + Mìnima in su riproduidore a ventanedda + Mìnima in s\'isfundu + Nudda + Atzione cando colas a un\'àtera aplicatzione dae su riproduidore de vìdeos printzipale — %s + Mìnima mudende aplicatzione + Agiornamentos + Lìmita sa risolutzione durante s\'impreu de sos datos mòbiles + Perunu lìmite + Refuda + Atzeto + Pro pòdere rispetare su Regulamentu Europeu Generale de Amparu de sos Datos (GDPR) ti pedimus de dare cara a sa polìtica de riservadesa de NewPipe. +\n La depes atzetare pro nos pòdere imbiare sa sinnalatzione de errore. + Reseta + Passu + Avantzamentu lestru durante su silèntziu + Iscollega (diat pòdere causare istorchimentos) + Tonu + Ritmu + Controllos de sa lestresa de riprodutzione + Ammenta·ti chi custa operatzione diat pòdere impreare meda sa retza tua. +\n +\n Cheres sighire\? + IDtuo, soundcloud.com/IDtuo + Carrigamentu de s\'immàgine fallidu + Impossìbile otènnere unu flussu + Sos flussos in direta non sunt galu suportados + Impostatzione de su menù de iscarrigamentu fallida + Cuntenutu no a disponimentu + No est istadu possìbile analizare de su totu su situ web + Anàlisi de su situ web fallida + Detziframentu de sa firma URL de su vìdeu fallida + No est istadu possìbile carrigare totu sas miniaduras + Errore de retza + Impossìbile iscarrigare in s\'ischeda SD esterna. Cheres resetare sa positzione de sa cartella de iscarrigamentu\? + Memòria esterna non disponìbile + Errore + Agiudu + Cheres iscantzellare totu sa cronologia de sas chircas\? + Iscantzella sa cronologia de sas paràulas chircadas + Iscantzella sa cronologia de chirca + Positziones de riprodutzione iscantzelladas. + Cheres iscantzellare totu sas positziones de riprodutzione\? + Iscantzella totu sas positziones de riprodutzione + Iscantzella sas positziones de riprodutzione + Cronologia de sos pompiados iscantzellada. + Cheres iscantzellare totu sa cronologia de sos pompiados\? + Iscantzellat sa cronologia de sos cuntenutos riproduidos e sas positziones de riprodutzione + Isbòida sa cronologia de sos pompiados + Esporta sa cronologia, sos abbonamentos e sas iscalitas + Subraiscriet sa cronologia e sos abbonamentos atuales tuos + Esporta sa base de datos + Importa sa base de datos + Cola a sa modalidade printzipale + Cola a sa ventanedda + Cola a s\'isfundu + Càmbia s\'orientamentu + [Disconnotu] + Notìficas pro una versione noa de NewPipe + Notìfica de agiornamentu de s\'aplicatzione + Notìficas pro sos riproduidores in s\'isfundu e a ventanedda de NewPipe + Notìficas de NewPipe + Documentu + Una borta ebbia + Semper + Riprodui totu + Documentu iscantzelladu + Annulla + Risolutzione mègius + Ridimensionende + Isbòida + Annoa + Filtru + Disabilitadu + Prus a tardu + Eja + Artista + Albums + Cantzones + Eventos + Impreadores + Rastas + Vìdeos + Iscalitas + Iscalita + Canales + Canale + Totu + Sinnalatzione de errores + Iscarrigamentos + Iscarrigamentos + In direta + Modalidade limitada de YouTube + Ammustra su vìdeu limitadu pro edade. Podes mudare custa optzione dae sas impostatziones. + Cuntenutu limitadu pro edade + Cuntenutos + Riprodui + Postu in lista in su riproduidore a ventanedda + Pone in lista in s\'isfundu + Riproduende in modalidade a ventanedda + Riproduende in s\'isfundu + Agiornamentos + Depuratzione de errores + Àteru + Aparèntzia + Ventanedda + Cronologia e memòria temporànea + Vìdeos e àudio + Cumportamentu + Riproduidore + S\'istàntzia esistit giai + Petzi sos URL HTTPS sunt suportados + Impossìbile cunvalidare s\'istàntzia + Inserta s\'URL de s\'istàntzia + Annanghe un\'istàntzia + Agata sas istàntzias chi t\'agradant in %s + Ischerta sas istàntzias de PeerTube preferidas tuas + Istàntzias de PeerTube + Limba predefinida pro sos cuntenutos + Servìtziu + Istadu predefinidu pro sos cuntenutos + URL non suportadu + Ammustra un\'impòsitu cando incarcas in su butone de isfundu o de sa ventanedda in sa pàgina de sos detàllios de unu vìdeu + Ammustra s\'impòsitu \"Mantene incarcadu pro pònnere in elencu\" + Ammustra sos vìdeos imbenientes e simigiantes + Riprodutzione automàtica + Imbeniente + Iscàrriga + Sighi a riproduire a pustis de sas interrutziones (a es. una mutida) + Sighi a riproduire + Sarva sa cronologia de sos elementos pompiados + Isbòida sos datos + Ammustra sos indicadores de sa positzione de riprodutzione in sas listas + Positziones in sas listas + Riprìstina s\'ùrtima positzione de riprodutzione + Sighi cun sa riprodutzione + Cronologia de sos pompiados + Sarva sas chircas in locale + Cronologia de sas chircas + Ammustra sos consìgios in sas chircas + Cussìgios de chirca + Imprea sos gestos pro controllare sa luminosidade e su volume de su riproduidore + Gestos de controllu de su riproduidore + Imprea sos gestos pro controllare sa luminosidade de su riproduidore + Gestos de controllu de sa luminosidade + Imprea sos gestos pro controllare su volume de su riproduidore + Gestos de controllu de su volume + Sighi a riproduire (chene ripetitziones) annanghende unu vìdeu correladu a sa lista + Annanghe automaticamente unu cuntenutu a sa lista + Memòria temporànea de sos metadatos iscarrigada + Boga totu sos datos de sa pàgina web in sa memòria temporànea + Iscantzella sos metadatos in sa memòria temporànea + Memòria temporànea de sas immàgines isboidada + Istuda pro prevènnere su carrigamentu de sas miniaduras, su sarvamentu de sos datos e s\'impreu de sa memòria. Sas modìficas ant a isbodiare siat sa memòria temporànea de sa memòria siat cussa de su discu. + Istuda pro cuare sos cummentos + Ammustra sos cummentos + Càrriga sas miniaduras + Longària de s\'avantzamentu e de sa torrada in segus lestros + Su moimentu inesatu permitit a su riproduidore de si mòere cara a una positzione in manera prus lestra ma prus pagu pretzisa. Su de si mòere de 5, 15 o 25 segundos non funtzionat, cun custa optzione. + Imprea su moimentu inesatu lestru + Ammenta sa mannària e sa positzione de sa ventanedda + Nieddu + Iscuru + Craru + Tema + Formadu vìdeu predefinidu + Formadu àudio predefinidu + Àudio + Una miniadura de su vìdeu benit ammustrada in s\'ischermada de blocu cando ses impreende su riproduidore in s\'isfundu + Ammustra un\'optzione pro riproduire unu vìdeu pro mèdiu de su tentru multimediale Kodi + Miniadura vìdeu de s\'ischermada de blocu + Ammustra s\'optzione \"Riprodui cun Kodi\" + Cheres installare s\'aplicatzione Kore chi mancat\? + Riprodui cun Kodi + Petzi unos cantos dispositivos podent riproduire vìdeos in 2K/4K + Ammustra sas risolutziones prus artas + Risolutzione predefinida de sa ventanedda + Risolutzione predefinida + Riproduet unu vìdeu cando NewPipe benit abertu dae un\'àtera aplicatzione + Riprodutzione automàtica + Càmbia sa cartella de iscarrigamentu pro chi tèngiat efetu + Issèbera sa cartella de iscarrigamentu pro sos documentos àudio + Sos documentos àudio iscarrigados benint sarvados inoghe + Cartella de iscarrigamentu de s\'àudio + Issèbera sa cartella de iscarrigamentu pro sos documentos de sos vìdeos + Sos documentos de sos vìdeos benint sarvados inoghe + Cartella de iscarrigamentu de sos vìdeos + Annanghe a + Ventanedda + Isfundu + Issèbera un\'ischeda + Ischeda noa + Iscalitas sarvadas + Iscritziones + Printzipale + Ammustra sas informatziones + Agiornamentu de s\'iscritzione fallidu + Mudadura de s\'iscritzione fallida + Non ses prus iscritu a su canale + Boga s\'iscritzione + Iscritu + Iscrie·ti + Modalidade a ventanedda + Imprea unu riproduidore àudio esternu + Bogat s\'àudio pro unas cantas risolutziones + Imprea unu riproduidore de vìdeos esternu + rotatzione + Issèbera su navigadore + Cumpartzi cun + Cherias nàrrere: %1$s\? + Impostatziones + Chirca + Iscàrriga su documentu de trasmissione + Iscarriga + Cumpartzi + Aberi in sa modalidade a ventanedda + Aberi in su navigadore web + Annulla + Installa + Perunu riproduidore de flussos agatadu. Cheres installare VLC\? + Publicadu su %1$s + %1$s visualizatziones + Toca \"Chirca\" pro incumintzare + \ No newline at end of file From a99667c54c872a87ad6429748603c058e1009494 Mon Sep 17 00:00:00 2001 From: Raymundo Date: Thu, 30 Jul 2020 05:25:26 +0000 Subject: [PATCH 021/137] Translated using Weblate (Spanish) Currently translated at 100.0% (584 of 584 strings) --- app/src/main/res/values-es/strings.xml | 40 ++++++++++++++++---------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index cbff74f70..0625a879d 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -51,17 +51,17 @@ No se pudo cargar las miniaturas No se pudo descifrar la URL del vídeo No se pudo analizar el sitio web - Mostrar vídeos «siguientes» y «similares» + Mostrar vídeos \'Siguientes\' y \'Similares\' Idioma predeterminado del contenido Miniatura de previsualización del vídeo Reproducir vídeo; duración: Me gusta No me gusta Miniatura del avatar del usuario - Aún no se admiten las transmisiones en vivo + Las transmisiones en vivo no son soportadas aún Contenido Contenido restringido por edad - Mostrar vídeo restringido por edad. Se pueden realizar más cambios desde los ajustes. + Mostrar vídeo restringido por edad. Se pueden realizar cambios futuros desde los ajustes. Toque «Buscar» para empezar Reproducción automática Reproducir un vídeo cuando NewPipe es llamado desde otra app @@ -101,12 +101,12 @@ URL mal escrito o Internet no disponible NewPipe está descargando Toque para ver detalles - Espere… + Espere, por favor… Copiado en el portapapeles Defina una carpeta de descargas más tarde en la configuración No se pudo cargar la imagen La interfaz de la app dejó de funcionar - Lo sucedido:\\nPetición:\\nIdioma del contenido:\\nServicio:\\nHora GMT:\\nPaquete:\\nVersión:\\nVersión del SO: + Lo sucedido:\\nPetición:\\nIdioma del Contenido:\\nPaís del contenido:\\nIdioma de la aplicación:\\nServicio:\\nHora GMT:\\nPaquete:\\nVersión:\\nVersión del SO: Negro Todo Canal @@ -114,7 +114,7 @@ Después k M - MM + G Abrir en modo emergente Se necesita este permiso \npara abrir en modo emergente @@ -193,7 +193,7 @@ Lista de reproducción Deshacer No hay resultados - Aquí no hay nada más que grillos + Nada aquí, sino grillos Sin suscriptores %s suscriptor @@ -241,12 +241,12 @@ Comenzar a reproducir aquí Comenzar a reproducir en segundo plano Reproducir en modo emergente - Mostrar consejo «Mantener presionado para agregar» + Mostrar consejo \"Mantener presionado para añadir\" Novedades Mantener presionado para agregar a la cola Donar NewPipe es desarrollado por voluntarios que emplean su tiempo libre para brindarle la mejor experiencia. Haga una aportación para ayudarlos a crear un NewPipe mejor mientras disfrutan de una taza de café. - Donar + Dar de vuelta Sitio web Visite el sitio web de NewPipe para más información y noticias. País predeterminado del contenido @@ -324,7 +324,7 @@ Archivo Archivo movido o eliminado La carpeta no existe - No existe la fuente del archivo/contenido + No existe tal archivo/origen del contenido El archivo no existe o carece de los permisos para leer o escribir en él El nombre del archivo no puede estar vacío Ocurrió un error: %1$s @@ -381,9 +381,11 @@ NewPipe es un software copyleft libre: puedes usarlo, estudiarlo, compartirlo y mejorarlo a voluntad. Específicamente, puedes redistribuirlo y/o modificarlo bajo los términos de la Licencia Pública General GNU publicada por la Free Software Foundation, ya sea la versión 3 de la Licencia, o (a tu elección) cualquier versión posterior. ¿Quiere importar también la configuración\? Normativa de privacidad de NewPipe - El proyecto NewPipe toma su privacidad muy en serio. Por ello, la aplicación no recopila ningún dato sin su consentimiento. La normativa de privacidad de NewPipe explica en detalle qué datos se envían y almacenan cuando envía un informe de fallo. + El proyecto NewPipe toma su privacidad muy en serio. Por ello, la aplicación no recopila algún dato sin su consentimiento. +\nLa normativa de privacidad de NewPipe explica en detalle qué datos se envían y almacenan cuando envía un informe de fallo. Leer la normativa de privacidad - Para cumplir con el Reglamento general europeo de protección de datos (GDPR), podemos llamar su atención sobre la política de privacidad de NewPipe. Por favor léelo cuidadosamente. Debe aceptarlo para enviarnos el informe de error. + Para cumplir con el Reglamento general europeo de protección de datos (GDPR), atraemos su atención sobre la política de privacidad de NewPipe. Por favor léase cuidadosamente. +\nDebe aceptarlo para enviarnos el informe de error. Aceptar Declinar Sin límite @@ -458,7 +460,7 @@ Usar SAF El \'Framework de Acceso al Almacenamiento\' permite descargar en una tarjeta SD externa. \nAlgunos dispositivos no son compatibles - Cancelar suscripción + Desuscribirse Pestaña nueva Elija la pestaña Control de volumen por gestos @@ -528,11 +530,11 @@ Generado automáticamente (no se encontró creador) Elige una instancia Miniatura de vídeo en pantalla de bloqueo - Se mostrará una miniatura del vídeo en la pantalla de bloqueo al usar el reproductor en segundo plano + Una miniatura del vídeo es mostrada en la pantalla de bloqueo cuando se está usando el reproductor en segundo plano Limpiar historial de descargas Eliminar archivos descargados Eliminadas %1$d descargas - Dar permisos para que se muestre por sobre otras apps + Permitir mostrar sobre otras aplicaciones Idioma de aplicación Predeterminado del sistema Pulse en «Hecho» cuando esté resuelto @@ -614,4 +616,12 @@ Los textos originales de los servicios serán visibles en los ítems de transmisiones Mostrar tiempo atrás original en ítems Modo restringido de YouTube + Página de lista de reproducción + Mostrar sólo suscripciones desagrupadas + Sin marcadores de lista de reproducción aún + Seleccione una lista de reproducción + Por favor revise si ya existe una discusión sobre su problema. Cuando se crean entradas duplicadas, toma tiempo de nosotros que podríamos usar para arreglar tal problema. + Reportar error en Github + Copiar reporte con formato + Mostrando resultados para: %s \ No newline at end of file From ae3953cbec5833cd8d27d66ad89fb0c829a56976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89frit?= Date: Thu, 30 Jul 2020 12:44:55 +0000 Subject: [PATCH 022/137] Translated using Weblate (French) Currently translated at 100.0% (584 of 584 strings) --- app/src/main/res/values-fr/strings.xml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 0d14f1390..f0fec8b85 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -116,7 +116,7 @@ Oui Plus tard Désactivés - Quoi :\\nRequête :\\nLangue du contenu :\\nService :\\nHeure UTC :\\nPaquet :\\nVersion :\\nVersion du système d’exploitation : + Quoi :\\nRequête :\\nLangue du contenu :\\nPays du contenu :\\nLangue de l’application :\\nService :\\nDate UTC :\\nPaquet :\\nVersion :\\nVersion du système d’exploitation : k M Cette autorisation est nécessaire pour @@ -614,4 +614,11 @@ Afficher la date originelle sur les items Mode restreint de YouTube Afficher les abonnements sans groupes uniquement + Page des listes de lecture + Aucune liste de lecture encore enregistrée + Sélectionner une liste de lecture + Veuillez vérifier si un ticket concernant votre problème existe déjà. Lorsque vous créez des tickets dupliqués, cela nous prend du temps que nous pourrions passer à résoudre effectivement le problème. + Rapporter l’erreur sur GitHub + Copier le rapport formaté + Affichage des résultats pour : %s \ No newline at end of file From 0bca4925d7863ff3e832fa3eb038d911ec7f4a36 Mon Sep 17 00:00:00 2001 From: Oymate Date: Thu, 30 Jul 2020 04:52:32 +0000 Subject: [PATCH 023/137] Translated using Weblate (Bengali (Bangladesh)) Currently translated at 32.7% (191 of 584 strings) --- app/src/main/res/values-bn-rBD/strings.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/src/main/res/values-bn-rBD/strings.xml b/app/src/main/res/values-bn-rBD/strings.xml index 0299457c3..355a91265 100644 --- a/app/src/main/res/values-bn-rBD/strings.xml +++ b/app/src/main/res/values-bn-rBD/strings.xml @@ -196,4 +196,16 @@ ভলিউম সংকেত নিয়ন্ত্রণ সম্পূর্ণ তালিকা + তালিকাতে পজিশন + শেষ প্লেব্যাক পজিশন এ যাও + পুনরায় প্লে ব্যাক চালু করো + সার্চগুলো স্থানীয়ভাবে জমা করো + সার্চের সময় পরামর্শ দেখাও + সার্চ পরামর্শ + প্লেয়ারের উজ্জ্বলতা এবং ভলিউম নিয়ন্ত্রণ করতে সংকেত ব্যবহার করো + রেজাল্ট দেখানো হচ্ছেঃ %s + সম্পর্কিত + সম্পর্কিত + নিউপাইপ এর সম্বন্ধে + ট্রেন্ডিং \ No newline at end of file From a842b063010819f7c4f3fad0caeb99f7897c9dfd Mon Sep 17 00:00:00 2001 From: Mateo Coltura <40e3004b-a296-47bd-a073-3dd8af36f77f@anonaddy.me> Date: Thu, 30 Jul 2020 20:42:13 +0000 Subject: [PATCH 024/137] Translated using Weblate (Flemish) Currently translated at 73.6% (430 of 584 strings) --- app/src/main/res/values-nl-rBE/strings.xml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/app/src/main/res/values-nl-rBE/strings.xml b/app/src/main/res/values-nl-rBE/strings.xml index a80cec9cc..028b3e2cf 100644 --- a/app/src/main/res/values-nl-rBE/strings.xml +++ b/app/src/main/res/values-nl-rBE/strings.xml @@ -3,7 +3,7 @@ Tik op zoeken voor te beginnen %1$s keer bekeken Gepubliceerd op %1$s - Geen speler met streamondersteuning gevonden. Wil je VLC installeren\? + Er is geen videospeler met streamondersteuning gevonden. Wilt u VLC installeren\? Geen speler met streamondersteuning gevonden (je kan VLC installeren om af te spelen). Installeren Annuleren @@ -19,9 +19,9 @@ Kies browser rotatie Externe videospeler gebruiken - Verwijdert het geluid bij SOMMIGE resoluties + Verwijdert het geluid bij sommige resoluties Externe audiospeler gebruiken - NewPipe-pop-upmodus + Pop-up-modus Abonneer Geabonneerd Abonnement opgezegd @@ -37,18 +37,18 @@ Toevoegen aan Downloadlocatie voor video’s Gedownloade videobestanden worden hier opgeslaan - Voer downloadlocatie in voor video’s + Kies de downloadlocatie voor videobestanden Downloadmap voor audio Gedownloade audiobestanden worden hier opgeslaan - Voer downloadlocatie voor audiobestanden in + Kies de downloadlocatie voor audiobestanden Automatisch afspelen Speelt video’s af wanneer dat NewPipe vanuit een anderen app word geopend Standaardresolutie Standaardresolutie voor pop-up Hogere resoluties weergeven - Video’s afspelen in 2K/4K wordt maar op sommige apparaten ondersteund + Slechts enkele toestellen kunnen 2K- en 4K-video\'s afspelen Afspelen met Kodi - Kore-app niet gevonden. Installeren? + Wilt u de missende Kore-app installeren\? Toon “Afspelen met Kodi”-optie Toont een optie voor ne video op een Kodi media center af te spelen Audio @@ -466,4 +466,5 @@ Kan commentaren niet laden Sluiten Vooruitgang verloren, omdat het bestand gedeletet werd + Resultaten aan het tonen voor: %s \ No newline at end of file From 4abf6b2f5cb7fe38b0f3b4cc13e48c46b0725a2e Mon Sep 17 00:00:00 2001 From: cool-student Date: Tue, 3 Mar 2020 00:35:44 +0100 Subject: [PATCH 025/137] Notification Improvements - add MediaStyle notifications for Background and Popup playback - reduce excessive notification updating ( / recreating of Notification.Builder object) when playing background / popup media - add new buffering state indicator (can be disabled) - upscale close icon / downscale replay icon - add notification slot settings - move notification settings to appearance - fix Metadata (song title, artist and album art) sometimes not being set correctly - other misc notification fixes Co-authored-by: wb9688 --- .../newpipe/player/BackgroundPlayer.java | 462 +++--- .../newpipe/player/NotificationUtil.java | 1379 +++++++++++++++++ .../newpipe/player/PopupVideoPlayer.java | 333 ++-- .../player/helper/MediaSessionManager.java | 97 +- .../settings/AppearanceSettingsFragment.java | 15 + .../res/drawable-hdpi/ic_close_white_32dp.png | Bin 0 -> 257 bytes .../drawable-hdpi/ic_replay_white_32dp.png | Bin 0 -> 804 bytes .../res/drawable-mdpi/ic_close_white_32dp.png | Bin 0 -> 542 bytes .../drawable-mdpi/ic_replay_white_32dp.png | Bin 0 -> 583 bytes .../drawable-xhdpi/ic_close_white_32dp.png | Bin 0 -> 666 bytes .../drawable-xhdpi/ic_replay_white_32dp.png | Bin 0 -> 1168 bytes .../drawable-xxhdpi/ic_close_white_32dp.png | Bin 0 -> 436 bytes .../drawable-xxhdpi/ic_replay_white_32dp.png | Bin 0 -> 908 bytes .../drawable-xxxhdpi/ic_close_white_32dp.png | Bin 0 -> 1852 bytes .../drawable-xxxhdpi/ic_replay_white_32dp.png | Bin 0 -> 2580 bytes app/src/main/res/values/settings_keys.xml | 107 ++ app/src/main/res/values/strings.xml | 14 +- app/src/main/res/xml/appearance_settings.xml | 92 +- app/src/main/res/xml/video_audio_settings.xml | 7 - 19 files changed, 2025 insertions(+), 481 deletions(-) create mode 100644 app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java create mode 100644 app/src/main/res/drawable-hdpi/ic_close_white_32dp.png create mode 100644 app/src/main/res/drawable-hdpi/ic_replay_white_32dp.png create mode 100644 app/src/main/res/drawable-mdpi/ic_close_white_32dp.png create mode 100644 app/src/main/res/drawable-mdpi/ic_replay_white_32dp.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_close_white_32dp.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_replay_white_32dp.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_close_white_32dp.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_replay_white_32dp.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_close_white_32dp.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_replay_white_32dp.png diff --git a/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java b/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java index 943d685b1..efbe2b912 100644 --- a/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/BackgroundPlayer.java @@ -19,44 +19,33 @@ package org.schabi.newpipe.player; -import android.app.NotificationManager; -import android.app.PendingIntent; import android.app.Service; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; -import android.content.res.Resources; import android.graphics.Bitmap; import android.os.Build; import android.os.IBinder; import android.preference.PreferenceManager; import android.util.Log; import android.view.View; -import android.widget.RemoteViews; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; -import androidx.core.app.NotificationCompat; import com.google.android.exoplayer2.PlaybackParameters; -import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.source.MediaSource; import com.nostra13.universalimageloader.core.assist.FailReason; -import org.schabi.newpipe.BuildConfig; import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.player.event.PlayerEventListener; import org.schabi.newpipe.player.playqueue.PlayQueueItem; import org.schabi.newpipe.player.resolver.AudioPlaybackResolver; import org.schabi.newpipe.player.resolver.MediaSourceTag; -import org.schabi.newpipe.util.BitmapUtils; -import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.ThemeHelper; -import static org.schabi.newpipe.player.helper.PlayerHelper.getTimeString; import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage; /** @@ -65,6 +54,9 @@ import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage; * @author mauriciocolli */ public final class BackgroundPlayer extends Service { + private static final String TAG = "BackgroundPlayer"; + private static final boolean DEBUG = BasePlayer.DEBUG; + public static final String ACTION_CLOSE = "org.schabi.newpipe.player.BackgroundPlayer.CLOSE"; public static final String ACTION_PLAY_PAUSE @@ -79,30 +71,27 @@ public final class BackgroundPlayer extends Service { = "org.schabi.newpipe.player.BackgroundPlayer.ACTION_FAST_REWIND"; public static final String ACTION_FAST_FORWARD = "org.schabi.newpipe.player.BackgroundPlayer.ACTION_FAST_FORWARD"; + public static final String ACTION_BUFFERING + = "org.schabi.newpipe.player.BackgroundPlayer.ACTION_BUFFERING"; + public static final String ACTION_SHUFFLE + = "org.schabi.newpipe.player.BackgroundPlayer.ACTION_SHUFFLE"; public static final String SET_IMAGE_RESOURCE_METHOD = "setImageResource"; - private static final String TAG = "BackgroundPlayer"; - private static final boolean DEBUG = BasePlayer.DEBUG; - private static final int NOTIFICATION_ID = 123789; - private static final int NOTIFICATION_UPDATES_BEFORE_RESET = 60; + + private BasePlayerImpl basePlayerImpl; + private SharedPreferences sharedPreferences; + + private boolean shouldUpdateOnProgress; // only used for old notifications + private boolean isForwardPressed; + private boolean isRewindPressed; /*////////////////////////////////////////////////////////////////////////// // Service-Activity Binder //////////////////////////////////////////////////////////////////////////*/ - private SharedPreferences sharedPreferences; - /*////////////////////////////////////////////////////////////////////////// - // Notification - //////////////////////////////////////////////////////////////////////////*/ private PlayerEventListener activityListener; private IBinder mBinder; - private NotificationManager notificationManager; - private NotificationCompat.Builder notBuilder; - private RemoteViews notRemoteView; - private RemoteViews bigNotRemoteView; - private boolean shouldUpdateOnProgress; - private int timesNotificationUpdated; /*////////////////////////////////////////////////////////////////////////// // Service's LifeCycle @@ -113,7 +102,7 @@ public final class BackgroundPlayer extends Service { if (DEBUG) { Log.d(TAG, "onCreate() called"); } - notificationManager = ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)); + sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); assureCorrectAppLanguage(this); ThemeHelper.setTheme(this); @@ -127,7 +116,7 @@ public final class BackgroundPlayer extends Service { @Override public int onStartCommand(final Intent intent, final int flags, final int startId) { if (DEBUG) { - Log.d(TAG, "onStartCommand() called with: intent = [" + intent + "], " + Log.d(TAG, "N_ onStartCommand() called with: intent = [" + intent + "], " + "flags = [" + flags + "], startId = [" + startId + "]"); } basePlayerImpl.handleIntent(intent); @@ -160,7 +149,7 @@ public final class BackgroundPlayer extends Service { //////////////////////////////////////////////////////////////////////////*/ private void onClose() { if (DEBUG) { - Log.d(TAG, "onClose() called"); + Log.d(TAG, "N_ onClose() called"); } if (basePlayerImpl != null) { @@ -168,9 +157,8 @@ public final class BackgroundPlayer extends Service { basePlayerImpl.stopActivityBinding(); basePlayerImpl.destroy(); } - if (notificationManager != null) { - notificationManager.cancel(NOTIFICATION_ID); - } + NotificationUtil.getInstance() + .cancelNotification(NotificationUtil.NOTIFICATION_ID_BACKGROUND); mBinder = null; basePlayerImpl = null; @@ -191,168 +179,9 @@ public final class BackgroundPlayer extends Service { } } - /*////////////////////////////////////////////////////////////////////////// - // Notification - //////////////////////////////////////////////////////////////////////////*/ - - private void resetNotification() { - notBuilder = createNotification(); - timesNotificationUpdated = 0; - } - - private NotificationCompat.Builder createNotification() { - notRemoteView = new RemoteViews(BuildConfig.APPLICATION_ID, - R.layout.player_background_notification); - bigNotRemoteView = new RemoteViews(BuildConfig.APPLICATION_ID, - R.layout.player_background_notification_expanded); - - setupNotification(notRemoteView); - setupNotification(bigNotRemoteView); - - NotificationCompat.Builder builder = new NotificationCompat - .Builder(this, getString(R.string.notification_channel_id)) - .setOngoing(true) - .setSmallIcon(R.drawable.ic_newpipe_triangle_white) - .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) - .setCustomContentView(notRemoteView) - .setCustomBigContentView(bigNotRemoteView); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - setLockScreenThumbnail(builder); - } - - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) { - builder.setPriority(NotificationCompat.PRIORITY_MAX); - } - return builder; - } - - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) - private void setLockScreenThumbnail(final NotificationCompat.Builder builder) { - boolean isLockScreenThumbnailEnabled = sharedPreferences.getBoolean( - getString(R.string.enable_lock_screen_video_thumbnail_key), true); - - if (isLockScreenThumbnailEnabled) { - basePlayerImpl.mediaSessionManager.setLockScreenArt( - builder, - getCenteredThumbnailBitmap() - ); - } else { - basePlayerImpl.mediaSessionManager.clearLockScreenArt(builder); - } - } - - @Nullable - private Bitmap getCenteredThumbnailBitmap() { - final int screenWidth = Resources.getSystem().getDisplayMetrics().widthPixels; - final int screenHeight = Resources.getSystem().getDisplayMetrics().heightPixels; - - return BitmapUtils.centerCrop(basePlayerImpl.getThumbnail(), screenWidth, screenHeight); - } - - private void setupNotification(final RemoteViews remoteViews) { - if (basePlayerImpl == null) { - return; - } - - remoteViews.setTextViewText(R.id.notificationSongName, basePlayerImpl.getVideoTitle()); - remoteViews.setTextViewText(R.id.notificationArtist, basePlayerImpl.getUploaderName()); - - remoteViews.setOnClickPendingIntent(R.id.notificationPlayPause, - PendingIntent.getBroadcast(this, NOTIFICATION_ID, - new Intent(ACTION_PLAY_PAUSE), PendingIntent.FLAG_UPDATE_CURRENT)); - remoteViews.setOnClickPendingIntent(R.id.notificationStop, - PendingIntent.getBroadcast(this, NOTIFICATION_ID, - new Intent(ACTION_CLOSE), PendingIntent.FLAG_UPDATE_CURRENT)); - remoteViews.setOnClickPendingIntent(R.id.notificationRepeat, - PendingIntent.getBroadcast(this, NOTIFICATION_ID, - new Intent(ACTION_REPEAT), PendingIntent.FLAG_UPDATE_CURRENT)); - - // Starts background player activity -- attempts to unlock lockscreen - final Intent intent = NavigationHelper.getBackgroundPlayerActivityIntent(this); - remoteViews.setOnClickPendingIntent(R.id.notificationContent, - PendingIntent.getActivity(this, NOTIFICATION_ID, intent, - PendingIntent.FLAG_UPDATE_CURRENT)); - - if (basePlayerImpl.playQueue != null && basePlayerImpl.playQueue.size() > 1) { - remoteViews.setInt(R.id.notificationFRewind, SET_IMAGE_RESOURCE_METHOD, - R.drawable.exo_controls_previous); - remoteViews.setInt(R.id.notificationFForward, SET_IMAGE_RESOURCE_METHOD, - R.drawable.exo_controls_next); - remoteViews.setOnClickPendingIntent(R.id.notificationFRewind, - PendingIntent.getBroadcast(this, NOTIFICATION_ID, - new Intent(ACTION_PLAY_PREVIOUS), PendingIntent.FLAG_UPDATE_CURRENT)); - remoteViews.setOnClickPendingIntent(R.id.notificationFForward, - PendingIntent.getBroadcast(this, NOTIFICATION_ID, - new Intent(ACTION_PLAY_NEXT), PendingIntent.FLAG_UPDATE_CURRENT)); - } else { - remoteViews.setInt(R.id.notificationFRewind, SET_IMAGE_RESOURCE_METHOD, - R.drawable.exo_controls_rewind); - remoteViews.setInt(R.id.notificationFForward, SET_IMAGE_RESOURCE_METHOD, - R.drawable.exo_controls_fastforward); - remoteViews.setOnClickPendingIntent(R.id.notificationFRewind, - PendingIntent.getBroadcast(this, NOTIFICATION_ID, - new Intent(ACTION_FAST_REWIND), PendingIntent.FLAG_UPDATE_CURRENT)); - remoteViews.setOnClickPendingIntent(R.id.notificationFForward, - PendingIntent.getBroadcast(this, NOTIFICATION_ID, - new Intent(ACTION_FAST_FORWARD), PendingIntent.FLAG_UPDATE_CURRENT)); - } - - setRepeatModeIcon(remoteViews, basePlayerImpl.getRepeatMode()); - } - - /** - * Updates the notification, and the play/pause button in it. - * Used for changes on the remoteView - * - * @param drawableId if != -1, sets the drawable with that id on the play/pause button - */ - private synchronized void updateNotification(final int drawableId) { -// if (DEBUG) { -// Log.d(TAG, "updateNotification() called with: drawableId = [" + drawableId + "]"); -// } - if (notBuilder == null) { - return; - } - if (drawableId != -1) { - if (notRemoteView != null) { - notRemoteView.setImageViewResource(R.id.notificationPlayPause, drawableId); - } - if (bigNotRemoteView != null) { - bigNotRemoteView.setImageViewResource(R.id.notificationPlayPause, drawableId); - } - } - notificationManager.notify(NOTIFICATION_ID, notBuilder.build()); - timesNotificationUpdated++; - } - - /*////////////////////////////////////////////////////////////////////////// - // Utils - //////////////////////////////////////////////////////////////////////////*/ - - private void setRepeatModeIcon(final RemoteViews remoteViews, final int repeatMode) { - switch (repeatMode) { - case Player.REPEAT_MODE_OFF: - remoteViews.setInt(R.id.notificationRepeat, SET_IMAGE_RESOURCE_METHOD, - R.drawable.exo_controls_repeat_off); - break; - case Player.REPEAT_MODE_ONE: - remoteViews.setInt(R.id.notificationRepeat, SET_IMAGE_RESOURCE_METHOD, - R.drawable.exo_controls_repeat_one); - break; - case Player.REPEAT_MODE_ALL: - remoteViews.setInt(R.id.notificationRepeat, SET_IMAGE_RESOURCE_METHOD, - R.drawable.exo_controls_repeat_all); - break; - } - } - ////////////////////////////////////////////////////////////////////////// - protected class BasePlayerImpl extends BasePlayer { @NonNull private final AudioPlaybackResolver resolver; - private int cachedDuration; - private String cachedDurationString; BasePlayerImpl(final Context context) { super(context); @@ -367,51 +196,49 @@ public final class BackgroundPlayer extends Service { @Override public void handleIntent(final Intent intent) { super.handleIntent(intent); - - resetNotification(); - if (bigNotRemoteView != null) { - bigNotRemoteView.setProgressBar(R.id.notificationProgressBar, 100, 0, false); + if (DEBUG) { + Log.d(TAG, "N_ handleIntent()"); } - if (notRemoteView != null) { - notRemoteView.setProgressBar(R.id.notificationProgressBar, 100, 0, false); - } - startForeground(NOTIFICATION_ID, notBuilder.build()); + NotificationUtil.getInstance().recreateBackgroundPlayerNotification(context, + basePlayerImpl.mediaSessionManager.getSessionToken(), basePlayerImpl, + sharedPreferences, true); // false + NotificationUtil.getInstance().setProgressbarOnOldNotifications(100, 0, false); + startForeground(NotificationUtil.NOTIFICATION_ID_BACKGROUND, + NotificationUtil.getInstance().notificationBuilder.build()); } /*////////////////////////////////////////////////////////////////////////// // Thumbnail Loading //////////////////////////////////////////////////////////////////////////*/ - private void updateNotificationThumbnail() { - if (basePlayerImpl == null) { - return; - } - if (notRemoteView != null) { - notRemoteView.setImageViewBitmap(R.id.notificationCover, - basePlayerImpl.getThumbnail()); - } - if (bigNotRemoteView != null) { - bigNotRemoteView.setImageViewBitmap(R.id.notificationCover, - basePlayerImpl.getThumbnail()); - } - } - @Override public void onLoadingComplete(final String imageUri, final View view, final Bitmap loadedImage) { super.onLoadingComplete(imageUri, view, loadedImage); - resetNotification(); - updateNotificationThumbnail(); - updateNotification(-1); + if (DEBUG) { + Log.d(TAG, "N_ onLoadingComplete()"); + } + NotificationUtil.getInstance().recreateBackgroundPlayerNotification(context, + basePlayerImpl.mediaSessionManager.getSessionToken(), basePlayerImpl, + sharedPreferences, true); //true + NotificationUtil.getInstance().updateOldNotificationsThumbnail(basePlayerImpl); + NotificationUtil.getInstance().updateBackgroundPlayerNotification(-1, + getBaseContext(), basePlayerImpl, sharedPreferences); } @Override public void onLoadingFailed(final String imageUri, final View view, final FailReason failReason) { super.onLoadingFailed(imageUri, view, failReason); - resetNotification(); - updateNotificationThumbnail(); - updateNotification(-1); + if (DEBUG) { + Log.d(TAG, "N_ onLoadingFailed()"); + } + NotificationUtil.getInstance().recreateBackgroundPlayerNotification(context, + basePlayerImpl.mediaSessionManager.getSessionToken(), basePlayerImpl, + sharedPreferences, true); //true + NotificationUtil.getInstance().updateOldNotificationsThumbnail(basePlayerImpl); + NotificationUtil.getInstance().updateBackgroundPlayerNotification(-1, + getBaseContext(), basePlayerImpl, sharedPreferences); } /*////////////////////////////////////////////////////////////////////////// @@ -426,6 +253,14 @@ public final class BackgroundPlayer extends Service { @Override public void onShuffleClicked() { super.onShuffleClicked(); + if (DEBUG) { + Log.d(TAG, "N_ onShuffleClicked:"); + } + NotificationUtil.getInstance().recreateBackgroundPlayerNotification(context, + basePlayerImpl.mediaSessionManager.getSessionToken(), basePlayerImpl, + sharedPreferences); + NotificationUtil.getInstance().updateBackgroundPlayerNotification(-1, + getBaseContext(), basePlayerImpl, sharedPreferences); updatePlayback(); } @@ -440,31 +275,35 @@ public final class BackgroundPlayer extends Service { final int bufferPercent) { updateProgress(currentProgress, duration, bufferPercent); - if (!shouldUpdateOnProgress) { - return; - } - if (timesNotificationUpdated > NOTIFICATION_UPDATES_BEFORE_RESET) { - resetNotification(); + // setMetadata only updates the metadata when any of the metadata keys are null + basePlayerImpl.mediaSessionManager.setMetadata(basePlayerImpl.getVideoTitle(), + basePlayerImpl.getUploaderName(), basePlayerImpl.getThumbnail(), duration); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O /*Oreo*/) { - updateNotificationThumbnail(); + boolean areOldNotificationsEnabled = sharedPreferences.getBoolean( + getString(R.string.enable_old_notifications_key), false); + if (areOldNotificationsEnabled) { + if (!shouldUpdateOnProgress) { + return; } - } - if (bigNotRemoteView != null) { - if (cachedDuration != duration) { - cachedDuration = duration; - cachedDurationString = getTimeString(duration); + if (NotificationUtil.timesNotificationUpdated + > NotificationUtil.NOTIFICATION_UPDATES_BEFORE_RESET) { + NotificationUtil.getInstance().recreateBackgroundPlayerNotification(context, + basePlayerImpl.mediaSessionManager.getSessionToken(), basePlayerImpl, + sharedPreferences); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + NotificationUtil.getInstance() + .updateOldNotificationsThumbnail(basePlayerImpl); + } } - bigNotRemoteView.setProgressBar(R.id.notificationProgressBar, duration, + + NotificationUtil.getInstance().setCachedDuration(currentProgress, duration); + NotificationUtil.getInstance().setProgressbarOnOldNotifications(duration, currentProgress, false); - bigNotRemoteView.setTextViewText(R.id.notificationTime, - getTimeString(currentProgress) + " / " + cachedDurationString); + + NotificationUtil.getInstance().updateBackgroundPlayerNotification(-1, + getBaseContext(), basePlayerImpl, sharedPreferences); } - if (notRemoteView != null) { - notRemoteView.setProgressBar(R.id.notificationProgressBar, duration, - currentProgress, false); - } - updateNotification(-1); } @Override @@ -482,12 +321,7 @@ public final class BackgroundPlayer extends Service { @Override public void destroy() { super.destroy(); - if (notRemoteView != null) { - notRemoteView.setImageViewBitmap(R.id.notificationCover, null); - } - if (bigNotRemoteView != null) { - bigNotRemoteView.setImageViewBitmap(R.id.notificationCover, null); - } + NotificationUtil.getInstance().unsetImageInOldNotifications(); } /*////////////////////////////////////////////////////////////////////////// @@ -507,8 +341,14 @@ public final class BackgroundPlayer extends Service { @Override public void onRepeatModeChanged(final int i) { - resetNotification(); - updateNotification(-1); + if (DEBUG) { + Log.d(TAG, "N_ onRepeatModeChanged()"); + } + NotificationUtil.getInstance().recreateBackgroundPlayerNotification(context, + basePlayerImpl.mediaSessionManager.getSessionToken(), basePlayerImpl, + sharedPreferences); + NotificationUtil.getInstance().updateBackgroundPlayerNotification(-1, + getBaseContext(), basePlayerImpl, sharedPreferences); updatePlayback(); } @@ -518,9 +358,15 @@ public final class BackgroundPlayer extends Service { protected void onMetadataChanged(@NonNull final MediaSourceTag tag) { super.onMetadataChanged(tag); - resetNotification(); - updateNotificationThumbnail(); - updateNotification(-1); + if (DEBUG) { + Log.d(TAG, "N_ onMetadataChanged()"); + } + NotificationUtil.getInstance().recreateBackgroundPlayerNotification(context, + basePlayerImpl.mediaSessionManager.getSessionToken(), basePlayerImpl, + sharedPreferences); + NotificationUtil.getInstance().updateOldNotificationsThumbnail(basePlayerImpl); + NotificationUtil.getInstance().updateBackgroundPlayerNotification(-1, + getBaseContext(), basePlayerImpl, sharedPreferences); updateMetadata(); } @@ -585,31 +431,36 @@ public final class BackgroundPlayer extends Service { //////////////////////////////////////////////////////////////////////////*/ @Override - protected void setupBroadcastReceiver(final IntentFilter intentFltr) { - super.setupBroadcastReceiver(intentFltr); - intentFltr.addAction(ACTION_CLOSE); - intentFltr.addAction(ACTION_PLAY_PAUSE); - intentFltr.addAction(ACTION_REPEAT); - intentFltr.addAction(ACTION_PLAY_PREVIOUS); - intentFltr.addAction(ACTION_PLAY_NEXT); - intentFltr.addAction(ACTION_FAST_REWIND); - intentFltr.addAction(ACTION_FAST_FORWARD); + protected void setupBroadcastReceiver(final IntentFilter intentFilter) { + super.setupBroadcastReceiver(intentFilter); + intentFilter.addAction(ACTION_CLOSE); + intentFilter.addAction(ACTION_PLAY_PAUSE); + intentFilter.addAction(ACTION_REPEAT); + intentFilter.addAction(ACTION_PLAY_PREVIOUS); + intentFilter.addAction(ACTION_PLAY_NEXT); + intentFilter.addAction(ACTION_FAST_REWIND); + intentFilter.addAction(ACTION_FAST_FORWARD); + intentFilter.addAction(ACTION_BUFFERING); + intentFilter.addAction(ACTION_SHUFFLE); + intentFilter.addAction(Intent.ACTION_SCREEN_ON); + intentFilter.addAction(Intent.ACTION_SCREEN_OFF); - intentFltr.addAction(Intent.ACTION_SCREEN_ON); - intentFltr.addAction(Intent.ACTION_SCREEN_OFF); - - intentFltr.addAction(Intent.ACTION_HEADSET_PLUG); + intentFilter.addAction(Intent.ACTION_HEADSET_PLUG); } @Override public void onBroadcastReceived(final Intent intent) { super.onBroadcastReceived(intent); + if (intent == null || intent.getAction() == null) { return; } + if (DEBUG) { - Log.d(TAG, "onBroadcastReceived() called with: intent = [" + intent + "]"); + // FIXME remove N_ + Log.d(TAG, "N_ onBroadcastReceived() called with: intent = [" + intent + "]"); } + switch (intent.getAction()) { case ACTION_CLOSE: onClose(); @@ -627,9 +478,11 @@ public final class BackgroundPlayer extends Service { onPlayPrevious(); break; case ACTION_FAST_FORWARD: + isForwardPressed = true; onFastForward(); break; case ACTION_FAST_REWIND: + isRewindPressed = true; onFastRewind(); break; case Intent.ACTION_SCREEN_ON: @@ -638,6 +491,17 @@ public final class BackgroundPlayer extends Service { case Intent.ACTION_SCREEN_OFF: onScreenOnOff(false); break; + case ACTION_BUFFERING: + onBuffering(); + break; + case ACTION_SHUFFLE: + onShuffleClicked(); + break; + case "android.intent.action.HEADSET_PLUG": //FIXME + /*notificationManager.cancel(NOTIFICATION_ID); + mediaSessionManager.dispose(); + mediaSessionManager.enable(getBaseContext(), basePlayerImpl.simpleExoPlayer);*/ + break; } } @@ -645,6 +509,31 @@ public final class BackgroundPlayer extends Service { // States //////////////////////////////////////////////////////////////////////////*/ + @Override + public void onBuffering() { + super.onBuffering(); + if (NotificationUtil.getInstance().notificationSlot0.contains("buffering") + || NotificationUtil.getInstance().notificationSlot1.contains("buffering") + || NotificationUtil.getInstance().notificationSlot2.contains("buffering") + || NotificationUtil.getInstance().notificationSlot3.contains("buffering") + || NotificationUtil.getInstance().notificationSlot4.contains("buffering")) { + if (basePlayerImpl.getCurrentState() == BasePlayer.STATE_PREFLIGHT + || basePlayerImpl.getCurrentState() == BasePlayer.STATE_BLOCKED + || basePlayerImpl.getCurrentState() == BasePlayer.STATE_BUFFERING) { + if (!(isForwardPressed || isRewindPressed)) { + if (DEBUG) { + Log.d(TAG, "N_ onBuffering()"); + } + NotificationUtil.getInstance().updateBackgroundPlayerNotification(-1, + getBaseContext(), basePlayerImpl, sharedPreferences); + } else { + isForwardPressed = false; + isRewindPressed = false; + } + } + } + } + @Override public void changeState(final int state) { super.changeState(state); @@ -654,31 +543,50 @@ public final class BackgroundPlayer extends Service { @Override public void onPlaying() { super.onPlaying(); - resetNotification(); - updateNotificationThumbnail(); - updateNotification(R.drawable.exo_controls_pause); + + if (DEBUG) { + Log.d(TAG, "N_ onPlaying()"); + } + NotificationUtil.getInstance().recreateBackgroundPlayerNotification(context, + basePlayerImpl.mediaSessionManager.getSessionToken(), basePlayerImpl, + sharedPreferences); + NotificationUtil.getInstance().updateOldNotificationsThumbnail(basePlayerImpl); + NotificationUtil.getInstance() + .updateBackgroundPlayerNotification(R.drawable.ic_pause_white_24dp, + getBaseContext(), basePlayerImpl, sharedPreferences); } @Override public void onPaused() { super.onPaused(); - resetNotification(); - updateNotificationThumbnail(); - updateNotification(R.drawable.exo_controls_play); + + if (DEBUG) { + Log.d(TAG, "N_ onPaused()"); + } + NotificationUtil.getInstance().recreateBackgroundPlayerNotification(context, + basePlayerImpl.mediaSessionManager.getSessionToken(), basePlayerImpl, + sharedPreferences); + NotificationUtil.getInstance().updateOldNotificationsThumbnail(basePlayerImpl); + NotificationUtil.getInstance() + .updateBackgroundPlayerNotification(R.drawable.ic_play_arrow_white_24dp, + getBaseContext(), basePlayerImpl, sharedPreferences); } @Override public void onCompleted() { super.onCompleted(); - resetNotification(); - if (bigNotRemoteView != null) { - bigNotRemoteView.setProgressBar(R.id.notificationProgressBar, 100, 100, false); + if (DEBUG) { + Log.d(TAG, "N_ onCompleted()"); } - if (notRemoteView != null) { - notRemoteView.setProgressBar(R.id.notificationProgressBar, 100, 100, false); - } - updateNotificationThumbnail(); - updateNotification(R.drawable.ic_replay_white_24dp); + + NotificationUtil.getInstance().recreateBackgroundPlayerNotification(context, + basePlayerImpl.mediaSessionManager.getSessionToken(), basePlayerImpl, + sharedPreferences); + NotificationUtil.getInstance().setProgressbarOnOldNotifications(100, 100, false); + NotificationUtil.getInstance().updateOldNotificationsThumbnail(basePlayerImpl); + NotificationUtil.getInstance() + .updateBackgroundPlayerNotification(R.drawable.ic_replay_white_24dp, + getBaseContext(), basePlayerImpl, sharedPreferences); } } } diff --git a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java new file mode 100644 index 000000000..68648a8ad --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java @@ -0,0 +1,1379 @@ +package org.schabi.newpipe.player; + +import android.annotation.SuppressLint; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.Bitmap; +import android.graphics.Matrix; +import android.os.Build; +import android.support.v4.media.session.MediaSessionCompat; +import android.util.Log; +import android.widget.RemoteViews; + +import androidx.core.app.NotificationCompat; +import androidx.core.content.ContextCompat; + +import com.google.android.exoplayer2.Player; + +import org.schabi.newpipe.BuildConfig; +import org.schabi.newpipe.R; +import org.schabi.newpipe.util.NavigationHelper; + +import static android.content.Context.NOTIFICATION_SERVICE; +import static org.schabi.newpipe.player.helper.PlayerHelper.getTimeString; + +/** + * This is a utility class for player notifications. + * + * @author cool-student + */ +public final class NotificationUtil { + private static final String TAG = "NotificationUtil"; + private static final boolean DEBUG = BasePlayer.DEBUG; + + public static final int NOTIFICATION_ID_BACKGROUND = 123789; + public static final int NOTIFICATION_ID_POPUP = 40028922; + static final int NOTIFICATION_UPDATES_BEFORE_RESET = 60; // only used for old notifications + + static int timesNotificationUpdated; // only used for old notifications + + NotificationCompat.Builder notificationBuilder; + + String notificationSlot0 = "smart_rewind_prev"; + String notificationSlot1 = "play_pause_buffering"; + String notificationSlot2 = "smart_forward_next"; + String notificationSlot3 = "repeat"; + String notificationSlot4 = "close"; + + private NotificationManager notificationManager; + /*private NotificationManager notificationManager; + private NotificationCompat.Builder notificationBuilder;*/ + + private RemoteViews notificationPopupRemoteView; + private RemoteViews notificationRemoteView; // always null when new notifications are used + private RemoteViews bigNotificationRemoteView; // always null when new notifications are used + + private int cachedDuration; // only used for old notifications + private String cachedDurationString; // only used for old notifications + + private NotificationUtil() { } + + public static NotificationUtil getInstance() { + return LazyHolder.INSTANCE; + } + + void recreatePopupPlayerNotification(final Context context, + final MediaSessionCompat.Token mediaSessionCompatToken, + final PopupVideoPlayer.VideoPlayerImpl playerImpl, + final SharedPreferences sharedPreferences, + final boolean recreate) { + final boolean areOldNotificationsEnabled = sharedPreferences + .getBoolean(context.getString(R.string.enable_old_notifications_key), false); + if (areOldNotificationsEnabled) { + notificationBuilder = createOldPopupPlayerNotification(context, playerImpl); + } else if (notificationBuilder == null || recreate) { + Log.d(TAG, "N_ recreatePopupPlayerNotification(true)"); + notificationBuilder = createPopupPlayerNotification(context, mediaSessionCompatToken, + playerImpl, sharedPreferences); + } + timesNotificationUpdated = 0; + } + + void recreatePopupPlayerNotification(final Context context, + final MediaSessionCompat.Token mediaSessionCompatToken, + final PopupVideoPlayer.VideoPlayerImpl playerImpl, + final SharedPreferences sharedPreferences) { + final boolean areOldNotificationsEnabled = sharedPreferences + .getBoolean(context.getString(R.string.enable_old_notifications_key), false); + if (areOldNotificationsEnabled) { + notificationBuilder = createOldPopupPlayerNotification(context, playerImpl); + } else if (notificationBuilder == null) { + Log.d(TAG, "N_ recreatePopupPlayerNotification()"); + notificationBuilder = createPopupPlayerNotification(context, + mediaSessionCompatToken, playerImpl, sharedPreferences); + } + timesNotificationUpdated = 0; + } + + void recreateBackgroundPlayerNotification( + final Context context, final MediaSessionCompat.Token mediaSessionCompatToken, + final BackgroundPlayer.BasePlayerImpl basePlayerImpl, + final SharedPreferences sharedPreferences, final boolean recreate) { + final boolean areOldNotificationsEnabled = sharedPreferences + .getBoolean(context.getString(R.string.enable_old_notifications_key), false); + if (notificationBuilder == null || recreate || areOldNotificationsEnabled) { + Log.d(TAG, "N_ recreateBackgroundPlayerNotification(true)"); + notificationBuilder = createBackgroundPlayerNotification(context, + mediaSessionCompatToken, basePlayerImpl, sharedPreferences); + } + timesNotificationUpdated = 0; + } + + void recreateBackgroundPlayerNotification( + final Context context, final MediaSessionCompat.Token mediaSessionCompatToken, + final BackgroundPlayer.BasePlayerImpl basePlayerImpl, + final SharedPreferences sharedPreferences) { + final boolean areOldNotificationsEnabled = sharedPreferences + .getBoolean(context.getString(R.string.enable_old_notifications_key), false); + if (notificationBuilder == null || areOldNotificationsEnabled) { + Log.d(TAG, "N_ recreateBackgroundPlayerNotification()"); + notificationBuilder = createBackgroundPlayerNotification(context, + mediaSessionCompatToken, basePlayerImpl, sharedPreferences); + } + timesNotificationUpdated = 0; + } + + NotificationCompat.Builder createBackgroundPlayerNotification( + final Context context, final MediaSessionCompat.Token mediaSessionCompatToken, + final BackgroundPlayer.BasePlayerImpl basePlayerImpl, + final SharedPreferences sharedPreferences) { + notificationManager = ((NotificationManager) context + .getSystemService(NOTIFICATION_SERVICE)); + NotificationCompat.Builder builder = new NotificationCompat.Builder(context, + context.getString(R.string.notification_channel_id)); + + final boolean areOldNotificationsEnabled = sharedPreferences + .getBoolean(context.getString(R.string.enable_old_notifications_key), false); + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP || areOldNotificationsEnabled) { + notificationRemoteView = new RemoteViews(BuildConfig.APPLICATION_ID, + R.layout.player_background_notification); + bigNotificationRemoteView = new RemoteViews(BuildConfig.APPLICATION_ID, + R.layout.player_background_notification_expanded); + + setupOldNotification(notificationRemoteView, context, basePlayerImpl); + setupOldNotification(bigNotificationRemoteView, context, basePlayerImpl); + + builder + .setOngoing(true) + .setSmallIcon(R.drawable.ic_newpipe_triangle_white) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + .setCustomContentView(notificationRemoteView) + .setCustomBigContentView(bigNotificationRemoteView) + .setPriority(NotificationCompat.PRIORITY_MAX); + } else { + String compactView = sharedPreferences.getString(context.getString( + R.string.settings_notifications_compact_view_key), "0,1,2"); + int compactSlot0; + int compactSlot1; + int compactSlot2; + try { + String[] parts = compactView.split(","); + compactSlot0 = Integer.parseInt(parts[0]); + compactSlot1 = Integer.parseInt(parts[1]); + compactSlot2 = Integer.parseInt(parts[2]); + if (compactSlot0 > 4) { + compactSlot0 = 0; + } + if (compactSlot1 > 4) { + compactSlot1 = 1; + } + if (compactSlot2 > 4) { + compactSlot2 = 2; + } + } catch (Exception e) { + e.printStackTrace(); + compactSlot0 = 0; + compactSlot1 = 1; + compactSlot2 = 2; + } + + builder + .setStyle(new androidx.media.app.NotificationCompat.MediaStyle() + .setMediaSession(mediaSessionCompatToken) + .setShowCancelButton(false) + .setShowActionsInCompactView(compactSlot0, compactSlot1, compactSlot2)) + .setOngoing(false) + .setContentIntent(PendingIntent.getActivity(context, NOTIFICATION_ID_BACKGROUND, + new Intent(NavigationHelper.getBackgroundPlayerActivityIntent(context)), + PendingIntent.FLAG_UPDATE_CURRENT)) + .setSmallIcon(R.drawable.ic_newpipe_triangle_white) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + .setContentTitle(basePlayerImpl.getVideoTitle()) + .setContentText(basePlayerImpl.getUploaderName()) + .setDeleteIntent(PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_CLOSE), + PendingIntent.FLAG_UPDATE_CURRENT)) + .setColor(ContextCompat.getColor(context, R.color.gray)) + .setPriority(NotificationCompat.PRIORITY_HIGH); + final boolean scaleImageToSquareAspectRatio = sharedPreferences.getBoolean(context + .getString(R.string.scale_to_square_image_in_notifications_key), false); + if (scaleImageToSquareAspectRatio) { + builder.setLargeIcon(getBitmapWithSquareAspectRatio(basePlayerImpl.getThumbnail())); + } else { + builder.setLargeIcon(basePlayerImpl.getThumbnail()); + } + + notificationSlot0 = sharedPreferences.getString( + context.getString(R.string.notification_slot_0_key), notificationSlot0); + notificationSlot1 = sharedPreferences.getString( + context.getString(R.string.notification_slot_1_key), notificationSlot1); + notificationSlot2 = sharedPreferences.getString( + context.getString(R.string.notification_slot_2_key), notificationSlot2); + notificationSlot3 = sharedPreferences.getString( + context.getString(R.string.notification_slot_3_key), notificationSlot3); + notificationSlot4 = sharedPreferences.getString( + context.getString(R.string.notification_slot_4_key), notificationSlot4); + + addAction(context, builder, basePlayerImpl, notificationSlot0); + addAction(context, builder, basePlayerImpl, notificationSlot1); + addAction(context, builder, basePlayerImpl, notificationSlot2); + addAction(context, builder, basePlayerImpl, notificationSlot3); + addAction(context, builder, basePlayerImpl, notificationSlot4); + } + + return builder; + } + + private void addAction(final Context context, final NotificationCompat.Builder builder, + final BackgroundPlayer.BasePlayerImpl basePlayerImpl, + final String slot) { + switch (slot) { + case "play_pause_buffering": + if (basePlayerImpl.getCurrentState() == BasePlayer.STATE_PREFLIGHT + || basePlayerImpl.getCurrentState() == BasePlayer.STATE_BLOCKED + || basePlayerImpl.getCurrentState() == BasePlayer.STATE_BUFFERING) { + builder.addAction(R.drawable.ic_file_download_white_24dp, "Buffering", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_BUFFERING), + PendingIntent.FLAG_UPDATE_CURRENT)); + builder.setSmallIcon(android.R.drawable.stat_sys_download); + } else { + builder.setSmallIcon(R.drawable.ic_newpipe_triangle_white); + if (basePlayerImpl.isPlaying()) { + builder.addAction(R.drawable.exo_notification_pause, "Pause", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_PLAY_PAUSE), + PendingIntent.FLAG_UPDATE_CURRENT)); + } else { + builder.addAction(R.drawable.exo_notification_play, "Play", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_PLAY_PAUSE), + PendingIntent.FLAG_UPDATE_CURRENT)); + } + } + break; + case "play_pause": + if (basePlayerImpl.getCurrentState() == BasePlayer.STATE_PREFLIGHT + || basePlayerImpl.getCurrentState() == BasePlayer.STATE_BLOCKED + || basePlayerImpl.getCurrentState() == BasePlayer.STATE_BUFFERING) { + builder.addAction(R.drawable.exo_notification_pause, "Pause", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_PLAY_PAUSE), + PendingIntent.FLAG_UPDATE_CURRENT)); + } else if (basePlayerImpl.isPlaying()) { + builder.addAction(R.drawable.exo_notification_pause, "Pause", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_PLAY_PAUSE), + PendingIntent.FLAG_UPDATE_CURRENT)); + } else { + builder.addAction(R.drawable.exo_notification_play, "Play", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_PLAY_PAUSE), + PendingIntent.FLAG_UPDATE_CURRENT)); + } + break; + case "rewind": + builder.addAction(R.drawable.exo_controls_rewind, "Rewind", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_FAST_REWIND), + PendingIntent.FLAG_UPDATE_CURRENT)); + break; + case "smart_rewind_prev": + if (basePlayerImpl.playQueue != null && basePlayerImpl.playQueue.size() > 1) { + builder.addAction(R.drawable.exo_notification_previous, "Prev", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_PLAY_PREVIOUS), + PendingIntent.FLAG_UPDATE_CURRENT)); + } else { + builder.addAction(R.drawable.exo_controls_rewind, "Rewind", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_FAST_REWIND), + PendingIntent.FLAG_UPDATE_CURRENT)); + } + break; + case "forward": + builder.addAction(R.drawable.exo_controls_fastforward, "Forward", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_FAST_FORWARD), + PendingIntent.FLAG_UPDATE_CURRENT)); + break; + case "smart_forward_next": + if (basePlayerImpl.playQueue != null && basePlayerImpl.playQueue.size() > 1) { + builder.addAction(R.drawable.exo_notification_next, "Next", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_PLAY_NEXT), + PendingIntent.FLAG_UPDATE_CURRENT)); + } else { + builder.addAction(R.drawable.exo_controls_fastforward, "Forward", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_FAST_FORWARD), + PendingIntent.FLAG_UPDATE_CURRENT)); + } + break; + case "next": + builder.addAction(R.drawable.exo_notification_next, "Next", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_PLAY_NEXT), + PendingIntent.FLAG_UPDATE_CURRENT)); + break; + case "repeat": + switch (basePlayerImpl.getRepeatMode()) { + case Player.REPEAT_MODE_ONE: + builder.addAction(R.drawable.exo_controls_repeat_one, "RepeatOne", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_REPEAT), + PendingIntent.FLAG_UPDATE_CURRENT)); + break; + case Player.REPEAT_MODE_ALL: + builder.addAction(R.drawable.exo_controls_repeat_all, "RepeatAll", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_REPEAT), + PendingIntent.FLAG_UPDATE_CURRENT)); + break; + case Player.REPEAT_MODE_OFF: + default: + builder.addAction(R.drawable.exo_controls_repeat_off, "RepeatOff", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_REPEAT), + PendingIntent.FLAG_UPDATE_CURRENT)); + break; + } + break; + case "shuffle": + if (basePlayerImpl.playQueue.isShuffled()) { + builder.addAction(R.drawable.exo_controls_shuffle_on, "ShuffleOn", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_SHUFFLE), + PendingIntent.FLAG_UPDATE_CURRENT)); + } else { + builder.addAction(R.drawable.exo_controls_shuffle_off, "ShuffleOff", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_SHUFFLE), + PendingIntent.FLAG_UPDATE_CURRENT)); + } + break; + case "close": + builder.addAction(R.drawable.ic_close_white_32dp, "Close", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_CLOSE), + PendingIntent.FLAG_UPDATE_CURRENT)); + break; + case "n/a": + // do nothing + break; + case "prev": + default: + builder.addAction(R.drawable.exo_notification_previous, "Prev", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_PLAY_PREVIOUS), + PendingIntent.FLAG_UPDATE_CURRENT)); + break; + } + } + + /** + * Updates the notification, and the button icons depending on the playback state. + * On old notifications used for changes on the remoteView + * + * @param drawableId if != -1, sets the drawable with that id on the play/pause button + * @param context + * @param basePlayerImpl + * @param sharedPreferences + */ + synchronized void updateBackgroundPlayerNotification( + final int drawableId, final Context context, + final BackgroundPlayer.BasePlayerImpl basePlayerImpl, + final SharedPreferences sharedPreferences) { + if (DEBUG) { + Log.d(TAG, "N_ updateBackgroundPlayerNotification()"); + } + + if (notificationBuilder == null) { + return; + } + if (drawableId != -1) { + if (notificationRemoteView != null) { + notificationRemoteView.setImageViewResource(R.id.notificationPlayPause, drawableId); + } + if (bigNotificationRemoteView != null) { + bigNotificationRemoteView + .setImageViewResource(R.id.notificationPlayPause, drawableId); + } + } + + final boolean areOldNotificationsEnabled = sharedPreferences + .getBoolean(context.getString(R.string.enable_old_notifications_key), false); + if (!areOldNotificationsEnabled) { + notificationBuilder.setContentTitle(basePlayerImpl.getVideoTitle()); + notificationBuilder.setContentText(basePlayerImpl.getUploaderName()); + final boolean scaleImageToSquareAspectRatio = sharedPreferences.getBoolean( + context.getString(R.string.scale_to_square_image_in_notifications_key), false); + if (scaleImageToSquareAspectRatio) { + notificationBuilder.setLargeIcon(getBitmapWithSquareAspectRatio(basePlayerImpl + .getThumbnail())); + } else { + notificationBuilder.setLargeIcon(basePlayerImpl.getThumbnail()); + } + + setAction(context, basePlayerImpl, notificationSlot0, 0); + setAction(context, basePlayerImpl, notificationSlot1, 1); + setAction(context, basePlayerImpl, notificationSlot2, 2); + setAction(context, basePlayerImpl, notificationSlot3, 3); + setAction(context, basePlayerImpl, notificationSlot4, 4); + } + + notificationManager.notify(NOTIFICATION_ID_BACKGROUND, notificationBuilder.build()); + + if (areOldNotificationsEnabled) { + timesNotificationUpdated++; + } + } + + @SuppressLint("RestrictedApi") + private void setAction(final Context context, + final BackgroundPlayer.BasePlayerImpl basePlayerImpl, + final String slot, final int slotNumber) { + switch (slot) { + case "play_pause_buffering": + if (basePlayerImpl.getCurrentState() == BasePlayer.STATE_PREFLIGHT + || basePlayerImpl.getCurrentState() == BasePlayer.STATE_BLOCKED + || basePlayerImpl.getCurrentState() == BasePlayer.STATE_BUFFERING) { + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.ic_file_download_white_24dp, + "Buffering", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_BUFFERING), + PendingIntent.FLAG_UPDATE_CURRENT))); + notificationBuilder.setSmallIcon(android.R.drawable.stat_sys_download); + } else if (basePlayerImpl.getCurrentState() == BasePlayer.STATE_COMPLETED) { + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.ic_replay_white_32dp, + "Completed", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_PLAY_PAUSE), + PendingIntent.FLAG_UPDATE_CURRENT))); + } else { + notificationBuilder.setSmallIcon(R.drawable.ic_newpipe_triangle_white); + if (basePlayerImpl.isPlaying()) { + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_notification_pause, + "Pause", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_PLAY_PAUSE), + PendingIntent.FLAG_UPDATE_CURRENT))); + } else { + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_notification_play, + "Play", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_PLAY_PAUSE), + PendingIntent.FLAG_UPDATE_CURRENT))); + } + } + break; + case "play_pause": + if (basePlayerImpl.getCurrentState() == BasePlayer.STATE_PREFLIGHT + || basePlayerImpl.getCurrentState() == BasePlayer.STATE_BLOCKED + || basePlayerImpl.getCurrentState() == BasePlayer.STATE_BUFFERING) { + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_notification_pause, + "Pause", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_PLAY_PAUSE), + PendingIntent.FLAG_UPDATE_CURRENT))); + } else if (basePlayerImpl.getCurrentState() == BasePlayer.STATE_COMPLETED) { + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.ic_replay_white_32dp, + "Completed", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_PLAY_PAUSE), + PendingIntent.FLAG_UPDATE_CURRENT))); + } else { + if (basePlayerImpl.isPlaying()) { + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_notification_pause, + "Pause", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_PLAY_PAUSE), + PendingIntent.FLAG_UPDATE_CURRENT))); + } else { + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_notification_play, + "Play", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_PLAY_PAUSE), + PendingIntent.FLAG_UPDATE_CURRENT))); + } + } + break; + case "rewind": + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_controls_rewind, "Rewind", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_FAST_REWIND), + PendingIntent.FLAG_UPDATE_CURRENT))); + break; + case "smart_rewind_prev": + if (basePlayerImpl.playQueue != null && basePlayerImpl.playQueue.size() > 1) { + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_notification_previous, + "Prev", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_PLAY_PREVIOUS), + PendingIntent.FLAG_UPDATE_CURRENT))); + } else { + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_controls_rewind, "Rewind", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_FAST_REWIND), + PendingIntent.FLAG_UPDATE_CURRENT))); + } + break; + case "forward": + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_controls_fastforward, + "Forward", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_FAST_FORWARD), + PendingIntent.FLAG_UPDATE_CURRENT))); + break; + case "smart_forward_next": + if (basePlayerImpl.playQueue != null && basePlayerImpl.playQueue.size() > 1) { + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_notification_next, "Next", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_PLAY_NEXT), + PendingIntent.FLAG_UPDATE_CURRENT))); + } else { + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_controls_fastforward, + "Forward", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_FAST_FORWARD), + PendingIntent.FLAG_UPDATE_CURRENT))); + } + break; + case "next": + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_notification_next, "Next", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_PLAY_NEXT), + PendingIntent.FLAG_UPDATE_CURRENT))); + break; + case "repeat": + switch (basePlayerImpl.getRepeatMode()) { + case Player.REPEAT_MODE_ONE: + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_controls_repeat_one, + "RepeatOne", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_REPEAT), + PendingIntent.FLAG_UPDATE_CURRENT))); + break; + case Player.REPEAT_MODE_ALL: + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_controls_repeat_all, + "RepeatAll", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_REPEAT), + PendingIntent.FLAG_UPDATE_CURRENT))); + break; + case Player.REPEAT_MODE_OFF: + default: + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_controls_repeat_off, + "RepeatOff", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_REPEAT), + PendingIntent.FLAG_UPDATE_CURRENT))); + break; + } + break; + case "shuffle": + if (basePlayerImpl.playQueue.isShuffled()) { + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_controls_shuffle_on, + "ShuffleOn", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_SHUFFLE), + PendingIntent.FLAG_UPDATE_CURRENT))); + } else { + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_controls_shuffle_off, + "ShuffleOff", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_SHUFFLE), + PendingIntent.FLAG_UPDATE_CURRENT))); + } + break; + case "close": + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.ic_close_white_32dp, "Close", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_CLOSE), + PendingIntent.FLAG_UPDATE_CURRENT))); + break; + case "n/a": + // do nothing + break; + case "prev": + default: + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_notification_previous, "Prev", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_PLAY_PREVIOUS), + PendingIntent.FLAG_UPDATE_CURRENT))); + break; + } + } + + private NotificationCompat.Builder createPopupPlayerNotification( + final Context context, final MediaSessionCompat.Token mediaSessionCompatToken, + final PopupVideoPlayer.VideoPlayerImpl playerImpl, + final SharedPreferences sharedPreferences) { + notificationManager = ((NotificationManager) context + .getSystemService(NOTIFICATION_SERVICE)); + NotificationCompat.Builder builder = new NotificationCompat.Builder(context, + context.getString(R.string.notification_channel_id)); + + String compactView = sharedPreferences.getString(context + .getString(R.string.settings_notifications_compact_view_key), "0,1,2"); + int compactSlot0; + int compactSlot1; + int compactSlot2; + try { + String[] parts = compactView.split(","); + compactSlot0 = Integer.parseInt(parts[0]); + compactSlot1 = Integer.parseInt(parts[1]); + compactSlot2 = Integer.parseInt(parts[2]); + if (compactSlot0 > 4) { + compactSlot0 = 0; + } + if (compactSlot1 > 4) { + compactSlot1 = 1; + } + if (compactSlot2 > 4) { + compactSlot2 = 2; + } + } catch (Exception e) { + e.printStackTrace(); + compactSlot0 = 0; + compactSlot1 = 1; + compactSlot2 = 2; + } + + builder + .setStyle( + new androidx.media.app.NotificationCompat.MediaStyle() + .setMediaSession(mediaSessionCompatToken) + .setShowCancelButton(false) + .setShowActionsInCompactView(compactSlot0, compactSlot1, + compactSlot2)) + .setOngoing(false) + .setContentIntent(PendingIntent.getActivity(context, NOTIFICATION_ID_POPUP, + new Intent(NavigationHelper.getPopupPlayerActivityIntent(context)), + PendingIntent.FLAG_UPDATE_CURRENT)) + .setSmallIcon(R.drawable.ic_newpipe_triangle_white) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + .setContentTitle(playerImpl.getVideoTitle()) + .setContentText(playerImpl.getUploaderName()) + .setDeleteIntent(PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_CLOSE), + PendingIntent.FLAG_UPDATE_CURRENT)) + .setColor(ContextCompat.getColor(context, R.color.gray)); + boolean scaleImageToSquareAspectRatio = sharedPreferences.getBoolean(context + .getString(R.string.scale_to_square_image_in_notifications_key), false); + if (scaleImageToSquareAspectRatio) { + builder.setLargeIcon(getBitmapWithSquareAspectRatio(playerImpl.getThumbnail())); + } else { + builder.setLargeIcon(playerImpl.getThumbnail()); + } + notificationSlot0 = sharedPreferences.getString(context + .getString(R.string.notification_slot_0_key), notificationSlot0); + notificationSlot1 = sharedPreferences.getString(context + .getString(R.string.notification_slot_1_key), notificationSlot1); + notificationSlot2 = sharedPreferences.getString(context. + getString(R.string.notification_slot_2_key), notificationSlot2); + notificationSlot3 = sharedPreferences.getString(context + .getString(R.string.notification_slot_3_key), notificationSlot3); + notificationSlot4 = sharedPreferences.getString(context + .getString(R.string.notification_slot_4_key), notificationSlot4); + + addAction(context, builder, playerImpl, notificationSlot0); + addAction(context, builder, playerImpl, notificationSlot1); + addAction(context, builder, playerImpl, notificationSlot2); + addAction(context, builder, playerImpl, notificationSlot3); + addAction(context, builder, playerImpl, notificationSlot4); + + builder.setPriority(NotificationCompat.PRIORITY_HIGH); + return builder; + } + + private void addAction(final Context context, final NotificationCompat.Builder builder, + final PopupVideoPlayer.VideoPlayerImpl playerImpl, final String slot) { + switch (slot) { + case "play_pause_buffering": + if (playerImpl.getCurrentState() == BasePlayer.STATE_PREFLIGHT + || playerImpl.getCurrentState() == BasePlayer.STATE_BLOCKED + || playerImpl.getCurrentState() == BasePlayer.STATE_BUFFERING) { + builder.addAction(R.drawable.ic_file_download_white_24dp, "Buffering", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_BUFFERING), + PendingIntent.FLAG_UPDATE_CURRENT)); + builder.setSmallIcon(android.R.drawable.stat_sys_download); + } else { + builder.setSmallIcon(R.drawable.ic_newpipe_triangle_white); + if (playerImpl.isPlaying()) { + builder.addAction(R.drawable.exo_notification_pause, "Pause", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_PLAY_PAUSE), + PendingIntent.FLAG_UPDATE_CURRENT)); + } else { + builder.addAction(R.drawable.exo_notification_play, "Play", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_PLAY_PAUSE), + PendingIntent.FLAG_UPDATE_CURRENT)); + } + } + break; + case "play_pause": + if (playerImpl.getCurrentState() == BasePlayer.STATE_PREFLIGHT + || playerImpl.getCurrentState() == BasePlayer.STATE_BLOCKED + || playerImpl.getCurrentState() == BasePlayer.STATE_BUFFERING) { + builder.addAction(R.drawable.exo_notification_pause, "Pause", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_PLAY_PAUSE), + PendingIntent.FLAG_UPDATE_CURRENT)); + } else if (playerImpl.isPlaying()) { + builder.addAction(R.drawable.exo_notification_pause, "Pause", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_PLAY_PAUSE), + PendingIntent.FLAG_UPDATE_CURRENT)); + } else { + builder.addAction(R.drawable.exo_notification_play, "Play", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_PLAY_PAUSE), + PendingIntent.FLAG_UPDATE_CURRENT)); + } + break; + case "rewind": + builder.addAction(R.drawable.exo_controls_rewind, "Rewind", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_FAST_REWIND), + PendingIntent.FLAG_UPDATE_CURRENT)); + break; + case "smart_rewind_prev": + if (playerImpl.playQueue != null && playerImpl.playQueue.size() > 1) { + builder.addAction(R.drawable.exo_notification_previous, "Prev", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_PLAY_PREVIOUS), + PendingIntent.FLAG_UPDATE_CURRENT)); + } else { + builder.addAction(R.drawable.exo_controls_rewind, "Rewind", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_FAST_REWIND), + PendingIntent.FLAG_UPDATE_CURRENT)); + } + break; + case "forward": + builder.addAction(R.drawable.exo_controls_fastforward, "Forward", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_FAST_FORWARD), + PendingIntent.FLAG_UPDATE_CURRENT)); + break; + case "smart_forward_next": + if (playerImpl.playQueue != null && playerImpl.playQueue.size() > 1) { + builder.addAction(R.drawable.exo_notification_next, "Next", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_PLAY_NEXT), + PendingIntent.FLAG_UPDATE_CURRENT)); + } else { + builder.addAction(R.drawable.exo_controls_fastforward, "Forward", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_FAST_FORWARD), + PendingIntent.FLAG_UPDATE_CURRENT)); + } + break; + case "next": + builder.addAction(R.drawable.exo_notification_next, "Next", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_PLAY_NEXT), + PendingIntent.FLAG_UPDATE_CURRENT)); + break; + case "repeat": + switch (playerImpl.getRepeatMode()) { + case Player.REPEAT_MODE_ONE: + builder.addAction(R.drawable.exo_controls_repeat_one, "RepeatOne", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_REPEAT), + PendingIntent.FLAG_UPDATE_CURRENT)); + break; + case Player.REPEAT_MODE_ALL: + builder.addAction(R.drawable.exo_controls_repeat_all, "RepeatAll", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_REPEAT), + PendingIntent.FLAG_UPDATE_CURRENT)); + break; + case Player.REPEAT_MODE_OFF: + default: + builder.addAction(R.drawable.exo_controls_repeat_off, "RepeatOff", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_REPEAT), + PendingIntent.FLAG_UPDATE_CURRENT)); + break; + } + break; + case "shuffle": + if (playerImpl.playQueue.isShuffled()) { + builder.addAction(R.drawable.exo_controls_shuffle_on, "ShuffleOn", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_SHUFFLE), + PendingIntent.FLAG_UPDATE_CURRENT)); + } else { + builder.addAction(R.drawable.exo_controls_shuffle_off, "ShuffleOff", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_SHUFFLE), + PendingIntent.FLAG_UPDATE_CURRENT)); + } + break; + case "close": + builder.addAction(R.drawable.ic_close_white_32dp, "Close", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_CLOSE), + PendingIntent.FLAG_UPDATE_CURRENT)); + break; + case "n/a": + // do nothing + break; + case "prev": + default: + builder.addAction(R.drawable.exo_notification_previous, "Prev", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_PLAY_PREVIOUS), + PendingIntent.FLAG_UPDATE_CURRENT)); + break; + } + } + + /** + * Updates the notification, and the button icons depending on the playback state. + * On old notifications used for changes on the remoteView + * + * @param drawableId if != -1, sets the drawable with that id on the play/pause button + * @param context + * @param playerImpl + * @param sharedPreferences + */ + @SuppressLint("RestrictedApi") + synchronized void updatePopupPlayerNotification( + final int drawableId, final Context context, + final PopupVideoPlayer.VideoPlayerImpl playerImpl, + final SharedPreferences sharedPreferences) { + if (DEBUG) { + Log.d(TAG, "N_ updatePopupPlayerNotification()"); + } + + if (notificationBuilder == null) { + return; + } + + boolean areOldNotificationsEnabled = sharedPreferences.getBoolean(context + .getString(R.string.enable_old_notifications_key), false); + if (areOldNotificationsEnabled) { + updateOldPopupPlayerNotification(drawableId); + } else { + notificationBuilder.setContentTitle(playerImpl.getVideoTitle()); + notificationBuilder.setContentText(playerImpl.getUploaderName()); + boolean scaleImageToSquareAspectRatio = sharedPreferences.getBoolean(context. + getString(R.string.scale_to_square_image_in_notifications_key), false); + if (scaleImageToSquareAspectRatio) { + notificationBuilder + .setLargeIcon(getBitmapWithSquareAspectRatio(playerImpl.getThumbnail())); + } else { + notificationBuilder.setLargeIcon(playerImpl.getThumbnail()); + } + + setAction(context, playerImpl, notificationSlot0, 0); + setAction(context, playerImpl, notificationSlot1, 1); + setAction(context, playerImpl, notificationSlot2, 2); + setAction(context, playerImpl, notificationSlot3, 3); + setAction(context, playerImpl, notificationSlot4, 4); + } + + notificationManager.notify(NOTIFICATION_ID_POPUP, notificationBuilder.build()); + + if (areOldNotificationsEnabled) { + timesNotificationUpdated++; + } + } + + @SuppressLint("RestrictedApi") + private void setAction(final Context context, final PopupVideoPlayer.VideoPlayerImpl playerImpl, + final String slot, final int slotNumber) { + switch (slot) { + case "play_pause_buffering": + if (playerImpl.getCurrentState() == BasePlayer.STATE_PREFLIGHT + || playerImpl.getCurrentState() == BasePlayer.STATE_BLOCKED + || playerImpl.getCurrentState() == BasePlayer.STATE_BUFFERING) { + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.ic_file_download_white_24dp, + "Buffering", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_BUFFERING), + PendingIntent.FLAG_UPDATE_CURRENT))); + notificationBuilder.setSmallIcon(android.R.drawable.stat_sys_download); + } else if (playerImpl.getCurrentState() == BasePlayer.STATE_COMPLETED) { + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.ic_replay_white_32dp, + "Completed", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_PLAY_PAUSE), + PendingIntent.FLAG_UPDATE_CURRENT))); + } else { + notificationBuilder.setSmallIcon(R.drawable.ic_newpipe_triangle_white); + if (playerImpl.isPlaying()) { + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_notification_pause, + "Pause", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_PLAY_PAUSE), + PendingIntent.FLAG_UPDATE_CURRENT))); + } else { + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_notification_play, + "Play", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_PLAY_PAUSE), + PendingIntent.FLAG_UPDATE_CURRENT))); + } + } + break; + case "play_pause": + if (playerImpl.getCurrentState() == BasePlayer.STATE_PREFLIGHT + || playerImpl.getCurrentState() == BasePlayer.STATE_BLOCKED + || playerImpl.getCurrentState() == BasePlayer.STATE_BUFFERING) { + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_notification_pause, + "Pause", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_PLAY_PAUSE), + PendingIntent.FLAG_UPDATE_CURRENT))); + } else if (playerImpl.getCurrentState() == BasePlayer.STATE_COMPLETED) { + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.ic_replay_white_32dp, + "Completed", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_PLAY_PAUSE), + PendingIntent.FLAG_UPDATE_CURRENT))); + } else { + if (playerImpl.isPlaying()) { + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_notification_pause, + "Pause", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_PLAY_PAUSE), + PendingIntent.FLAG_UPDATE_CURRENT))); + } else { + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_notification_play, + "Play", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_PLAY_PAUSE), + PendingIntent.FLAG_UPDATE_CURRENT))); + } + } + break; + case "rewind": + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_controls_rewind, + "Rewind", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_FAST_REWIND), + PendingIntent.FLAG_UPDATE_CURRENT))); + break; + case "smart_rewind_prev": + if (playerImpl.playQueue != null && playerImpl.playQueue.size() > 1) { + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_notification_previous, + "Prev", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_PLAY_PREVIOUS), + PendingIntent.FLAG_UPDATE_CURRENT))); + } else { + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_controls_rewind, + "Rewind", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_FAST_REWIND), + PendingIntent.FLAG_UPDATE_CURRENT))); + } + break; + case "forward": + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_controls_fastforward, + "Forward", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_FAST_FORWARD), + PendingIntent.FLAG_UPDATE_CURRENT))); + break; + case "smart_forward_next": + if (playerImpl.playQueue != null && playerImpl.playQueue.size() > 1) { + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_notification_next, "Next", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_PLAY_NEXT), + PendingIntent.FLAG_UPDATE_CURRENT))); + } else { + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_controls_fastforward, + "Forward", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_FAST_FORWARD), + PendingIntent.FLAG_UPDATE_CURRENT))); + } + break; + case "next": + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_notification_next, "Next", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_PLAY_NEXT), + PendingIntent.FLAG_UPDATE_CURRENT))); + break; + case "repeat": + switch (playerImpl.getRepeatMode()) { + case Player.REPEAT_MODE_ONE: + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_controls_repeat_one, + "RepeatOne", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_REPEAT), + PendingIntent.FLAG_UPDATE_CURRENT))); + break; + case Player.REPEAT_MODE_ALL: + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_controls_repeat_all, + "RepeatAll", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_REPEAT), + PendingIntent.FLAG_UPDATE_CURRENT))); + break; + case Player.REPEAT_MODE_OFF: + default: + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_controls_repeat_off, + "RepeatOff", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_REPEAT), + PendingIntent.FLAG_UPDATE_CURRENT))); + break; + } + break; + case "shuffle": + if (playerImpl.playQueue.isShuffled()) { + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_controls_shuffle_on, + "ShuffleOn", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_SHUFFLE), + PendingIntent.FLAG_UPDATE_CURRENT))); + } else { + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_controls_shuffle_off, + "ShuffleOff", PendingIntent.getBroadcast(context, + NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_SHUFFLE), + PendingIntent.FLAG_UPDATE_CURRENT))); + } + break; + case "close": + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.ic_close_white_32dp, "Close", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_CLOSE), + PendingIntent.FLAG_UPDATE_CURRENT))); + break; + case "n/a": // do nothing + /*try { //FIXME maybe do nothing here ? + notificationBuilder.mActions.remove(slotNumber); + } catch (ArrayIndexOutOfBoundsException e) { + e.printStackTrace(); + }*/ + break; + case "prev": + default: + notificationBuilder.mActions.set(slotNumber, + new NotificationCompat.Action(R.drawable.exo_notification_previous, "Prev", + PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_PLAY_PREVIOUS), + PendingIntent.FLAG_UPDATE_CURRENT))); + break; + } + } + + private Bitmap getBitmapWithSquareAspectRatio(final Bitmap bitmap) { + return getResizedBitmap(bitmap, bitmap.getWidth(), bitmap.getWidth()); + } + + private Bitmap getResizedBitmap(final Bitmap bitmap, final int newWidth, final int newHeight) { + int width = bitmap.getWidth(); + int height = bitmap.getHeight(); + float scaleWidth = ((float) newWidth) / width; + float scaleHeight = ((float) newHeight) / height; + Matrix matrix = new Matrix(); + matrix.postScale(scaleWidth, scaleHeight); + return Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, false); + } + + @Deprecated // only used for old notifications + private void setupOldNotification(final RemoteViews remoteViews, final Context context, + final BackgroundPlayer.BasePlayerImpl basePlayerImpl) { + if (basePlayerImpl == null) { + return; + } + + remoteViews.setTextViewText(R.id.notificationSongName, basePlayerImpl.getVideoTitle()); + remoteViews.setTextViewText(R.id.notificationArtist, basePlayerImpl.getUploaderName()); + + remoteViews.setOnClickPendingIntent(R.id.notificationPlayPause, + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_PLAY_PAUSE), + PendingIntent.FLAG_UPDATE_CURRENT)); + remoteViews.setOnClickPendingIntent(R.id.notificationStop, + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_CLOSE), + PendingIntent.FLAG_UPDATE_CURRENT)); + remoteViews.setOnClickPendingIntent(R.id.notificationRepeat, + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_REPEAT), + PendingIntent.FLAG_UPDATE_CURRENT)); + + // Starts background player activity -- attempts to unlock lockscreen + final Intent intent = NavigationHelper.getBackgroundPlayerActivityIntent(context); + remoteViews.setOnClickPendingIntent(R.id.notificationContent, + PendingIntent.getActivity(context, NOTIFICATION_ID_BACKGROUND, intent, + PendingIntent.FLAG_UPDATE_CURRENT)); + + if (basePlayerImpl.playQueue != null && basePlayerImpl.playQueue.size() > 1) { + remoteViews.setInt(R.id.notificationFRewind, + BackgroundPlayer.SET_IMAGE_RESOURCE_METHOD, R.drawable.exo_controls_previous); + remoteViews.setInt(R.id.notificationFForward, + BackgroundPlayer.SET_IMAGE_RESOURCE_METHOD, R.drawable.exo_controls_next); + remoteViews.setOnClickPendingIntent(R.id.notificationFRewind, + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_PLAY_PREVIOUS), + PendingIntent.FLAG_UPDATE_CURRENT)); + remoteViews.setOnClickPendingIntent(R.id.notificationFForward, + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_PLAY_NEXT), + PendingIntent.FLAG_UPDATE_CURRENT)); + } else { + remoteViews.setInt(R.id.notificationFRewind, + BackgroundPlayer.SET_IMAGE_RESOURCE_METHOD, R.drawable.exo_controls_rewind); + remoteViews.setInt(R.id.notificationFForward, + BackgroundPlayer.SET_IMAGE_RESOURCE_METHOD, + R.drawable.exo_controls_fastforward); + remoteViews.setOnClickPendingIntent(R.id.notificationFRewind, + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_FAST_REWIND), + PendingIntent.FLAG_UPDATE_CURRENT)); + remoteViews.setOnClickPendingIntent(R.id.notificationFForward, + PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, + new Intent(BackgroundPlayer.ACTION_FAST_FORWARD), + PendingIntent.FLAG_UPDATE_CURRENT)); + } + + setRepeatModeIcon(remoteViews, basePlayerImpl.getRepeatMode()); + } + + @Deprecated // only used for old notifications + private void setRepeatModeIcon(final RemoteViews remoteViews, final int repeatMode) { + switch (repeatMode) { + case Player.REPEAT_MODE_OFF: + remoteViews.setInt(R.id.notificationRepeat, + BackgroundPlayer.SET_IMAGE_RESOURCE_METHOD, + R.drawable.exo_controls_repeat_off); + break; + case Player.REPEAT_MODE_ONE: + remoteViews.setInt(R.id.notificationRepeat, + BackgroundPlayer.SET_IMAGE_RESOURCE_METHOD, + R.drawable.exo_controls_repeat_one); + break; + case Player.REPEAT_MODE_ALL: + remoteViews.setInt(R.id.notificationRepeat, + BackgroundPlayer.SET_IMAGE_RESOURCE_METHOD, + R.drawable.exo_controls_repeat_all); + break; + } + } + + @Deprecated // only used for old notifications + public void updateOldNotificationsThumbnail( + final BackgroundPlayer.BasePlayerImpl basePlayerImpl) { + if (basePlayerImpl == null) { + return; + } + if (notificationRemoteView != null) { + notificationRemoteView.setImageViewBitmap(R.id.notificationCover, + basePlayerImpl.getThumbnail()); + } + if (bigNotificationRemoteView != null) { + bigNotificationRemoteView.setImageViewBitmap(R.id.notificationCover, + basePlayerImpl.getThumbnail()); + } + } + + @Deprecated // only used for old notifications + public void setProgressbarOnOldNotifications(final int max, final int progress, + final boolean indeterminate) { + if (bigNotificationRemoteView != null) { //FIXME put in Util and turn into a method + bigNotificationRemoteView.setProgressBar(R.id.notificationProgressBar, max, progress, + indeterminate); + } + if (notificationRemoteView != null) { + notificationRemoteView.setProgressBar(R.id.notificationProgressBar, max, progress, + indeterminate); + } + } + + @Deprecated // only used for old notifications + public void unsetImageInOldNotifications() { + if (notificationRemoteView != null) { + notificationRemoteView.setImageViewBitmap(R.id.notificationCover, null); + } + if (bigNotificationRemoteView != null) { + bigNotificationRemoteView.setImageViewBitmap(R.id.notificationCover, null); + } + } + + @Deprecated // only used for old notifications + public void setCachedDuration(final int currentProgress, final int duration) { + if (bigNotificationRemoteView != null) { + if (cachedDuration != duration) { + cachedDuration = duration; + cachedDurationString = getTimeString(duration); + } + bigNotificationRemoteView.setTextViewText(R.id.notificationTime, + getTimeString(currentProgress) + " / " + cachedDurationString); + } + } + + @Deprecated + private NotificationCompat.Builder createOldPopupPlayerNotification( + final Context context, final PopupVideoPlayer.VideoPlayerImpl playerImpl) { + notificationManager = ((NotificationManager) context + .getSystemService(NOTIFICATION_SERVICE)); + notificationBuilder = new NotificationCompat.Builder(context, + context.getString(R.string.notification_channel_id)); + + notificationPopupRemoteView = new RemoteViews(BuildConfig.APPLICATION_ID, + R.layout.player_popup_notification); + + notificationPopupRemoteView.setTextViewText(R.id.notificationSongName, + playerImpl.getVideoTitle()); + notificationPopupRemoteView.setTextViewText(R.id.notificationArtist, + playerImpl.getUploaderName()); + notificationPopupRemoteView.setImageViewBitmap(R.id.notificationCover, + playerImpl.getThumbnail()); + + notificationPopupRemoteView.setOnClickPendingIntent(R.id.notificationPlayPause, + PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_PLAY_PAUSE), + PendingIntent.FLAG_UPDATE_CURRENT)); + notificationPopupRemoteView.setOnClickPendingIntent(R.id.notificationStop, + PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_CLOSE), + PendingIntent.FLAG_UPDATE_CURRENT)); + notificationPopupRemoteView.setOnClickPendingIntent(R.id.notificationRepeat, + PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, + new Intent(PopupVideoPlayer.ACTION_REPEAT), + PendingIntent.FLAG_UPDATE_CURRENT)); + + // Starts popup player activity -- attempts to unlock lockscreen + final Intent intent = NavigationHelper.getPopupPlayerActivityIntent(context); + notificationPopupRemoteView.setOnClickPendingIntent(R.id.notificationContent, + PendingIntent.getActivity(context, NOTIFICATION_ID_POPUP, intent, + PendingIntent.FLAG_UPDATE_CURRENT)); + + setRepeatPopupModeRemote(notificationPopupRemoteView, playerImpl.getRepeatMode()); + + NotificationCompat.Builder builder = new NotificationCompat.Builder(context, + context.getString(R.string.notification_channel_id)) + .setOngoing(true) + .setSmallIcon(R.drawable.ic_newpipe_triangle_white) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + .setContent(notificationPopupRemoteView); + + builder.setPriority(NotificationCompat.PRIORITY_MAX); + return builder; + } + + /* + * Updates the notification, and the play/pause button in it. + * Used for changes on the remoteView + * + * @param drawableId if != -1, sets the drawable with that id on the play/pause button + */ + @Deprecated + private void updateOldPopupPlayerNotification(final int drawableId) { + if (DEBUG) { + Log.d(TAG, "updateNotification() called with: drawableId = [" + drawableId + "]"); + } + if (notificationBuilder == null || notificationPopupRemoteView == null) { + return; + } + if (drawableId != -1) { + notificationPopupRemoteView.setImageViewResource(R.id.notificationPlayPause, + drawableId); + } + notificationManager.notify(NOTIFICATION_ID_POPUP, notificationBuilder.build()); + } + + @Deprecated // only used for old notifications + protected void setRepeatPopupModeRemote(final RemoteViews remoteViews, final int repeatMode) { + final String methodName = "setImageResource"; + + if (remoteViews == null) { + return; + } + + switch (repeatMode) { + case Player.REPEAT_MODE_OFF: + remoteViews.setInt(R.id.notificationRepeat, methodName, + R.drawable.exo_controls_repeat_off); + break; + case Player.REPEAT_MODE_ONE: + remoteViews.setInt(R.id.notificationRepeat, methodName, + R.drawable.exo_controls_repeat_one); + break; + case Player.REPEAT_MODE_ALL: + remoteViews.setInt(R.id.notificationRepeat, methodName, + R.drawable.exo_controls_repeat_all); + break; + } + } + + @Deprecated // only used for old notifications + public void unsetImageInOldPopupNotifications() { + if (notificationRemoteView != null) { + notificationRemoteView.setImageViewBitmap(R.id.notificationCover, null); + } + } + + public void cancelNotification(final int id) { + try { + if (notificationManager != null) { + notificationManager.cancel(id); + } + } catch (Exception e) { + Log.e("NotificationUtil", "Exception", e); + } + } + + private static class LazyHolder { + private static final NotificationUtil INSTANCE = new NotificationUtil(); + } + +} diff --git a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java index 0ccec3067..a1ad139f6 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java @@ -22,8 +22,6 @@ package org.schabi.newpipe.player; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.annotation.SuppressLint; -import android.app.NotificationManager; -import android.app.PendingIntent; import android.app.Service; import android.content.Context; import android.content.Intent; @@ -48,23 +46,19 @@ import android.view.animation.AnticipateInterpolator; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.PopupMenu; -import android.widget.RemoteViews; import android.widget.SeekBar; import android.widget.TextView; import androidx.annotation.NonNull; -import androidx.core.app.NotificationCompat; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.PlaybackParameters; -import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.text.CaptionStyleCompat; import com.google.android.exoplayer2.ui.AspectRatioFrameLayout; import com.google.android.exoplayer2.ui.SubtitleView; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.nostra13.universalimageloader.core.assist.FailReason; -import org.schabi.newpipe.BuildConfig; import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.stream.VideoStream; import org.schabi.newpipe.player.event.PlayerEventListener; @@ -89,13 +83,28 @@ import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage; * @author mauriciocolli */ public final class PopupVideoPlayer extends Service { - public static final String ACTION_CLOSE = "org.schabi.newpipe.player.PopupVideoPlayer.CLOSE"; - public static final String ACTION_PLAY_PAUSE - = "org.schabi.newpipe.player.PopupVideoPlayer.PLAY_PAUSE"; - public static final String ACTION_REPEAT = "org.schabi.newpipe.player.PopupVideoPlayer.REPEAT"; private static final String TAG = ".PopupVideoPlayer"; private static final boolean DEBUG = BasePlayer.DEBUG; - private static final int NOTIFICATION_ID = 40028922; + + public static final String ACTION_CLOSE + = "org.schabi.newpipe.player.PopupVideoPlayer.CLOSE"; + public static final String ACTION_PLAY_PAUSE + = "org.schabi.newpipe.player.PopupVideoPlayer.PLAY_PAUSE"; + public static final String ACTION_REPEAT + = "org.schabi.newpipe.player.PopupVideoPlayer.REPEAT"; + public static final String ACTION_FAST_REWIND + = "org.schabi.newpipe.player.PopupVideoPlayer.ACTION_FAST_REWIND"; + public static final String ACTION_FAST_FORWARD + = "org.schabi.newpipe.player.PopupVideoPlayer.ACTION_FAST_FORWARD"; + public static final String ACTION_PLAY_NEXT + = "org.schabi.newpipe.player.PopupVideoPlayer.ACTION_PLAY_NEXT"; + public static final String ACTION_PLAY_PREVIOUS + = "org.schabi.newpipe.player.PopupVideoPlayer.ACTION_PLAY_PREVIOUS"; + public static final String ACTION_BUFFERING + = "org.schabi.newpipe.player.PopupVideoPlayer.ACTION_BUFFERING"; + public static final String ACTION_SHUFFLE + = "org.schabi.newpipe.player.PopupVideoPlayer.ACTION_SHUFFLE"; + private static final String POPUP_SAVED_WIDTH = "popup_saved_width"; private static final String POPUP_SAVED_X = "popup_saved_x"; private static final String POPUP_SAVED_Y = "popup_saved_y"; @@ -126,12 +135,12 @@ public final class PopupVideoPlayer extends Service { private float maximumWidth; private float maximumHeight; - private NotificationManager notificationManager; - private NotificationCompat.Builder notBuilder; - private RemoteViews notRemoteView; + private boolean isForwardPressed; + private boolean isRewindPressed; private VideoPlayerImpl playerImpl; private boolean isPopupClosing = false; + private SharedPreferences sharedPreferences; /*////////////////////////////////////////////////////////////////////////// // Service-Activity Binder @@ -148,7 +157,7 @@ public final class PopupVideoPlayer extends Service { public void onCreate() { assureCorrectAppLanguage(this); windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); - notificationManager = ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)); + sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); playerImpl = new VideoPlayerImpl(this); ThemeHelper.setTheme(this); @@ -220,9 +229,9 @@ public final class PopupVideoPlayer extends Service { final boolean popupRememberSizeAndPos = PlayerHelper.isRememberingPopupDimensions(this); final float defaultSize = getResources().getDimension(R.dimen.popup_default_width); - SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); + final SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); popupWidth = popupRememberSizeAndPos - ? sharedPreferences.getFloat(POPUP_SAVED_WIDTH, defaultSize) : defaultSize; + ? sharedPrefs.getFloat(POPUP_SAVED_WIDTH, defaultSize) : defaultSize; final int layoutParamType = Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O ? WindowManager.LayoutParams.TYPE_PHONE @@ -236,16 +245,16 @@ public final class PopupVideoPlayer extends Service { popupLayoutParams.gravity = Gravity.LEFT | Gravity.TOP; popupLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; - int centerX = (int) (screenWidth / 2f - popupWidth / 2f); - int centerY = (int) (screenHeight / 2f - popupHeight / 2f); + final int centerX = (int) (screenWidth / 2f - popupWidth / 2f); + final int centerY = (int) (screenHeight / 2f - popupHeight / 2f); popupLayoutParams.x = popupRememberSizeAndPos - ? sharedPreferences.getInt(POPUP_SAVED_X, centerX) : centerX; + ? sharedPrefs.getInt(POPUP_SAVED_X, centerX) : centerX; popupLayoutParams.y = popupRememberSizeAndPos - ? sharedPreferences.getInt(POPUP_SAVED_Y, centerY) : centerY; + ? sharedPrefs.getInt(POPUP_SAVED_Y, centerY) : centerY; checkPopupPositionBounds(); - PopupWindowGestureListener listener = new PopupWindowGestureListener(); + final PopupWindowGestureListener listener = new PopupWindowGestureListener(); popupGestureDetector = new GestureDetector(this, listener); rootView.setOnTouchListener(listener); @@ -282,71 +291,6 @@ public final class PopupVideoPlayer extends Service { windowManager.addView(closeOverlayView, closeOverlayLayoutParams); } - /*////////////////////////////////////////////////////////////////////////// - // Notification - //////////////////////////////////////////////////////////////////////////*/ - - private void resetNotification() { - notBuilder = createNotification(); - } - - private NotificationCompat.Builder createNotification() { - notRemoteView = new RemoteViews(BuildConfig.APPLICATION_ID, - R.layout.player_popup_notification); - - notRemoteView.setTextViewText(R.id.notificationSongName, playerImpl.getVideoTitle()); - notRemoteView.setTextViewText(R.id.notificationArtist, playerImpl.getUploaderName()); - notRemoteView.setImageViewBitmap(R.id.notificationCover, playerImpl.getThumbnail()); - - notRemoteView.setOnClickPendingIntent(R.id.notificationPlayPause, - PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_PLAY_PAUSE), - PendingIntent.FLAG_UPDATE_CURRENT)); - notRemoteView.setOnClickPendingIntent(R.id.notificationStop, - PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_CLOSE), - PendingIntent.FLAG_UPDATE_CURRENT)); - notRemoteView.setOnClickPendingIntent(R.id.notificationRepeat, - PendingIntent.getBroadcast(this, NOTIFICATION_ID, new Intent(ACTION_REPEAT), - PendingIntent.FLAG_UPDATE_CURRENT)); - - // Starts popup player activity -- attempts to unlock lockscreen - final Intent intent = NavigationHelper.getPopupPlayerActivityIntent(this); - notRemoteView.setOnClickPendingIntent(R.id.notificationContent, - PendingIntent.getActivity(this, NOTIFICATION_ID, intent, - PendingIntent.FLAG_UPDATE_CURRENT)); - - setRepeatModeRemote(notRemoteView, playerImpl.getRepeatMode()); - - NotificationCompat.Builder builder = new NotificationCompat - .Builder(this, getString(R.string.notification_channel_id)) - .setOngoing(true) - .setSmallIcon(R.drawable.ic_newpipe_triangle_white) - .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) - .setContent(notRemoteView); - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) { - builder.setPriority(NotificationCompat.PRIORITY_MAX); - } - return builder; - } - - /** - * Updates the notification, and the play/pause button in it. - * Used for changes on the remoteView - * - * @param drawableId if != -1, sets the drawable with that id on the play/pause button - */ - private void updateNotification(final int drawableId) { - if (DEBUG) { - Log.d(TAG, "updateNotification() called with: drawableId = [" + drawableId + "]"); - } - if (notBuilder == null || notRemoteView == null) { - return; - } - if (drawableId != -1) { - notRemoteView.setImageViewResource(R.id.notificationPlayPause, drawableId); - } - notificationManager.notify(NOTIFICATION_ID, notBuilder.build()); - } - /*////////////////////////////////////////////////////////////////////////// // Misc //////////////////////////////////////////////////////////////////////////*/ @@ -372,9 +316,8 @@ public final class PopupVideoPlayer extends Service { } mBinder = null; - if (notificationManager != null) { - notificationManager.cancel(NOTIFICATION_ID); - } + + NotificationUtil.getInstance().cancelNotification(NotificationUtil.NOTIFICATION_ID_POPUP); animateOverlayAndFinishService(); } @@ -461,11 +404,11 @@ public final class PopupVideoPlayer extends Service { } private void savePositionAndSize() { - SharedPreferences sharedPreferences = PreferenceManager + final SharedPreferences sharedPrefs = PreferenceManager .getDefaultSharedPreferences(PopupVideoPlayer.this); - sharedPreferences.edit().putInt(POPUP_SAVED_X, popupLayoutParams.x).apply(); - sharedPreferences.edit().putInt(POPUP_SAVED_Y, popupLayoutParams.y).apply(); - sharedPreferences.edit().putFloat(POPUP_SAVED_WIDTH, popupLayoutParams.width).apply(); + sharedPrefs.edit().putInt(POPUP_SAVED_X, popupLayoutParams.x).apply(); + sharedPrefs.edit().putInt(POPUP_SAVED_Y, popupLayoutParams.y).apply(); + sharedPrefs.edit().putFloat(POPUP_SAVED_WIDTH, popupLayoutParams.width).apply(); } private float getMinimumVideoHeight(final float width) { @@ -530,29 +473,6 @@ public final class PopupVideoPlayer extends Service { windowManager.updateViewLayout(playerImpl.getRootView(), popupLayoutParams); } - protected void setRepeatModeRemote(final RemoteViews remoteViews, final int repeatMode) { - final String methodName = "setImageResource"; - - if (remoteViews == null) { - return; - } - - switch (repeatMode) { - case Player.REPEAT_MODE_OFF: - remoteViews.setInt(R.id.notificationRepeat, methodName, - R.drawable.exo_controls_repeat_off); - break; - case Player.REPEAT_MODE_ONE: - remoteViews.setInt(R.id.notificationRepeat, methodName, - R.drawable.exo_controls_repeat_one); - break; - case Player.REPEAT_MODE_ALL: - remoteViews.setInt(R.id.notificationRepeat, methodName, - R.drawable.exo_controls_repeat_all); - break; - } - } - private void updateWindowFlags(final int flags) { if (popupLayoutParams == null || windowManager == null || playerImpl == null) { return; @@ -579,8 +499,11 @@ public final class PopupVideoPlayer extends Service { public void handleIntent(final Intent intent) { super.handleIntent(intent); - resetNotification(); - startForeground(NOTIFICATION_ID, notBuilder.build()); + NotificationUtil.getInstance().recreatePopupPlayerNotification(context, + playerImpl.mediaSessionManager.getSessionToken(), playerImpl, sharedPreferences, + true); + startForeground(NotificationUtil.NOTIFICATION_ID_POPUP, + NotificationUtil.getInstance().notificationBuilder.build()); } @Override @@ -622,9 +545,7 @@ public final class PopupVideoPlayer extends Service { @Override public void destroy() { - if (notRemoteView != null) { - notRemoteView.setImageViewBitmap(R.id.notificationCover, null); - } + NotificationUtil.getInstance().unsetImageInOldPopupNotifications(); super.destroy(); } @@ -683,6 +604,11 @@ public final class PopupVideoPlayer extends Service { @Override public void onShuffleClicked() { super.onShuffleClicked(); + NotificationUtil.getInstance().recreatePopupPlayerNotification(context, + playerImpl.mediaSessionManager.getSessionToken(), playerImpl, + sharedPreferences); + NotificationUtil.getInstance().updatePopupPlayerNotification(-1, + getBaseContext(), playerImpl, sharedPreferences); updatePlayback(); } @@ -697,6 +623,10 @@ public final class PopupVideoPlayer extends Service { final int bufferPercent) { updateProgress(currentProgress, duration, bufferPercent); super.onUpdateProgress(currentProgress, duration, bufferPercent); + + // setMetadata only updates the metadata when any of the metadata keys are null + playerImpl.mediaSessionManager.setMetadata(playerImpl.getVideoTitle(), + playerImpl.getUploaderName(), playerImpl.getThumbnail(), duration); } @Override @@ -724,28 +654,38 @@ public final class PopupVideoPlayer extends Service { public void onLoadingComplete(final String imageUri, final View view, final Bitmap loadedImage) { super.onLoadingComplete(imageUri, view, loadedImage); + if (playerImpl == null) { return; } - // rebuild notification here since remote view does not release bitmaps, + // rebuild (old) notification here since remote view does not release bitmaps, // causing memory leaks - resetNotification(); - updateNotification(-1); + NotificationUtil.getInstance().recreatePopupPlayerNotification(context, + playerImpl.mediaSessionManager.getSessionToken(), playerImpl, sharedPreferences, + true); + NotificationUtil.getInstance().updatePopupPlayerNotification(-1, + getBaseContext(), playerImpl, sharedPreferences); } @Override public void onLoadingFailed(final String imageUri, final View view, final FailReason failReason) { super.onLoadingFailed(imageUri, view, failReason); - resetNotification(); - updateNotification(-1); + NotificationUtil.getInstance().recreatePopupPlayerNotification(context, + playerImpl.mediaSessionManager.getSessionToken(), playerImpl, sharedPreferences, + true); + NotificationUtil.getInstance().updatePopupPlayerNotification(-1, + getBaseContext(), playerImpl, sharedPreferences); } @Override public void onLoadingCancelled(final String imageUri, final View view) { super.onLoadingCancelled(imageUri, view); - resetNotification(); - updateNotification(-1); + NotificationUtil.getInstance().recreatePopupPlayerNotification(context, + playerImpl.mediaSessionManager.getSessionToken(), playerImpl, sharedPreferences, + true); + NotificationUtil.getInstance().updatePopupPlayerNotification(-1, + getBaseContext(), playerImpl, sharedPreferences); } /*////////////////////////////////////////////////////////////////////////// @@ -799,10 +739,12 @@ public final class PopupVideoPlayer extends Service { @Override public void onRepeatModeChanged(final int i) { super.onRepeatModeChanged(i); - setRepeatModeRemote(notRemoteView, i); updatePlayback(); - resetNotification(); - updateNotification(-1); + NotificationUtil.getInstance().recreatePopupPlayerNotification(context, + playerImpl.mediaSessionManager.getSessionToken(), playerImpl, + sharedPreferences); + NotificationUtil.getInstance().updatePopupPlayerNotification(-1, + getBaseContext(), playerImpl, sharedPreferences); } @Override @@ -817,8 +759,11 @@ public final class PopupVideoPlayer extends Service { protected void onMetadataChanged(@NonNull final MediaSourceTag tag) { super.onMetadataChanged(tag); - resetNotification(); - updateNotification(-1); + NotificationUtil.getInstance().recreatePopupPlayerNotification(context, + playerImpl.mediaSessionManager.getSessionToken(), playerImpl, + sharedPreferences); + NotificationUtil.getInstance().updatePopupPlayerNotification(-1, + getBaseContext(), playerImpl, sharedPreferences); updateMetadata(); } @@ -833,18 +778,25 @@ public final class PopupVideoPlayer extends Service { //////////////////////////////////////////////////////////////////////////*/ @Override - protected void setupBroadcastReceiver(final IntentFilter intentFltr) { - super.setupBroadcastReceiver(intentFltr); + + protected void setupBroadcastReceiver(final IntentFilter intentFilter) { + super.setupBroadcastReceiver(intentFilter); if (DEBUG) { Log.d(TAG, "setupBroadcastReceiver() called with: " - + "intentFilter = [" + intentFltr + "]"); + + "intentFilter = [" + intentFilter + "]"); } - intentFltr.addAction(ACTION_CLOSE); - intentFltr.addAction(ACTION_PLAY_PAUSE); - intentFltr.addAction(ACTION_REPEAT); + intentFilter.addAction(ACTION_CLOSE); + intentFilter.addAction(ACTION_PLAY_PAUSE); + intentFilter.addAction(ACTION_REPEAT); + intentFilter.addAction(ACTION_PLAY_PREVIOUS); + intentFilter.addAction(ACTION_PLAY_NEXT); + intentFilter.addAction(ACTION_FAST_REWIND); + intentFilter.addAction(ACTION_FAST_FORWARD); + intentFilter.addAction(ACTION_BUFFERING); + intentFilter.addAction(ACTION_SHUFFLE); - intentFltr.addAction(Intent.ACTION_SCREEN_ON); - intentFltr.addAction(Intent.ACTION_SCREEN_OFF); + intentFilter.addAction(Intent.ACTION_SCREEN_ON); + intentFilter.addAction(Intent.ACTION_SCREEN_OFF); } @Override @@ -872,6 +824,26 @@ public final class PopupVideoPlayer extends Service { case Intent.ACTION_SCREEN_OFF: enableVideoRenderer(false); break; + case ACTION_PLAY_NEXT: + onPlayNext(); + break; + case ACTION_PLAY_PREVIOUS: + onPlayPrevious(); + break; + case ACTION_FAST_FORWARD: + isForwardPressed = true; + onFastForward(); + break; + case ACTION_FAST_REWIND: + isRewindPressed = true; + onFastRewind(); + break; + case ACTION_BUFFERING: + onBuffering(); + break; + case ACTION_SHUFFLE: + onShuffleClicked(); + break; } } @@ -888,8 +860,13 @@ public final class PopupVideoPlayer extends Service { @Override public void onBlocked() { super.onBlocked(); - resetNotification(); - updateNotification(R.drawable.exo_controls_play); + + NotificationUtil.getInstance().recreatePopupPlayerNotification(context, + playerImpl.mediaSessionManager.getSessionToken(), playerImpl, + sharedPreferences); + NotificationUtil.getInstance() + .updatePopupPlayerNotification(R.drawable.ic_play_arrow_white_24dp, + getBaseContext(), playerImpl, sharedPreferences); } @Override @@ -898,20 +875,48 @@ public final class PopupVideoPlayer extends Service { updateWindowFlags(ONGOING_PLAYBACK_WINDOW_FLAGS); - resetNotification(); - updateNotification(R.drawable.exo_controls_pause); + NotificationUtil.getInstance().recreatePopupPlayerNotification(context, + playerImpl.mediaSessionManager.getSessionToken(), playerImpl, + sharedPreferences); + NotificationUtil.getInstance() + .updatePopupPlayerNotification(R.drawable.ic_pause_white_24dp, getBaseContext(), + playerImpl, sharedPreferences); videoPlayPause.setBackgroundResource(R.drawable.exo_controls_pause); hideControls(DEFAULT_CONTROLS_DURATION, DEFAULT_CONTROLS_HIDE_TIME); - startForeground(NOTIFICATION_ID, notBuilder.build()); + startForeground(NotificationUtil.NOTIFICATION_ID_POPUP, + NotificationUtil.getInstance().notificationBuilder.build()); } @Override public void onBuffering() { super.onBuffering(); - resetNotification(); - updateNotification(R.drawable.exo_controls_play); + + NotificationUtil.getInstance().recreatePopupPlayerNotification(context, + playerImpl.mediaSessionManager.getSessionToken(), playerImpl, + sharedPreferences); + if (NotificationUtil.getInstance().notificationSlot0.contains("buffering") + || NotificationUtil.getInstance().notificationSlot1.contains("buffering") + || NotificationUtil.getInstance().notificationSlot2.contains("buffering") + || NotificationUtil.getInstance().notificationSlot3.contains("buffering") + || NotificationUtil.getInstance().notificationSlot4.contains("buffering")) { + if (playerImpl.getCurrentState() == BasePlayer.STATE_PREFLIGHT + || playerImpl.getCurrentState() == BasePlayer.STATE_BLOCKED + || playerImpl.getCurrentState() == BasePlayer.STATE_BUFFERING) { + if (!(isForwardPressed || isRewindPressed)) { + if (DEBUG) { + Log.d(TAG, "N_ onBuffering()"); + } + NotificationUtil.getInstance() + .updatePopupPlayerNotification(R.drawable.ic_play_arrow_white_24dp, + getBaseContext(), playerImpl, sharedPreferences); + } else { + isForwardPressed = false; + isRewindPressed = false; + } + } + } } @Override @@ -920,9 +925,14 @@ public final class PopupVideoPlayer extends Service { updateWindowFlags(IDLE_WINDOW_FLAGS); - resetNotification(); - updateNotification(R.drawable.exo_controls_play); - videoPlayPause.setBackgroundResource(R.drawable.exo_controls_play); + NotificationUtil.getInstance().recreatePopupPlayerNotification(context, + playerImpl.mediaSessionManager.getSessionToken(), playerImpl, + sharedPreferences); + NotificationUtil.getInstance() + .updatePopupPlayerNotification(R.drawable.ic_play_arrow_white_24dp, + getBaseContext(), playerImpl, sharedPreferences); + + videoPlayPause.setBackgroundResource(R.drawable.ic_play_arrow_white_24dp); stopForeground(false); } @@ -930,8 +940,13 @@ public final class PopupVideoPlayer extends Service { @Override public void onPausedSeek() { super.onPausedSeek(); - resetNotification(); - updateNotification(R.drawable.exo_controls_play); + + NotificationUtil.getInstance().recreatePopupPlayerNotification(context, + playerImpl.mediaSessionManager.getSessionToken(), playerImpl, + sharedPreferences); + NotificationUtil.getInstance() + .updatePopupPlayerNotification(R.drawable.ic_play_arrow_white_24dp, + getBaseContext(), playerImpl, sharedPreferences); videoPlayPause.setBackgroundResource(R.drawable.exo_controls_play); } @@ -942,8 +957,13 @@ public final class PopupVideoPlayer extends Service { updateWindowFlags(IDLE_WINDOW_FLAGS); - resetNotification(); - updateNotification(R.drawable.ic_replay_white_24dp); + NotificationUtil.getInstance().recreatePopupPlayerNotification(context, + playerImpl.mediaSessionManager.getSessionToken(), playerImpl, + sharedPreferences); + NotificationUtil.getInstance() + .updatePopupPlayerNotification(R.drawable.ic_replay_white_24dp, + getBaseContext(), playerImpl, sharedPreferences); + videoPlayPause.setBackgroundResource(R.drawable.ic_replay_white_24dp); stopForeground(false); @@ -1004,7 +1024,6 @@ public final class PopupVideoPlayer extends Service { private float initSecPointerX = -1; private float initSecPointerY = -1; - @Override public boolean onDoubleTap(final MotionEvent e) { if (DEBUG) { diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/MediaSessionManager.java b/app/src/main/java/org/schabi/newpipe/player/helper/MediaSessionManager.java index e101e2185..d0939a914 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/MediaSessionManager.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/MediaSessionManager.java @@ -3,17 +3,14 @@ package org.schabi.newpipe.player.helper; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; -import android.media.MediaMetadata; -import android.os.Build; import android.support.v4.media.MediaMetadataCompat; import android.support.v4.media.session.MediaSessionCompat; +import android.support.v4.media.session.PlaybackStateCompat; +import android.util.Log; import android.view.KeyEvent; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; -import androidx.core.app.NotificationCompat; -import androidx.media.app.NotificationCompat.MediaStyle; import androidx.media.session.MediaButtonReceiver; import com.google.android.exoplayer2.Player; @@ -30,13 +27,29 @@ public class MediaSessionManager { private final MediaSessionCompat mediaSession; @NonNull private final MediaSessionConnector sessionConnector; + @NonNull + private final PlaybackStateCompat.Builder playbackStateCompatBuilder; + + private int tmpThumbHash; public MediaSessionManager(@NonNull final Context context, @NonNull final Player player, @NonNull final MediaSessionCallback callback) { this.mediaSession = new MediaSessionCompat(context, TAG); + this.mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS + | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); this.mediaSession.setActive(true); + this.playbackStateCompatBuilder = new PlaybackStateCompat.Builder(); + this.playbackStateCompatBuilder.setState(PlaybackStateCompat.STATE_NONE, -1, 1); + this.playbackStateCompatBuilder.setActions(PlaybackStateCompat.ACTION_SEEK_TO + | PlaybackStateCompat.ACTION_PLAY + | PlaybackStateCompat.ACTION_PAUSE // was play and pause now play/pause + | PlaybackStateCompat.ACTION_SKIP_TO_NEXT + | PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS + | PlaybackStateCompat.ACTION_SET_REPEAT_MODE | PlaybackStateCompat.ACTION_STOP); + this.mediaSession.setPlaybackState(playbackStateCompatBuilder.build()); + this.sessionConnector = new MediaSessionConnector(mediaSession); this.sessionConnector.setControlDispatcher(new PlayQueuePlaybackController(callback)); this.sessionConnector.setQueueNavigator(new PlayQueueNavigator(mediaSession, callback)); @@ -49,37 +62,65 @@ public class MediaSessionManager { return MediaButtonReceiver.handleIntent(mediaSession, intent); } - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) - public void setLockScreenArt(final NotificationCompat.Builder builder, - @Nullable final Bitmap thumbnailBitmap) { - if (thumbnailBitmap == null || !mediaSession.isActive()) { + public MediaSessionCompat.Token getSessionToken() { + return this.mediaSession.getSessionToken(); + } + + public void setMetadata(final String title, final String artist, final Bitmap albumArt, + final long duration) { + if (albumArt == null || !mediaSession.isActive()) { return; } - mediaSession.setMetadata( - new MediaMetadataCompat.Builder() - .putBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, thumbnailBitmap) - .build() - ); + if (getMetadataAlbumArt() == null) { + Log.d(TAG, "N_getMetadataAlbumArt: thumb == null"); + } + if (getMetadataTitle() == null) { + Log.d(TAG, "N_getMetadataTitle: title == null"); + } + if (getMetadataArtist() == null) { + Log.d(TAG, "N_getMetadataArtist: artist == null"); + } + if (getMetadataDuration() <= 1) { + Log.d(TAG, "N_getMetadataDuration: duration <= 1; " + getMetadataDuration()); + } - MediaStyle mediaStyle = new MediaStyle() - .setMediaSession(mediaSession.getSessionToken()); - - builder.setStyle(mediaStyle); + if (getMetadataAlbumArt() == null || getMetadataTitle() == null + || getMetadataArtist() == null || getMetadataDuration() <= 1 + || albumArt.hashCode() != tmpThumbHash) { + Log.d(TAG, "setMetadata: N_Metadata update: t: " + title + " a: " + artist + + " thumb: " + albumArt.hashCode() + " d: " + duration); + mediaSession.setMetadata( + new MediaMetadataCompat.Builder() + .putString(MediaMetadataCompat.METADATA_KEY_TITLE, title) + .putString(MediaMetadataCompat.METADATA_KEY_ARTIST, artist) + .putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, albumArt) + .putBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON, albumArt) + .putLong(MediaMetadataCompat.METADATA_KEY_DURATION, duration) + .build() + ); + tmpThumbHash = albumArt.hashCode(); + } } - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) - public void clearLockScreenArt(final NotificationCompat.Builder builder) { - mediaSession.setMetadata( - new MediaMetadataCompat.Builder() - .putBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, null) - .build() - ); + private Bitmap getMetadataAlbumArt() { + return mediaSession.getController().getMetadata() + .getBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART); + } - MediaStyle mediaStyle = new MediaStyle() - .setMediaSession(mediaSession.getSessionToken()); + private String getMetadataTitle() { + return mediaSession.getController().getMetadata() + .getString(MediaMetadataCompat.METADATA_KEY_TITLE); + } - builder.setStyle(mediaStyle); + private String getMetadataArtist() { + return mediaSession.getController().getMetadata() + .getString(MediaMetadataCompat.METADATA_KEY_ARTIST); + } + + private long getMetadataDuration() { + return mediaSession.getController().getMetadata() + .getLong(MediaMetadataCompat.METADATA_KEY_DURATION); } /** diff --git a/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java index a9531693c..c9367c4c9 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java @@ -11,6 +11,7 @@ import androidx.annotation.Nullable; import androidx.preference.Preference; import org.schabi.newpipe.R; +import org.schabi.newpipe.player.NotificationUtil; import org.schabi.newpipe.util.Constants; public class AppearanceSettingsFragment extends BasePreferenceFragment { @@ -52,8 +53,22 @@ public class AppearanceSettingsFragment extends BasePreferenceFragment { final Preference captionSettings = findPreference(captionSettingsKey); getPreferenceScreen().removePreference(captionSettings); } + + findPreference(getString(R.string.enable_old_notifications_key)) + .setOnPreferenceChangeListener(oldNotificationsOnPreferenceChangeListener); } + private Preference.OnPreferenceChangeListener oldNotificationsOnPreferenceChangeListener + = (preference, newValue) -> { +// NotificationUtil.getInstance().toast(getContext(), +// "Killed background / popup player notification(s) !"); + NotificationUtil.getInstance() + .cancelNotification(NotificationUtil.NOTIFICATION_ID_BACKGROUND); + NotificationUtil.getInstance().cancelNotification(NotificationUtil.NOTIFICATION_ID_POPUP); + + return true; + }; + @Override public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) { addPreferencesFromResource(R.xml.appearance_settings); diff --git a/app/src/main/res/drawable-hdpi/ic_close_white_32dp.png b/app/src/main/res/drawable-hdpi/ic_close_white_32dp.png new file mode 100644 index 0000000000000000000000000000000000000000..b7c7ffd0e795ba76ed3a062566c9016448795f7a GIT binary patch literal 257 zcmV+c0sj7pP) zOA5m<3jYBNi%A&<@ZO?$P9};P4Y5CjG5$M&YXI45J{s}~# zf|&?x1_gn4B7+hS@X!l}&!voFhmZP^sujifL@~PKMMM~{6xH}^g$q7WOzwCQ5vHTU z6`v~H@rlA8e;CUh_(b84zg=+ih`wG<)HiJjzSlQx5#CnjMR;A)R^jtaTa9;7rSy)7O%~`cm?ZjXImW?6TYRT<;U^@VKiSj`soFk00000NkvXX Hu0mjfhD&W| literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/ic_replay_white_32dp.png b/app/src/main/res/drawable-hdpi/ic_replay_white_32dp.png new file mode 100644 index 0000000000000000000000000000000000000000..ac1dd1a6659904ba44561dbfe1b3b3caed950058 GIT binary patch literal 804 zcmV+<1Ka$GP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0=Y>Ua!!*MzB~-b zcPe>dSN|c`ndF7t{f0bqlNT=1U&ygAdEsLHg#6|vZ+@fC=nZ;~4$-zlEDw?>lY9~1 z(FxjhxXN6x?V3yIA$m_Ej?iX&wQH!j&RfW$hU_?Ow@~q-My#W2=pK5EKA=3#(4NC~ z3l$eO!bMWJw1)Q4sr&(IM8DpI-810YLNDS%)2KW3XH3|Y3+@O#jSEh5D)|Lordfoj9<&It1B9TGq4d+uaz%JeY(|X>Kb)ARWN7 z=t*taT^q$h9~C&mvEB6{*e?1Nhy91Pz_r&A#Xv6=FoU+!&7RB%sILbhI*e3qgziPT zab2W22)c=M+zZj0ICpo_Jt%zg;vLdwm*yex4${FpL}Nnx`GvES${-Ecu+NK6=!T27 z0~PF{yhaF3vDy;fN7|TeSo*DN^5uPv5Z!%Np(4GByzW#Lb(?mdd(AdV#S~tjs60{lf39H8_eGT0000& literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_close_white_32dp.png b/app/src/main/res/drawable-mdpi/ic_close_white_32dp.png new file mode 100644 index 0000000000000000000000000000000000000000..20b61eaeec893baf305a701f78fc9c18eee0217d GIT binary patch literal 542 zcmV+(0^$9MP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0kcU&K~z{r?UqYU z0zni-(V?J2*o-c~&pJf+060|H7;Zoqh$HzVO3FzR68}UcLM3 z)Ag!L1qu{M!fZA>fJd4-emjh9!LfZi(y}={aMTvo;Shm{vJab7_dH|;*vs$=KH5hUmqyJ)vH?d4 zHeug_11Q0jZ-PEe_yUeR_5o_bsgEue5`tkTCQy?o+Z-mU;1iE|f(@JV!vPdD1kl#D zY?fVT9#;NLaZWj(;8uWO6>61XC%W(!wqehG0|(E1ZBqeZ?SxjV;2-dnfNzxV@E$g3 z$9|++1A*EK48K8pN^xUzChWTW8(^j3p7)@RU}~zaBS_2>xq$fcJy*bMZ9QezeX)5W z7Z6Om=hPST#0&h9CvpMJklSPLx$1B^Po#P~5`k6)p~c)Dd(YJeHHpQyqeXSIRE%>t z^RWe$+Y|4(Y>d%vg|}k_rIGzH!hiWWPLPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0o+MMK~z{r?Up@D z!%!548!hOdv<0i9j_RP`p!f%L7VYNl>gJ$>n}a{YNjEzRx;O|fej#-eoI6y74t@~d z_vTGWNMq9W8W8%x!%fb)=bUS;iMfA`>$=Oj%pMMhue!|^e>ij%%8uZ0qHs1~UT8Q` z>hHm<$Z)X+nH$ws`)EMB;Xyv(Ijq0|mD&Lf(;OhkHJnws9ndiD5SwrhUche##5-J3 zxgF3jatNgixSfV)CgIV9OG?`T4MT@exCKHEJTyss?9ni3K2!%p043C%>`%2jZ zP0b;68v(fztV68~#%@@`7899Q#cuHrnjcdb-&<(QmJ8$Y6*KOlM)ncm{N}#EGd-;_o~KcU8(e-h*nLx z#|@lRIu`EHUY}E_Y=@w*2p`x*@cF+B$F-#eViSTtVCW^hrT3_XEl~ V_uUT1{e}Pl002ovPDHLkV1lm9{aOG3 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_close_white_32dp.png b/app/src/main/res/drawable-xhdpi/ic_close_white_32dp.png new file mode 100644 index 0000000000000000000000000000000000000000..cc13347341479e29fc567f6af466875e91e4048c GIT binary patch literal 666 zcmV;L0%iS)P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0xwBKK~#8N?V4du z0x=MU(H~w16Yv6_0Zy%_&_u7GzwmozAY|O_E^D{6?0m^fgmydAz6TQ6RS*P05ClOG z1VJ!?!{P9Vp6y{VR1>Z3VRpSaWP{-OhVxDoYYH$L4lXpYtA?o0J4SXJc(S@1e;_ zNzijP)`c=ejLr> zyoWW1l2Go)QHrgRev)sbHb5XocB<}CqX@IY`7d0)h#kQ zglpd-vq5(@Tpo%q^Cqbv2!bF8f*=Tjc3G`{0C;dH`T`V^N&o-=07*qoM6N<$f@YH? A5dZ)H literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_replay_white_32dp.png b/app/src/main/res/drawable-xhdpi/ic_replay_white_32dp.png new file mode 100644 index 0000000000000000000000000000000000000000..dfa4344735f31f4726c06f74a8282554c0eec7a2 GIT binary patch literal 1168 zcmV;B1aJF^P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1SLsCK~#8N?V8_< z6=fL5_efgpvvr?4ngx z5WHCxL7{9>Q7{wwwK@B+;?YU%&MqDmkEV2J_AtG8Lx*Pv)Z13Pp_lp}YITY?^m2bgo!;UNx%4m8 zm|DCcxBi6sIu>upwf~^D%;F8X_ZQTat9V00YNI7v8q{PzZ;zri(Sd9ZqC4nMbP=6F z=UT1SB(}G(;!&=5K7(86JG2o!q3OehM9V5Z$rZE*J*`lsGDkLKmZC4w1)8uSIua@* zSkw~pZU6#6O} z;O8^Bh6xF#HbE|#;Mzi8M1x!&pcQfr6B6_`K`-Y5cWc7IXrRk+xrGZ!I!(|^xnamW z^jkF8W|DhRl#kUQ#&>@Gp!2cokdv(!K8W|)*g{T+ zv|SDa`vCc^owhnx;El0~W7r7h2MdcyJp4ucCmaPL{>~V6<{Zy&w*Wjq^bk=dv8Payw zAm+=MweemX$7FL+v;n@~**3=~@n%=qjePkRx)&$}UAG$$dqR`sZ`8GQdSVTtI~F*> zc_gojAi%CDl*{*WsT^V*ibFc=luLCGty(ibwV9xh7w~t>@>3{a<2my!CO^fcq*6H`6 zqTezOHV66?*?OOk8^~_dx(|VEbvErIY1kvJRdO#3V^?dAG%WU8a<2yx*oN#K@5C=? zGn%VmshE#^ZA>RD=2i`xF{PY0Br<~e7G+(9?;=|XK8q&MqcuTW99@Q9M{l64TkLyi zJ3o1UjCTWoCagmCf1awjj8-aaSdiF!v>*M4%EspW8qHU@a3RUH=maVYo9j(Y-#d`B zHR2m&_Xn6?(TivvGVGtC*OC2G^fWqw#<32ETvhYyB39D^lU%DgQgv&#U%8l^-CA%qY@2qA=!B5=cm zUgehujQG*l{{`@rPr!f|fEk^>KI9WteE@ilV6HEl&_rJ@p_zU*;T}RirIc{5NocNLm*7JGdV(AM zYYDFOvk5~8{Z*t_>U=!XvoehUSEh=adIga45oe)B9kGgT}7UT3Cirmr(oHPv^YQ1-p=Hlh5u;xggf zX{&yw+El-OrrKQJRl@b7x{HLmNkj95`a#LLnW{Veb2C+!`ppt#r)=g4@?c8RY{yJj~W@W|h^mU4q`i)2y~Rw@J`jIh$1%|In!~{Tb{nMqaxlgb+dq eA%qY@zJ@mriVM?qfwL0;00007!(!0)U7tJ0c*i|=W=`GD{Rhrh*S+VSbLJ}_yb|Y} z2=nyPP+9@g9^_WikSR{kYsy-hy zEku#&*XNV6oCC6@Y0~GT-ej9>Czv`dtH=_DbXwRliC~qaN~fj83SwBz>9x4qN(Rvr ze!Z60m#~`DYlFi_98nBIuPvr=tUC1CrC;Y$3W(^FgzQC`p+k!}pOw6jBq=iPfkh0TWmS)dUz^Bf7(L-mV&-4}J$XOF7sBlc6Scm>hhDc(^Uj{LXd-%JWIiC2AM`rMs#_tFGOcEm> zQ6{J?t)HM6bg;rDU%4Peu#|sCR!~qE~FTC?knj22pV}>5;)E~ds^l}5-05`x5 ia0A=`H^2>0aQz3T@7w=K#~w`p0000Rol24V(Ul{cf{Ft-O^TClm@M})Kx4+>gFppf_Al9 z#ZupGE6zrcR@~QaqeT$ZRuoaI`|%I#4>R+;&olGR%=^sqOcse~F9%hJfcj#!iW);ZTYO z>T=`0X?%9WrcrsC_4A<7*sb<(ZqAXCz$&?zvtCH)DOTz*!{g)CUw2Q0|C}824PDMP z{$6;es_Q`y_y6;2&Fj*OPLzVPYLCjEjk4Z}J3<9+DeG=LyRliiHMy^7kYa3n-Q4^r z=Je=Wh=B)$5psZ;8FFDrR_u@>qb1o1CW4Lrhu0eYPa_i2OYrb(DZ%v))2sppo^;_8 zwb0{z5aLC)COh6l@b#o`w)J1gE$qmZkTWeSW5#}~Xiul~Dxm4=GI?L5oo$KYsh#st zwF=q4KstT`?fKPzz&H~P!{@!{OvE10md89lIPwS=WZaj)>KZoRD~V{@46XE6=K{7Z z#TJUPzMa;tA4a)CC9urOT$T|k$R(Y8;K}A59pxC00f8W^h%BO>TYr4?7hHASPMEOW+xq zFH~-%I>LxXKFc)6rpyej6+LE67n2X3+)vBbZ6Xq*vPwnFK{koOF-)46tJkHbt`_CC z4~~`Y+2)BOl531IJ#YOAt5e85f)%tuz@ip4c$?e*j<+^{78Qn(p*6SlH~cb_wYzPx5QLsf0a_{(8oi)_v$2D9_qHUS znS#W~8YucFs*MdqD!%#701|5{e;~DD{uS=EI3H9Ap~GU1M3Z)YNZ>Qi;Aq{#ZVJO8 zkZ_a8!%)rgo*_inYCPk%r?6Rz^*@$I=u1TC@(p8%JXJG5{>i&cGGi$W`=ovkX|n{5 zNG@FM-Se{a0r>_AZlQ{kc z;$*=H;?31f0JTDAa&-*Rz&Xkz)X+*{FX!Np=|rriNJQduu(;8=`;?G7n!pV{ro*%j z_jT!190rJ5o*7(4HhNQ2yAMaBe-ptSN=qc-eHQ7-`1QRE+kgk0Q#7_{655_0V@?mq2q203()6r6+x2FiJqPX|2^x7}2$3tNsI zn?0;zlfo9k4wg=6!``}M%V9A>27v)~tEs` zOZ=Us)a$C+p_WVFS6eBx_1}#`02qtJ`c5=Krxav*hS1(&vwD7grZ4tZ2tFCF>Aj|m8d`?t9S6@!6^#L z@*k^9m(K|S&7>;w1mNb_%*kx=#$CN0sd;;|kmG+5c6jPe+dYcY8C$$ZUy9mJ|3DMF z>mba?#m=aIh>>CEH8;}79hKz&_TG~AZEG(6?{C6Z^GyBYk0go2y13oxb;^&x#{)Uq L5p5grL8<=&`?GV8 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_replay_white_32dp.png b/app/src/main/res/drawable-xxxhdpi/ic_replay_white_32dp.png new file mode 100644 index 0000000000000000000000000000000000000000..b51ecf755901c5f87d42a5ac6383f09cf93849e0 GIT binary patch literal 2580 zcmZvec{mhm8^*`J?;1koxN0f2g<2pi4E*@Z&v+`|9>@$O&EMG3C_lfzzJ zvxd4v-P$O^^eNjYC&n~aVoTJx94#c5%dl8gZ9+k=B<`k-+NqReUI(_tGS5SXv}G6l zW0ZZ`Rm(wwVtR?Ru{@$o|0=;GRN&cdVVs4CEJ_>kVs7$h7WdY)(Ods->$J_E*NWGR zskGwv>xHwElX-kkmM;7%BW;u5FKjd_;xT_-9Pr2VEmJE?+qUy6zfYrR2-SWHM|)39 z(7(F|Z?5DRHoG`xc*?_}m>m0L0fchz? zD6!QvwO4uu!@g=NyJ^qjzSptG5;c$iezklsRWHU~iVxf8x;6U(z1AmJ#rI7YKwP@s zs+{XAzw1t3dC2uCYMJsz3MpCJ+rD_tMa*$`&WTH6Kvc1+> z({1pokhkX8q6E`zrt{GwaQGX3RnUj17zCtJ^lNO{{&>3Zt8E&+U<;B+gFxDc259D^(kM!xJrMBTd%qO!TYymj+YOB2S zxM4SzfT^((ELg|Bu<`n4mI|B1x|THc8pjjton+iX2J2Rfo8`x~3m?Cx7!96I%eUx) zdC9mT(m_eH%+QBU3lIxe0TKNRT0rUGs{9UIo-l4wyuVZ6lpoJ#*R0+zPQDNGfojCh z?{|D>MkgqLhE!4!Bq5Dk<@p^ZH~68O>8?Z`qLo&*oQEM?#;#+9gJHs*_waMw^mjzT zktU0D1l-xKqmskz#i3h|ubkP^c(S!rpeN5s@d<(X6#N-K-$e0V)ZEa`ATh##gkf1} zaHVD)*&pwvglkHV1kzxQ?~TMXmV5F$+VW352$TKTC==zMC7Y3fsu5bpOrl+L(S6>X z28c-Qq5u$x&Vjld7zk$XMUl`ep7Wy9GkHMiFj{_xIqk`V1g-KTk;mIS(=*q&gpOJ` zFkfMPyDG3By5g7FBwj(_jYYzIg8M}uL@WM?Y~3-WHNuKqGAhXzlQnm`Ws@)(WkEbwIbj=tA5qJ<>9L1wy0pj8jh5_L<%CT|XH{jRB$jv&sR+iZykk zd0menD?JgT)yb7dS6V$_!~Wik zSI}ycDJ^sG+*nN0l`HDs9MJk*Du@Hhgf03IuM($1lX`m0sEoJog)JOz6r5b_tRG$Q zx&I_u(j`*j>Cv-DLa{s$#I_|>Q*;NnoM_`3n`kBS(4z#=n;71U3dAW*QSDA_m~qNVwI~DwVjax~v5b&mMRl zo~G%~HQ;OS(DZ#rXLak%-WN+H2#uLrm$G9sQ#{v|))$A)G z=_wfPc91?bNW1hM=G|)nLs>KahVr{#E+tLFS&=rz8OMhH`bB#NCAEAxNHT8V??HNU z_+FK*TOknbpc1#og;2~9k-EaYMM1c%K}_Pvs&I-=kZBJaX{?43^O?anxl}_dk9T@U z1IdWO+nU59o-e2xp!nHCz{njruqUDSMrFx`63xUUX!l3IXvvq5q=BLPBVEygZz0$| z;l&W)+M5Km<{^_U3F|e())=LKLeBJd*Eb8D+AVOTU-{W7zu6Ncfp6r`94Zma57Wvi zVEzMi05b|Cdaj(~&h$)~b~ik+l68WUUA+3>2$+O2JV~&tieTunq(8n9hd}HdBG>Xdf~OQ9$s@z^)Kr#l zVXtrWv81EeGoVq>TFxCoB<#~n9(ZpLg^;mcX@V?xD2*XPtlf6L|Af~ECryp?caLo< z*9A9h#7RYb`;vW{F$-J{Q5|y9vR`8iWcxF0qq6xf8BNd!D;1y>d6%8&mZt9;5CVdk ze%fu7;oO6P?2(}6Q}Z#?iy zQ2mkeLDwr0T$javy!&D<6ZsPX9^vPY9Yr@}o~P41U7yMa?w^=cD9Sp15z}=50AgrICBg2dTv}+(H$=ZfD06-aj-^Yr;qW={h#y69>C;d8BXbY{rV%AK4?G zwew0e-nlSrc{?yi!Yl5^FeB^qiAjTP_>T%?W=5T&%c{u4vU$wCkzlkG5VC@#Z;|^2 zgih`Q>17{>;gyx?!gATCK+?pdkJ(nLxx%e-&4)befY9Y9*O zBk?X-W9RobdRb*69XSYjS-DvxDv46slDUzr82d6{qokY-9`TVoSgK*^dcrCW7RBMg z!oO~gydfnTA_2yLgrg;uq`)tuF~L^p|5Rt1CV23UFL}85RZqGp)aG2OA144p + enable_old_notifications + notifications_compact_view + 0,1,2 + scale_to_square_image_in_notifications + + prev + next + rewind + forward + smart_rewind_prev + smart_forward_next + play_pause_buffering + play_pause + repeat + shuffle + close + n/a + + notification_slot_0_key + @string/notification_slot_smart_rewind_prev_key + + Rewind / Previous + Previous + Rewind + + + @string/notification_slot_smart_rewind_prev_key + @string/notification_slot_prev_key + @string/notification_slot_rewind_key + + + notification_slot_1_key + @string/notification_slot_play_pause_buffering_key + + Play / Pause / Buffering + Play / Pause + Rewind + + + @string/notification_slot_play_pause_buffering_key + @string/notification_slot_play_pause_key + @string/notification_slot_rewind_key + + + + notification_slot_2_key + @string/notification_slot_smart_forward_next_key + + Forward / Next + Forward + Next + Play / Pause / Buffering + Play / Pause + + + @string/notification_slot_smart_forward_next_key + @string/notification_slot_forward_key + @string/notification_slot_next_key + @string/notification_slot_play_pause_buffering_key + @string/notification_slot_play_pause_key + + + notification_slot_3_key + @string/notification_slot_repeat_key + + Repeat + Shuffle + Previous + Forward + Forward / Next + Rewind + Rewind / Previous + Close + N/A + + + @string/notification_slot_repeat_key + @string/notification_slot_shuffle_key + @string/notification_slot_prev_key + @string/notification_slot_forward_key + @string/notification_slot_smart_forward_next_key + @string/notification_slot_rewind_key + @string/notification_slot_smart_rewind_prev_key + @string/notification_slot_close_key + @string/notification_slot_n_a_key + + + notification_slot_4_key + @string/notification_slot_close_key + + Close + Repeat + Shuffle + Next + Forward + Forward / Next + N/A + + + @string/notification_slot_close_key + @string/notification_slot_repeat_key + @string/notification_slot_shuffle_key + @string/notification_slot_next_key + @string/notification_slot_forward_key + @string/notification_slot_smart_forward_next_key + @string/notification_slot_n_a_key + video_mp4 video_webm diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3625e67f4..1d1c67364 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -57,9 +57,18 @@ Install missing Kore app? org.xbmc.kore Show \"Play with Kodi\" option - Lock screen video thumbnail Display an option to play a video via Kodi media center - A video thumbnail is shown on the lock screen when using the background player + Enable old notifications + This enables the old \"Custom RemoteViews\" notifications. If disabled modern MediaStyle notifications will be used. + Scale image to 1:1 aspect ratio + This will scale the notification image from 16:9 to 1:1 aspect ratio + Notification slot 0 + Notification slot 1 + Notification slot 2 + Notification slot 3 + Notification slot 4 + Notification compact view + Notification slots to show in compact view Audio Default audio format Default video format @@ -129,6 +138,7 @@ Other Debug Updates + Notifications Playing in background Playing in popup mode Queued on background player diff --git a/app/src/main/res/xml/appearance_settings.xml b/app/src/main/res/xml/appearance_settings.xml index 31be267af..a77663843 100644 --- a/app/src/main/res/xml/appearance_settings.xml +++ b/app/src/main/res/xml/appearance_settings.xml @@ -1,38 +1,110 @@ - + android:title="@string/theme_title" + app:iconSpaceReserved="false" /> + app:iconSpaceReserved="false" /> + android:title="@string/list_view_mode" + app:iconSpaceReserved="false" /> + app:iconSpaceReserved="false" /> + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/xml/video_audio_settings.xml b/app/src/main/res/xml/video_audio_settings.xml index d1757919b..0ff43ce90 100644 --- a/app/src/main/res/xml/video_audio_settings.xml +++ b/app/src/main/res/xml/video_audio_settings.xml @@ -81,13 +81,6 @@ android:summary="@string/show_play_with_kodi_summary" android:title="@string/show_play_with_kodi_title"/> - - Date: Thu, 14 May 2020 17:05:09 +0200 Subject: [PATCH 026/137] Use vector drawables for close and replay --- .../schabi/newpipe/player/NotificationUtil.java | 16 ++++++++-------- .../res/drawable-hdpi/ic_close_white_24dp.png | Bin 221 -> 0 bytes .../res/drawable-hdpi/ic_close_white_32dp.png | Bin 257 -> 0 bytes .../res/drawable-hdpi/ic_replay_white_24dp.png | Bin 675 -> 0 bytes .../res/drawable-hdpi/ic_replay_white_32dp.png | Bin 804 -> 0 bytes .../res/drawable-mdpi/ic_close_white_24dp.png | Bin 175 -> 0 bytes .../res/drawable-mdpi/ic_close_white_32dp.png | Bin 542 -> 0 bytes .../res/drawable-mdpi/ic_replay_white_24dp.png | Bin 457 -> 0 bytes .../res/drawable-mdpi/ic_replay_white_32dp.png | Bin 583 -> 0 bytes .../res/drawable-xhdpi/ic_close_white_24dp.png | Bin 257 -> 0 bytes .../res/drawable-xhdpi/ic_close_white_32dp.png | Bin 666 -> 0 bytes .../res/drawable-xhdpi/ic_replay_white_24dp.png | Bin 908 -> 0 bytes .../res/drawable-xhdpi/ic_replay_white_32dp.png | Bin 1168 -> 0 bytes .../res/drawable-xxhdpi/ic_close_white_24dp.png | Bin 347 -> 0 bytes .../res/drawable-xxhdpi/ic_close_white_32dp.png | Bin 436 -> 0 bytes .../drawable-xxhdpi/ic_replay_white_24dp.png | Bin 1390 -> 0 bytes .../drawable-xxhdpi/ic_replay_white_32dp.png | Bin 908 -> 0 bytes .../drawable-xxxhdpi/ic_close_white_24dp.png | Bin 436 -> 0 bytes .../drawable-xxxhdpi/ic_close_white_32dp.png | Bin 1852 -> 0 bytes .../drawable-xxxhdpi/ic_replay_white_24dp.png | Bin 1885 -> 0 bytes .../drawable-xxxhdpi/ic_replay_white_32dp.png | Bin 2580 -> 0 bytes .../main/res/drawable/ic_close_white_24dp.xml | 9 +++++++++ .../main/res/drawable/ic_replay_white_24dp.xml | 9 +++++++++ .../layout-large-land/activity_main_player.xml | 10 +++++----- .../main/res/layout/activity_main_player.xml | 12 ++++++------ .../layout/player_background_notification.xml | 12 ++++++------ .../player_background_notification_expanded.xml | 6 +++--- .../res/layout/player_popup_close_overlay.xml | 9 ++++----- .../res/layout/player_popup_notification.xml | 6 +++--- .../main/res/layout/toolbar_search_layout.xml | 4 ++-- 30 files changed, 55 insertions(+), 38 deletions(-) delete mode 100644 app/src/main/res/drawable-hdpi/ic_close_white_24dp.png delete mode 100644 app/src/main/res/drawable-hdpi/ic_close_white_32dp.png delete mode 100644 app/src/main/res/drawable-hdpi/ic_replay_white_24dp.png delete mode 100644 app/src/main/res/drawable-hdpi/ic_replay_white_32dp.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_close_white_24dp.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_close_white_32dp.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_replay_white_24dp.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_replay_white_32dp.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_close_white_24dp.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_close_white_32dp.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_replay_white_24dp.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_replay_white_32dp.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_close_white_24dp.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_close_white_32dp.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_replay_white_24dp.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_replay_white_32dp.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_close_white_24dp.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_close_white_32dp.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_replay_white_24dp.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_replay_white_32dp.png create mode 100644 app/src/main/res/drawable/ic_close_white_24dp.xml create mode 100644 app/src/main/res/drawable/ic_replay_white_24dp.xml diff --git a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java index 68648a8ad..62f25810b 100644 --- a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java +++ b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java @@ -356,7 +356,7 @@ public final class NotificationUtil { } break; case "close": - builder.addAction(R.drawable.ic_close_white_32dp, "Close", + builder.addAction(R.drawable.ic_close_white_24dp, "Close", PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, new Intent(BackgroundPlayer.ACTION_CLOSE), PendingIntent.FLAG_UPDATE_CURRENT)); @@ -450,7 +450,7 @@ public final class NotificationUtil { notificationBuilder.setSmallIcon(android.R.drawable.stat_sys_download); } else if (basePlayerImpl.getCurrentState() == BasePlayer.STATE_COMPLETED) { notificationBuilder.mActions.set(slotNumber, - new NotificationCompat.Action(R.drawable.ic_replay_white_32dp, + new NotificationCompat.Action(R.drawable.ic_replay_white_24dp, "Completed", PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, new Intent(BackgroundPlayer.ACTION_PLAY_PAUSE), @@ -486,7 +486,7 @@ public final class NotificationUtil { PendingIntent.FLAG_UPDATE_CURRENT))); } else if (basePlayerImpl.getCurrentState() == BasePlayer.STATE_COMPLETED) { notificationBuilder.mActions.set(slotNumber, - new NotificationCompat.Action(R.drawable.ic_replay_white_32dp, + new NotificationCompat.Action(R.drawable.ic_replay_white_24dp, "Completed", PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, new Intent(BackgroundPlayer.ACTION_PLAY_PAUSE), @@ -611,7 +611,7 @@ public final class NotificationUtil { break; case "close": notificationBuilder.mActions.set(slotNumber, - new NotificationCompat.Action(R.drawable.ic_close_white_32dp, "Close", + new NotificationCompat.Action(R.drawable.ic_close_white_24dp, "Close", PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, new Intent(BackgroundPlayer.ACTION_CLOSE), PendingIntent.FLAG_UPDATE_CURRENT))); @@ -840,7 +840,7 @@ public final class NotificationUtil { } break; case "close": - builder.addAction(R.drawable.ic_close_white_32dp, "Close", + builder.addAction(R.drawable.ic_close_white_24dp, "Close", PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, new Intent(PopupVideoPlayer.ACTION_CLOSE), PendingIntent.FLAG_UPDATE_CURRENT)); @@ -927,7 +927,7 @@ public final class NotificationUtil { notificationBuilder.setSmallIcon(android.R.drawable.stat_sys_download); } else if (playerImpl.getCurrentState() == BasePlayer.STATE_COMPLETED) { notificationBuilder.mActions.set(slotNumber, - new NotificationCompat.Action(R.drawable.ic_replay_white_32dp, + new NotificationCompat.Action(R.drawable.ic_replay_white_24dp, "Completed", PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, new Intent(PopupVideoPlayer.ACTION_PLAY_PAUSE), @@ -963,7 +963,7 @@ public final class NotificationUtil { PendingIntent.FLAG_UPDATE_CURRENT))); } else if (playerImpl.getCurrentState() == BasePlayer.STATE_COMPLETED) { notificationBuilder.mActions.set(slotNumber, - new NotificationCompat.Action(R.drawable.ic_replay_white_32dp, + new NotificationCompat.Action(R.drawable.ic_replay_white_24dp, "Completed", PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, new Intent(PopupVideoPlayer.ACTION_PLAY_PAUSE), @@ -1090,7 +1090,7 @@ public final class NotificationUtil { break; case "close": notificationBuilder.mActions.set(slotNumber, - new NotificationCompat.Action(R.drawable.ic_close_white_32dp, "Close", + new NotificationCompat.Action(R.drawable.ic_close_white_24dp, "Close", PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, new Intent(PopupVideoPlayer.ACTION_CLOSE), PendingIntent.FLAG_UPDATE_CURRENT))); diff --git a/app/src/main/res/drawable-hdpi/ic_close_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_close_white_24dp.png deleted file mode 100644 index ceb1a1eebf2b2cc9a008f42010e144f4dab968de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 221 zcmV<303!d1P)og+*{ z>6z1@lfD*AYSPav7 zOA5m<3jYBNi%A&<@ZO?$P9};P4Y5CjG5$M&YXI45J{s}~# zf|&?x1_gn4B7+hS@X!l}&!voFhmZP^sujifL@~PKMMM~{6xH}^g$q7WOzwCQ5vHTU z6`v~H@rlA8e;CUh_(b84zg=+ih`wG<)HiJjzSlQx5#CnjMR;A)R^jtaTa9;7rSy)7O%~`cm?ZjXImW?6TYRT<;U^@VKiSj`soFk00000NkvXX Hu0mjfhD&W| diff --git a/app/src/main/res/drawable-hdpi/ic_replay_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_replay_white_24dp.png deleted file mode 100644 index fcddcf02ddb58ee1680889e7315757d76419b4b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 675 zcmV;U0$lxxP)i^4O#T$_9m82|5VvpF*wP4OP zM$UZi@^>7mIp;Yu=T~<=&tBi0Ip_J;@t6l6eCkO56W1~dg3&=h1q zQ;-2oK?XDh8PF7DKvR$bO+kjAeDJ~pr|dFMzEwenMqRT?w%I|3a4PK3rz1$XY>?9M z$o%dYv=53msmx64U;8dHjIzKUk9_ChB>7>S;1G`>C)ufEh%>(Om`-|fb*SR^#z4}` zk1=8_ANv5(l+5L85*Xb37G?llB;BT5>A(ui94pbtcshM*TjCYGR_ z-6MNIjB5B%pCT4Cy!N|@y;y<{>^_Y1h{sr_j%UPd_@F#~6P7u_$u$?{J9LdWv<^B( zTt-`dtRg&yta3*15X;emvQ!XfRzVjCmrT?J+75nB>W0d9%nhW=(93#VAeC5$p_bT;=ksFy7&G{R+*d}}W7vaE1LouAaX zWSLB>FM)fQW1AE1DN&Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0=Y>Ua!!*MzB~-b zcPe>dSN|c`ndF7t{f0bqlNT=1U&ygAdEsLHg#6|vZ+@fC=nZ;~4$-zlEDw?>lY9~1 z(FxjhxXN6x?V3yIA$m_Ej?iX&wQH!j&RfW$hU_?Ow@~q-My#W2=pK5EKA=3#(4NC~ z3l$eO!bMWJw1)Q4sr&(IM8DpI-810YLNDS%)2KW3XH3|Y3+@O#jSEh5D)|Lordfoj9<&It1B9TGq4d+uaz%JeY(|X>Kb)ARWN7 z=t*taT^q$h9~C&mvEB6{*e?1Nhy91Pz_r&A#Xv6=FoU+!&7RB%sILbhI*e3qgziPT zab2W22)c=M+zZj0ICpo_Jt%zg;vLdwm*yex4${FpL}Nnx`GvES${-Ecu+NK6=!T27 z0~PF{yhaF3vDy;fN7|TeSo*DN^5uPv5Z!%Np(4GByzW#Lb(?mdd(AdV#S~tjs60{lf39H8_eGT0000& diff --git a/app/src/main/res/drawable-mdpi/ic_close_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_close_white_24dp.png deleted file mode 100644 index af7f8288da6854204dcc4e6678b9053cd72032c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 175 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_+iGEW!B5R21KC-3Avpdi4K$<+1X zay^SH!@6{thMdKZi+L1hS^BMZUAdKCT}(HRw{NeWg~AlBHtr3jj>2B5kK^|J))MUC zlz7ydwCsb8xn}W?^r?}5wtsjdmvX{3=JbT!J9sKPrYmk={m|7^>A|Z*7j^D$`>}ry Zqi^Z9GQN4ct^!@a;OXk;vd$@?2>?I&LQeny diff --git a/app/src/main/res/drawable-mdpi/ic_close_white_32dp.png b/app/src/main/res/drawable-mdpi/ic_close_white_32dp.png deleted file mode 100644 index 20b61eaeec893baf305a701f78fc9c18eee0217d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 542 zcmV+(0^$9MP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0kcU&K~z{r?UqYU z0zni-(V?J2*o-c~&pJf+060|H7;Zoqh$HzVO3FzR68}UcLM3 z)Ag!L1qu{M!fZA>fJd4-emjh9!LfZi(y}={aMTvo;Shm{vJab7_dH|;*vs$=KH5hUmqyJ)vH?d4 zHeug_11Q0jZ-PEe_yUeR_5o_bsgEue5`tkTCQy?o+Z-mU;1iE|f(@JV!vPdD1kl#D zY?fVT9#;NLaZWj(;8uWO6>61XC%W(!wqehG0|(E1ZBqeZ?SxjV;2-dnfNzxV@E$g3 z$9|++1A*EK48K8pN^xUzChWTW8(^j3p7)@RU}~zaBS_2>xq$fcJy*bMZ9QezeX)5W z7Z6Om=hPST#0&h9CvpMJklSPLx$1B^Po#P~5`k6)p~c)Dd(YJeHHpQyqeXSIRE%>t z^RWe$+Y|4(Y>d%vg|}k_rIGzH!hiWWPLFTt0oJ-PWqJo#>PDsS z`vtg-Yj!6pzPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0o+MMK~z{r?Up@D z!%!548!hOdv<0i9j_RP`p!f%L7VYNl>gJ$>n}a{YNjEzRx;O|fej#-eoI6y74t@~d z_vTGWNMq9W8W8%x!%fb)=bUS;iMfA`>$=Oj%pMMhue!|^e>ij%%8uZ0qHs1~UT8Q` z>hHm<$Z)X+nH$ws`)EMB;Xyv(Ijq0|mD&Lf(;OhkHJnws9ndiD5SwrhUche##5-J3 zxgF3jatNgixSfV)CgIV9OG?`T4MT@exCKHEJTyss?9ni3K2!%p043C%>`%2jZ zP0b;68v(fztV68~#%@@`7899Q#cuHrnjcdb-&<(QmJ8$Y6*KOlM)ncm{N}#EGd-;_o~KcU8(e-h*nLx z#|@lRIu`EHUY}E_Y=@w*2p`x*@cF+B$F-#eViSTtVCW^hrT3_XEl~ V_uUT1{e}Pl002ovPDHLkV1lm9{aOG3 diff --git a/app/src/main/res/drawable-xhdpi/ic_close_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_close_white_24dp.png deleted file mode 100644 index b7c7ffd0e795ba76ed3a062566c9016448795f7a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 257 zcmV+c0sj7pP) zOA5m<3jYBNi%A&<@ZO?$P9};P4Y5CjG5$M&YXI45J{s}~# zf|&?x1_gn4B7+hS@X!l}&!voFhmZP^sujifL@~PKMMM~{6xH}^g$q7WOzwCQ5vHTU z6`v~H@rlA8e;CUh_(b84zg=+ih`wG<)HiJjzSlQx5#CnjMR;A)R^jtaTa9;7rSy)7O%~`cm?ZjXImW?6TYRT<;U^@VKiSj`soFk00000NkvXX Hu0mjfhD&W| diff --git a/app/src/main/res/drawable-xhdpi/ic_close_white_32dp.png b/app/src/main/res/drawable-xhdpi/ic_close_white_32dp.png deleted file mode 100644 index cc13347341479e29fc567f6af466875e91e4048c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 666 zcmV;L0%iS)P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0xwBKK~#8N?V4du z0x=MU(H~w16Yv6_0Zy%_&_u7GzwmozAY|O_E^D{6?0m^fgmydAz6TQ6RS*P05ClOG z1VJ!?!{P9Vp6y{VR1>Z3VRpSaWP{-OhVxDoYYH$L4lXpYtA?o0J4SXJc(S@1e;_ zNzijP)`c=ejLr> zyoWW1l2Go)QHrgRev)sbHb5XocB<}CqX@IY`7d0)h#kQ zglpd-vq5(@Tpo%q^Cqbv2!bF8f*=Tjc3G`{0C;dH`T`V^N&o-=07*qoM6N<$f@YH? A5dZ)H diff --git a/app/src/main/res/drawable-xhdpi/ic_replay_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_replay_white_24dp.png deleted file mode 100644 index 1573fb111b535e5e0df9371ff7f804ce2c40a0fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 908 zcmV;719SX|P)7!(!0)U7tJ0c*i|=W=`GD{Rhrh*S+VSbLJ}_yb|Y} z2=nyPP+9@g9^_WikSR{kYsy-hy zEku#&*XNV6oCC6@Y0~GT-ej9>Czv`dtH=_DbXwRliC~qaN~fj83SwBz>9x4qN(Rvr ze!Z60m#~`DYlFi_98nBIuPvr=tUC1CrC;Y$3W(^FgzQC`p+k!}pOw6jBq=iPfkh0TWmS)dUz^Bf7(L-mV&-4}J$XOF7sBlc6Scm>hhDc(^Uj{LXd-%JWIiC2AM`rMs#_tFGOcEm> zQ6{J?t)HM6bg;rDU%4Peu#|sCR!~qE~FTC?knj22pV}>5;)E~ds^l}5-05`x5 ia0A=`H^2>0aQz3T@7w=K#~w`p0000Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1SLsCK~#8N?V8_< z6=fL5_efgpvvr?4ngx z5WHCxL7{9>Q7{wwwK@B+;?YU%&MqDmkEV2J_AtG8Lx*Pv)Z13Pp_lp}YITY?^m2bgo!;UNx%4m8 zm|DCcxBi6sIu>upwf~^D%;F8X_ZQTat9V00YNI7v8q{PzZ;zri(Sd9ZqC4nMbP=6F z=UT1SB(}G(;!&=5K7(86JG2o!q3OehM9V5Z$rZE*J*`lsGDkLKmZC4w1)8uSIua@* zSkw~pZU6#6O} z;O8^Bh6xF#HbE|#;Mzi8M1x!&pcQfr6B6_`K`-Y5cWc7IXrRk+xrGZ!I!(|^xnamW z^jkF8W|DhRl#kUQ#&>@Gp!2cokdv(!K8W|)*g{T+ zv|SDa`vCc^owhnx;El0~W7r7h2MdcyJp4ucCmaPL{>~V6<{Zy&w*Wjq^bk=dv8Payw zAm+=MweemX$7FL+v;n@~**3=~@n%=qjePkRx)&$}UAG$$dqR`sZ`8GQdSVTtI~F*> zc_gojAi%CDl*{*WsT^V*ibFc=luLCGty(ibwV9xh7w~t>@>3{a<2my!CO^fcq*6H`6 zqTezOHV66?*?OOk8^~_dx(|VEbvErIY1kvJRdO#3V^?dAG%WU8a<2yx*oN#K@5C=? zGn%VmshE#^ZA>RD=2i`xF{PY0Br<~e7G+(9?;=|XK8q&MqcuTW99@Q9M{l64TkLyi zJ3o1UjCTWoCagmCf1awjj8-aaSdiF!v>*M4%EspW8qHU@a3RUH=maVYo9j(Y-#d`B zHR2m&_Xn6?(TivvGVGtC*OC2G^fWqw#<vMkH8EXyh{JTRaptiwcq@D(P;=ehLbl?EMKm*m7(@7_siS}}k zNFtnck{HL4mc!ypcyUoqJV~4rM^fS3C#iAnkyJU3biCmDy`VZLOv=LXld^HVq32ETvhYyB39D^lU%DgQgv&#U%8l^-CA%qY@2qA=!B5=cm zUgehujQG*l{{`@rPr!f|fEk^>KI9WteE@ilV6HEl&_rJ@p_zU*;T}RirIc{5NocNLm*7JGdV(AM zYYDFOvk5~8{Z*t_>U=!XvoehUSEh=adIga45oe)B9kGgT}7UT3Cirmr(oHPv^YQ1-p=Hlh5u;xggf zX{&yw+El-OrrKQJRl@b7x{HLmNkj95`a#LLnW{Veb2C+!`ppt#r)=g4@?c8RY{yJj~W@W|h^mU4q`i)2y~Rw@J`jIh$1%|In!~{Tb{nMqaxlgb+dq eA%qY@zJ@mriVM?qfwL0;0000BgE0Bosd;&l!5{GB}Nw&aWDv$#(+==h%zxz{0{`dg+v3oNsZEs1O#b7TU=z3 zN+U>6X{oItF;)nPJ2M7_WMc9%Um4!^-ghT8^Ukw#zTbcF!Mpd}bI-XHnCAtLxJ@r7 z*+WWFkh~r@MJBk;QR;*R$?I{j$^*{OAS_5;j{}dp93n0(NM4VF=X6pdEJ$9DgITg9 zR8TMzWb_kr@e}pBNC)$pcHQP(8I2%dRM20TlCA~t5IK}Qkj#7O)Q^3r9eOSQH4a|6K{m=!i&(jnw*l3S} zAo;|Y#mrR|c`AQ73Aj>W`=NK1ad*g$rgcHjacN zsE$?43`9cEp#0VI1I#Q^C$1+=0W+iFH7}gO##wPe=dsZho}dOi%*>M#)$=KDF|$HC z%=VYN*tj4n=n^*Wgxi952pdam7t`|<%h)&=uAn&2u`wd{|1*k>Nn)W2a<^>@q#HZO z!*3+7VHO(;>=dXW7O*kRCla0ZS?o+w8>*fZ|6u2s%rHxW3G57$2u;t&j9}+4Hb_nT zWC$WhETqMGkRZO19H<*2h`taM#pox9o3bOB^}HsC9El2lT!REL$7j+rtL+3cT*2i! z#R$QC8-=m(9KlS|RH2RiIl)|u#=`OrwtD`Z#efJ`%0Sgyv2>j;V3?^)IpJQ zC~$)oVryJ;_A*F;awzhBRG;YTz@uDdxXb~P?psnaT;V0<;<@!m_9(Wo#9CP45&fK^ zm0dKDWCIB{)4(oTIZZ#0Sz#>{I2`q70$a!<#VdblmKEeqBTtav5BJ6{FUU`l0m9~* z`?oM!L%nU}35z-RnM+)dA!%+A1~=V*R#Jl8+0QtYYudtsG%831sUQ`k wf>e+SQb8(6qk>eB3Q|ETNCl}N6{IobUk;_uiK)$-$N&HU07*qoM6N<$g8NE^b^rhX diff --git a/app/src/main/res/drawable-xxhdpi/ic_replay_white_32dp.png b/app/src/main/res/drawable-xxhdpi/ic_replay_white_32dp.png deleted file mode 100644 index 1573fb111b535e5e0df9371ff7f804ce2c40a0fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 908 zcmV;719SX|P)7!(!0)U7tJ0c*i|=W=`GD{Rhrh*S+VSbLJ}_yb|Y} z2=nyPP+9@g9^_WikSR{kYsy-hy zEku#&*XNV6oCC6@Y0~GT-ej9>Czv`dtH=_DbXwRliC~qaN~fj83SwBz>9x4qN(Rvr ze!Z60m#~`DYlFi_98nBIuPvr=tUC1CrC;Y$3W(^FgzQC`p+k!}pOw6jBq=iPfkh0TWmS)dUz^Bf7(L-mV&-4}J$XOF7sBlc6Scm>hhDc(^Uj{LXd-%JWIiC2AM`rMs#_tFGOcEm> zQ6{J?t)HM6bg;rDU%4Peu#|sCR!~qE~FTC?knj22pV}>5;)E~ds^l}5-05`x5 ia0A=`H^2>0aQz3T@7w=K#~w`p000032ETvhYyB39D^lU%DgQgv&#U%8l^-CA%qY@2qA=!B5=cm zUgehujQG*l{{`@rPr!f|fEk^>KI9WteE@ilV6HEl&_rJ@p_zU*;T}RirIc{5NocNLm*7JGdV(AM zYYDFOvk5~8{Z*t_>U=!XvoehUSEh=adIga45oe)B9kGgT}7UT3Cirmr(oHPv^YQ1-p=Hlh5u;xggf zX{&yw+El-OrrKQJRl@b7x{HLmNkj95`a#LLnW{Veb2C+!`ppt#r)=g4@?c8RY{yJj~W@W|h^mU4q`i)2y~Rw@J`jIh$1%|In!~{Tb{nMqaxlgb+dq eA%qY@zJ@mriVM?qfwL0;0000Rol24V(Ul{cf{Ft-O^TClm@M})Kx4+>gFppf_Al9 z#ZupGE6zrcR@~QaqeT$ZRuoaI`|%I#4>R+;&olGR%=^sqOcse~F9%hJfcj#!iW);ZTYO z>T=`0X?%9WrcrsC_4A<7*sb<(ZqAXCz$&?zvtCH)DOTz*!{g)CUw2Q0|C}824PDMP z{$6;es_Q`y_y6;2&Fj*OPLzVPYLCjEjk4Z}J3<9+DeG=LyRliiHMy^7kYa3n-Q4^r z=Je=Wh=B)$5psZ;8FFDrR_u@>qb1o1CW4Lrhu0eYPa_i2OYrb(DZ%v))2sppo^;_8 zwb0{z5aLC)COh6l@b#o`w)J1gE$qmZkTWeSW5#}~Xiul~Dxm4=GI?L5oo$KYsh#st zwF=q4KstT`?fKPzz&H~P!{@!{OvE10md89lIPwS=WZaj)>KZoRD~V{@46XE6=K{7Z z#TJUPzMa;tA4a)CC9urOT$T|k$R(Y8;K}A59pxC00f8W^h%BO>TYr4?7hHASPMEOW+xq zFH~-%I>LxXKFc)6rpyej6+LE67n2X3+)vBbZ6Xq*vPwnFK{koOF-)46tJkHbt`_CC z4~~`Y+2)BOl531IJ#YOAt5e85f)%tuz@ip4c$?e*j<+^{78Qn(p*6SlH~cb_wYzPx5QLsf0a_{(8oi)_v$2D9_qHUS znS#W~8YucFs*MdqD!%#701|5{e;~DD{uS=EI3H9Ap~GU1M3Z)YNZ>Qi;Aq{#ZVJO8 zkZ_a8!%)rgo*_inYCPk%r?6Rz^*@$I=u1TC@(p8%JXJG5{>i&cGGi$W`=ovkX|n{5 zNG@FM-Se{a0r>_AZlQ{kc z;$*=H;?31f0JTDAa&-*Rz&Xkz)X+*{FX!Np=|rriNJQduu(;8=`;?G7n!pV{ro*%j z_jT!190rJ5o*7(4HhNQ2yAMaBe-ptSN=qc-eHQ7-`1QRE+kgk0Q#7_{655_0V@?mq2q203()6r6+x2FiJqPX|2^x7}2$3tNsI zn?0;zlfo9k4wg=6!``}M%V9A>27v)~tEs` zOZ=Us)a$C+p_WVFS6eBx_1}#`02qtJ`c5=Krxav*hS1(&vwD7grZ4tZ2tFCF>Aj|m8d`?t9S6@!6^#L z@*k^9m(K|S&7>;w1mNb_%*kx=#$CN0sd;;|kmG+5c6jPe+dYcY8C$$ZUy9mJ|3DMF z>mba?#m=aIh>>CEH8;}79hKz&_TG~AZEG(6?{C6Z^GyBYk0go2y13oxb;^&x#{)Uq L5p5grL8<=&`?GV8 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_replay_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_replay_white_24dp.png deleted file mode 100644 index 04cbde9af1926410c77e666492a8c5407d938f2b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1885 zcmV-j2cr0iP)G0000LhNkl?*|(>Q-}x=BZLQ4&YpE&mJ&MS+o(x;tb+l&fx65xW;&^oP6*;;qZ`277j0&B;g2y13QyVxcB2x=EDkM`q92JwP7LF>&R0l^@ zWU7IqT37j=K`wEM_jsFaJi{v5DanN4NXjtpvz;}}lo=0>dN|9gbkZzyEgbbU#4aA8 zQRXK&((omlnJeIN0diU~(n^z$bb4~{H3$n7c`99eROtxQ(2;K-J9 ztWdGw$ePz^QIX)tno}%Rk>JRh5uQ|$;K-g=Xi#zB$etcrRU9~~)5H{JvygjP&5P`! zk0Gk{A=6bHII5uQP@;q9+0P)AJIgE;2abwqTr_YWuQNbpF3_&xz)>Lu(9CLjC==fW zW~n%ER78=mfZdD{*IA~kIB--zkujGyxI#Srw5m98#HLv2;281r(4gYL5tCw~#8Z4l z99=3B9I>bZ+{!z|u}(#TBL-E7XBj1`5f-UPa73nxaTn)^>JwU2Bsd~c6_`pNQEgYT z;D|(3p_Ri#Q|2KR3yug>B^v1_n$Ngd#eyS9Rii{V(fmV2gCjsSKqH5V;xfNi(cth> zP0&goQ5;b5;P6n5(8hV9SgGQ{F)q~%cQZ=Z2^A5Jaj1rPo+utw5#hKY)fD>(>sK-1 zxB=A^Q}~*&2UScsuA>^`X~KF{R5*S^HAad55K?BIiVDXyRC9DNM#xJlE*!t21h9jU zFPNm_!to0wfVqqj^00~w$Ip}qx(Rtp#fIZYN(2ij<2OK)iVepPln{CeS*fDKffB+R zLb_ydN(e0s;&(s}pO7bHl0ySS_;tx7i39i@lSvXU;5R6fB<>_+woGy; zF^pfQOp@rwZ@o;C=*Dl0Op@4$-(Hy{u@=80GD%`7ekWy;Lqo1 zGD)HtzcHnatN1l3$7sfHOljkL{H7?!Xv1$rX=4z-*~&5I;P;2zgmqK_?+S${7w4vO-xwGeh{5S)d$Y5oP=aXi|2ti;#aRN7zHiPGt#?5Hd!) za)S9>C8SeXLL*-i@`iGPorGLslCp)(gj`{RC89@{O zCW=w!Df`$;G`lG&11PbFXf`Pin9Mn%*-fKTMiYC8=2Kdf53C@n!?Y?z+`_+zrpyD% z4_+gxKH8KLrttw$btzA1;WSa5=WeBdd-$BFKBigu!eT~ zNgVr_qB>zJ?-Ivqp|mlQH7yW3uv%>6|65F}hix8e$Q97$dI#F-`f$EG`gVnO@e=qAJnCIu24M zzVpn~#6UY2sLUWcxSs}9fJrRlO$MpVdFE*1U>0Yo+zyvz!kWGch&c!DmDF+?1L9Az7iGef3Um`x|^ z*}`6qaFUA*Fv1vPjPNZNImr?BvW4|@a+{1X#u#IaF~%5Uj4{R-V~jDz7-NhvCN=*D X>#M$jzV5xv00000NkvXXu0mjfXY*@a diff --git a/app/src/main/res/drawable-xxxhdpi/ic_replay_white_32dp.png b/app/src/main/res/drawable-xxxhdpi/ic_replay_white_32dp.png deleted file mode 100644 index b51ecf755901c5f87d42a5ac6383f09cf93849e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2580 zcmZvec{mhm8^*`J?;1koxN0f2g<2pi4E*@Z&v+`|9>@$O&EMG3C_lfzzJ zvxd4v-P$O^^eNjYC&n~aVoTJx94#c5%dl8gZ9+k=B<`k-+NqReUI(_tGS5SXv}G6l zW0ZZ`Rm(wwVtR?Ru{@$o|0=;GRN&cdVVs4CEJ_>kVs7$h7WdY)(Ods->$J_E*NWGR zskGwv>xHwElX-kkmM;7%BW;u5FKjd_;xT_-9Pr2VEmJE?+qUy6zfYrR2-SWHM|)39 z(7(F|Z?5DRHoG`xc*?_}m>m0L0fchz? zD6!QvwO4uu!@g=NyJ^qjzSptG5;c$iezklsRWHU~iVxf8x;6U(z1AmJ#rI7YKwP@s zs+{XAzw1t3dC2uCYMJsz3MpCJ+rD_tMa*$`&WTH6Kvc1+> z({1pokhkX8q6E`zrt{GwaQGX3RnUj17zCtJ^lNO{{&>3Zt8E&+U<;B+gFxDc259D^(kM!xJrMBTd%qO!TYymj+YOB2S zxM4SzfT^((ELg|Bu<`n4mI|B1x|THc8pjjton+iX2J2Rfo8`x~3m?Cx7!96I%eUx) zdC9mT(m_eH%+QBU3lIxe0TKNRT0rUGs{9UIo-l4wyuVZ6lpoJ#*R0+zPQDNGfojCh z?{|D>MkgqLhE!4!Bq5Dk<@p^ZH~68O>8?Z`qLo&*oQEM?#;#+9gJHs*_waMw^mjzT zktU0D1l-xKqmskz#i3h|ubkP^c(S!rpeN5s@d<(X6#N-K-$e0V)ZEa`ATh##gkf1} zaHVD)*&pwvglkHV1kzxQ?~TMXmV5F$+VW352$TKTC==zMC7Y3fsu5bpOrl+L(S6>X z28c-Qq5u$x&Vjld7zk$XMUl`ep7Wy9GkHMiFj{_xIqk`V1g-KTk;mIS(=*q&gpOJ` zFkfMPyDG3By5g7FBwj(_jYYzIg8M}uL@WM?Y~3-WHNuKqGAhXzlQnm`Ws@)(WkEbwIbj=tA5qJ<>9L1wy0pj8jh5_L<%CT|XH{jRB$jv&sR+iZykk zd0menD?JgT)yb7dS6V$_!~Wik zSI}ycDJ^sG+*nN0l`HDs9MJk*Du@Hhgf03IuM($1lX`m0sEoJog)JOz6r5b_tRG$Q zx&I_u(j`*j>Cv-DLa{s$#I_|>Q*;NnoM_`3n`kBS(4z#=n;71U3dAW*QSDA_m~qNVwI~DwVjax~v5b&mMRl zo~G%~HQ;OS(DZ#rXLak%-WN+H2#uLrm$G9sQ#{v|))$A)G z=_wfPc91?bNW1hM=G|)nLs>KahVr{#E+tLFS&=rz8OMhH`bB#NCAEAxNHT8V??HNU z_+FK*TOknbpc1#og;2~9k-EaYMM1c%K}_Pvs&I-=kZBJaX{?43^O?anxl}_dk9T@U z1IdWO+nU59o-e2xp!nHCz{njruqUDSMrFx`63xUUX!l3IXvvq5q=BLPBVEygZz0$| z;l&W)+M5Km<{^_U3F|e())=LKLeBJd*Eb8D+AVOTU-{W7zu6Ncfp6r`94Zma57Wvi zVEzMi05b|Cdaj(~&h$)~b~ik+l68WUUA+3>2$+O2JV~&tieTunq(8n9hd}HdBG>Xdf~OQ9$s@z^)Kr#l zVXtrWv81EeGoVq>TFxCoB<#~n9(ZpLg^;mcX@V?xD2*XPtlf6L|Af~ECryp?caLo< z*9A9h#7RYb`;vW{F$-J{Q5|y9vR`8iWcxF0qq6xf8BNd!D;1y>d6%8&mZt9;5CVdk ze%fu7;oO6P?2(}6Q}Z#?iy zQ2mkeLDwr0T$javy!&D<6ZsPX9^vPY9Yr@}o~P41U7yMa?w^=cD9Sp15z}=50AgrICBg2dTv}+(H$=ZfD06-aj-^Yr;qW={h#y69>C;d8BXbY{rV%AK4?G zwew0e-nlSrc{?yi!Yl5^FeB^qiAjTP_>T%?W=5T&%c{u4vU$wCkzlkG5VC@#Z;|^2 zgih`Q>17{>;gyx?!gATCK+?pdkJ(nLxx%e-&4)befY9Y9*O zBk?X-W9RobdRb*69XSYjS-DvxDv46slDUzr82d6{qokY-9`TVoSgK*^dcrCW7RBMg z!oO~gydfnTA_2yLgrg;uq`)tuF~L^p|5Rt1CV23UFL}85RZqGp)aG2OA + + diff --git a/app/src/main/res/drawable/ic_replay_white_24dp.xml b/app/src/main/res/drawable/ic_replay_white_24dp.xml new file mode 100644 index 000000000..8e84c195b --- /dev/null +++ b/app/src/main/res/drawable/ic_replay_white_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout-large-land/activity_main_player.xml b/app/src/main/res/layout-large-land/activity_main_player.xml index 16dcff639..8f683ccdf 100644 --- a/app/src/main/res/layout-large-land/activity_main_player.xml +++ b/app/src/main/res/layout-large-land/activity_main_player.xml @@ -65,18 +65,18 @@ android:id="@+id/playQueueClose" android:layout_width="50dp" android:layout_height="50dp" - android:layout_centerVertical="true" - android:layout_alignParentRight="true" android:layout_alignParentEnd="true" - android:layout_marginRight="40dp" + android:layout_alignParentRight="true" + android:layout_centerVertical="true" android:layout_marginEnd="40dp" - android:padding="10dp" + android:layout_marginRight="40dp" + android:background="?android:selectableItemBackground" android:clickable="true" android:focusable="true" + android:padding="10dp" android:scaleType="fitXY" android:tint="?attr/colorAccent" app:srcCompat="@drawable/ic_close_white_24dp" - android:background="?android:selectableItemBackground" tools:ignore="ContentDescription"/> + tools:ignore="ContentDescription" /> + android:layout_height="64dp" + xmlns:tools="http://schemas.android.com/tools" + xmlns:app="http://schemas.android.com/apk/res-auto"> + app:srcCompat="@drawable/ic_close_white_24dp" + tools:ignore="ContentDescription,RtlHardcoded" /> - \ No newline at end of file + diff --git a/app/src/main/res/layout/player_background_notification_expanded.xml b/app/src/main/res/layout/player_background_notification_expanded.xml index e5a9b632b..80bc22627 100644 --- a/app/src/main/res/layout/player_background_notification_expanded.xml +++ b/app/src/main/res/layout/player_background_notification_expanded.xml @@ -29,8 +29,8 @@ android:focusable="true" android:padding="8dp" android:scaleType="fitCenter" - android:src="@drawable/ic_close_white_24dp" - tools:ignore="ContentDescription,RtlHardcoded"/> + app:srcCompat="@drawable/ic_close_white_24dp" + tools:ignore="ContentDescription,RtlHardcoded" /> - \ No newline at end of file + diff --git a/app/src/main/res/layout/player_popup_close_overlay.xml b/app/src/main/res/layout/player_popup_close_overlay.xml index cba06874e..e7607edaf 100644 --- a/app/src/main/res/layout/player_popup_close_overlay.xml +++ b/app/src/main/res/layout/player_popup_close_overlay.xml @@ -1,6 +1,5 @@ - @@ -11,8 +10,8 @@ android:layout_height="wrap_content" android:layout_gravity="bottom|center_horizontal" android:layout_marginBottom="24dp" - app:srcCompat="@drawable/ic_close_white_24dp" app:backgroundTint="@color/light_youtube_primary_color" app:borderWidth="0dp" - app:fabSize="normal"/> - \ No newline at end of file + app:fabSize="normal" + app:srcCompat="@drawable/ic_close_white_24dp" /> + diff --git a/app/src/main/res/layout/player_popup_notification.xml b/app/src/main/res/layout/player_popup_notification.xml index e8b077ecc..1aa767c58 100644 --- a/app/src/main/res/layout/player_popup_notification.xml +++ b/app/src/main/res/layout/player_popup_notification.xml @@ -83,6 +83,6 @@ android:focusable="true" android:padding="5dp" android:scaleType="fitCenter" - android:src="@drawable/ic_close_white_24dp" - tools:ignore="ContentDescription,RtlHardcoded"/> - \ No newline at end of file + app:srcCompat="@drawable/ic_close_white_24dp" + tools:ignore="ContentDescription,RtlHardcoded" /> + diff --git a/app/src/main/res/layout/toolbar_search_layout.xml b/app/src/main/res/layout/toolbar_search_layout.xml index 9a7d56a6e..74647e2e0 100644 --- a/app/src/main/res/layout/toolbar_search_layout.xml +++ b/app/src/main/res/layout/toolbar_search_layout.xml @@ -47,7 +47,7 @@ android:contentDescription="@string/search" android:scaleType="fitCenter" app:srcCompat="?attr/ic_close" - tools:ignore="RtlHardcoded"/> + tools:ignore="RtlHardcoded" /> - \ No newline at end of file + From caf7c55069804dce58b4be8e9df5b8211ae5ac78 Mon Sep 17 00:00:00 2001 From: wb9688 Date: Fri, 15 May 2020 15:05:20 +0200 Subject: [PATCH 027/137] Log only in debug build --- .../newpipe/player/NotificationUtil.java | 16 +++++-- .../player/helper/MediaSessionManager.java | 48 ++++++++++--------- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java index 62f25810b..d88a26b2f 100644 --- a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java +++ b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java @@ -75,7 +75,9 @@ public final class NotificationUtil { if (areOldNotificationsEnabled) { notificationBuilder = createOldPopupPlayerNotification(context, playerImpl); } else if (notificationBuilder == null || recreate) { - Log.d(TAG, "N_ recreatePopupPlayerNotification(true)"); + if (DEBUG) { + Log.d(TAG, "N_ recreatePopupPlayerNotification(true)"); + } notificationBuilder = createPopupPlayerNotification(context, mediaSessionCompatToken, playerImpl, sharedPreferences); } @@ -91,7 +93,9 @@ public final class NotificationUtil { if (areOldNotificationsEnabled) { notificationBuilder = createOldPopupPlayerNotification(context, playerImpl); } else if (notificationBuilder == null) { - Log.d(TAG, "N_ recreatePopupPlayerNotification()"); + if (DEBUG) { + Log.d(TAG, "N_ recreatePopupPlayerNotification()"); + } notificationBuilder = createPopupPlayerNotification(context, mediaSessionCompatToken, playerImpl, sharedPreferences); } @@ -105,7 +109,9 @@ public final class NotificationUtil { final boolean areOldNotificationsEnabled = sharedPreferences .getBoolean(context.getString(R.string.enable_old_notifications_key), false); if (notificationBuilder == null || recreate || areOldNotificationsEnabled) { - Log.d(TAG, "N_ recreateBackgroundPlayerNotification(true)"); + if (DEBUG) { + Log.d(TAG, "N_ recreateBackgroundPlayerNotification(true)"); + } notificationBuilder = createBackgroundPlayerNotification(context, mediaSessionCompatToken, basePlayerImpl, sharedPreferences); } @@ -119,7 +125,9 @@ public final class NotificationUtil { final boolean areOldNotificationsEnabled = sharedPreferences .getBoolean(context.getString(R.string.enable_old_notifications_key), false); if (notificationBuilder == null || areOldNotificationsEnabled) { - Log.d(TAG, "N_ recreateBackgroundPlayerNotification()"); + if (DEBUG) { + Log.d(TAG, "N_ recreateBackgroundPlayerNotification()"); + } notificationBuilder = createBackgroundPlayerNotification(context, mediaSessionCompatToken, basePlayerImpl, sharedPreferences); } diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/MediaSessionManager.java b/app/src/main/java/org/schabi/newpipe/player/helper/MediaSessionManager.java index d0939a914..3bb2965a2 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/MediaSessionManager.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/MediaSessionManager.java @@ -16,12 +16,14 @@ import androidx.media.session.MediaButtonReceiver; import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector; +import org.schabi.newpipe.BuildConfig; import org.schabi.newpipe.player.mediasession.MediaSessionCallback; import org.schabi.newpipe.player.mediasession.PlayQueueNavigator; import org.schabi.newpipe.player.mediasession.PlayQueuePlaybackController; public class MediaSessionManager { private static final String TAG = "MediaSessionManager"; + public static final boolean DEBUG = !BuildConfig.BUILD_TYPE.equals("release"); @NonNull private final MediaSessionCompat mediaSession; @@ -72,33 +74,35 @@ public class MediaSessionManager { return; } - if (getMetadataAlbumArt() == null) { - Log.d(TAG, "N_getMetadataAlbumArt: thumb == null"); - } - if (getMetadataTitle() == null) { - Log.d(TAG, "N_getMetadataTitle: title == null"); - } - if (getMetadataArtist() == null) { - Log.d(TAG, "N_getMetadataArtist: artist == null"); - } - if (getMetadataDuration() <= 1) { - Log.d(TAG, "N_getMetadataDuration: duration <= 1; " + getMetadataDuration()); + if (DEBUG) { + if (getMetadataAlbumArt() == null) { + Log.d(TAG, "N_getMetadataAlbumArt: thumb == null"); + } + if (getMetadataTitle() == null) { + Log.d(TAG, "N_getMetadataTitle: title == null"); + } + if (getMetadataArtist() == null) { + Log.d(TAG, "N_getMetadataArtist: artist == null"); + } + if (getMetadataDuration() <= 1) { + Log.d(TAG, "N_getMetadataDuration: duration <= 1; " + getMetadataDuration()); + } } if (getMetadataAlbumArt() == null || getMetadataTitle() == null || getMetadataArtist() == null || getMetadataDuration() <= 1 || albumArt.hashCode() != tmpThumbHash) { - Log.d(TAG, "setMetadata: N_Metadata update: t: " + title + " a: " + artist - + " thumb: " + albumArt.hashCode() + " d: " + duration); - mediaSession.setMetadata( - new MediaMetadataCompat.Builder() - .putString(MediaMetadataCompat.METADATA_KEY_TITLE, title) - .putString(MediaMetadataCompat.METADATA_KEY_ARTIST, artist) - .putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, albumArt) - .putBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON, albumArt) - .putLong(MediaMetadataCompat.METADATA_KEY_DURATION, duration) - .build() - ); + if (DEBUG) { + Log.d(TAG, "setMetadata: N_Metadata update: t: " + title + " a: " + artist + + " thumb: " + albumArt.hashCode() + " d: " + duration); + } + + mediaSession.setMetadata(new MediaMetadataCompat.Builder() + .putString(MediaMetadataCompat.METADATA_KEY_TITLE, title) + .putString(MediaMetadataCompat.METADATA_KEY_ARTIST, artist) + .putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, albumArt) + .putBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON, albumArt) + .putLong(MediaMetadataCompat.METADATA_KEY_DURATION, duration).build()); tmpThumbHash = albumArt.hashCode(); } } From 6de03f2bf0bf328fccf29bd7dd0d2407b0e1ed9b Mon Sep 17 00:00:00 2001 From: wb9688 Date: Fri, 31 Jul 2020 09:25:32 +0200 Subject: [PATCH 028/137] Fix crash when playing stream in background with shuffle in notification --- .../java/org/schabi/newpipe/player/NotificationUtil.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java index d88a26b2f..f1b8356a8 100644 --- a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java +++ b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java @@ -351,7 +351,7 @@ public final class NotificationUtil { } break; case "shuffle": - if (basePlayerImpl.playQueue.isShuffled()) { + if (basePlayerImpl.playQueue != null && basePlayerImpl.playQueue.isShuffled()) { builder.addAction(R.drawable.exo_controls_shuffle_on, "ShuffleOn", PendingIntent.getBroadcast(context, NOTIFICATION_ID_BACKGROUND, new Intent(BackgroundPlayer.ACTION_SHUFFLE), @@ -601,7 +601,7 @@ public final class NotificationUtil { } break; case "shuffle": - if (basePlayerImpl.playQueue.isShuffled()) { + if (basePlayerImpl.playQueue != null && basePlayerImpl.playQueue.isShuffled()) { notificationBuilder.mActions.set(slotNumber, new NotificationCompat.Action(R.drawable.exo_controls_shuffle_on, "ShuffleOn", PendingIntent.getBroadcast(context, @@ -835,7 +835,7 @@ public final class NotificationUtil { } break; case "shuffle": - if (playerImpl.playQueue.isShuffled()) { + if (playerImpl.playQueue != null && playerImpl.playQueue.isShuffled()) { builder.addAction(R.drawable.exo_controls_shuffle_on, "ShuffleOn", PendingIntent.getBroadcast(context, NOTIFICATION_ID_POPUP, new Intent(PopupVideoPlayer.ACTION_SHUFFLE), @@ -1080,7 +1080,7 @@ public final class NotificationUtil { } break; case "shuffle": - if (playerImpl.playQueue.isShuffled()) { + if (playerImpl.playQueue != null && playerImpl.playQueue.isShuffled()) { notificationBuilder.mActions.set(slotNumber, new NotificationCompat.Action(R.drawable.exo_controls_shuffle_on, "ShuffleOn", PendingIntent.getBroadcast(context, From baaf2815e4303c28bbf9e4e77521e56443a9c31d Mon Sep 17 00:00:00 2001 From: Artyom Date: Sat, 1 Aug 2020 02:46:43 +0000 Subject: [PATCH 029/137] Translated using Weblate (Russian) Currently translated at 100.0% (584 of 584 strings) --- app/src/main/res/values-ru/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 9d06e455d..10e8ef153 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -49,7 +49,7 @@ Папка для скачанного аудио Папка для скачанного аудио Введите путь к папке для скачивания аудио - Начните с поиска + Нажмите \"Поиск\", чтобы начать погружение в мир бесчисленного видеоконтента Подождите… Файл уже существует Потоки From b17a667a9d0216b400af097295eb59108c6d28c3 Mon Sep 17 00:00:00 2001 From: Laszlo Almasi Date: Sun, 2 Aug 2020 10:07:41 +0000 Subject: [PATCH 030/137] Translated using Weblate (Hungarian) Currently translated at 62.3% (364 of 584 strings) --- app/src/main/res/values-hu/strings.xml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 1dcfb9413..f631df591 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -388,4 +388,18 @@ Lejátszás folytatása Megjeleníti a videó bélyegképét a képernyőzáron, amikor a háttér lejátszó van használva Változtasd meg a letöltési helyet, hogy érvénybe lépjen + "Jelentés új NewPipe verzióról " + Alkalmazás-frissítés jelzése + File törölve + Frissítések + Tipp mutatása háttér vagy felbukkanó gomb megnyomásakor a videó részletei oldalon + Automatikus lejátszás + Adatok törlése + Lejátszási pozíciók mutatása a listákban + Pozíciók a listákban + Gesztusvezérlés használata hangerő és fényerő szabályzásra + Gesztusvezérlés használata fényerő szabályzásra + Fényerő gesztus + Gesztusvezérlés használata hangerő szabályzásra + Hangerő gesztus \ No newline at end of file From 2d8fd9bedf6fdf55f761a3b371d8fc65c59a5141 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sun, 2 Aug 2020 10:06:21 +0000 Subject: [PATCH 031/137] Translated using Weblate (Hungarian) Currently translated at 62.3% (364 of 584 strings) --- app/src/main/res/values-hu/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index f631df591..5d32e6824 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -105,7 +105,7 @@ Új küldetés Csatornáról leiratkozva Nem sikerült megváltoztatni a feliratkozást - "Nem sikerült frissíteni a feliratkozást " + Nem sikerült frissíteni a feliratkozást Főoldal Feliratkozások Könyvjelzőzött lejátszási listák @@ -131,7 +131,7 @@ Keresési előzmények Előzmények Megnézett videók nyomon követése - "Lejátszás folytatása félbeszakítás után (pl.: telefonhívás) " + Lejátszás folytatása félbeszakítás után (pl.: telefonhívás) Lejátszó Működés Előzmények és gyorsítótár From d77463c9f18ea71c3a0580b9874e51b62bb328a3 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sun, 2 Aug 2020 08:59:23 +0000 Subject: [PATCH 032/137] Translated using Weblate (German) Currently translated at 100.0% (584 of 584 strings) --- app/src/main/res/values-de/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 1902fff85..b88b502b3 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -617,7 +617,7 @@ Von %s Nur nicht gruppierte Abonnements anzeigen Playlist-Seite - Keine Playlist Bookmarks bis jetzt + Bisher keine Lesezeichen für Wiedergabelisten Playlist auswählen Bitte überprüfen Sie, ob es schon Fragen zu diesem Thema gibt. Doppelt erstellte Tickets kosten uns Zeit, die wir nutzen könnten, um diesen Fehler zu beheben. Zeige Ergebnisse für: %s From 3b719803bb1cf707d35a0947d965b87396520a41 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sun, 2 Aug 2020 10:14:00 +0000 Subject: [PATCH 033/137] Translated using Weblate (Hungarian) Currently translated at 72.9% (426 of 584 strings) --- app/src/main/res/values-hu/strings.xml | 57 +++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 5d32e6824..42d521061 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -388,7 +388,7 @@ Lejátszás folytatása Megjeleníti a videó bélyegképét a képernyőzáron, amikor a háttér lejátszó van használva Változtasd meg a letöltési helyet, hogy érvénybe lépjen - "Jelentés új NewPipe verzióról " + Jelentés új NewPipe verzióról Alkalmazás-frissítés jelzése File törölve Frissítések @@ -402,4 +402,59 @@ Fényerő gesztus Gesztusvezérlés használata hangerő szabályzásra Hangerő gesztus + A rendszer megkérdezi, hogy hova mentse el az egyes letöltéseket + Kérdezze meg, hova töltse le + Letöltések szüneteltetése + Letöltések indítása + Egyszerre egy letöltés fog futni ugyanabban az időben + Korlátozza a letöltési sort + Bezár + Hasznos, amikor átvált a mobil adatokra, bár néhány letöltést nem lehet felfüggeszteni + Megszakítás a mért hálózatokon + A letöltés megszakítása előtti kísérletek maximális száma + Maximális próbálkozások + Állj + %1$s letöltés törölve + Letöltött fájlok törlése + Törli a letöltési előzményeket, vagy törli az összes letöltött fájlt\? + Letöltési előzmények törlése + A letöltést nem lehet visszaállítani + Kapcsolat időtúllépés + A folyamat elveszett, mert a fájlt törölték + Nincs hely az eszközön + NewPipe leállt a fájl feldolgozása közben + Utófeldolgozás sikertelen + Nincs talalat + A szerver nem fogad többszálú letöltést, próbálkozzon újra @ string / msg_threads = 1 + A szerver nem küld adatokat + Nem lehet csatlakozni a szerverhez + A szerver nem talalható + Nem sikerült biztonságos kapcsolatot létesíteni + A rendszer megtagadta az engedélyt + A célmappa nem hozható létre + A fájlt nem lehet létrehozni + Kód + Hiba megjelenítése + Ezzel a névvel egy letötés már várakozás alatt áll + Ezzel a névvel egy letöltés már folyamatban van + Az ilyen névvel letöltött fájl már létezik + Az ilyen névű fájl már létezik + Átír + Generáljon egyedi nevet + %s letöltés kész + Letöltés kész + Letöltés sikertelen + Helyrehozás + Utófeldolgozás + Sorban álló + Szünet + Függőben lévő + Befejezett + Kattints a letöltéshez + NewPipe frissítés elérhető! + Nézet váltás + Auto + Rács + Lista + Lista nézet \ No newline at end of file From a5918c29ee82b981765ced1483882d42bc9ecbb9 Mon Sep 17 00:00:00 2001 From: Laszlo Almasi Date: Sun, 2 Aug 2020 10:08:08 +0000 Subject: [PATCH 034/137] Translated using Weblate (Hungarian) Currently translated at 72.9% (426 of 584 strings) --- app/src/main/res/values-hu/strings.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 42d521061..b5ef00e80 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -457,4 +457,11 @@ Rács Lista Lista nézet + File áthelyezve vagy törölve + Külső SD-kártyára mentés nem lehetséges. Visszaállítsuk a letöltési mappa helyét\? + Külső tárhely nem elérhető + Lejátszási pozíciók törölve. + Összes lejátszási pozíció törlése\? + Összes lejátszási pozíció törlése + Lejátszási pozíciók törlése \ No newline at end of file From a732233db6c519ebe1455b649debbb922146c767 Mon Sep 17 00:00:00 2001 From: Igor Nedoboy Date: Sat, 1 Aug 2020 17:33:58 +0000 Subject: [PATCH 035/137] Translated using Weblate (Russian) Currently translated at 100.0% (584 of 584 strings) --- app/src/main/res/values-ru/strings.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 10e8ef153..e1d667f99 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -49,7 +49,7 @@ Папка для скачанного аудио Папка для скачанного аудио Введите путь к папке для скачивания аудио - Нажмите \"Поиск\", чтобы начать погружение в мир бесчисленного видеоконтента + Нажмите \"Поиск\", чтобы начать Подождите… Файл уже существует Потоки @@ -121,7 +121,7 @@ Всё Фильтр Новая цель - Что:\\nЗапрос:\\nЯзык содержимого:\\nСтрана содержимого:\\nЯзык приложения:\\nСервис:\\nВремя по Гринвичу:\\nПакет:\\nВерсия:\\nВерсия ОС: + Что:\\nЗапрос:\\nЯзык контента:\\nСтрана контента:\\nЯзык приложения:\\nСервис:\\nВремя по Гринвичу:\\nПакет:\\nВерсия:\\nВерсия ОС: Это разрешение нужно для \nвоспроизведения в окне Открыть во всплывающем окне @@ -624,8 +624,8 @@ От %s Создано %s Миниатюра значка канала - Показывать только несгруппированные подписки - Вы ещё не добавили ни одного плейлиста в закладки + Только несгруппированные + Плейлистов ещё нет Пожалуйста, проверьте, существует ли вопрос по вашей ошибке. Создавая дубликаты, вы отнимаете у нас время, которое мы могли бы использовать на решение проблемы. Результаты для: %s Страница плейлиста From d5685f2255e8ad8dae5e883e13c92c2f904230bc Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sun, 2 Aug 2020 09:54:26 +0000 Subject: [PATCH 036/137] Translated using Weblate (Slovenian) Currently translated at 55.9% (327 of 584 strings) --- app/src/main/res/values-sl/strings.xml | 215 +++++++++++++++---------- 1 file changed, 132 insertions(+), 83 deletions(-) diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index c1cc8d963..c2d39e397 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -1,4 +1,4 @@ - + %1$s pogledov Objavljeno %1$s @@ -16,8 +16,8 @@ usmerjenost Uporabi zunanji predvajalnik videa Uporabi zunanji predvajalnik zvoka - Pot do mape za prejem videa - Pot do mape za prejem video datotek + Mapa z prenesenimi videi + Preneseni video so shranjeni tukaj Vpis poti za prejem videa Privzeta ločljivost Predvajaj s Kodi @@ -35,26 +35,21 @@ Sličica predogleda videa Sličica objavitelja Pokaži možnost predvajanja videa preko predstavnega središča Kodi - Všeč mi je Ni mi všeč Predvajanje v ozadju Predvajaj - Tema Temna Svetla - Videz Drugo Omrežna napaka - Uporabi Tor (Preizkusno) Vsili prenos prejema preko sistema Tor za povečanje zasebnosti (pretakanje videa ni še podprto). Pot do mape za prejem zvočnih datotek Pot do mape, ki je določena za prejem zvočnih datotek Vpis poti za prejem zvočnih datotek - Ni mogoče ustvariti mape za prejem \'%1$s\' Ustvarjena je mapa za prejem \'%1$s\' Napaka @@ -62,17 +57,11 @@ Ni mogoče odšifrirati podpisa naslova URL videa Ni mogoče razčleniti spletišča. Vsebina ni na voljo. - Ni mogoče nastaviti menija za prejem datotek. - - Posnetek je pretok v živo. Ta vrsta prenosa še ni podprta. - - Vsebina Pokaži starostno omejeno vsebino Starostna omejitev ogleda. Pred ogledom tovrstnih posnetkov, je treba ustrezno nastaviti omejitve. - Ni mogoče dokončno razčleniti spletišča. Ni mogoče pridobiti pretoka. Do te napake naj ne bi prišlo. @@ -82,8 +71,6 @@ Podrobnosti: Kaj se je zgodilo: Podrobnosi: - - Video Zvok Poskusi znova @@ -93,17 +80,13 @@ Predvaja vsebino, če je program zagnan iz drugega programa Pošlji poročilo o napaki Poročilo uporabnika - v živo - Začnite z iskanjem Začni Premor Predvajaj Izbriši Nadzorna vsota - - Ime datoteke Nizi Napaka @@ -115,68 +98,49 @@ Počakajte … Kopirano v odložišče. Izberite mapo za prejem. - Nova naloga V redu Prejemi Prejemi Poročilo o napaki - Slike ni mogoče naložiti Program se je sesul! Izziv reCAPTCHA Zahteva izziva reCAPTCHA - Predmet:\\nZahteva:\\nJezik vsebine:\\nStoritev:\\nČas v GMT:\\nPaket:\\nRazličica:\\nRazličica OS: Črna - Vse Kanal - - k mio mrd - Da Kasneje - - Odpri v pojavnem načinu Dovoljenje je zahtevano za odpiranje v pojavnem načinu - Pojavni način NewPipe - Predvajanje v pojavnem načinu Onemogočeno - Prednostni zapis video datoteke Privzeta ločljivost pojavnega okna Pokaži večje ločljivosti Predvajanje posnetkov 2K/4K omogočajo le nekatere naprave. - Ozadje Pojavno okno - Filter Osveži Počisti - Zapomni si položaj in velikost pojavnega okna Zapomni si položaj in velikost pojavnega okna - Pojavno okno Prilagajanje velikosti - Pri nekaterih ločljivostih bo posnetek brez zvoka, če je ta možnost omogočena Upravljanje predvajalnika s potezami Uporabi poteze za nadzor svetlosti in glasnosti predvajalnika Predlogi iskanja Pokaži predloge med iskanjem - -Najboljša ločljivost - + Najboljša ločljivost O programu Nastavitve O programu @@ -196,33 +160,24 @@ odpiranje v pojavnem načinu Kanal ni naročen Ni mogoče spremeniti naročnine Ni mogoče posodobiti naročnine - Glavno Naročnine - Kaj je novega - Prejmi Dovoljeni znaki v imenih datotek Neveljavni znaki so zamenjani z znakom Znak za zamenjavo - Črke in številke Večina posebnih znakov - Preišči zgodovino Iskalne poizvedbe shranjuj krajevno Zgodovina Sledi zgodovini predvajanih posnetkov Nadaljuj po prekinitvi Nadaljuj s predvajanjem po prekinitvi (na primer zaradi telefonskega klica) - - Obvestila NewPipe Obvestila predvajalnika NewPipe - Doprinos k projektu - Zgodovina Preiskano Predvajano @@ -230,47 +185,39 @@ odpiranje v pojavnem načinu Zgodovina Zgodovina je prazna! Zgodovina je počiščena - -Če imate odlične zamisli, predloge za prevode in oblikovne spremembe, izboljšave kode ali obvladate programiranje in bi želeli sodelovati, vedite, da je pomoč vedno dobrodošla! + Če imate odlične zamisli, predloge za prevode in oblikovne spremembe, izboljšave kode ali obvladate programiranje in bi želeli sodelovati, vedite, da je pomoč vedno dobrodošla! Predvajalnik Obnašanje Zgodovina Seznam predvajanja Razveljavi - Ni rezultatov iskanja Tu ni ničesar! - Ni naročnikov - %s naročnik - %s naročnika - %s naročniki - %s naročnikov - - + %s naročnik + %s naročnika + %s naročniki + %s naročnikov + Ni še zabeleženih ogledov - %s ogled - %s ogleda - %s ogledi - %s ogledov - - + %s ogled + %s ogleda + %s ogledi + %s ogledov + Ni posnetkov - %s video posnetek - %s video posnetka - %s video posnetkov - %s posnetkov - - + %s video posnetek + %s video posnetka + %s video posnetkov + %s posnetkov + Predmet je izbrisan -Ali želite izbrisati predmet iz zgodovine iskanja? -Predvajaj vse - + Ali želite izbrisati predmet iz zgodovine iskanja? + Predvajaj vse [ Neznano ] - Predvajanje pretoka je spodletelo Vsebina glavne strani Prazna stran @@ -291,30 +238,132 @@ odpiranje v pojavnem načinu Neveljaven naslov URL Prejmi datoteko pretoka. Pokaži podrobnosti - Zaznamki - Dodaj k - Razhroščevanje Vedno Le enkrat - Preklopi usmerjenost Preklopi na ozadje Preklopi na pojavno Preklopi na osnovno okno - Uvozi podatkovno zbirko Izvozi podatkovno zbirko Ni najdenega video pretoka Ni najdenega zvočnega pretoka - Ustvari Izbriši eno Izbriši vse Opusti Preimenuj - Naloži sličice - + Jezik aplikacije + Uporabi SAF + Vprašaj kam shraniti + Začasno ustavi prenašanja + Začni prenose + Naenkrat bo potekal en prenos + Zapri + Uporabno ko preklopite na mobilne podatke, četudi nekateri prenosi ne morejo biti začasno ustavljeni + Največje število poskusov pred preklicom prenosa + Izbriši prenesene datoteke + Želite počistiti zgodovino prenosov ali izbrisati vse prenose\? + Počisti zgodovino prenosa + Ni mogoče povrniti prenos + Napredek je izgubljen, ker je bila datoteka izbrisana + Ni več prostora v vaši napravi + NewPipe se je zaprl medtem ko je delal z datoteko + Ni najden + Strežnik ne pošilja informacij + Ni mogoče vspostaviti povezavo s strežnikom + Strežnika ni mogoče najti + Ni mogoče vspostaviti varne povezave + Sistem je zavrnil dovoljenje + Ni mogoče ustvariti datoteke + Koda + Prenesena datoteka s tem imenom že obstaja + Datoteka s tem imenom že obstaja + Ustvari edinstveno ime + %s prenosom je končanih + Prenos končan + Prenos spodletel + Pavza + Končano + Tapnite da prenesete + Seznam + Posodobitve + Sprejmi + Resetiraj + Ni mogoče izvoziti naročnine + Ni mogoče uvoziti naročnine + Prejšnji izvoz + Uvozi datoteko + Izvažanje… + Uvažanje… + Izvozi k + Uvozi iz + Uvozi + Uvozi/Izvozi + Omogoči LeakCanary + Povečaj + Napolni + Seznama predvajanja ni bilo mogoče izbrisati. + Seznam predvajanja je bil ustvarjen + Izbrišem seznam predvajanja\? + Dodaj v seznam predvajanja + Preimenuj + Izbriši + Nov seznam predvajanja + Nalaganje zahtevano vsebino + Pridobivanje podatkov… + Vedno vprašaj + Predvajalnik videa + Tu se bo kmalu nekaj pojavilo ;D + Začni igrati v ozadju + Najbolj všečkan + Dodano nedolgo nazaj + Lokalno + Jezik se bo spremenil po ponovnem zagonu aplikacije. + Ni mogoče naložiti komentarjev + Ni veljavne ZIP datoteke + Uvoženo + Izvoženo + Ni še nobene naročnine + Izbira + Najbolj igrano + Nazadnje igrano + Preberi pravilnik zasebnosti + NewPipe-ovi pravilnik zasebnosti + Obiščite spletno mesto od NewPipe za več informacij in novic. + Končano + Ni komantarjev + Nobeden ne posluša + Nobeden ne gleda + Zgodila se je napaka: %1$s + Ni take mape + Datoteka premaknjena ali izbrisana + Prenašanje na zunanjo SD kartico ni mogoče. Resetiram lokacijo mape z prenosi\? + Vsa zgodovina gledanja izbrisana. + Izbrišem vso zgodovino gledanja\? + Izbriši zgodovino gledanja + Izvozi zgodovino, naročnine in sezname predvajanja + Obvestila posodobitve aplikacije + Datoteka + Datoteka izbrisana + Uporabniki + Seznami predvajanja + Kanali + Posodobitve + Samo HTTPS URL-ji so podprti + Prikaži namig \"Drži za dodajanje\" + Počisti podatke + Pozicija v seznamih + Avtomatsko predvajaj naslednji video + Izbriši shranjene metapodatke + Predshramba za slike je bila izbrisana + Prikaži komentar + Izberi Zavihek + Nov Zavihek + Odjava + Predvajalnika pretoka ni mogoče najti (namestite lahko VLC program za predvajanje). + \ No newline at end of file From f0fb55640e7fa42efb7474eceeb255d162ea3412 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sun, 2 Aug 2020 10:15:34 +0000 Subject: [PATCH 037/137] Translated using Weblate (Romanian) Currently translated at 69.5% (406 of 584 strings) --- app/src/main/res/values-ro/strings.xml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 2d08addb9..581964a6c 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -407,4 +407,19 @@ pentru a deschide în mod pop-up Salvează playlist-ul Activează LeakCanary Limitați rezoluția când folosiți date mobile + Acordă permisiunea de a afișa peste alte aplicații + Ștergeți toate pozițiile din playback\? + Șterge toate pozițiile din playback + Videoclipuri + Instanța există deja + Doar adresele URL HTTPS sunt suportate + Nu sa putut valida instanța + Introdu adresa URL a instanței + Adaugă instanță + Găsește instanța care îți place în %s + Selectează instanța preferată PeerTube + Instanțe PeerTube + Durată redare-înainte/derulare + O miniatură a videoclipului apare pe ecran blocare când folosești redarea pe fundal + Miniatură pentru ecran blocare \ No newline at end of file From 7fc5a77e7e9056cd5ffac81a3ea06cb6e557f4d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Fri, 31 Jul 2020 05:06:45 +0000 Subject: [PATCH 038/137] Translated using Weblate (Turkish) Currently translated at 99.6% (582 of 584 strings) --- app/src/main/res/values-tr/strings.xml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index bc4808f59..14ca044ae 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -69,7 +69,7 @@ Bildir Bilgi: Ne oldu: - Ne:\\nİstek:\\nİçerik Dili:\\nHizmet:\\nGMT Zamanı:\\nPaket:\\nSürüm:\\nİşletim sistemi sürümü: + Ne:\\nİstek:\\nİçerik Dili:\\nİçerik Ülkesi:\\nUygulama Dili:\\nHizmet:\\nGMT Zamanı:\\nPaket:\\nSürüm:\\nİşletim sistemi sürümü: Videoyu oynat, süre: Yükleyicinin avatar küçük resmi Beğeni @@ -378,7 +378,7 @@ NewPipe projesi, gizliliğinizi çok ciddiye alıyor. Bu nedenle, uygulama sizin izniniz olmadan herhangi bir veri toplamaz. \nNewPipe\'ın gizlilik ilkesi, çökme raporu gönderdiğinizde hangi verilerin gönderildiğini ve saklandığını ayrıntılı olarak açıklar. Gizlilik ilkesini oku - Avrupa Genel Veri Koruma Yönetmeliğine (GDPR) uymak için, dikkatinizi NewPipe\'ın gizlilik ilkesine çekiyoruz. Lütfen dikkatlice okuyun. + Avrupa Genel Veri Koruma Yönetmeliğine (GDPR) uymak için, dikkatinizi NewPipe\'ın gizlilik ilkesine çekiyoruz. Lütfen dikkatlice okuyun. \nBize hata bildirimini göndermek için kabul etmelisiniz. Kabul et Reddet @@ -614,4 +614,9 @@ %s tarafından oluşturuldu Kanalın avatar küçük resmi Yalnızca kümelenmemiş abonelikleri göster + Oynatma listesi sayfası + Oynatma listesi seç + Hatayı GitHub\'da bildir + Biçimlendirilmiş raporu kopyala + Sonuçlar gösteriliyor: %s \ No newline at end of file From 7911b7e6376b4b4c71ef6776a5a9c38a69e052a5 Mon Sep 17 00:00:00 2001 From: WaldiS Date: Fri, 31 Jul 2020 10:09:38 +0000 Subject: [PATCH 039/137] Translated using Weblate (Polish) Currently translated at 100.0% (584 of 584 strings) --- app/src/main/res/values-pl/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 461bcfe2c..3526313f0 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -625,7 +625,7 @@ Miniatura awatara kanału Pokaż tylko niezgrupowane subskrypcje Strona playlisty - Nie ma jeszcze zakładek list odtwarzania + Nie ma jeszcze zakładek do playlist Wybierz playlistę Sprawdź, czy problem dotyczący Twojej awarii już istnieje. Tworząc zduplikowane wpisy, zajmujesz nam czas, który możemy poświęcić na naprawienie rzeczywistego błędu. Zgłoś błąd na GitHub From e160a1f794259bb47b826f61cddfcc6d66de0667 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sun, 2 Aug 2020 09:29:30 +0000 Subject: [PATCH 040/137] Translated using Weblate (Armenian) Currently translated at 12.8% (75 of 584 strings) --- app/src/main/res/values-hy/strings.xml | 31 ++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/app/src/main/res/values-hy/strings.xml b/app/src/main/res/values-hy/strings.xml index 083796907..73060075b 100644 --- a/app/src/main/res/values-hy/strings.xml +++ b/app/src/main/res/values-hy/strings.xml @@ -1,4 +1,4 @@ - + Սեղմեք որոնման կոճակը որ սկսել Որոնել @@ -18,8 +18,6 @@ Այո Ջնջել Սկսել - - Հավանում եմ Չեմ հավանում Մաքրել @@ -29,4 +27,29 @@ Վերացնել Բացել բրաուզերում Ընտրեք բրաուզերը - + Ձայնային բեռնման պանակ + Ընտրեք ներբեռնման թղթապանակը տեսաֆայլերի համար + Ներբեռնված տեսաֆայլերը պահվում են այստեղ + Տեսանյութի ներբեռնման պանակ + Ավելացնել + Թռուցիկ + Ետին պլան + Ընտրեք ներդիր + Նոր էջանշան + Էջանշված երգացանկեր + Բաժանորդագրումները + Հիմնական + Ցուցադրել տեղեկույթը + Հնարավոր չէ թարմացնել բաժանորդագրումը + Հնարավոր չէ փոխել Բաժանորդագրումը + Չեղարկել բաժանորդագրման հեռացումը + Բաժանորդագրման հեռացու + Բաժանորդագրվել + Հառացնում է ձայնը որոշ լուծաչափերոկմ + Դիրք + Կիսվել + Բեռնել հոսքի նշքը + Բացել լողացող պատուհանում + Նվագարկիչ չի գտնվել (դուք կարող եք լբեռնել VLC և դիտել)։ + Նվագարկիչ չի գտնվել, ցանկանո՞ւմ եք բեռնել VLC։ + \ No newline at end of file From 433485470eecbfa8440bdcd1317eef25cd0886be Mon Sep 17 00:00:00 2001 From: ktln Date: Sun, 2 Aug 2020 09:26:56 +0000 Subject: [PATCH 041/137] Translated using Weblate (Armenian) Currently translated at 12.8% (75 of 584 strings) --- app/src/main/res/values-hy/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-hy/strings.xml b/app/src/main/res/values-hy/strings.xml index 73060075b..40a39f6bb 100644 --- a/app/src/main/res/values-hy/strings.xml +++ b/app/src/main/res/values-hy/strings.xml @@ -52,4 +52,6 @@ Բացել լողացող պատուհանում Նվագարկիչ չի գտնվել (դուք կարող եք լբեռնել VLC և դիտել)։ Նվագարկիչ չի գտնվել, ցանկանո՞ւմ եք բեռնել VLC։ + Օգտագործել արտաքին աուդիո նվագարկիչ + Օգտագործել արտաքին դերակատար \ No newline at end of file From 212fddd8e1c72b19dd92f61d184f37f5ac568fd0 Mon Sep 17 00:00:00 2001 From: Kim Nyberg Date: Fri, 31 Jul 2020 16:36:44 +0000 Subject: [PATCH 042/137] Translated using Weblate (Swedish) Currently translated at 98.2% (574 of 584 strings) --- app/src/main/res/values-sv/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 23be5276b..7f9526abc 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -594,4 +594,8 @@ Inget utrymme kvar på enhet NewPipe stängdes under arbete med en fil Tillåtelse nekat av systemet + Vänligen kontrollera om en felrapport som tar upp din krasch redan finns. Att skapa ärenden när en felrapport redan finns, tar av den tid som vi annars kunde ha ägnat åt att fixa den faktiska buggen. + Rapportera fel på GitHub + Kopiera formaterad felrapport + Visar resultat för: %s \ No newline at end of file From 3b46d5a440dcb815231058d4e389469caaccf1db Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sun, 2 Aug 2020 10:04:24 +0000 Subject: [PATCH 043/137] Translated using Weblate (Catalan) Currently translated at 85.2% (498 of 584 strings) --- app/src/main/res/values-ca/strings.xml | 42 +++++++++++++++++++++----- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index d77c6a63a..71c1e1020 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -38,7 +38,7 @@ Contingut Desactiva les restriccions per edat Mostra el vídeo restringit per edat. Podeu permetre aquesta mena de continguts des dels paràmetres. - EN DIRECTE + Directe Baixades Baixades Tot @@ -123,7 +123,7 @@ Comparteix-ho amb rotació Reproductor de vídeo extern - Mode emergent del NewPipe + Mode emergent Heu eliminat la subscripció a aquest canal No s\'ha pogut modificar la subscripció No s\'ha pogut actualitzar la subscripció @@ -140,13 +140,13 @@ Mostra resolucions superiors No tots els dispositius són compatibles amb la reproducció de vídeos en 2K/4K Reprodueix amb el Kodi - No s\'ha trobat l\'aplicació Kodi. Voleu instal·lar-la\? + No s\'ha trobat l\'aplicació Kore. Voleu instal·lar-la\? Mostra «Reprodueix amb el Kodi» Mostra una opció per reproduir un vídeo amb el centre multimèdia Kodi Reproductor emergent intel·ligent Recorda la darrera mida i posició del reproductor emergent Cerca ràpida poc precisa - La cerca poc precisa permet que el reproductor cerqui una posició més ràpidament amb menys precisió + La cerca poc precisa permet que el reproductor cerqui una posició més ràpidament amb menys precisió. Cerques de 5, 15 o 25 segons no hi funcionaran. Carrega les miniatures S\'ha eliminat la memòria cau d\'imatges Elimina les metadades de la memòria cau @@ -193,7 +193,7 @@ S\'ha produït un error: %1$s Informeu de l\'error per correu electrònic S\'han produït alguns errors. - INFORME + Informe Informació: Què ha passat: Comentari (en anglès): @@ -205,7 +205,7 @@ No m\'agrada Fes servir el Tor (En proves) Força el trànsit de baixada a través del Tor per a més privadesa (no compatible encara amb les emissions de vídeo). - Notifiqueu un error + Notifiqueu error Informe de l\'usuari Cap resultat No hi ha res aquí @@ -274,7 +274,7 @@ Controls de la velocitat de reproducció Tempo To - Feu un toc al botó de cerca per començar + Toca \"Cercar\" per començar Elimina l\'àudio en algunes resolucions Reproductor d\'àudio extern Desactiveu-ho per no generar miniatures i estalviar dades i memòria. Canviant aquesta opció, s\'eliminarà la memòria cau d\'imatges tant de la memòria com de l\'emmagatzematge. @@ -505,8 +505,34 @@ Cap reproducció %s escoltant - %s escoltant + %s escoltants Es canviarà la llengua en reiniciar l\'aplicació. Tendències + Ensenya el temps passat original sobre els \"items\" + Auto-generat (no es troba cap uploader) + Desactivar Silenci + Silenciar + Prem \"Fet\" quan estigui resolt + ∞ vídeos + 100+ vídeos + Dona permís per mostrarse per sobre d\'altres apps. + Ajuda + Artistes + Albums + Cançons + Vídeos + Aquest vídeo té una restricció per edat. +\n +\nSi desitges visualitzar-lo, activa el «Contingut restringit per edat» en la configuració. + Mode de restricció del YouTube + La instància introduïda ja existeix + Només estàn soportades URLs HTTPS + No ha estat possible validar la instància + Introdueix l\'enllaç d\'una instància + Afegeix-hi una instància + Troba les instàncies que t\'agraden en %s + Selecciona les teves instàncies preferides del PeerTube + Instàncies del PeerTube + Avançar/-rebobinar duració cerca \ No newline at end of file From b11fa7a28ed0bb8dd513e22b1db70777406a4107 Mon Sep 17 00:00:00 2001 From: ButterflyOfFire Date: Mon, 3 Aug 2020 11:04:34 +0000 Subject: [PATCH 044/137] Translated using Weblate (Kabyle) Currently translated at 6.5% (38 of 584 strings) --- app/src/main/res/values-kab/strings.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/src/main/res/values-kab/strings.xml b/app/src/main/res/values-kab/strings.xml index 98d8d8edc..b2ded59ac 100644 --- a/app/src/main/res/values-kab/strings.xml +++ b/app/src/main/res/values-kab/strings.xml @@ -1,4 +1,16 @@ Iccer amaynut + Tavidyutt akked d imesli + Γef + Γef + Amaynut + Akk + Sbedd asnas n Kore yexxuṣen\? + Sbedd + %s n isidar id yeffuken + Asider + Isidar + Isidar + Iɣewwaṛen \ No newline at end of file From 1a8ff8108709f15228712ad2942919d5c38662fa Mon Sep 17 00:00:00 2001 From: wb9688 Date: Mon, 3 Aug 2020 14:17:12 +0200 Subject: [PATCH 045/137] Use AppCompatImageButton to not crash on 4.4 --- app/src/main/res/layout-large-land/player.xml | 2 +- app/src/main/res/layout/player.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/layout-large-land/player.xml b/app/src/main/res/layout-large-land/player.xml index 9db51df26..3fa187906 100644 --- a/app/src/main/res/layout-large-land/player.xml +++ b/app/src/main/res/layout-large-land/player.xml @@ -465,7 +465,7 @@ android:layout_height="60dp" android:id="@+id/playQueueControl"> - - From 05b8c3f35f89cc2175411ab4e216138214574306 Mon Sep 17 00:00:00 2001 From: Selyan Sliman Amiri Date: Mon, 3 Aug 2020 17:10:58 +0000 Subject: [PATCH 046/137] Translated using Weblate (Kabyle) Currently translated at 31.1% (182 of 584 strings) --- app/src/main/res/values-kab/strings.xml | 150 ++++++++++++++++++++++++ 1 file changed, 150 insertions(+) diff --git a/app/src/main/res/values-kab/strings.xml b/app/src/main/res/values-kab/strings.xml index b2ded59ac..c2391dcf7 100644 --- a/app/src/main/res/values-kab/strings.xml +++ b/app/src/main/res/values-kab/strings.xml @@ -13,4 +13,154 @@ Isidar Isidar Iɣewwaṛen + Akter… + Tulya n telɣut… + Iɣewwaṛen + Awurman + Afaylu + Semɣeṛ + Tabdert n tɣuri + Iberdan + Nniḍen + Tallalt + Susem + Yal tikelt + Timeẓri + Agejdan + Seḥbes + Isem n ufaylu + Nadi + Bdu + Seṛǧu + ɣer + Tuɣdaṭ tamaynut + 100+Tividyutin + Jerred + Sifeḍ ɣer + Rnu ɣer + Azdam immed + Fren iminig + Amecwaṛ + Ih + Azdam n NewPipe + Err-d imezwar + Yerna-t %s + Kkes tabdart-a n tɣuri\? + Sfeḍ + Ittwarna taggara-agi + Amasal n imesli amezwer + Agbur n usebter agejdan + + %d n tesdat + %d n tesdatin + + Ffeɣ seg ujerred + Tabdert n tɣuri tamaynut + Tiddin + Fren tabdert n tɣuri + Kkes yiwen + Sken-d tuccḍa + ɣer + + %d i yettwafren + %d i yettwafernen + + Ibuda + Srid + Aččar + Nadi amazray + Imesli + Sefsex + Kkes + Mdel + Ticki + Tidyanin + Ulac iwenniten + Isem + Isedγiten + Ameẓlu + Isem + Yettraǧu + Iɣewwaren n umeslaw + Sermed imesli + Tuccḍa + Iẓiki + Imzizdig + Immed + Adigan + Immed + Wennez + Snulfu-d + Qbel + Kkes + D acu-t umaynut + Sken talɣut + Ittwarermed + Imesli + Iselkinen + Tangalt + Afaw + Sider + Asfaylu udhim + Ttu + A + Kter + Ih + Kkes akk + Amazray + Liste + Iseqdacen + Sfeḍ isefka + Ulac + Aḍris yettwanγel γef afus + Tibdarin n tɣuri + Aneggaru yettwaslekmen + Taɣuri tawurmant + Aneqqis + Sismeḍ + Sider + Tuccḍa + Iɛǧeb-iyi + Tiddin + Imɛiwnen + Eɛreḍ tikkelt-nniḍen + Talqayt + Agbur + Ubrik + Taɣuri tawurmant + S %s + Kkes + Ulac talast + Écraser + Ulac igmad + Sefex + Ttekki + Ijerriden + Asmel web + Agwi + Beqqeḍ iwenniten + Ɣer zdat + Ameɣri + Isaragen + Isedγiten + Tafrant + Asentel + Ubrik + Bḍu + Tawsa + Débugger + Threads + Pas + Amezwer n unagraw + Snifel isem + Nnal akken ad tessidreḍ + Asfaylu udhim + Asider ur yeddi ara + Tamwalit + o + Aɣawas n deffir + Amazray + Asteεfu + Snifel isem + Tividyutin \ No newline at end of file From b9cb65b24eb275b75dde64f099a4895f825f65d6 Mon Sep 17 00:00:00 2001 From: ButterflyOfFire Date: Thu, 6 Aug 2020 11:44:08 +0000 Subject: [PATCH 047/137] Translated using Weblate (Kabyle) Currently translated at 31.5% (184 of 584 strings) --- app/src/main/res/values-kab/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-kab/strings.xml b/app/src/main/res/values-kab/strings.xml index c2391dcf7..b0195ec9c 100644 --- a/app/src/main/res/values-kab/strings.xml +++ b/app/src/main/res/values-kab/strings.xml @@ -163,4 +163,6 @@ Asteεfu Snifel isem Tividyutin + Ldi deg uminig + %1$s n tmeẓriyin \ No newline at end of file From 50b2fad1805bd44934c05651513e8853fe8c6b34 Mon Sep 17 00:00:00 2001 From: Terry Louwers Date: Mon, 3 Aug 2020 07:30:43 +0000 Subject: [PATCH 048/137] Translated using Weblate (Dutch) Currently translated at 100.0% (584 of 584 strings) --- app/src/main/res/values-nl/strings.xml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index ca4539a60..3ccf96670 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -84,7 +84,7 @@ Foutrapport Kan afbeelding niet laden App/UI gecrasht - Wat:\\nVerzoek:\\nTaal van inhoud:\\nDienst:\\nTijd in GMT:\\nPakket:\\nVersie:\\nVersie van besturingssysteem: + Wat:\\nVerzoek:\\nTaal van inhoud:\\nTaal van land:\\nTaal van Applicatie:\\nDienst:\\nTijd in GMT:\\nPakket:\\nVersie:\\nVersie van besturingssysteem: Meld een probleem Gebruikersrapport Geef eerst toegang tot de opslag @@ -483,7 +483,7 @@ Er is al een download met deze naam bezig Geen ruimte meer op het apparaat Voortgang verloren, omdat bestand was verwijderd - Wil je je downloadgeschiedenis wissen of alle gedownloade bestanden verwijderen\? + Wilt u de downloadgeschiedenis of alle gedownloade bestanden verwijderen\? Limiteer de download wachtrij Er zal maximaal 1 bestand tegelijk worden gedownload Download starten @@ -613,4 +613,12 @@ De avatar-miniatuur van het kanaal Door %s Gecreëerd door %s + Afspeellijst pagina + Toon enkel ongegroepeerde abonnementen + Geen afspeellijst bookmarks + Selecteer een afspeellijst + Controleer of er al een probleem bestaat dat uw crash beschrijft. Wanneer u dubbele tickets aanmaakt, neemt dit tijd van ons in beslag die we beter kunnen besteden aan het oplossen van het daadwerkelijke probleem. + Foutmelding in GitHub rapporteren + Kopieer opgemaakt rapport + Gevonden resultaten voor: %s \ No newline at end of file From 6b5c37f17f7ba626b18e3099cae22d8cfedc46fe Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sun, 2 Aug 2020 15:49:17 +0000 Subject: [PATCH 049/137] Translated using Weblate (Greek) Currently translated at 83.2% (486 of 584 strings) --- app/src/main/res/values-el/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index ed5a6b299..46133d24b 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -519,4 +519,7 @@ Μικρογραφίας βίντεο στην οθόνη κλειδώματος Χρήση μικρογραφίας βίντεο στην οθόνη κλειδώματος Διάρκεια fastforward και rewind + Προεπιλογή συστήματος + Βίντεο + Εμφάνιση αποτελεσμάτων για: \ No newline at end of file From 5379cf05444873c4b99baa8976696d271b61c9d0 Mon Sep 17 00:00:00 2001 From: karnak2016 Date: Wed, 5 Aug 2020 15:33:20 +0000 Subject: [PATCH 050/137] Translated using Weblate (Ukrainian) Currently translated at 98.9% (578 of 584 strings) --- app/src/main/res/values-uk/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 20e9dbde1..9c17ad41e 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -622,4 +622,9 @@ Ескіз аватара каналу Оригінальні тексти сервісів будуть видимі в потокових елементах Режим обмеженого доступу YouTube + Результати для: %s + Створено %s + Показати лише незгруповані підписки + Скопіювати відформатований звіт + Повідомити про помилку на GitBub \ No newline at end of file From 701c87eefa7af5e6086da74b3df534cbc16c5cc2 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sun, 2 Aug 2020 15:58:49 +0000 Subject: [PATCH 051/137] Translated using Weblate (Ukrainian) Currently translated at 98.9% (578 of 584 strings) --- app/src/main/res/values-uk/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 9c17ad41e..8eca0dfb7 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -627,4 +627,8 @@ Показати лише незгруповані підписки Скопіювати відформатований звіт Повідомити про помилку на GitBub + Перевірте, будь ласка, чи проблема що спричинила збій вже відома спільноті та розробникам. Дублюючи запити на вирішення помилок Ви забираєте час розробників який можна було б так на вирішення існуючих проблем. + Вибрати плейліст + Жоден плейліст ще не додано + Сторінка плейлісту \ No newline at end of file From f9f84cbd890548cedfc50a602e481f0c556050aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emin=20Tufan=20=C3=87etin?= Date: Tue, 4 Aug 2020 14:49:17 +0000 Subject: [PATCH 052/137] Translated using Weblate (Turkish) Currently translated at 100.0% (584 of 584 strings) --- app/src/main/res/values-tr/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 14ca044ae..c32341c33 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -619,4 +619,6 @@ Hatayı GitHub\'da bildir Biçimlendirilmiş raporu kopyala Sonuçlar gösteriliyor: %s + Lütfen yaşadığınız hatayı tartışan bildirimin daha önce oluşturulup oluşturulmadığını gözden geçirin. Yineleyen hata bildirimi oluşturarak, gerçek hatayı gidermekte harcadığımız zamanı uzatırsınız. + Henüz oynatma listesi yer imleri yok \ No newline at end of file From b7ac16c7d950c941817eb4a9615eec7c507f55bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20Carvalho=20de=20Ara=C3=BAjo?= Date: Mon, 3 Aug 2020 18:14:33 +0000 Subject: [PATCH 053/137] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (584 of 584 strings) --- app/src/main/res/values-pt-rBR/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index e96e61c75..5beb0cf66 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -615,7 +615,7 @@ Capa do avatar do canal Mostrar apenas inscrições não agrupadas Mostrando resultados para\? %s - Ainda não há playlists favoritas + Ainda não há favoritos de playlists Página da playlist Selecione uma playlist Verifique se já existe um assunto discutindo essa falha. Criar duplicatas tirará um tempo que poderíamos gastar corrigindo o bug real. From 3a6f87659aa1274a0d7cbd15cf9fe69438f84bcd Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sun, 2 Aug 2020 15:47:41 +0000 Subject: [PATCH 054/137] Translated using Weblate (Armenian) Currently translated at 13.0% (76 of 584 strings) --- app/src/main/res/values-hy/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-hy/strings.xml b/app/src/main/res/values-hy/strings.xml index 40a39f6bb..1268c5630 100644 --- a/app/src/main/res/values-hy/strings.xml +++ b/app/src/main/res/values-hy/strings.xml @@ -54,4 +54,5 @@ Նվագարկիչ չի գտնվել, ցանկանո՞ւմ եք բեռնել VLC։ Օգտագործել արտաքին աուդիո նվագարկիչ Օգտագործել արտաքին դերակատար + Լողացող ռեժիմ NewPipe \ No newline at end of file From 767ac6a51b097bc374c3e00c3cd43b6f69f5c777 Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Sun, 2 Aug 2020 14:23:48 +0000 Subject: [PATCH 055/137] Translated using Weblate (Hebrew) Currently translated at 100.0% (584 of 584 strings) --- app/src/main/res/values-he/strings.xml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index 0ac642b19..4777daf75 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -97,7 +97,7 @@ דיווח מידע: מה קרה: - מה:\\nבקשה:\\nשפת התוכן:\\nשירות:\\nשעון גריניץ׳:\\nחבילה:\\nגרסה:\\nגרסת מערכת ההפעלה: + מה:\\nבקשה:\\nשפת התוכן:\\nמדינת התוכן:\\nשפת היישומון:\\nשירות:\\nשעון גריניץ׳:\\nחבילה:\\nגרסה:\\nגרסת מערכת ההפעלה: עריכת מינוי נרשמת ביטול מינוי לערוץ @@ -634,4 +634,11 @@ נוצר ע״י %s תמונה ממוזערת של הערוץ להציג רק מינויים שאינם בקבוצות + עמוד רשימת נגינה + אין עדיין סימניות ברשימת הנגינה + בחירת רשימת נגינה + נא לבדוק אם כבר קיים דיווח על הקריסה שלך. יצירת דיווחים כפולים גוזלת מאתנו זמן שיכולנו להשקיע בתיקון התקלה עצמה. + דיווח על שגיאה ב־GitHub + העתקת דוח מעוצב + מוצגות תוצאות עבור: %s \ No newline at end of file From ad72c64e329927be8c1fc552224e1e92986e702b Mon Sep 17 00:00:00 2001 From: Kim Nyberg Date: Tue, 4 Aug 2020 11:33:52 +0000 Subject: [PATCH 056/137] Translated using Weblate (Swedish) Currently translated at 98.6% (576 of 584 strings) --- app/src/main/res/values-sv/strings.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 7f9526abc..2c0f16972 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -134,7 +134,7 @@ Allvarligt spelarfel inträffade Återhämtar sig från spelarfel Rapportera detta fel via e-post - Vad:\\nBegäran:\\nInnehållsspråk:\\nTjänst:\\nGMT Tid:\\nPaket:\\nVersion:\\nOS-version: + Vad:\\nBegäran:\\nInnehållsspråk:\\nInnehållsland:\\nApp-språk:\\nTjänst:\\nGMT-tid:\\nPaket:\\nVersion:\\nOS-version: Videons miniatyrbild Spela video, längd: Uppladdarens avatar miniatyrbild @@ -598,4 +598,5 @@ Rapportera fel på GitHub Kopiera formaterad felrapport Visar resultat för: %s + Välj en spellista \ No newline at end of file From 244e95d959840c9b7e71dfe69ee11dda00d83372 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sun, 2 Aug 2020 15:49:43 +0000 Subject: [PATCH 057/137] Translated using Weblate (Telugu) Currently translated at 23.9% (140 of 584 strings) --- app/src/main/res/values-te/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-te/strings.xml b/app/src/main/res/values-te/strings.xml index 1f2fd4ce1..0e8136ab0 100644 --- a/app/src/main/res/values-te/strings.xml +++ b/app/src/main/res/values-te/strings.xml @@ -184,4 +184,5 @@ డిఫాల్ట్ పాపప్ స్పష్టత ప్రసార ఫైల్ను డౌన్లోడ్ చేయండి బాహ్య వీడియో ప్లేయర్ని ఉపయోగించండి + కొన్ని రెసొల్యూషన్స్ లో ఆడియో తీసేస్తుంది \ No newline at end of file From 24fe8fe9a04d3c6945c0d92c408bab20735de4ae Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sun, 2 Aug 2020 15:46:12 +0000 Subject: [PATCH 058/137] Translated using Weblate (Azerbaijani) Currently translated at 10.2% (60 of 584 strings) --- app/src/main/res/values-az/strings.xml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml index bf3b0f3f2..caca40862 100644 --- a/app/src/main/res/values-az/strings.xml +++ b/app/src/main/res/values-az/strings.xml @@ -1,5 +1,6 @@ - -Başlamaq üçün axtarışa bas + + + Başlamaq üçün axtarışa bas %1$s baxış Dərc edilib %1$s Axın oynadıcısı tapılmadı. VLC ni yükləmək istərdinizmi? @@ -22,22 +23,17 @@ Abunə olunub Kanal Məlumat göstər - Əsas Abunəliklər Əlfəcinlər - Yeni nə var - Arxa fon Video yükləmə ünvanı Yüklənən videoları saxlamaq üçün yer Videolar üçün yükləmə yerini daxil et - Audio yükləmə yeri Yüklənən audioları saxlamaq üçün yer Audiolar üçün yükləmə yerini daxil et - NewPipe başqa bir uyğulamadan çağrıldığı zaman avtomatik olaraq videonu oynadır Defolt ölçü Daha böyük ölçüləri göstər @@ -52,4 +48,8 @@ Açıq Qaranlıq Qara - + Abunəlik ləğvi + Açılan pəncərə + Fırlanma + Açılan pəncərə modunda aç + \ No newline at end of file From f0a51d4ab4f6efaca5abffa1cbab8e57b048972b Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sun, 2 Aug 2020 15:56:42 +0000 Subject: [PATCH 059/137] Translated using Weblate (Belarusian) Currently translated at 77.7% (454 of 584 strings) --- app/src/main/res/values-be/strings.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index fbd7a99c0..fe827f7ba 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -496,4 +496,11 @@ Выкарыстоўваць SAF Storage Framework Access дазваляе захоўваць файлы на вонкавым назапашвальніку. \nПадтрымліваецца не ўсімі прыладамі + Пераключыць службу, выбраную ў дадзены момант: + Выдаліць ўсе пазіцыі прайгравання + Абмежаваны рэжым YouTube + Падтрымліваюцца толькі адрасы URL HTTPS + Дадаць інстанцыю + Інстанцыі PeerTube + Змяніце папкі загрузкі, каб змены ўступілі ў сілу \ No newline at end of file From 02bcbc3221a16d5d57a50ac9c8b0bb25c22e2a0c Mon Sep 17 00:00:00 2001 From: Deleted User Date: Tue, 4 Aug 2020 12:57:42 +0000 Subject: [PATCH 060/137] Translated using Weblate (Malay) Currently translated at 72.0% (421 of 584 strings) --- app/src/main/res/values-ms/strings.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-ms/strings.xml b/app/src/main/res/values-ms/strings.xml index 1944877f8..ee8165071 100644 --- a/app/src/main/res/values-ms/strings.xml +++ b/app/src/main/res/values-ms/strings.xml @@ -21,7 +21,7 @@ Guna pemain video luaran Menghapus audio pada SESETENGAH resolusi Gunakan pemain audio luaran - Mod popup NewPipe + Mod popup Langgan Dilanggan Langganan saluran dihenti @@ -49,7 +49,7 @@ Resolusi utama Resolusi popup utama Papar resolusi yang lebih tinggi - Hanya peranti tertentu yang mampu bermain video 2K/4K + Hanya peranti tertentu yang boleh bermain video 2K/4K Main dengan Kodi App Kore tidak dijumpai. Pasangkan\? Paparkan opsyen \"Main dengan Kodi\" @@ -459,4 +459,5 @@ Menunggu Ubah folder muat turun untuk melihat kesan Dayakan lakaran kecil video skrin kunci + Menunjuk carian untuk: %s \ No newline at end of file From fb7035bf22bc6e260af18d1579fde670c7321975 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rebolo=20Magari=C3=B1os?= Date: Wed, 5 Aug 2020 23:01:30 +0000 Subject: [PATCH 061/137] Translated using Weblate (Galician) Currently translated at 100.0% (584 of 584 strings) --- app/src/main/res/values-gl/strings.xml | 477 +++++++++++++++++-------- 1 file changed, 322 insertions(+), 155 deletions(-) diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 8450d60c8..ed1ac7180 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -1,59 +1,54 @@ - -Toque em «Procurar» para comezar + + + Toque en \"Buscar\" para comezar %1$s visualizacións Publicado o día %1$s - Non foi encontrado ningún reprodutor. Desexa instalar o VLC? - Non foi encontrado ningún reprodutor (pode instalar o VLC para o reproducir) + Non foi encontrado ningún reprodutor. Quere instalar o VLC\? + Non foi encontrado ningún reprodutor (pode instalar o VLC para o reproducir). Instalar Cancelar Abrir no navegador Abrir no modo popup Compartillar Descarregar - Descarregar o ficheiro de emisión. + Descargar o ficheiro de transmisión Procurar Opcións - Non querería dicir «%1$s»? + Non querería dicir %1$s\? Compartillar con Escoller un navegador rotación Usar un reprodutor de vídeo externo - Podería NON haber audio con algunhas resolucións se esta opción estiver activa + Elimina o audio con algunhas resolucións Usar un reprodutor externo de audio - Modo popup do NewPipe + Modo xurdir de repente do NewPipe Subscribir Subscrito Xa non está subscrito ao canal - Non foi posíbel modificar a subscrición - Non foi posíbel actualizar a subscrición + Non se pode modificar a subscrición + Non se pode actualizar a subscrición Mostrar información - Principal Subscricións - Favoritos - + Listas de reprodución marcadas Novidades - Segundo plano Modo popup Engadir a - - Ruta de descarga de vídeos - Ruta onde gardar os vídeos descarregados - Introduza a ruta de descarga de vídeos - - Ruta de descarga de audio - Ruta onde gardar o audio descarregado - Introduza a ruta de descarga dos ficheiros de audio - + Cartafol de descargas para os vídeos + Os vídeos descargados están almacenados aquí + Elixa un cartafol de descargas para os vídeos + Cartafol de descarga de audio + Os audios descargados están gardados aquí + Elixa un cartafol para descargar os audios Reproducir automaticamente Reproducir o vídeo pedido cando o NewPipe sexa invocado por outro aplicativo Resolución predeterminada Resolución predeterminada do popup Mostrar resolucións máis altas - Moitos dispositivos non permiten reproducir vídeos en 2K/4K + Só algúns dispositivos poden reproducir vídeos en 2K/4K Reproducir co Kodi - O aplicativo Kore non foi encontrado. Desexa instalalo? + Quere instalar o aplicativo Kore que falta\? Mostrar a opción «Reproducir co Kodi» Mostrar unha opción para reproducir o vídeo co Kodi Media Center Audio @@ -66,38 +61,38 @@ Lembrar o tamaño e a posición do «popup» Lembrar o tamaño e a posición anteriores do «popup» Usar un salto inexacto mais inexacto - O salto inexacto permite saltar a posicións máis rápido, mais con menos precisión + Busca incorrecta permite ao xogador buscar posicións máis rápidas con precisión reducida. A busca de 5, 15 ou 25 segundos non funciona con isto. Carregar miniaturas - Desactíveo para evitar a carga de miniaturas e poupar datos e memoria. Modificar esta opción limpa a caché de imaxes da memoria e do disco + Desactíveo para evitar a carga de miniaturas e poupar datos e memoria. Modificar esta opción limpa a caché de imaxes da memoria e do disco. A caché de imaxes foi limpada Os metadatos da caché foron eliminados Eliminar todos os datos de páxinas en caché Os metadatos da caché foron eliminados Colocar a seguinte emisión na cola automaticamente - Engadir automaticamente unha emisión ao reproducir a última emisión nunha cola sen repetición + Continúa rematando (non se repite) a cola de reprodución engadindo unha transmisión relacionada Controis de xesto do reprodutor - Usar xestos para controlar o brillo e volume do reprodutor + Use xestos para controlar o brillo e o volume do reprodutor Suxestións de procura Mostrar suxestións ao procurar Historial de procura Gardar os termos de pesquisa localmente - Historial e caché + Ver o historial Gardar historial de vídeos vistos - Retormar o vídeo ao enfocar - Continuar a reprodución após interrupcións (como chamadas) + Retormar o vídeo reproducíndoo + Continuar reproducindo o vídeo despois das interrupcións (como, por exemplo, as chamadas) Descarregar - Vídeo seguinte - Mostrar vídeos «seguintes» e «semellantes» - Mostrar a suxestión «Manteña presionado para engadir á cola» - Mostrar unha suxestión ao premer o botón de segundo plano ou o de popup na páxina de detalles do vídeo - Este URL non está soportado + Seguinte + Mostrar vídeos \"seguintes\" e \"semellantes\" + Mostrar a suxestión \"Manteña presionado para engadir á cola\" + Amosar o consello ao premer o fondo ou o botón emerxente \"Detalles:\" no vídeo + URL non soportado País predeterminado para o contido Servizo Reprodutor Comportamento - Vídeo e audio - Historial e caché - Popup + Vídeo & audio + Historial & caché + Xurdir Aparencia Outros Depuración @@ -107,9 +102,9 @@ Na cola do reprodutor popup Reproducir Contido - Mostrar contido con restrición de idade - Vídeo con restrición de idade. Pode permitir a reprodución deste material nas Opcións. - en directo + Contido restrinxido para certa idade + Mostrar vídeo restrinxido por idade. Os cambios futuros son posibles na configuración. + En directo Descargas Descargas Relatorio de erro @@ -133,28 +128,24 @@ Sempre Só unha vez Ficheiro - Notificación do NewPipe - Notificacións para o NewPipe e os reprodutores «popup» - + Notificacións para os reprodutores de fondo e reprodutores emerxentes de NewPipe [Descoñecido] - Mudar a orientación Mudar para o segundo plano Mudar para o «popup» Mudar para principal - Importar base de datos Exportar base de datos - Isto vai sobreescribir o seu historial e as súas subscricións actuais + Anula o teu historial e subscricións actuais Exportar historial, subscricións e listas de reprodución Limpar historial de reproducións - Elimina o historial de emisións reproducidas - Elimina todo o historial de reproducións. + Elimina o historial de transmisións reproducidas e as posicións da reprodución + Eliminar todo o historial de reproducións\? O historial de reproducións foi eliminado. Limpar o historial de procura Elimina o historial de termos procurados - Elimina todo o historial de procura. + Eliminar todo o historial de procura\? O historial de procuras foi eliminado. Erro Erro de rede @@ -162,10 +153,9 @@ Non foi posíbel descifrar a asinatura do vídeo Non foi posíbel procesar o sitio web Non foi posíbel procesar o sitio web por completo - O contido non está dispoñíbel -\n + Contido non dispoñíbel Non foi posíbel configurar o menú de descargas - Isto é unha emisión en directo, polo que aínda non está soportado. + Isto é unha emisión en directo, polo que aínda non está soportado Non foi posíbel obter unha emisión Non foi posíbel carregar a imaxe O aplicativo pechouse @@ -176,67 +166,57 @@ URL inválido Non foi encontrada ningunha emisión de vídeo Non foi encontrada ningunha emisión de audio - Directorio inválido - A fonte do ficheiro ou contido é inválida - O ficheiro non existe ou non ten permisos suficientes para o ler ou escribir - O nome do ficheiro non pode estar vacío + Non hai ningún cartafol + Non hai ningún ficheiro / fonte de contido + O ficheiro non existe ou falta permiso para lelo ou escribilo + O nome do ficheiro non pode estar baleiro Ocorreu un erro: %1$s Non hai emisións para descargar - Deculpe, isto non debería ter acontecido. - Informar do erro por correo electrónico + Informar deste erro por enderezo electrónico Desculpe, ocorreron algúns erros. - Relatorio + Informe Información: Que ocorreu: - Problema:\\nPetición:\\nIdioma do contido:\\nServizo:\\nHora GMT:\\nPaquete:\\nVersión:\\nVersión do SO: + Que: \\n Solicitar: \\n Idioma de contido: \\n País de contido: \\n Idioma do aplicativo: \\nServicio: \\n Tempo GMT: \\n Paquete: \\n Versión: \\n versión de nOS: O teu comentario (en inglés): Detalles: - - Miniatura do vídeo - Miniatura do vídeo + Reproducir o vídeo, duración: Miniatura do avatar do autor Gosto Non gosto Usar o Tor (Experimental) Redirixir o tráfico polo Tor para aumentar a privacidade (as emisións aínda non están soportadas). - Informar dun erro + Informe do erro Relatorio do usuario Non hai resultados - Nada que ver + Nada que ver aquí Arrastre para reordenar - Non foi posíbel crear o directorio «%1$s» O directorio de descargas «%1$s» foi creado - Vídeo Audio Tentar de novo - A permisión de acceso ao almacenamento foi denegada - - K + Outorga primeiro o acceso ao almacenamento + k M - MM - + B Ningún subscrito - %s subscrito - %s subscritos - - + %s subscrito + %s subscritos + Ningunha visualización - %s visualización - %s visualizacións - - + %s visualización + %s visualizacións + Ningún vídeo - %s vídeo - %s vídeos - - + %s vídeo + %s vídeos + Comezar Pausar Reproducir @@ -247,38 +227,31 @@ Suma de comprobación Descartar Renomear - Nova misión OK - Nome do ficheiro Fios Erro - O servidor non está soportado + Servidor non soportado O ficheiro xa existe O URL está mal formado ou a Internet non está dispoñíbel Descarga do NewPipe Toque para ver detalles Por favor, agarde… Copiado para o portarretallos - Por favor, seleccione o directorio para descargas + Selecciona un cartafol de descarga máis tarde na configuración Esta permisión é necesaria \npara abrir o vídeo no modo «popup» 1 elemento foi eliminado. - Desafío reCAPTCHA - Desafío reCAPTCHA solicitado - + ReCAPTCHA reto solicitado Descarregar Caracteres permitidos nos nomes de ficheiros Os caracteres inválidos serán substituídos por este valor Carácter de substitución - Letras e díxitos A maioría dos caracteres especiais - Non hai ningún aplicativo instalado para reproducir este ficheiro - Sobre o NewPipe Opcións Sobre @@ -294,7 +267,7 @@ Se ten ideas de tradución, mudanzas ao deseño, limpeza de código ou mudanzas serias deste—a axuda sempre é benvida. Canto máis fixermos, tanto máis vai mellorar! Ver no GitHub Doar - O NewPipe é desenvolvido por voluntarios que empregan o seu tempo libre para lle ofrecer a mellor experiencia. Pode retribuír e así axudar os desenvolvedores a tornaren o NewPipe aínda mellor en canto desfrutan dunha cunca de café. + NewPipe é desenvolvido por voluntarios que pasan o seu tempo libre para brindarte a mellor experiencia de usuario. Regresa aos desenvolvedores para que NewPipe sexa aínda mellor mentres gozan dunha cunca de café. Retribuír Sitio web Visite o sitio web do NewPipe para saber máis e ver noticias sobre o proxecto. @@ -303,14 +276,12 @@ \nA política de privacidade do NewPipe explica con máis detalle que datos son enviados e gardados cando envía un relatorio de erros. Ler a política de privacidade Licenza do NewPipe - O NewPipe é software copyleft libre: pode usalo, estudalo, compartillalo e melloralo como quixer. En concreto, pode redistribuílo e/ou modificalo so os termos da Licenza Pública Xeral GNU, publicada pola Free Software Foundation, quer a versión 3 da Licenza, ou calquera outra versión posterior da súa escolla. + NewPipe é un software libre copyleft: Podes usar, estudar compartir e melloralo a vontade. En concreto, pode redistribuír e / ou modificala segundo os termos da Licenza Pública Xeral GNU publicada pola Free Software Foundation, xa sexa a versión 3 da licenza, ou (na súa opción) calquera outra versión posterior. Ler a licenza - - Historial Procurado Visto - O historial está desactivado + A historia está desactivada Historial O historial está vacío O historial foi limpado @@ -320,7 +291,6 @@ Ten a certeza de querer eliminar todos os elementos do historial? Última reprodución Máis reproducido - Contido da páxina principal Páxina en branco Páxina do «kiosk» @@ -328,94 +298,74 @@ Páxina da fonte Páxina do canal Seleccione un canal - Non subscribiu ningún canal + Non se subscribiu a ningunha canle aínda Seleccione un «kiosk» - Exportación completa - Importación completada + Exportado + Importado Ficheiro ZIP inválido Aviso: non todos os ficheiros foron importados. Isto vai reescribir a súa configuración actual. Desexa importar tamén as opcións? - - Kiosk + Quiosco Tendencias Top 50 Novo e popular - Reprodutor en segundo plano - Reprodutor «popup» + Reprodutor de fondo + Reprodutor emerxente Eliminar Detalles Opcións de audio - Manteña para colocar na cola - Colocar na cola de segundo plano - Colocar na cola de popup + Manteña para colocalo na cola + Colocar na cola en segundo plano + Executa nunha xanela emerxente Comezar a reprodución aquí - Comezar aquí en segundo plano - Comezar aquí en popup - + Comezar a reproducir en segundo plano + Comezar reproducindo nunha xanela emerxente Abrir o menú Fechar o menú Algo vai xurdir aquí en breve ;D - - Acción «abrir» preferida Acción predeterminada ao abrir o contido — %s - Reprodutor de vídeo Reprodutor en segundo plano Reprodutor en popup Preguntar sempre - Obtendo información… Carregando o contido solicitado - - Crear unha nova lista de reprodución - Eliminar a lista de reprodución - Renomear a lista de reprodución + Nova lista de reprodución + Eliminar + Renomear Nome Engadir á lista de reprodución Estabelecer como miniatura da lista de reprodución - Gardar a lista de reprodución nos marcadores Eliminar o marcador - - Desexa eliminar esta lista de reprodución? + Eliminar esta lista de reprodución\? A lista de reprodución foi creada - O vídeo foi engadido á lista de reprodución - A miniatura da lista de reprodución foi modificada - Non foi posíbel eliminar a lista de reprodución - + Lista de reprodución + A miniatura da lista de reprodución foi modificada. + Non foi posíbel eliminar a lista de reprodución. Sen lenda - Axustar Encher Zoom - Xerado automaticamente - Lenda - Modificar a escala de texto da lenda e os estilos de segundo plano do reprodutor. Para ter efecto, é preciso reiniciar o aplicativo - - Activar LeakCanary + Modificar a escala de texto da lenda e os estilos de segundo plano do reprodutor. Para ter efecto, é preciso reiniciar o aplicativo. + LeakCanary A monitorización de fugas de memoria pode facer que o aplicativo deixe de responder cando hai vertedura da pila - - Informar de erros de fóra do ciclo de vida + Informar de erros fóra do ciclo de vida Forzar a comunicación de excepcións Rx non entregábeis fóra do ciclo de vida do fragmento ou actividade após o descarte - - Importar/Exportar + Importar/exportar Importar Importar de Exportar a - Importando… Exportando… - Importar un ficheiro Exportación anterior - Non foi posíbel importar as subscricións Non foi posíbel exportar as subscricións - Pode importar as súas subscricións de YouTube descarregando o ficheiro de exportacións: \n \n1. Acceda ao URL %1$s @@ -428,30 +378,247 @@ \n3. Inicie a sesión cando lle for solicitado \n4. Copie o URL de perfil a que foi redirixido. oseuID, soundcloud.com/oseuid - Teña en conta que esta operación pode consumir moitos recursos de rede. \n \nDesexa continuar? - Controis de velocidade da reprodución - Tempo + A tempo Ton - Desvincular (pode causar distorsión) + Desactivar (pode causar distorsións) Avanzar rápido durante os momentos de silencio Paso Reiniciar - Para cumprirmos co Regulamento Xeral Europeo de Protección de Datos (GDPR), chamamos a súa atención sobre a nova política de privacidade do NewPipe. Por favor, léao con coidado. \nDebe aceptalo para nos enviar un relatorio de erro. Aceptar Recusar - Sen límite Limitar a resolución ao usar datos móbiles - Minimizar ao mudar de aplicativo - Acción ao mudar de aplicativo desde o reprodutor orixinal — %s + Minimizar cando se mude de aplicativo + Acción ao cambiar a outro aplicativo do reprodutor de vídeo principal -% s Ningunha Minimizar ao reprodutor en segundo plano Minimizar o reprodutor popup - - + Limitado + Só son compatibles os URLs HTTPS + Control xestual do volume + Desactíveo para agochar os comentarios + Retomar a reprodución + Páxina das listas de reprodución + Por %s + Creado por %s + Miniatura do avatar da canle + NewPipe aínda non é compatible con este contido. +\n +\nCon toda esperanza será compatible cunha futura versión. + Cres que a carga de alimentación é demasiado lenta\? En caso afirmativo, intente habilitar a carga rápida (pode cambiala na configuración ou premendo o botón a continuación). +\n +\nNewPipe ofrece dúas estratexias de carga de fontes: +\n• Obtendo toda a canle de subscrición, que é lenta pero completa. +\n• Usar un punto final de servizo dedicado, rápido pero normalmente non completo. +\n +\nA diferenza entre ambos é que o rápido normalmente carece de información, como a duración ou o tipo do elemento (non pode distinguir entre os vídeos en directo e os normais) e pode devolver menos elementos. +\n +\nYouTube é un exemplo dun servizo que ofrece este método rápido coa súa fonte RSS. +\n +\nDe modo que a elección redúcese ao que prefires: velocidade ou información precisa. + Desactivar o modo rápido + Activa o modo rápido + Dispoñible nalgúns servizos, normalmente é moito máis rápido pero pode devolver unha cantidade limitada de elementos e moitas veces información incompleta (por exemplo, sen duración, tipo de elemento, sen estado en directo). + Obtén unha transmisión dedicada cando estea dispoñible + Sempre actualizado + Tempo despois da última actualización antes de que se subscriba unha subscrición -% s + Limiar da actualización das fontes + Transmisión + Amosar só as subscricións non agrupadas + Novo + Quere eliminar este grupo\? + Nome + Nome do grupo vacío + + %d seleccionado + %d seleccionados + + Non se seleccionou ningunha subscrición + Seleccionar subscricións + Procesando a transmisión… + Cargando transmisión… + Non se cargou:% d + Actualizada a última información:% s + Grupos da canle + + %d día + %d días + + + %d hora + %d horas + + + %d minuto + %d minutos + + + %d segundo + %d segundos + + Debido ás restricións de ExoPlayer, a duración da busca estableceuse en% d segundos + Si, e visualizou parcialmente estes vídeos + Eliminaranse os vídeos vistos antes e despois de seren engadidos á lista de reprodución. +\nEstás seguro\? Isto non se pode desfacer.! + Borrar todos os vídeos vistos\? + Eliminar o visto + Sistema predeterminado + Lingua do aplicativo + Elixir unha instancia + O \'Framework Access Framework\' permite a descarga a unha tarxeta SD externa. +\nAlgúns dispositivos son incompatibles + Usar SAF + Preguntaralle onde gardar cada descarga. +\nEscolla SAF se o desexa descargar nunha tarxeta SD externa + Preguntaralle onde gardar cada descarga + Pregunta onde se descarga + Parar as descagas + Comezar as descargas + Executarase unha descarga ao mesmo tempo + Limitar a cola de descarga + Pechar + Útil para cambiar aos datos móbiles, aínda que non se poden suspender algunhas descargas + Interrupción en redes contadas + Número máximo de intentos antes de cancelar a descarga + Reintento máximo + Parar + Eliminar %1$d descargas + Eliminar os ficheiros descargados + Quere limpar o seu historial de descargas ou eliminar todos os ficheiros descargados\? + Borrar o historial de descargas + Non se pode recuperar esta descarga + O tempo de espera da conexión + Perdeuse o progreso porque se eliminou o ficheiro + Non queda espazo no dispositivo + NewPipe pechouse mentres se traballaba no ficheiro + Fallou o post-procesamento + Non se atopou + O servidor non acepta descargas múltiples con fíos e tente con @ string / msg_threads = 1 + O servidor non envía datos + Non se pode conectar ao servidor + Non se puido atopar o servidor + Non se puido establecer unha conexión segura + Permiso denegado polo sistema + Non se pode crear o cartafol de destino + Non se puido crear este ficheiro + Código + Amosar o erro + Hai unha descarga pendente con este nome + Hai unha descarga en curso con este nome + Non se pode sobreescribir este ficheiro + Xa existe un ficheiro descargado con este nome + Xa existe un ficheiro con este nome + Sobreescribir + Xera un nome único + rematáronse %s descargas + Rematou a descarga + Fallou a descarga + Acción denegada polo sistema + En cola + recuperando + post-procesamento + en cola + pausado + Pendente + Rematado + Prema para descargar + A actualización de NewPipe está dispoñible! + Cambiar a vista + Automático + Amosar indicadores de posición de reprodución en listas + Use xestos para controlar o brillo do reprodutor + Rede + Lista + Modo de visualización da lista + Amosar unha notificación para solicitar a actualización do aplicativo cando unha nova versión estea dispoñible + Actualizacións + Os textos orixinais dos servizos serán visibles nos elementos do fluxo + Amosar o tempo orixinal anterior nos elementos + Xerado automaticamente (non se atopou ningún cargador) + Non silenciar + Silenciar + 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 + Quiosco predeterminado + Selección + Que lapelas se amosan na páxina principal + Feito + Prema \"Feito\" cando o resolva + Ningún comentario + ∞ vídeos + +100 vídeos + + %s oínte + %s oíntes + + Ninguén está escoitando + + %s vendo + %s véndoos + + Ninguén está vendo + Non hai dispoñible conta de subscritores + Cambiar o servizo actualmente seleccionado: + Verifique se xa existe un problema que fala do seu fallo. Ao crear billetes duplicados, gasta o tempo que nós poderiamos gastar en solucionar o erro real. + Informar dun erro en GitHub + Copia o informe con formato + Dar permiso para mostrar noutros aplicativos + Quere restaurar os valores predeterminados\? + Restaurar os valores predeterminados + Non se puideron ler as pestanas gardadas, polo que usar as predeterminadas + Ficheiro movido ou eliminado + Non é posible descargar na tarxeta SD externa. Restaurar a localización do cartafol de descarga\? + Non hai dispoñible almacenamento externo + Axuda + Elimináronse as posicións de reprodución. + Eliminas todas as posicións de reprodución\? + Elimina todas as posicións de reprodución + Elimina as posicións de reprodución + Notificacións para a nova versión de NewPipe + Notificación da actualización do aplicativo + Ficheiro eliminado + Artistas + Álbumes + Cancións + Eventos + Vídeos + Este vídeo está restrinxido por idade. +\n +\nSe desexa visualizalo, habilite \"Contido restrinxido por idade\" nos axustes. + Modo restrinxido de YouTube + Actualizacións + A instancia xa existe + Non se puido validar a instancia + Introduza o URL da instancia + Engadir instancia + Atopar as instancias que lle gustan en %s + Selecciona as instancias favoritas de PeerTube + Instancias de PeerTube + Idioma do contido predeterminado + Reprodución automática + Eliminar datos + Posicións nas listas + Restaurar a última posición de reprodución + Control do xesto de brillo + Use xestos para controlar o volume do reprodutor + Amosar comentarios + Duración da busca rápida cara a adiante / cara atrás + Na pantalla de bloqueo móstrase unha miniatura de vídeo cando se usa o reprodutor de fondo + Miniatura do vídeo de pantalla de bloqueo + Cambie os cartafoles de descarga para facer efecto + Elixir lapela + Nova lapela + Darse de baixa + Amosando resultados para: %s + \ No newline at end of file From f815ae5973319761ed6e6a1a20914a4721873c96 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Sun, 2 Aug 2020 15:53:32 +0000 Subject: [PATCH 062/137] Translated using Weblate (Filipino) Currently translated at 11.1% (65 of 584 strings) --- app/src/main/res/values-fil/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/main/res/values-fil/strings.xml b/app/src/main/res/values-fil/strings.xml index d52b1f4b9..54af24c74 100644 --- a/app/src/main/res/values-fil/strings.xml +++ b/app/src/main/res/values-fil/strings.xml @@ -42,4 +42,9 @@ Pumili ng folder kung saan ido-download ang mga bidyo Nakaimbak sa folder na ito ang mga nai-download na mga audio files Pumili ng folder kung saan ido-download ang mga audio files + Maliwanag + Buksan gamit Kodi + Madilim + Palitan ang folder na paglalagyan ng download para umipekto + Dito makikita ang mga nadownload na video \ No newline at end of file From 1b3f3cedb349a85e1eb6036a3f20fa93c0399913 Mon Sep 17 00:00:00 2001 From: BenjaminForster Date: Sun, 2 Aug 2020 15:45:05 +0000 Subject: [PATCH 063/137] Translated using Weblate (Afrikaans) Currently translated at 4.6% (27 of 584 strings) --- app/src/main/res/values-af/strings.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-af/strings.xml b/app/src/main/res/values-af/strings.xml index a6b3daec9..3db41ae26 100644 --- a/app/src/main/res/values-af/strings.xml +++ b/app/src/main/res/values-af/strings.xml @@ -1,2 +1,5 @@ - \ No newline at end of file + + Geen stream-speler gevind nie. Installeer VLC\? + Tik op \"Soek\" om aan die gang te kom + \ No newline at end of file From 05a83beb447e0c215db4e7aab3b370c42c60ad34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Sun, 9 Aug 2020 07:56:59 +0000 Subject: [PATCH 064/137] =?UTF-8?q?Translated=20using=20Weblate=20(Norwegi?= =?UTF-8?q?an=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 88.1% (515 of 584 strings) --- app/src/main/res/values-nb-rNO/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index 6adb1c9f8..0904b28f5 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -65,7 +65,7 @@ Kunne ikke tolke nettside fullstendig Innholdet er utilgjengelig Kunne ikke sette opp nedlastingsmeny - Direktesendinger støttes ikke ennå + Direktesendinger støttes ikke enda Kunne ikke finne noen strømmer Beklager, dette skal ikke skje. Rapporter feil via e-post @@ -427,7 +427,7 @@ Rutenett Auto Veksle visning - NewPipe-oppdatering tilgjengelig! + Ny NewPipe-versjon tilgjengelig. Trykk for å laste ned Fullført pauset From 45ae05f1b511156c5c4332df18d0da1fc272adef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Mon, 10 Aug 2020 11:08:11 +0000 Subject: [PATCH 065/137] =?UTF-8?q?Translated=20using=20Weblate=20(Norwegi?= =?UTF-8?q?an=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 88.3% (516 of 584 strings) --- app/src/main/res/values-nb-rNO/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index 0904b28f5..53efdc1d3 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -101,7 +101,7 @@ Trykk for detaljer Vent… Kopiert til utklippstavle - Hva:\\nForespørsel:\\nInnholdsspråk:\\nTjeneste:\\nGMT-tid:\\nPakke:\\nVersjon:\\nOperativsystemsversjon: + Hva:\\nForespørsel:\\nInnholdsspråk:\\nInnholdsland:\\nProgramspråk:\\nTjeneste:\\nGMT-tid:\\nPakke:\\nVersjon:\\nOS-versjon: Start Nytt mål Feilaktig nettadresse eller manglende internettilknytning From e693d80857a2084cd63d6b426f6330191dbdb2a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Marques?= Date: Wed, 12 Aug 2020 01:30:16 +0200 Subject: [PATCH 066/137] Added translation using Weblate (Portuguese (Portugal)) --- app/src/main/res/values-pt-rPT/strings.xml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 app/src/main/res/values-pt-rPT/strings.xml diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml new file mode 100644 index 000000000..a6b3daec9 --- /dev/null +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file From 1e7504dc5aee4e4a2f0159670855998b48f965f4 Mon Sep 17 00:00:00 2001 From: Hakim Oubouali Date: Fri, 14 Aug 2020 10:14:05 +0200 Subject: [PATCH 067/137] Added translation using Weblate (Berber) --- app/src/main/res/values-ber/strings.xml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 app/src/main/res/values-ber/strings.xml diff --git a/app/src/main/res/values-ber/strings.xml b/app/src/main/res/values-ber/strings.xml new file mode 100644 index 000000000..a6b3daec9 --- /dev/null +++ b/app/src/main/res/values-ber/strings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file From 68555573ad4fa54faeddf1839b2cb62d631a6ca6 Mon Sep 17 00:00:00 2001 From: Juraj Liso Date: Thu, 13 Aug 2020 22:24:15 +0000 Subject: [PATCH 068/137] Translated using Weblate (Slovak) Currently translated at 97.9% (572 of 584 strings) --- app/src/main/res/values-sk/strings.xml | 59 +++++++++++++------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 3352c81f8..7fc42ccbf 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -62,7 +62,7 @@ Prehrá video pri zavolaní NewPipe inou aplikáciou Obsah Vekovo obmedzený obsah - Toto video je vekovo obmedzené. Povoľte zobrazenie obsahu v nastavení. + Zobrazit video s vekovým obmezením. Zmenit túto voľbu môžete v nastaveniach. Naživo Nemožno kompletne zanalyzovať web Nemožno nastaviť menu preberania @@ -105,7 +105,7 @@ Hlásenie o chybe Nemožno načítať obrázok Aplikácia/UP zlyhalo - Čo:\\nPožiadavka:\\nJazyk obsahu:\\nSlužba:\\nČas v GMT:\\nBalík:\\nVerzia:\\nVerzia OS: + Čo:\\nPožiadavka:\\nJazyk obsahu:\\nKrajina Obsahu:\\nJazyk Aplikácie:\\nSlužba:\\nČas v GMT:\\nBalík:\\nVerzia:\\nVerzia OS: Výzva reCAPTCHA Čierna Všetko @@ -218,7 +218,7 @@ Uložené zoznamy Pridať do Zobrazovať tip \"Pridať podržaním\" - Zobraziť tip pre stlačenie tlačidiel \"Pozadie\" alebo \"V okne\" na stránke videa + Zobraziť tip pre stlačenie tlačidiel \"Pozadie\" alebo \"V okne\" v detailoch videa Predvolený obsah pre krajinu Služba Pridané do zoznamu prehrávača na pozadí @@ -252,7 +252,7 @@ Aplikácia NewPipe je vyvíjaná dobrovoľníkmi vo voľnom čase. Ak sa vám aplikácia páči, odmeňte vývojárov aby mohli NewPipe naďalej vylepšovať. Určite ich poteší napríklad šálka dobrej kávy. Daruj Webstránka - "Pre viac informácií a noviniek navštívte webstránku NewPipe." + Pre viac informácií a noviniek navštívte webstránku NewPipe. Chcete odstrániť túto položku z histórie vyhľadávania? Chcete odstrániť túto položku z histórie pozretých videí? Ste si istý, že chcete vymazať všetky položky z histórie? @@ -342,10 +342,8 @@ Nahlásiť mimo-cyklické chyby Vynútiť hlásenie výnimiek nedoručiteľných Rx mimo časového cyklu fragmentov alebo aktivity po zneškodnení Import/export - Import -\n - Importovať z -\n + Import + Importovať z Exportovať do Importovanie… Exportovanie… @@ -353,18 +351,17 @@ Predchádzajúci export Nemožno importovať odbery Nemožno exportovať odbery - Import odberov služby YouTube pomocou exportovaného zoznamu + Import odberov služby YouTube pomocou exportovaného zoznamu \n \n1. Prejdite na túto adresu URL: %1$s \n2. Po výzve sa prihláste do svojho účtu -\n3. Sťahovanie by malo začať (to je exportovaný zoznam) -\n - "Importovať SoundCloud profil zadaním URL adresy alebo vášho ID: +\n3. Sťahovanie by malo začať (to je exportovaný zoznam) + Importovať SoundCloud profil zadaním URL adresy alebo vášho ID: \n -\n1. Prepnite režim na \"desktop\" (web nie je dostupný pre mobilné zariadenia) +\n1. Prepnite režim na \"desktop\" (web nie je dostupný pre mobilné zariadenia) \n2. Prejdite na túto URL adresu: %1$s -\n3. Po výzve sa prihláste do svojho účtu -\n4. Skopírujte adresu URL, na ktorú ste boli presmerovaní. " +\n3. Po výzve sa prihláste do svojho účtu +\n4. Skopírujte adresu URL, na ktorú ste boli presmerovaní. vašeID, soundcloud.com/vašeid Operácia môže byť náročná na počet prenesených dát. \n @@ -372,7 +369,7 @@ Ovládanie rýchlosti prehrávania Rýchlosť Výška - Spomalenie (môže spôsobovať skreslenie) + Spraviť nezavislími (môže spôsobovať skreslenie) Vymazať históriu pozretí Odstráni históriu a pozície prehrávaných streamov Vymazať celú históriu pozretí\? @@ -388,7 +385,8 @@ \nNewPipe v ochrane súkromia podrobne vysvetľuje, aké údaje budú odoslané a uložené pri hlásení o páde. Prečítajte si pravidlá ochrany osobných údajov Chcete zároveň importovať aj nastavenia? - V súlade s Európskym Všeobecným Nariadením o Ochrane Údajov (GDPR), chceme upriamiť vašu pozornosť na ochranu osobných údajov v NewPipe. Starostlivo si ich prečítajte. Musíte ich prijať pred nahlásením chyby. + V súlade s Európskym Všeobecným Nariadením o Ochrane Údajov (GDPR), chceme upriamiť vašu pozornosť na ochranu osobných údajov v NewPipe. Starostlivo si ich prečítajte. +\nMusíte ich prijať pred nahlásením chyby. Prijať Odmietnuť Bez limitu @@ -496,7 +494,7 @@ Pri každom sťahovaní súboru sa bude vyžadovať zadanie cieľového adresára \nZvoľte SAF pokiaľ chcete ukladať na externé úložisko Použiť SAF - Storage Access Framework umožňuje sťahovanie na externú SD kartu. + Storage Access Framework umožňuje sťahovanie na externú SD kartu. \nPoznámka: Niektoré zariadenia nie sú kompatibilné Odstrániť pozície prehrávania Odstráni všetky pozície prehrávania @@ -520,7 +518,7 @@ Dĺžka rýchleho pretáčania Inštancie PeerTube Vyberte si svoje obľúbené inštancie PeerTube - Nájdite najvyhovujúcejšie inštancie na %s + Vyhladať inštancie, ktoré sa vám páčia, na %s Pridať inštanciu Vložiť URL inštancie Nepodarilo sa overiť inštanciu @@ -592,16 +590,16 @@ Služba je dostupná len pre určité zdroje, zvyčajne je rýchlejšia ale môže vrátiť obmedzený počet položiek alebo neúplné informácie (napr. dĺžka, typ, status). Povoliť rýchly režim Zakázať rýchly režim - Myslíte si, že načítavanie informačného kanála je príliš pomalé\? Ak áno, skúste povoliť rýchle načítanie (môžete ho zmeniť v nastaveniach alebo stlačením tlačidla nižšie). -\n -\nNewPipe ponúka dve stratégie načítania informačného kanála: -\n• Načítava sa celý kanál prihlásenia na odber, ktorý je pomalý, ale úplný. -\n• Používanie vyhradeného koncového bodu služby, ktorý je rýchly, ale zvyčajne nie je kompletný. -\n -\nRozdiel medzi nimi je ten, že v prípade rýchleho videa zvyčajne chýbajú nejaké informácie, napríklad trvanie alebo typ položky (nedá sa rozlíšiť medzi živými videami a normálnymi videami) a môže sa vrátiť menej položiek. -\n -\nYouTube je príkladom služby, ktorá ponúka túto rýchlu metódu s informačným kanálom RSS. -\n + Myslíte si, že načítavanie informačného kanála je príliš pomalé\? Ak áno, skúste povoliť rýchle načítanie (môžete ho zmeniť v nastaveniach alebo stlačením tlačidla nižšie). +\n +\nNewPipe ponúka dve stratégie načítania informačného kanála: +\n• Načítava sa celý kanál prihlásenia na odber, ktorý je pomalý, ale úplný. +\n• Používanie vyhradeného koncového bodu služby, ktorý je rýchly, ale zvyčajne nie je kompletný. +\n +\nRozdiel medzi nimi je ten, že v prípade rýchleho zvyčajne chýbajú nejaké informácie, napríklad trvanie alebo typ položky (nedá sa rozlíšiť medzi živými videami a normálnymi videami) a môže načítať menej položiek. +\n +\nYouTube je príkladom služby, ktorá ponúka túto rýchlu metódu s informačným kanálom RSS. +\n \nTakže výber sa zredukuje na to, čo uprednostňujete: rýchlosť alebo presné informácie. Tento obsah ešte nie je podporovaný v NwPipe. \n @@ -625,4 +623,7 @@ %s Vytvoril %s Minuatúrny avatar kanála + Nahlásiť chybu na GitHub + Kopírovať formátované hlásenie + Zobrazujú sa výsledky pre: %s \ No newline at end of file From 6e17af91fbc432ee641d7ecc8583574662584a1f Mon Sep 17 00:00:00 2001 From: Juraj Liso Date: Thu, 13 Aug 2020 22:25:51 +0000 Subject: [PATCH 069/137] Translated using Weblate (Czech) Currently translated at 98.4% (575 of 584 strings) --- app/src/main/res/values-cs/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index f18da7ba0..905039622 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -314,7 +314,7 @@ otevření ve vyskakovacím okně Vyplnit Zvětšit Ladění - "Automaticky generováno " + Automaticky generováno LeakCanary Monitoring úniku paměti může způsobit nereagování aplikace při heap dumpingu Nahlásit mimo-cyklické chyby From 7fd27fac450361e28568ed0b081f01cf655f9c1d Mon Sep 17 00:00:00 2001 From: sivemortenfan Date: Thu, 13 Aug 2020 08:44:12 +0000 Subject: [PATCH 070/137] Translated using Weblate (Malayalam) Currently translated at 100.0% (584 of 584 strings) --- app/src/main/res/values-ml/strings.xml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml index bc27edaa4..52db70898 100644 --- a/app/src/main/res/values-ml/strings.xml +++ b/app/src/main/res/values-ml/strings.xml @@ -132,7 +132,7 @@ കൂടുതൽ വിവരങ്ങൾക്കും വാർത്തകൾക്കും ന്യൂപൈപ്പിന്റെ വെബ്സൈറ്റ് സന്ദർശിക്കുക. വെബ്സൈറ്റ് തിരികെ നൽകുക - What:\\nRequest:\\nContent Lang:\\nService:\\nGMT Time:\\nPackage:\\nVersion:\\nOS version: + എന്താണ്:\\nഅപേക്ഷ:\\nഉള്ളടക്കത്തിന്റെ ഭാഷ:\\nഉള്ളടക്കത്തിന്റെ രാജ്യം:\\n അപ്ലിക്കേഷന്റെ ഭാഷ:\\nസേവനം:\\nGMT സമയം:\\nപാക്കേജ്:\\nപതിപ്പ്:\\nOS ന്റെ പതിപ്പ്: നിങ്ങൾക്ക് മികച്ച ഉപഭോക്തൃ അനുഭവം നൽകാനായി പ്രയത്‌നിക്കുന്ന ലോകമെമ്പാടുമുള്ള വൊളന്റിയർമാരാണ് ന്യൂപൈപ്പിന്റെ ശക്തി. ന്യൂപൈപ്പിനെ ഇനിയും മികവുറ്റതാക്കാൻ നിങ്ങൾക്ക് കഴിയും, നിങ്ങളുടെ സംഭാവനയിലൂടെ. സംഭാവന ചെയ്യുക ജിറ്റ്ഹബിൽ കാണുക @@ -612,4 +612,12 @@ സേവനങ്ങളിൽ നിന്നുള്ള യഥാർത്ഥ വാചകങ്ങൾ സ്ട്രീം ഇനങ്ങളിൽ ദൃശ്യമാകും ഇനങ്ങളിൽ യഥാർത്ഥ സമയം മുമ്പ് കാണിക്കുക യുട്യൂബ് നിയന്ത്രിത മോഡ് + ഇതിനായുള്ള ഫലങ്ങൾ കാണിക്കുന്നു:% s + ഗ്രൂപ്പുചെയ്യാത്ത സബ്‌സ്‌ക്രിപ്‌ഷനുകൾ മാത്രം കാണിക്കുക + ഇതുവരെ ഒരു പ്ലേലിസ്റ്റ് ബുക്ക്മാർക്കുകളും ഇല്ല + ഒരു പ്ലേലിസ്റ്റ് തിരഞ്ഞെടുക്കുക + നിങ്ങളുടെ ക്രാഷ് ചർച്ച ചെയ്യുന്ന ഒരു പ്രശ്നം ഇതിനകം നിലവിലുണ്ടോയെന്ന് ദയവായി പരിശോധിക്കുക. തനിപ്പകർപ്പ് ആയ ടിക്കറ്റുകള്‍ സൃഷ്ടിക്കുമ്പോൾ, യഥാർത്ഥ ബഗ് പരിഹരിക്കുവാന്‍ വേണ്ടി ഞങ്ങ‍ള്‍ക്ക് ചെലവഴിക്കാൻ കഴിയുമായിരുന്ന സമയം നിങ്ങൾ ഞങ്ങളിൽ നിന്ന് എടുക്കുകയാണ് ചെയ്യുന്നത്. + ഫോർമാറ്റുചെയ്‌ത റിപ്പോർട്ട് പകർത്തുക + പ്ലേലിസ്റ്റ് പേജ് + തെറ്റ് GitHub ല്‍ റിപ്പോര്‍ട്ട് ചെയ്യുക \ No newline at end of file From fcf9131aae29b5978bd773884f6a7cb6fe7d37db Mon Sep 17 00:00:00 2001 From: ssantos Date: Wed, 12 Aug 2020 14:52:20 +0000 Subject: [PATCH 071/137] Translated using Weblate (Portuguese (Portugal)) Currently translated at 100.0% (584 of 584 strings) --- app/src/main/res/values-pt-rPT/strings.xml | 623 ++++++++++++++++++++- 1 file changed, 622 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index a6b3daec9..fbd7f6fde 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -1,2 +1,623 @@ - \ No newline at end of file + + Quiosque + Recusar + Item eliminado + Iniciar reprodução em segundo plano + Tenha em atenção que esta operação pode sobrecarregar a sua rede. +\n +\nDeseja continuar\? + Toque em \"Pesquisar\" para iniciar + Uma miniatura de vídeo é mostrada no ecrã de bloqueio quando utilizando o leitor de fundo + Continuar reprodução + Processos + Os carateres inválidos são substituídos por este valor + Transferir + Remove o áudio em algumas resoluções + %s transferências concluídas + Predefinição do sistema + Minimizar ao trocar de aplicação + Ativar som + Iniciar reprodução num popup + Código + suaID, soundcloud.com/suaID + Resolução da janela popup predefinida + Reprodutor \'popup\' + Aviso: não foi possível importar todos os ficheiros. + Já existe uma transferência em progresso com este nome + Ver no GitHub + Conteúdo da página principal + Progresso perdido, porque o ficheiro foi eliminado + Canal não subscrito + Nome do ficheiro + Mostrar indicadores de posição de reprodução em listas + Notificações para o NewPipe e para os reprodutores \"popup\" + Desligar (pode causar distorção) + Mostrar sugestões ao pesquisar + Ficheiro ZIP inválido + Sem visualizações + Claro + Não foi possível alterar a subscrição + Já existe um ficheiro transferido com este nome + Criado diretorio de transferência \'%1$s\' + Permissão negada pelo sistema + Pesquisado + Legendas + Restaurar predefinições + Ocorreu um erro: %1$s + Popup + Não foi possível processar totalmente o site da Web + Transferência do NewPipe + Nome + Devido às restrições do ExoPlayer, a duração da procura foi definida para %d segundos + Sobrescrever + Silenciar + Ver histórico + + %s visualização + %s visualizações + + Quer limpar o seu histórico de transferências ou apagar todos os ficheiros transferidos\? + Histórico e cache + Continuar reprodução após interrupções (ex. chamadas) + Transferir ficheiro de vídeo + +100 vídeos + Seleção + Ajustar + Atualizar sempre + Reproduzir todos + Eliminar esta lista de reprodução\? + O histórico está vazio + Informação: + Licenças + Interromper em redes limitadas + Reproduzir vídeo, duração: + Novo + Este conteúdo ainda não é suportado pelo NewPipe. +\n +\nEsperamos que seja suportado em uma versão futura. + Nenhuma + Escolha a pasta de transferencias para ficheiros de vídeo + Quer apagar este grupo\? + Filtrar + Não foi possível encontrar o servidor + Não foi possível importar as subscrições + Transferências + A processar feed… + Gestos para controlar de volume + Este vídeo tem restrição de idade. +\n +\nSe quiser vê-lo, ative \"Conteúdo com restrição de idade\" nas definições. + Ler licença + Ajuda + Somente URLs HTTPS são suportada + Falha ao validar a instância + Eliminar todos + Limpar histórico de transferências + Colocar em fila em segundo plano + Eliminar todas as posições de reprodução\? + Mudar visualização + Limitar a fila de transferências + Conteúdo com restrição de idade + O projeto NewPipe leva a sua privacidade muito a sério. Sendo assim, o aplicativo não coleta nenhum dado sem seu consentimento. +\nA polícia de privacidade do NewPipe explica em detalhes qual dado é enviado e salvo quando você envia um relatório de erros. + Ficheiro + Principal + Adicionar a + Elimina todas as posições de reprodução + Criar + Miniatura do vídeo no ecrã de bloqueio + Mostrar vídeo com restrição de idade. Alterações serão possíveis nas definições. + Alternar orientação + Subscrever + Artistas + Não é possível ligar ao servidor + Exibir uma opção para reproduzir o vídeo via Kodi media center + Modo de exibição de lista + A busca inexata permite que a busca seja mais rápida diminuindo a precisão. Procurar por 5, 15 ou 25 segundos não funciona com isto. + Permitir sobreposição da janela sobre outras aplicações + Reprodução automática + Exportar para + Acerca de NewPipe + Página vazia + Conceder primeiro acesso ao armazenamento + Geração automática (não foi encontrado nenhum enviador) + Resolução predefinida + Reportar erro no GitHub + Gostos + O histórico está desativado + Pasta para transferir o vídeo + Pressionar \"Aceitar\" quando terminar + A carregar feed… + Áudio + Mostrar tempo original que passou em itens + Ficheiro já existe + Quiosque Predefinição + Criada a ista de reprodução + Criado por %s + + %d segundo + %d segundos + + + %d selecionada + %d selecionadas + + Partilhar + Ler a política de privacidade + Ocorreu um erro irrecuperável do reprodutor + Modo restrito do YouTube + A pasta não existe + Tudo + Desculpe, isso não deveria ter acontecido. + Anular + Não existem canais subscritos + Comportamento + Por favor, defina mais tarde uma pasta de transferências nas definições + Posições nas listas + Uma transferências será executada ao mesmo tempo + Não encontrado + Reprodução em segundo plano + Mostrar resoluções mais altas + Sem subscritores + Utilizar reprodutor de áudio externo + Desative para parar o carregamento das miniaturas, poupar dados e utilização da memória. As alterações limpam a cache de imagem do disco e da memória. + Quis dizer: %1$s\? + Mostrar uma notificação para pedir a atualização da aplicação se existir uma nova versão + Fila + Ninguém está a ver + Apagar ficheiros transferidos + Idioma da aplicação + Utilizadores + Os vídeos que tenham sido vistos antes e depois de serem adicionados à lista de reprodução serão removidos. +\nTem certeza\? Isto não pode ser desfeito! + + %s a ver + %s a ver + + Por favor, aguarde… + Redimensionar + Toque para transferir + Limpar + Cancelar subscrição + Deseja eliminar este item do histórico de visualizações\? + Conteúdo + Textos originais dos serviços serão visíveis nos itens de fluxo + Publicado em %1$s + Transferência concluída + Avanço rápido durante silêncio + Não foram encontradas emissões de áudio + NewPipe foi fechado enquanto trabalhava no ficheiro + Nova lista de reprodução + © %1$s de %2$s nos termos da %3$s + Preto + Ninguém está a ouvir + Miniatura da lista de reprodução alterada. + Não foi possível carregar os comentários + País predefinido dos conteúdos + Aplicação livre de reprodução de emissões para Android. + Idioma do conteúdo predefinido + Importe as subscrições do YouTube transferindo o ficheiro de exportação: +\n +\n1. Aceda a este URL: %1$s +\n2. Inicie a sessão +\n3. A transferência deveria iniciar (esse é o ficheiro de exportação) + Ativar o reprodutor em segundo plano + Mais tarde + Desafio reCAPTCHA solicitado + Reprodução automática + A instância já existe + NewPipe é desenvolvido por voluntários que utilizam o tempo livre deles para proporcionar-lhe a melhor experiência. Retribua para ajudar os programadores a tornarem o NewPipe ainda melhor enquanto desfruta de um café. + URL inválido ou Internet não disponível + Continuar terminando (sem repetição) a fila de reprodução anexando um vídeo relacionado + Sempre + Para cumprir com o Regulamento Geral da Proteção de Dados (RGPD), nós chamamos a sua atenção para a política de privacidade do NewPipe. Por favor, leia com atenção. +\nTem que aceitar esta política para nos poder enviar o seu relatório. + Grupos de canais + Instalar + Novo separador + Também deseja importar as definições\? + Guardar lista de reprodução como favorita + Não foi possível carregar a imagem + Passo + Top 50 + Não gostar + Importar ficheiro + Notificação do NewPipe + Desculpe, ocorreram alguns erros. + Tema + A pasta de destino não pode ser criada + Licenças de terceiros + Gerar nome único + Ação a executar ao trocar para outra aplicação a partir do menu principal - %s + Usar reprodutor de vídeo externo + O quê:\\nPedido:\\nIdioma do conteúdo:\\nPaís do conteúdo\\nIdioma da app\\nServiço:\\nHora GMT:\\nPacote:\\nVersão:\\nVersão do SO: + Se tem ideias para: tradução, alterações de desenho, limpeza de código, ou alterações significativas no código fonte - todas as ajudas são bem-vindas. Quanto mais se faz, melhor ficará! + Limpar dados + Apenas uma vez + Não carregado: %d + Preencher + Escuro + Definições + Tentar novamente + Mostrar vídeos \'Seguintes\' e \'Semelhantes\' + na fila + Abrir no navegador + Tendências + Elimina o histórico das palavras-chave de pesquisa + Notificação de atualização + Não foi possível desencriptar a assinatura do URL do vídeo + Serviço + Controlo de reprodução por gestos + Selecione uma lista de reprodução + Última atualização do feed: %s + Importar base de dados + Relatório de erro + Não há espaço disponível no dispositivo + Número máximo de tentativas antes de cancelar a transferência + A recuperar de um erro do reprodutor + Outros + LeakCanary + Em direto + Limite de atualização do feed + OK + Não foi possível obter a emissão + Não foi possível atualizar a subscrição + Não existe uma aplicação para reproduzir este ficheiro + Sim, e tambem os vídeos parcialmente vistos + M + Ainda não há marcadores de listas de reprodução + Em fila no reprodutor de janela popup + + %s ouvinte + %s ouvintes + + Eliminar todo o histórico de pesquisa\? + Reportar erro por e-mail + Escolher separador + Utilizar gestos para controlar o volume do reprodutor + Grelha + Exportados + Escolha a pasta de transferência para ficheiros de áudio + Atualização do NewPipe disponível! + Eventos + Nova missão + Política de privacidade do NewPipe + Não foi possível carregar todas as miniaturas + Áudio + Cancelar + Falha no pós-processamento + Eliminar todo o histórico de visualizações\? + A obter a informação… + Sugestões de pesquisa + Definir como Miniatura da Lista de Reprodução + Não foi possível eliminar a lista de reprodução. + Gestos para controlar o brilho + Abrir menu + + %s subscritor + %s subscritores + + Deseja restaurar as predefinições\? + Os reprodutores externos não suportam este tipo de hiperligações + Renomear + O \'Storage Access Framework\' permite transferências para um cartão SD externo. +\nAlguns aparelhos não são compatíveis + Duração da busca de avanço/retrocesso rápido + Canal + Ficheiro movido ou eliminado + Última reprodução + Visite o website do NewPipe para obter mais informação e novidades. + Importe o seu perfil do SoundCloud digitando o URL ou a sua Id.: +\n +\n1. Ative o modo de PC no navegador da Web (o site não está disponível para aparelhos móveis) +\n2. Aceda a este URL: %1$s +\n3. Inicie a sessão +\n4. Copie o URL do perfil em que foi redirecionado. + Limpar os metadados em cache + Não foi possível analisar o site da Web + Sem comentários + Iniciar reprodução aqui + pós-processamento + não é possível sobrescrever o ficheiro + Esse ficheiro/fonte de conteúdo não existe + Notificações para uma nova versão do NewPipe + Utilizar gestos para controlar o brilho e o volume do reprodutor + Histórico + Lista + Remover vídeos vistos\? + + %d minuto + %d minutos + + Terminada + Histórico de vídeos apagado. + Nenhum reprodutor de vídeo encontrado. Instalar o VLC\? + Desativar para ocultar comentários + Limitar resolução se estiver a usar dados móveis + Histórico limpo + Quais os separadores que são mostrados na página principal + Definições de áudio + Eliminar + Ritmo + Instâncias do PeerTube + Seguinte + Reprodutor + Depuração + Digite o URL da instância + Ação de \'abrir\' preferida + Vídeo e áudio + Letras e dígitos + Irá aparecer aqui qualquer coisa brevemente ;D + Atualizar + A monitorização de memória pode tornar a aplicação instável + Copiar relatório formatado + rotação + Ampliar + O nome do ficheiro não pode estar vazio + Lista de reprodução + Por %s + Maioria dos carateres especiais + Pasta de transferências de áudio + Detalhes: + Transferir + Feed + Página da lista de reprodução + Definições + Mais reproduzido + Pôr na fila num popup + Mostrando resultados para: %s + Mudar para segundo plano + Álbuns + Exportação anterior + Um ficheiro com este nome já existe + O servidor não aceita transferências de vários processos, tente novamente com @string/msg_threads = 1 + Arraste para reordenar + recuperando + Rejeitar + Controlos para velocidade de reprodução + Não foi possível exportar as subscrições + Forçar reportagem de exceções Rx não entregáveis ocorrendo fora do fragmento ou ciclo de vida da atividade após o eliminação + Recentemente adicionado + + %s vídeo + %s vídeos + + Importar + Elimina o histórico dos vídeos reproduzidos e as posições de reprodução + + %d dia + %d dias + + Pausar transferências + Desafio reCAPTCHA + Importar de + 1 elemento eliminado. + Não foram encontradas emissões de vídeo + Página de Quiosque + + %d hora + %d horas + + As emissões em direto ainda não são suportadas + Colocar vídeo seguinte na fila + Defina as suas instâncias favoritas de PeerTube + Importar/exportar + Exportar histórico, subscrições e listas de reprodução + Melhor resolução + Selecione um canal + Escolher navegador + Parar + Aqui não há nada para ver + Não foi possível configurar o menu de transferências + Ilimitado + Erro + Eliminar as posições de reprodução + A importar… + Novidades + Local + Aplicação/IU terminou em erro + Deseja eliminar este item do histórico de pesquisas\? + Continuar a reprodução + NewPipe é um software livre \"copyleft\": pode utilizar, estudar, partilhar e melhorar a aplicação. Especificamente, pode redistribuir e/ou modificar a aplicação nos termos da Licença Pública Geral GNU, conforme publicada pela Fundação de Software Livre, tanto a versão 3 da licença ou (por sua opção) qualquer versão superior. + ∞ vídeos + A exportar… + Os mais apreciados + Visualizado + Usar SAF + Detalhes + Erro de rede + Histórico de pesquisa + Alternar serviço, agora selecionado: + Remover + Comentários (em inglês): + Reprodutor de vídeo + Subscrições + Não foi possível estabelecer uma ligação segura + Listas de reprodução + Iniciar + Existe uma transferência pendente com este nome + Aceitar + Reproduzir vídeo se o NewPipe for invocado por outra aplicação + O que ocorreu: + Participar + Segundo plano + [Desconhecido] + Encontre as instâncias que gosta em %s + Selecione um \"kiosk\" + Canais + Tentativas máximas + Histórico + Velocidade + Sim + Não é possível recuperar esta transferência + Renomear + Nenhuma subscrição selecionada + Manter histórico dos vídeos vistos + Histórico de pesquisa eliminado. + Limpar o histórico de pesquisas + Erro + Lembrar tamanho e posição da janela + Os ficheiros de vídeo transferidos são armazenados aqui + Mudar para principal + Esta permissão é necessária +\npara o modo de janela popup + Sem vídeos + Miniatura do avatar do canal + O servidor não envia dados + Reportar erros \'out-of-lifecycle\' + Instalar a app Kore\? + Relatório + Nome + Copiado para a área de transferência + Carateres permitidos nos nomes de ficheiros + Gerado automaticamente + Listas de reprodução favoritas + Pendente + Importados + Automático + Substitui o histórico e as subscrições atuais + Popup + k + Não é possível criar a diretoria \'%1$s\' + B + Remover marcador + Útil quando mudar para dados móveis, embora algumas transferências não podem ser suspensas + Reprodutor em segundo plano + Toque longo para enfileirar + Transferências + O ficheiro não pode ser criado + Conferências + Não foi possível ler as guias gravadas, portanto usando as guias predefinidas + Fechar + Sem legendas + Website + Subscrições + Abrir website + Retribuir + Página de \"Feed\" + Formato de áudio predefinido + O ficheiro não existe ou as permissões para ler ou escrever faltam + O nome do grupo está vazio + Carregar miniaturas + Partilhar com + Tempo após a última atualização antes de uma subscrição ser considerada desatualizada - %s + Pesquisar + Atualizações + Miniatura de pré-visualização de vídeo + Atualizações + Iniciar transferências + Guardar termos de pesquisa localmente + URL não suportado + Colaboradores + Transferir + Licença do NewPipe + Ficheiro eliminado + Ativar o modo rápido + Miniatura do avatar do canal + %1$s visualizações + Reprodutor \'popup\' + Disponível em alguns serviços, é geralmente muito mais rápido, mas pode devolver uma quantidade limitada de itens e muitas vezes informações incompletas (por exemplo, sem duração, tipo de item, sem estado ativo). + Posições de reprodução eliminadas. + Perguntar para onde transferir + Reportar um erro + Mostrar informação + Limpar histórico de visualizações + Não é possível transferir para o cartão SD. Repor a localização da pasta de transferências\? + Modo popup + Servidor não suportado + Checksum + Restaurar a última posição de reprodução + Ativar o reprodutor \'popup\' + Buscar do feed dedicado quando disponível + Selecionar subscrições + Colocado na lista de reprodução + Eliminar um + Formato de vídeo predefinido + Mostrar dica \"Toque longo para colocar na fila\" + Escolha uma instância + Reproduzir + Remover todos os dados da página da Web em cache + Fechar menu + Utilizar gestos para controlar o brilho do reprodutor + Remover vistos + Não foi possível carregar a licença + Caráter de substituição + Vídeo + Sem vídeos disponíveis para transferir + Ficheiros de áudio transferidos são armazenados aqui + Vídeos + Metadados em cache eliminados + Mostrar sugestão quando o botão popup ou ambiente de trabalho é pressionado na página de detalhes do vídeo + Não foi encontrado nenhum reprodutor (pode instalar o VLC para reproduzir). + Será-lhe solicitado para onde guardar cada transferência + Será-lhe solicitado para onde guardar cada transferência. +\nEscolha SAF se pretender transferir para um cartão SD externo + Mostrar opção \"Reproduzir no Kodi\" + Eliminar + Sem resultados + Desativado + Tendências + Perguntar sempre + Tempo limite de conexão + Apenas alguns aparelhos suportam a reprodução de vídeos em 2K/4K + Aparência + Doar + Por favor, verifique se já existe um assunto a discutir o seu acidente. Criar bilhetes duplicados tirará-nos tempo que poderíamos gastar com a reparação do bug real. + Conteúdo indisponível + Subscrito + Cache de imagens limpa + URL inválido + Tem a certeza que deseja eliminar todos os itens do histórico\? + Sobre + Contagem de subscrições indisponível + Ação predefinida ao abrir o conteúdo — %s + Repor + Utilizar pesquisa rápida + Está prestes a substituir a configuração atual. + Mudar para \'popup\' + %1$d transferências apagadas + Adicionar à lista de reprodução + Reproduzir no modo de janela poppup + Acha que o carregamento do feed é muito lento\? Se sim, tente ativar o carregamento rápido (pode alterá-lo nas configurações ou pressionando no botão abaixo). +\n +\nNewPipe oferece duas estratégias de carregamento de alimentação: +\n- Obter todo o canal de subscrição, que é lento, mas completo. +\n- Usando um \'endpoint\' de serviço dedicado, que é rápido, mas normalmente não completo. +\n +\nA diferença entre os dois é que o rápido geralmente carece de alguma informação, como a duração ou tipo do item (não consegue distinguir entre vídeos em direto e vídeos normais) e pode mostar menos itens. +\n +\nO YouTube é um exemplo de um serviço que oferece este método rápido com o seu feed RSS. +\n +\nAssim, a escolha resume-se ao que prefere: velocidade ou informação precisa. + (Experimental) Forçar o tráfego de transferência via Tor para aumentar a privacidade (ainda não é suportada a emissão de vídeos). + Alterar as pastas de transferência para que tenham efeito + Abrir em modo popup + Pausa + A carregar o conteúdo solicitado + Página do canal + Exportar base de dados + Usar Tor + Mostrar apenas assinaturas não agrupadas + Incapaz de reproduzir este vídeo + Reprodutor em segundo plano + Reproduzir + Mostrar erro + Modificar escala das legendas e o estilo de fundo. Tem que reiniciar a aplicação para aplicar as alterações. + Ação recusada pelo sistema + Músicas + Sobre + Em lista de espera no reprodutor em segundo plano + O idioma mudará quando a app for reiniciada. + Adicionar instância + Faixas + Reproduzir no Kodi + Armazenamento externo indisponível + Transferência falhou + Relatório + Toque para detalhes + em pausa + Mostrar comentários + Aceitar + Desativar modo rápido + \ No newline at end of file From 970b636eb4e1f16c24ecd8cb9166c87152f07fd0 Mon Sep 17 00:00:00 2001 From: Hakim Oubouali Date: Fri, 14 Aug 2020 12:00:13 +0000 Subject: [PATCH 072/137] Translated using Weblate (Berber) Currently translated at 17.9% (105 of 584 strings) --- app/src/main/res/values-ber/strings.xml | 95 ++++++++++++++++++++++++- 1 file changed, 94 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-ber/strings.xml b/app/src/main/res/values-ber/strings.xml index a6b3daec9..8f442a4ad 100644 --- a/app/src/main/res/values-ber/strings.xml +++ b/app/src/main/res/values-ber/strings.xml @@ -1,2 +1,95 @@ - \ No newline at end of file + + ⴰⵎⴰⵢⵏⵓ + ⵉⵙⵎ + + %d ⴰⵙⵙ + %d ⵓⵙⵙⴰⵏ + + + %d ⵜⵙⵔⵉⴳⵜ + %d ⵜⵙⵔⵉⴳⵉⵏ + + + %d ⵜⵙⴷⵉⴷⵉⵜ + %d ⵜⵙⴷⵉⴷⵉⵏ + + ⵜⵓⵜⵍⴰⵢⵜ ⵏ ⵓⵙⵏⵙⵉ + ⵇⵇⵏ + ⵡⴰⵍⵓ + ⴰⵙⵓⵔⵉⴼ + ⵙⵎⵖⵕ + ⵙⵓⵙⵎ + ⵉⵙⵎ + ⵙⵏⴼⵍ ⵉⵙⵎ + ⴽⴽⵙ + ⵜⵉⵙⵖⴰⵍ ⵓⵎⵙⵍⴰⵢ + ⴽⴽⵙ + ⴰⵎⵣⵔⵓⵢ + ⵜⴻⵜⵜⵡⴰⵔⵣⵓⵏ + ⵜⴻⵜⵜⵓⵥⵕ + ⴰⵎⵣⵔⵓⵢ + ⴰⵙⵉⵜ + ⵥⵕ ⴳ GitHub + ⵜⵓⵔⴰⴳⵜ + ⵅⴼ + ⵕⵥⵎ ⴰⵙⵉⵜ + © %1$s ⵙⴳ %2$s ⴷⴷⴰⵡ %3$s + ⵅⴼ + ⵜⵉⵙⵖⴰⵍ + ⵅⴼ NewPipe + ⵕⴰⵊⴰ… + ⵜⴰⵣⴳⵍⵜ + ⵉⵙⵎ ⵓⴼⴰⵢⵍⵓ + ⵡⴰⵅⵅⴰ + ⵙⵙⵏⴼⵍ ⵉⵙⵎ + ⵙⵙⵔ + ⴽⴽⵙ ⵎⴰⵕⵕⴰ + ⴽⵙⵙ ⵢⴰⵏ + ⴽⴽⵙ + ⵖⵔ + ⵓⵔ ⵍⵍⵉⵏ ⵉⵡⴼⴰⵡⴰⵍⵏ + + %s ⵓⴼⵉⴷⵢⵓ + %s ⵉⴼⵉⴷⵢⵓⵜⵏ + + ∞ ⵉⴼⵉⴷⵢⵓⵜⵏ + 100+ ⵉⴼⵉⴷⵢⵓⵜⵏ + + + + ⴰⵎⵙⵍⴰⵢ + ⴰⴼⵉⴷⵢⵓ + ⵉⵔⵉⵜⵏ + ⵜⴰⵣⴳⵍⵜ + ⵜⵉⵡⵉⵙⵉ + ⴰⴼⴰⵢⵍⵓ + ⵖⵔ ⵎⴰⵕⵕⴰ + ⵉⵜⵜⵡⴰⴽⴽⵙ ⵓⴼⴰⵢⵍⵓ + ⴰⵙⵜⵜⴰⵢ + ⵢⴰⵀ + ⵉⴼⵉⴷⵢⵓⵜⵏ + ⵎⴰⵕⵕⴰ + ⵓⴳⴳⴰⵎⵏ + ⵓⴳⴳⴰⵎⵏ + ⵓⵙⵔⵉⴷ + ⵖⵔ + ⵢⴰⴹⵏ + ⴰⴼⵉⴷⵢⵓ ⴷ ⵓⵎⵙⵍⴰⵢ + ⴰⴳⵎ + ⵥⵕ ⴰⵎⵣⵔⵓⵢ + ⴰⵎⵣⵔⵓⵢ ⵏ ⵓⵔⵣⵣⵓ + ⴰⴱⵔⴽⴰⵏ + ⴰⵎⵙⵍⴰⵢ + ⵖⵔ ⵙ ⴽⵓⴷⵉ + ⵔⵏⵓ ⵖⵔ + ⵙⵜⵉ ⴰⵙⴽⵙⵍ + ⴰⵙⴽⵙⵍ ⴰⵎⴰⵢⵏⵓ + ⵔⵣⵓ ⵙ + ⵜⵉⵙⵖⴰⵍ + ⵔⵣⵓ + ⴰⴳⵎ + ⴱⴹⵓ + ⵙⵔⵙ + ⵙⵔ + \ No newline at end of file From adef9a8acfd8a141ac0393be16ba3d7ac619a3f4 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sat, 15 Aug 2020 15:16:17 +0200 Subject: [PATCH 073/137] Rename notification functions: they are not background player only --- .../org/schabi/newpipe/player/MainPlayer.java | 2 +- .../newpipe/player/NotificationUtil.java | 15 ++++++------- .../newpipe/player/VideoPlayerImpl.java | 22 +++++++++---------- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java b/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java index 5569b8d06..92c6a3c86 100644 --- a/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java @@ -244,7 +244,7 @@ public final class MainPlayer extends Service { } private void showNotificationAndStartForeground() { - NotificationUtil.getInstance().recreateBackgroundPlayerNotification(playerImpl, true); + NotificationUtil.getInstance().recreateNotification(playerImpl, true); NotificationUtil.getInstance().setProgressbarOnOldNotifications(100, 0, false); NotificationUtil.getInstance().startForegroundServiceWithNotification(this); } diff --git a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java index bfa698cd6..5f7398089 100644 --- a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java +++ b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java @@ -81,7 +81,7 @@ public final class NotificationUtil { // NOTIFICATION ///////////////////////////////////////////////////// - NotificationCompat.Builder createBackgroundPlayerNotification(final VideoPlayerImpl player) { + NotificationCompat.Builder createNotification(final VideoPlayerImpl player) { notificationManager = (NotificationManager) player.context.getSystemService(NOTIFICATION_SERVICE); NotificationCompat.Builder builder = new NotificationCompat.Builder(player.context, @@ -183,10 +183,10 @@ public final class NotificationUtil { * @param player the player currently open, to take data from * @param playPauseDrawable if != -1, sets the drawable with that id on the play/pause button */ - synchronized void updateBackgroundPlayerNotification(final VideoPlayerImpl player, - @DrawableRes final int playPauseDrawable) { + synchronized void updateNotification(final VideoPlayerImpl player, + @DrawableRes final int playPauseDrawable) { if (DEBUG) { - Log.d(TAG, "N_ updateBackgroundPlayerNotification()"); + Log.d(TAG, "N_ updateNotification()"); } if (notificationBuilder == null) { @@ -232,15 +232,14 @@ public final class NotificationUtil { } } - void recreateBackgroundPlayerNotification(final VideoPlayerImpl player, - final boolean recreate) { + void recreateNotification(final VideoPlayerImpl player, final boolean recreate) { final boolean areOldNotificationsEnabled = player.sharedPreferences.getBoolean( player.context.getString(R.string.enable_old_notifications_key), false); if (notificationBuilder == null || recreate || areOldNotificationsEnabled) { if (DEBUG) { - Log.d(TAG, "N_ recreateBackgroundPlayerNotification(true)"); + Log.d(TAG, "N_ recreateNotification(true)"); } - notificationBuilder = createBackgroundPlayerNotification(player); + notificationBuilder = createNotification(player); } timesNotificationUpdated = 0; } diff --git a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java index 1c89cc4b1..e9430be0b 100644 --- a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java +++ b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java @@ -652,7 +652,7 @@ public class VideoPlayerImpl extends VideoPlayer } if (NotificationUtil.getInstance().shouldRecreateOldNotification()) { - NotificationUtil.getInstance().recreateBackgroundPlayerNotification(this, false); + NotificationUtil.getInstance().recreateNotification(this, false); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationUtil.getInstance().updateOldNotificationsThumbnail(getThumbnail()); @@ -664,7 +664,7 @@ public class VideoPlayerImpl extends VideoPlayer NotificationUtil.getInstance().setProgressbarOnOldNotifications(duration, currentProgress, false); - NotificationUtil.getInstance().updateBackgroundPlayerNotification(this, -1); + NotificationUtil.getInstance().updateNotification(this, -1); } } @@ -1083,8 +1083,8 @@ public class VideoPlayerImpl extends VideoPlayer animatePlayButtons(false, 100); getRootView().setKeepScreenOn(false); - NotificationUtil.getInstance().recreateBackgroundPlayerNotification(this, false); - NotificationUtil.getInstance().updateBackgroundPlayerNotification( + NotificationUtil.getInstance().recreateNotification(this, false); + NotificationUtil.getInstance().updateNotification( this, R.drawable.ic_play_arrow_white_24dp); } @@ -1101,7 +1101,7 @@ public class VideoPlayerImpl extends VideoPlayer isForwardPressed = false; isRewindPressed = false; } else { - NotificationUtil.getInstance().updateBackgroundPlayerNotification(this, -1); + NotificationUtil.getInstance().updateNotification(this, -1); } } } @@ -1154,8 +1154,8 @@ public class VideoPlayerImpl extends VideoPlayer animatePlayButtons(false, 100); getRootView().setKeepScreenOn(true); - NotificationUtil.getInstance().recreateBackgroundPlayerNotification(this, false); - NotificationUtil.getInstance().updateBackgroundPlayerNotification( + NotificationUtil.getInstance().recreateNotification(this, false); + NotificationUtil.getInstance().updateNotification( this, R.drawable.ic_play_arrow_white_24dp); } @@ -1170,10 +1170,10 @@ public class VideoPlayerImpl extends VideoPlayer getRootView().setKeepScreenOn(false); updateWindowFlags(IDLE_WINDOW_FLAGS); - NotificationUtil.getInstance().recreateBackgroundPlayerNotification(this, false); + NotificationUtil.getInstance().recreateNotification(this, false); NotificationUtil.getInstance().setProgressbarOnOldNotifications(100, 100, false); NotificationUtil.getInstance().updateOldNotificationsThumbnail(getThumbnail()); - NotificationUtil.getInstance().updateBackgroundPlayerNotification( + NotificationUtil.getInstance().updateNotification( this, R.drawable.ic_replay_white_24dp); super.onCompleted(); @@ -1335,9 +1335,9 @@ public class VideoPlayerImpl extends VideoPlayer //////////////////////////////////////////////////////////////////////////*/ void resetNotification(final boolean recreate, @DrawableRes final int drawableId) { - NotificationUtil.getInstance().recreateBackgroundPlayerNotification(this, recreate); + NotificationUtil.getInstance().recreateNotification(this, recreate); NotificationUtil.getInstance().updateOldNotificationsThumbnail(getThumbnail()); - NotificationUtil.getInstance().updateBackgroundPlayerNotification(this, drawableId); + NotificationUtil.getInstance().updateNotification(this, drawableId); } @Override From e08480f34532daca4c8f432ef902454869b1a719 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sat, 15 Aug 2020 19:15:08 +0200 Subject: [PATCH 074/137] Completely remove old player notification --- .../org/schabi/newpipe/player/MainPlayer.java | 3 +- .../newpipe/player/NotificationUtil.java | 400 ++++++------------ .../newpipe/player/VideoPlayerImpl.java | 65 +-- .../settings/AppearanceSettingsFragment.java | 11 - app/src/main/res/values/settings_keys.xml | 1 - app/src/main/res/values/strings.xml | 2 - app/src/main/res/xml/appearance_settings.xml | 7 - 7 files changed, 140 insertions(+), 349 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java b/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java index 92c6a3c86..065efca02 100644 --- a/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java @@ -244,8 +244,7 @@ public final class MainPlayer extends Service { } private void showNotificationAndStartForeground() { - NotificationUtil.getInstance().recreateNotification(playerImpl, true); - NotificationUtil.getInstance().setProgressbarOnOldNotifications(100, 0, false); + NotificationUtil.getInstance().createNotificationIfNeeded(playerImpl, true); NotificationUtil.getInstance().startForegroundServiceWithNotification(this); } diff --git a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java index 5f7398089..32dd93bd4 100644 --- a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java +++ b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java @@ -7,16 +7,13 @@ import android.app.Service; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.Matrix; -import android.os.Build; import android.util.Log; -import android.widget.RemoteViews; import androidx.annotation.DrawableRes; import androidx.annotation.Nullable; import androidx.core.app.NotificationCompat; import androidx.core.content.ContextCompat; -import org.schabi.newpipe.BuildConfig; import org.schabi.newpipe.MainActivity; import org.schabi.newpipe.R; import org.schabi.newpipe.util.NavigationHelper; @@ -34,8 +31,6 @@ import static org.schabi.newpipe.player.MainPlayer.ACTION_PLAY_PAUSE; import static org.schabi.newpipe.player.MainPlayer.ACTION_PLAY_PREVIOUS; import static org.schabi.newpipe.player.MainPlayer.ACTION_REPEAT; import static org.schabi.newpipe.player.MainPlayer.ACTION_SHUFFLE; -import static org.schabi.newpipe.player.MainPlayer.SET_IMAGE_RESOURCE_METHOD; -import static org.schabi.newpipe.player.helper.PlayerHelper.getTimeString; /** * This is a utility class for player notifications. @@ -46,8 +41,6 @@ public final class NotificationUtil { private static final String TAG = "NotificationUtil"; private static final boolean DEBUG = BasePlayer.DEBUG; private static final int NOTIFICATION_ID = 123789; - // only used for old notifications - private static final int NOTIFICATION_UPDATES_BEFORE_RESET = 60; @Nullable private static NotificationUtil instance = null; @@ -58,14 +51,8 @@ public final class NotificationUtil { private String notificationSlot4 = "close"; private NotificationManager notificationManager; - private RemoteViews notificationRemoteView; // always null when new notifications are used - private RemoteViews bigNotificationRemoteView; // always null when new notifications are used private NotificationCompat.Builder notificationBuilder; - private int cachedDuration; // only used for old notifications - private String cachedDurationString; // only used for old notifications - private int timesNotificationUpdated; // only used for old notifications - private NotificationUtil() { } @@ -81,110 +68,13 @@ public final class NotificationUtil { // NOTIFICATION ///////////////////////////////////////////////////// - NotificationCompat.Builder createNotification(final VideoPlayerImpl player) { - notificationManager = - (NotificationManager) player.context.getSystemService(NOTIFICATION_SERVICE); - NotificationCompat.Builder builder = new NotificationCompat.Builder(player.context, - player.context.getString(R.string.notification_channel_id)); - - final boolean areOldNotificationsEnabled = player.sharedPreferences.getBoolean( - player.context.getString(R.string.enable_old_notifications_key), false); - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP || areOldNotificationsEnabled) { - notificationRemoteView = new RemoteViews(BuildConfig.APPLICATION_ID, - R.layout.player_notification); - bigNotificationRemoteView = new RemoteViews(BuildConfig.APPLICATION_ID, - R.layout.player_notification_expanded); - - setupOldNotification(notificationRemoteView, player); - setupOldNotification(bigNotificationRemoteView, player); - - builder - .setOngoing(true) - .setSmallIcon(R.drawable.ic_newpipe_triangle_white) - .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) - .setCustomContentView(notificationRemoteView) - .setCustomBigContentView(bigNotificationRemoteView) - .setPriority(NotificationCompat.PRIORITY_MAX); - } else { - final String compactView = player.sharedPreferences.getString(player.context.getString( - R.string.settings_notifications_compact_view_key), "0,1,2"); - int compactSlot0 = 0; - int compactSlot1 = 1; - int compactSlot2 = 2; - try { - if (compactView != null) { - final String[] parts = compactView.split(","); - compactSlot0 = Integer.parseInt(parts[0]); - compactSlot1 = Integer.parseInt(parts[1]); - compactSlot2 = Integer.parseInt(parts[2]); - if (compactSlot0 > 4) { - compactSlot0 = 0; - } - if (compactSlot1 > 4) { - compactSlot1 = 1; - } - if (compactSlot2 > 4) { - compactSlot2 = 2; - } - } - } catch (Exception e) { - e.printStackTrace(); - } - - builder.setStyle(new androidx.media.app.NotificationCompat.MediaStyle() - .setMediaSession(player.mediaSessionManager.getSessionToken()) - .setShowCancelButton(false) - .setShowActionsInCompactView(compactSlot0, compactSlot1, compactSlot2)) - .setOngoing(false) - .setContentIntent(PendingIntent.getActivity(player.context, NOTIFICATION_ID, - getIntentForNotification(player), FLAG_UPDATE_CURRENT)) - .setSmallIcon(R.drawable.ic_newpipe_triangle_white) - .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) - .setContentTitle(player.getVideoTitle()) - .setContentText(player.getUploaderName()) - .setDeleteIntent(PendingIntent.getActivity(player.context, NOTIFICATION_ID, - new Intent(ACTION_CLOSE), FLAG_UPDATE_CURRENT)) - .setColor(ContextCompat.getColor(player.context, R.color.gray)) - .setPriority(NotificationCompat.PRIORITY_HIGH); - final boolean scaleImageToSquareAspectRatio = player.sharedPreferences.getBoolean( - player.context.getString(R.string.scale_to_square_image_in_notifications_key), - false); - if (scaleImageToSquareAspectRatio) { - builder.setLargeIcon(getBitmapWithSquareAspectRatio(player.getThumbnail())); - } else { - builder.setLargeIcon(player.getThumbnail()); - } - - notificationSlot0 = player.sharedPreferences.getString( - player.context.getString(R.string.notification_slot_0_key), notificationSlot0); - notificationSlot1 = player.sharedPreferences.getString( - player.context.getString(R.string.notification_slot_1_key), notificationSlot1); - notificationSlot2 = player.sharedPreferences.getString( - player.context.getString(R.string.notification_slot_2_key), notificationSlot2); - notificationSlot3 = player.sharedPreferences.getString( - player.context.getString(R.string.notification_slot_3_key), notificationSlot3); - notificationSlot4 = player.sharedPreferences.getString( - player.context.getString(R.string.notification_slot_4_key), notificationSlot4); - - addAction(builder, player, notificationSlot0); - addAction(builder, player, notificationSlot1); - addAction(builder, player, notificationSlot2); - addAction(builder, player, notificationSlot3); - addAction(builder, player, notificationSlot4); - } - - return builder; - } - /** * Updates the notification, and the button icons depending on the playback state. * On old notifications used for changes on the remoteView * * @param player the player currently open, to take data from - * @param playPauseDrawable if != -1, sets the drawable with that id on the play/pause button */ - synchronized void updateNotification(final VideoPlayerImpl player, - @DrawableRes final int playPauseDrawable) { + synchronized void updateNotification(final VideoPlayerImpl player) { if (DEBUG) { Log.d(TAG, "N_ updateNotification()"); } @@ -192,56 +82,116 @@ public final class NotificationUtil { if (notificationBuilder == null) { return; } - if (playPauseDrawable != -1) { - if (notificationRemoteView != null) { - notificationRemoteView - .setImageViewResource(R.id.notificationPlayPause, playPauseDrawable); - } - if (bigNotificationRemoteView != null) { - bigNotificationRemoteView - .setImageViewResource(R.id.notificationPlayPause, playPauseDrawable); - } + + notificationBuilder.setContentTitle(player.getVideoTitle()); + notificationBuilder.setContentText(player.getUploaderName()); + final boolean scaleImageToSquareAspectRatio = player.sharedPreferences.getBoolean( + player.context.getString(R.string.scale_to_square_image_in_notifications_key), + false); + if (scaleImageToSquareAspectRatio) { + notificationBuilder.setLargeIcon( + getBitmapWithSquareAspectRatio(player.getThumbnail())); + } else { + notificationBuilder.setLargeIcon(player.getThumbnail()); } - final boolean areOldNotificationsEnabled = player.sharedPreferences.getBoolean( - player.context.getString(R.string.enable_old_notifications_key), false); - if (!areOldNotificationsEnabled) { - notificationBuilder.setContentTitle(player.getVideoTitle()); - notificationBuilder.setContentText(player.getUploaderName()); - final boolean scaleImageToSquareAspectRatio = player.sharedPreferences.getBoolean( - player.context.getString(R.string.scale_to_square_image_in_notifications_key), - false); - if (scaleImageToSquareAspectRatio) { - notificationBuilder.setLargeIcon( - getBitmapWithSquareAspectRatio(player.getThumbnail())); - } else { - notificationBuilder.setLargeIcon(player.getThumbnail()); - } - - setAction(player, notificationSlot0, 0); - setAction(player, notificationSlot1, 1); - setAction(player, notificationSlot2, 2); - setAction(player, notificationSlot3, 3); - setAction(player, notificationSlot4, 4); - } + setAction(player, notificationSlot0, 0); + setAction(player, notificationSlot1, 1); + setAction(player, notificationSlot2, 2); + setAction(player, notificationSlot3, 3); + setAction(player, notificationSlot4, 4); notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build()); - - if (areOldNotificationsEnabled) { - timesNotificationUpdated++; - } } - void recreateNotification(final VideoPlayerImpl player, final boolean recreate) { - final boolean areOldNotificationsEnabled = player.sharedPreferences.getBoolean( - player.context.getString(R.string.enable_old_notifications_key), false); - if (notificationBuilder == null || recreate || areOldNotificationsEnabled) { + /** + * Creates the notification, if it does not exist already or unless forceRecreate is true. + * @param player the player currently open, to take data from + * @param forceRecreate whether to force the recreation of the notification even if it already + * exists + */ + void createNotificationIfNeeded(final VideoPlayerImpl player, final boolean forceRecreate) { + if (notificationBuilder == null || forceRecreate) { if (DEBUG) { - Log.d(TAG, "N_ recreateNotification(true)"); + Log.d(TAG, "N_ createNotificationIfNeeded(true)"); } notificationBuilder = createNotification(player); } - timesNotificationUpdated = 0; + } + + private NotificationCompat.Builder createNotification(final VideoPlayerImpl player) { + notificationManager = + (NotificationManager) player.context.getSystemService(NOTIFICATION_SERVICE); + NotificationCompat.Builder builder = new NotificationCompat.Builder(player.context, + player.context.getString(R.string.notification_channel_id)); + + final String compactView = player.sharedPreferences.getString(player.context.getString( + R.string.settings_notifications_compact_view_key), "0,1,2"); + int compactSlot0 = 0; + int compactSlot1 = 1; + int compactSlot2 = 2; + try { + if (compactView != null) { + final String[] parts = compactView.split(","); + compactSlot0 = Integer.parseInt(parts[0]); + compactSlot1 = Integer.parseInt(parts[1]); + compactSlot2 = Integer.parseInt(parts[2]); + if (compactSlot0 > 4) { + compactSlot0 = 0; + } + if (compactSlot1 > 4) { + compactSlot1 = 1; + } + if (compactSlot2 > 4) { + compactSlot2 = 2; + } + } + } catch (Exception e) { + e.printStackTrace(); + } + + builder.setStyle(new androidx.media.app.NotificationCompat.MediaStyle() + .setMediaSession(player.mediaSessionManager.getSessionToken()) + .setShowCancelButton(false) + .setShowActionsInCompactView(compactSlot0, compactSlot1, compactSlot2)) + .setOngoing(false) + .setContentIntent(PendingIntent.getActivity(player.context, NOTIFICATION_ID, + getIntentForNotification(player), FLAG_UPDATE_CURRENT)) + .setSmallIcon(R.drawable.ic_newpipe_triangle_white) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + .setContentTitle(player.getVideoTitle()) + .setContentText(player.getUploaderName()) + .setDeleteIntent(PendingIntent.getActivity(player.context, NOTIFICATION_ID, + new Intent(ACTION_CLOSE), FLAG_UPDATE_CURRENT)) + .setColor(ContextCompat.getColor(player.context, R.color.gray)) + .setPriority(NotificationCompat.PRIORITY_HIGH); + final boolean scaleImageToSquareAspectRatio = player.sharedPreferences.getBoolean( + player.context.getString(R.string.scale_to_square_image_in_notifications_key), + false); + if (scaleImageToSquareAspectRatio) { + builder.setLargeIcon(getBitmapWithSquareAspectRatio(player.getThumbnail())); + } else { + builder.setLargeIcon(player.getThumbnail()); + } + + notificationSlot0 = player.sharedPreferences.getString( + player.context.getString(R.string.notification_slot_0_key), notificationSlot0); + notificationSlot1 = player.sharedPreferences.getString( + player.context.getString(R.string.notification_slot_1_key), notificationSlot1); + notificationSlot2 = player.sharedPreferences.getString( + player.context.getString(R.string.notification_slot_2_key), notificationSlot2); + notificationSlot3 = player.sharedPreferences.getString( + player.context.getString(R.string.notification_slot_3_key), notificationSlot3); + notificationSlot4 = player.sharedPreferences.getString( + player.context.getString(R.string.notification_slot_4_key), notificationSlot4); + + addAction(builder, player, notificationSlot0); + addAction(builder, player, notificationSlot1); + addAction(builder, player, notificationSlot2); + addAction(builder, player, notificationSlot3); + addAction(builder, player, notificationSlot4); + + return builder; } @@ -251,65 +201,18 @@ public final class NotificationUtil { boolean hasSlotWithBuffering() { - return notificationSlot0.contains("buffering") - || notificationSlot1.contains("buffering") - || notificationSlot2.contains("buffering") - || notificationSlot3.contains("buffering") - || notificationSlot4.contains("buffering"); - } - - - ///////////////////////////////////////////////////// - // OLD NOTIFICATION - ///////////////////////////////////////////////////// - - @Deprecated - boolean shouldRecreateOldNotification() { - return timesNotificationUpdated > NOTIFICATION_UPDATES_BEFORE_RESET; - } - - /** - * @param bitmap if null, the thumbnail will be removed - */ - @Deprecated // only used for old notifications - void updateOldNotificationsThumbnail(@Nullable final Bitmap bitmap) { - if (notificationRemoteView != null) { - notificationRemoteView.setImageViewBitmap(R.id.notificationCover, bitmap); - } - if (bigNotificationRemoteView != null) { - bigNotificationRemoteView.setImageViewBitmap(R.id.notificationCover, bitmap); - } - } - - @Deprecated // only used for old notifications - void setProgressbarOnOldNotifications(final int max, final int progress, - final boolean indeterminate) { - if (bigNotificationRemoteView != null) { //FIXME put in Util and turn into a method - bigNotificationRemoteView.setProgressBar(R.id.notificationProgressBar, max, progress, - indeterminate); - } - if (notificationRemoteView != null) { - notificationRemoteView.setProgressBar(R.id.notificationProgressBar, max, progress, - indeterminate); - } - } - - @Deprecated // only used for old notifications - void setCachedDuration(final int currentProgress, final int duration) { - if (bigNotificationRemoteView != null) { - if (cachedDuration != duration) { - cachedDuration = duration; - cachedDurationString = getTimeString(duration); - } - bigNotificationRemoteView.setTextViewText(R.id.notificationTime, - getTimeString(currentProgress) + " / " + cachedDurationString); - } + return notificationSlot0.equals("play_pause_buffering") + || notificationSlot1.equals("play_pause_buffering") + || notificationSlot2.equals("play_pause_buffering") + || notificationSlot3.equals("play_pause_buffering") + || notificationSlot4.equals("play_pause_buffering"); } public void cancelNotification() { try { if (notificationManager != null) { notificationManager.cancel(NOTIFICATION_ID); + notificationManager = null; } } catch (Exception e) { Log.e("NotificationUtil", "Exception", e); @@ -317,64 +220,6 @@ public final class NotificationUtil { } - ///////////////////////////////////////////////////// - // OLD NOTIFICATION UTILS - ///////////////////////////////////////////////////// - - @Deprecated // only used for old notifications - private void setupOldNotification(final RemoteViews remoteViews, - final VideoPlayerImpl player) { - remoteViews.setTextViewText(R.id.notificationSongName, player.getVideoTitle()); - remoteViews.setTextViewText(R.id.notificationArtist, player.getUploaderName()); - remoteViews.setImageViewBitmap(R.id.notificationCover, player.getThumbnail()); - - remoteViews.setOnClickPendingIntent(R.id.notificationPlayPause, - PendingIntent.getBroadcast(player.context, NOTIFICATION_ID, - new Intent(ACTION_PLAY_PAUSE), FLAG_UPDATE_CURRENT)); - remoteViews.setOnClickPendingIntent(R.id.notificationStop, - PendingIntent.getBroadcast(player.context, NOTIFICATION_ID, - new Intent(ACTION_CLOSE), FLAG_UPDATE_CURRENT)); - remoteViews.setOnClickPendingIntent(R.id.notificationRepeat, - PendingIntent.getBroadcast(player.context, NOTIFICATION_ID, - new Intent(ACTION_REPEAT), FLAG_UPDATE_CURRENT)); - remoteViews.setOnClickPendingIntent(R.id.notificationContent, - PendingIntent.getBroadcast(player.context, NOTIFICATION_ID, - getIntentForNotification(player), FLAG_UPDATE_CURRENT)); - - if (player.playQueue != null && player.playQueue.size() > 1) { - remoteViews.setInt(R.id.notificationFRewind, - SET_IMAGE_RESOURCE_METHOD, R.drawable.exo_controls_previous); - remoteViews.setInt(R.id.notificationFForward, - SET_IMAGE_RESOURCE_METHOD, R.drawable.exo_controls_next); - remoteViews.setOnClickPendingIntent(R.id.notificationFRewind, - PendingIntent.getBroadcast(player.context, NOTIFICATION_ID, - new Intent(ACTION_PLAY_PREVIOUS), FLAG_UPDATE_CURRENT)); - remoteViews.setOnClickPendingIntent(R.id.notificationFForward, - PendingIntent.getBroadcast(player.context, NOTIFICATION_ID, - new Intent(ACTION_PLAY_NEXT), FLAG_UPDATE_CURRENT)); - } else { - remoteViews.setInt(R.id.notificationFRewind, - SET_IMAGE_RESOURCE_METHOD, R.drawable.exo_controls_rewind); - remoteViews.setInt(R.id.notificationFForward, - SET_IMAGE_RESOURCE_METHOD, R.drawable.exo_controls_fastforward); - remoteViews.setOnClickPendingIntent(R.id.notificationFRewind, - PendingIntent.getBroadcast(player.context, NOTIFICATION_ID, - new Intent(ACTION_FAST_REWIND), FLAG_UPDATE_CURRENT)); - remoteViews.setOnClickPendingIntent(R.id.notificationFForward, - PendingIntent.getBroadcast(player.context, NOTIFICATION_ID, - new Intent(ACTION_FAST_FORWARD), FLAG_UPDATE_CURRENT)); - } - - setRepeatModeIcon(remoteViews, player.getRepeatMode()); - } - - @Deprecated // only used for old notifications - private void setRepeatModeIcon(final RemoteViews remoteViews, final int repeatMode) { - remoteViews.setInt(R.id.notificationRepeat, SET_IMAGE_RESOURCE_METHOD, - getRepeatModeDrawable(repeatMode)); - } - - ///////////////////////////////////////////////////// // ACTIONS ///////////////////////////////////////////////////// @@ -401,11 +246,11 @@ public final class NotificationUtil { || player.getCurrentState() == BasePlayer.STATE_BLOCKED || player.getCurrentState() == BasePlayer.STATE_BUFFERING) { builder.setSmallIcon(android.R.drawable.stat_sys_download); - return getAction(builder, player, R.drawable.ic_file_download_white_24dp, + return getAction(player, R.drawable.ic_file_download_white_24dp, "Buffering", ACTION_BUFFERING); } else { builder.setSmallIcon(R.drawable.ic_newpipe_triangle_white); - return getAction(builder, player, + return getAction(player, player.isPlaying() ? R.drawable.exo_notification_pause : R.drawable.exo_notification_play, player.isPlaying() ? "Pause" : "Play", @@ -416,51 +261,51 @@ public final class NotificationUtil { || player.getCurrentState() == BasePlayer.STATE_PREFLIGHT || player.getCurrentState() == BasePlayer.STATE_BLOCKED || player.getCurrentState() == BasePlayer.STATE_BUFFERING; - return getAction(builder, player, + return getAction(player, pauseOrPlay ? R.drawable.exo_notification_pause : R.drawable.exo_notification_play, pauseOrPlay ? "Pause" : "Play", ACTION_PLAY_PAUSE); case "rewind": - return getAction(builder, player, R.drawable.exo_controls_rewind, + return getAction(player, R.drawable.exo_controls_rewind, "Rewind", ACTION_FAST_REWIND); case "smart_rewind_prev": if (player.playQueue != null && player.playQueue.size() > 1) { - return getAction(builder, player, R.drawable.exo_notification_previous, + return getAction(player, R.drawable.exo_notification_previous, "Prev", ACTION_PLAY_PREVIOUS); } else { - return getAction(builder, player, R.drawable.exo_controls_rewind, + return getAction(player, R.drawable.exo_controls_rewind, "Rewind", ACTION_FAST_REWIND); } case "forward": - return getAction(builder, player, R.drawable.exo_controls_fastforward, + return getAction(player, R.drawable.exo_controls_fastforward, "Forward", ACTION_FAST_FORWARD); case "smart_forward_next": if (player.playQueue != null && player.playQueue.size() > 1) { - return getAction(builder, player, R.drawable.exo_notification_next, + return getAction(player, R.drawable.exo_notification_next, "Next", ACTION_PLAY_NEXT); } else { - return getAction(builder, player, R.drawable.exo_controls_fastforward, + return getAction(player, R.drawable.exo_controls_fastforward, "Forward", ACTION_FAST_FORWARD); } case "next": - return getAction(builder, player, R.drawable.exo_notification_next, + return getAction(player, R.drawable.exo_notification_next, "Next", ACTION_PLAY_NEXT); case "prev": - return getAction(builder, player, R.drawable.exo_notification_previous, + return getAction(player, R.drawable.exo_notification_previous, "Prev", ACTION_PLAY_PREVIOUS); case "repeat": - return getAction(builder, player, getRepeatModeDrawable(player.getRepeatMode()), + return getAction(player, getRepeatModeDrawable(player.getRepeatMode()), getRepeatModeTitle(player.getRepeatMode()), ACTION_REPEAT); case "shuffle": final boolean shuffled = player.playQueue != null && player.playQueue.isShuffled(); - return getAction(builder, player, + return getAction(player, shuffled ? R.drawable.exo_controls_shuffle_on : R.drawable.exo_controls_shuffle_off, shuffled ? "ShuffleOn" : "ShuffleOff", ACTION_SHUFFLE); case "close": - return getAction(builder, player, R.drawable.ic_close_white_24dp, + return getAction(player, R.drawable.ic_close_white_24dp, "Close", ACTION_CLOSE); case "n/a": default: @@ -469,8 +314,7 @@ public final class NotificationUtil { } } - private NotificationCompat.Action getAction(final NotificationCompat.Builder builder, - final VideoPlayerImpl player, + private NotificationCompat.Action getAction(final VideoPlayerImpl player, @DrawableRes final int drawable, final String title, final String intentAction) { diff --git a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java index e9430be0b..e9c8fd89b 100644 --- a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java +++ b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java @@ -57,7 +57,6 @@ import android.widget.RelativeLayout; import android.widget.SeekBar; import android.widget.TextView; -import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; @@ -577,7 +576,7 @@ public class VideoPlayerImpl extends VideoPlayer void onShuffleOrRepeatModeChanged() { updatePlaybackButtons(); updatePlayback(); - resetNotification(false, -1); + resetNotification(false); } @Override @@ -614,7 +613,7 @@ public class VideoPlayerImpl extends VideoPlayer titleTextView.setText(tag.getMetadata().getName()); channelTextView.setText(tag.getMetadata().getUploaderName()); - resetNotification(false, -1); + resetNotification(false); updateMetadata(); } @@ -642,30 +641,6 @@ public class VideoPlayerImpl extends VideoPlayer // setMetadata only updates the metadata when any of the metadata keys are null mediaSessionManager.setMetadata(getVideoTitle(), getUploaderName(), getThumbnail(), duration); - - final boolean areOldNotificationsEnabled = sharedPreferences.getBoolean( - context.getString(R.string.enable_old_notifications_key), false); - if (areOldNotificationsEnabled) { - if (!shouldUpdateOnProgress || getCurrentState() == BasePlayer.STATE_COMPLETED - || getCurrentState() == BasePlayer.STATE_PAUSED || getPlayQueue() == null) { - return; - } - - if (NotificationUtil.getInstance().shouldRecreateOldNotification()) { - NotificationUtil.getInstance().recreateNotification(this, false); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - NotificationUtil.getInstance().updateOldNotificationsThumbnail(getThumbnail()); - } - } - - - NotificationUtil.getInstance().setCachedDuration(currentProgress, duration); - NotificationUtil.getInstance().setProgressbarOnOldNotifications(duration, - currentProgress, false); - - NotificationUtil.getInstance().updateNotification(this, -1); - } } @Override @@ -1083,9 +1058,9 @@ public class VideoPlayerImpl extends VideoPlayer animatePlayButtons(false, 100); getRootView().setKeepScreenOn(false); - NotificationUtil.getInstance().recreateNotification(this, false); + NotificationUtil.getInstance().createNotificationIfNeeded(this, false); NotificationUtil.getInstance().updateNotification( - this, R.drawable.ic_play_arrow_white_24dp); + this); } @Override @@ -1101,7 +1076,7 @@ public class VideoPlayerImpl extends VideoPlayer isForwardPressed = false; isRewindPressed = false; } else { - NotificationUtil.getInstance().updateNotification(this, -1); + NotificationUtil.getInstance().updateNotification(this); } } } @@ -1121,7 +1096,7 @@ public class VideoPlayerImpl extends VideoPlayer checkLandscape(); getRootView().setKeepScreenOn(true); - resetNotification(false, R.drawable.ic_pause_white_24dp); + resetNotification(false); } @Override @@ -1137,7 +1112,7 @@ public class VideoPlayerImpl extends VideoPlayer updateWindowFlags(IDLE_WINDOW_FLAGS); - resetNotification(false, R.drawable.ic_play_arrow_white_24dp); + resetNotification(false); // Remove running notification when user don't want music (or video in popup) // to be played in background @@ -1154,9 +1129,9 @@ public class VideoPlayerImpl extends VideoPlayer animatePlayButtons(false, 100); getRootView().setKeepScreenOn(true); - NotificationUtil.getInstance().recreateNotification(this, false); + NotificationUtil.getInstance().createNotificationIfNeeded(this, false); NotificationUtil.getInstance().updateNotification( - this, R.drawable.ic_play_arrow_white_24dp); + this); } @@ -1170,11 +1145,8 @@ public class VideoPlayerImpl extends VideoPlayer getRootView().setKeepScreenOn(false); updateWindowFlags(IDLE_WINDOW_FLAGS); - NotificationUtil.getInstance().recreateNotification(this, false); - NotificationUtil.getInstance().setProgressbarOnOldNotifications(100, 100, false); - NotificationUtil.getInstance().updateOldNotificationsThumbnail(getThumbnail()); - NotificationUtil.getInstance().updateNotification( - this, R.drawable.ic_replay_white_24dp); + NotificationUtil.getInstance().createNotificationIfNeeded(this, false); + NotificationUtil.getInstance().updateNotification(this); super.onCompleted(); } @@ -1182,8 +1154,6 @@ public class VideoPlayerImpl extends VideoPlayer @Override public void destroy() { super.destroy(); - - NotificationUtil.getInstance().updateOldNotificationsThumbnail(null); service.getContentResolver().unregisterContentObserver(settingsContentObserver); } @@ -1334,10 +1304,9 @@ public class VideoPlayerImpl extends VideoPlayer // Thumbnail Loading //////////////////////////////////////////////////////////////////////////*/ - void resetNotification(final boolean recreate, @DrawableRes final int drawableId) { - NotificationUtil.getInstance().recreateNotification(this, recreate); - NotificationUtil.getInstance().updateOldNotificationsThumbnail(getThumbnail()); - NotificationUtil.getInstance().updateNotification(this, drawableId); + void resetNotification(final boolean recreate) { + NotificationUtil.getInstance().createNotificationIfNeeded(this, recreate); + NotificationUtil.getInstance().updateNotification(this); } @Override @@ -1347,7 +1316,7 @@ public class VideoPlayerImpl extends VideoPlayer // rebuild OLD notification here since remote view does not release bitmaps, // causing memory leaks super.onLoadingComplete(imageUri, view, loadedImage); - resetNotification(true, -1); + resetNotification(true); } @Override @@ -1355,13 +1324,13 @@ public class VideoPlayerImpl extends VideoPlayer final View view, final FailReason failReason) { super.onLoadingFailed(imageUri, view, failReason); - resetNotification(true, -1); + resetNotification(true); } @Override public void onLoadingCancelled(final String imageUri, final View view) { super.onLoadingCancelled(imageUri, view); - resetNotification(true, -1); + resetNotification(true); } /*////////////////////////////////////////////////////////////////////////// diff --git a/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java index 564e3c5ce..a9531693c 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java @@ -11,7 +11,6 @@ import androidx.annotation.Nullable; import androidx.preference.Preference; import org.schabi.newpipe.R; -import org.schabi.newpipe.player.NotificationUtil; import org.schabi.newpipe.util.Constants; public class AppearanceSettingsFragment extends BasePreferenceFragment { @@ -53,18 +52,8 @@ public class AppearanceSettingsFragment extends BasePreferenceFragment { final Preference captionSettings = findPreference(captionSettingsKey); getPreferenceScreen().removePreference(captionSettings); } - - findPreference(getString(R.string.enable_old_notifications_key)) - .setOnPreferenceChangeListener(oldNotificationsOnPreferenceChangeListener); } - private Preference.OnPreferenceChangeListener oldNotificationsOnPreferenceChangeListener - = (preference, newValue) -> { - // kill player notification - NotificationUtil.getInstance().cancelNotification(); - return true; - }; - @Override public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) { addPreferencesFromResource(R.xml.appearance_settings); diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index 98b62238a..36dde583c 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -114,7 +114,6 @@ 144p - enable_old_notifications notifications_compact_view 0,1,2 scale_to_square_image_in_notifications diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ce0ac40ec..20b6b81f6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -58,8 +58,6 @@ org.xbmc.kore Show \"Play with Kodi\" option Display an option to play a video via Kodi media center - Enable old notifications - This enables the old \"Custom RemoteViews\" notifications. If disabled modern MediaStyle notifications will be used. Scale image to 1:1 aspect ratio This will scale the notification image from 16:9 to 1:1 aspect ratio Notification slot 0 diff --git a/app/src/main/res/xml/appearance_settings.xml b/app/src/main/res/xml/appearance_settings.xml index a77663843..3cdaf8e9e 100644 --- a/app/src/main/res/xml/appearance_settings.xml +++ b/app/src/main/res/xml/appearance_settings.xml @@ -39,13 +39,6 @@ android:title="@string/settings_category_notifications_title" app:iconSpaceReserved="false"> - - Date: Tue, 18 Aug 2020 12:11:44 +0000 Subject: [PATCH 075/137] Translated using Weblate (Swedish) Currently translated at 99.1% (579 of 584 strings) --- app/src/main/res/values-sv/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 2c0f16972..ccd9f79e1 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -599,4 +599,7 @@ Kopiera formaterad felrapport Visar resultat för: %s Välj en spellista + Av %s + Skapad av %s + Ingen spellista bokmärkt än \ No newline at end of file From 9ad68097d0fc32a94d8eff30b2c4ea6a6cc9704f Mon Sep 17 00:00:00 2001 From: ssantos Date: Wed, 19 Aug 2020 13:57:26 +0000 Subject: [PATCH 076/137] Translated using Weblate (Portuguese) Currently translated at 100.0% (584 of 584 strings) --- app/src/main/res/values-pt/strings.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 8a3fb139f..5b50a4245 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -221,7 +221,7 @@ Selecione um canal Não existem canais subscritos Selecione um \"kiosk\" - Kiosk + Quiosque Tendências Top 50 Tendências @@ -343,7 +343,7 @@ Ritmo Limpar histórico de visualizações Continuar terminando (sem repetição) a fila de reprodução anexando um vídeo relacionado - Mostrar dica \"Toque longo para colocar na fila\" + Mostrar dica \"Toque longo para pôr na fila\" Mostrar sugestão quando o botão popup ou ambiente de trabalho é pressionado na página de detalhes do vídeo Canais Listas de reprodução @@ -478,7 +478,7 @@ não é possível sobrescrever o ficheiro Existe uma transferência pendente com este nome NewPipe foi fechado enquanto trabalhava no ficheiro - Não há espaço disponível no dispositivo + Não há espaço disponível no aparelho Progresso perdido, porque o ficheiro foi eliminado Tempo limite de conexão Quer limpar o seu histórico de transferências ou apagar todos os ficheiros transferidos\? @@ -591,9 +591,9 @@ Silenciar Ajuda Vídeos - Este conteúdo ainda não é suportado pelo NewPipe. -\n -\nEsperamos que seja suportado em uma versão futura. + Este conteúdo ainda não é suportado pelo NewPipe. +\n +\nEsperamos que seja suportado numa versão futura. ∞ vídeos +100 vídeos Artistas From 97a366d62e9d00992065f883e618539573625398 Mon Sep 17 00:00:00 2001 From: Kim Nyberg Date: Thu, 20 Aug 2020 08:56:27 +0000 Subject: [PATCH 077/137] Translated using Weblate (Swedish) Currently translated at 99.3% (580 of 584 strings) --- app/src/main/res/values-sv/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index ccd9f79e1..bfa1c8cc2 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -602,4 +602,5 @@ Av %s Skapad av %s Ingen spellista bokmärkt än + Visa endast prenumerationer som inte grupperats \ No newline at end of file From b860980df4584aa3c66dacd9ac71dd452842c44f Mon Sep 17 00:00:00 2001 From: Ivo Andonov Date: Fri, 21 Aug 2020 08:13:10 +0000 Subject: [PATCH 078/137] Translated using Weblate (Bulgarian) Currently translated at 65.2% (381 of 584 strings) --- app/src/main/res/values-bg/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 400c8d280..25cd939e8 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -415,4 +415,5 @@ Промени Продължи възпроизвеждане Изтрии данни + Показване на резултати за: %s \ No newline at end of file From 7ead581953b5bc933d6002643795bf75473d1bc5 Mon Sep 17 00:00:00 2001 From: ssantos Date: Wed, 19 Aug 2020 13:57:03 +0000 Subject: [PATCH 079/137] Translated using Weblate (Portuguese (Portugal)) Currently translated at 100.0% (584 of 584 strings) --- app/src/main/res/values-pt-rPT/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index fbd7f6fde..6003629c1 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -75,7 +75,7 @@ Novo Este conteúdo ainda não é suportado pelo NewPipe. \n -\nEsperamos que seja suportado em uma versão futura. +\nEsperamos que seja suportado numa versão futura. Nenhuma Escolha a pasta de transferencias para ficheiros de vídeo Quer apagar este grupo\? @@ -253,7 +253,7 @@ Última atualização do feed: %s Importar base de dados Relatório de erro - Não há espaço disponível no dispositivo + Não há espaço disponível no aparelho Número máximo de tentativas antes de cancelar a transferência A recuperar de um erro do reprodutor Outros @@ -534,7 +534,7 @@ Colocado na lista de reprodução Eliminar um Formato de vídeo predefinido - Mostrar dica \"Toque longo para colocar na fila\" + Mostrar dica \"Toque longo para pôr na fila\" Escolha uma instância Reproduzir Remover todos os dados da página da Web em cache From 59fc1e4b5f2eaedac039e14ebf08a9ad378f8d6b Mon Sep 17 00:00:00 2001 From: Hakim Oubouali Date: Sun, 23 Aug 2020 08:50:00 +0000 Subject: [PATCH 080/137] Translated using Weblate (Berber) Currently translated at 24.3% (142 of 584 strings) --- app/src/main/res/values-ber/strings.xml | 41 +++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-ber/strings.xml b/app/src/main/res/values-ber/strings.xml index 8f442a4ad..cccd53a91 100644 --- a/app/src/main/res/values-ber/strings.xml +++ b/app/src/main/res/values-ber/strings.xml @@ -3,7 +3,7 @@ ⴰⵎⴰⵢⵏⵓ ⵉⵙⵎ - %d ⴰⵙⵙ + %d ⵡⴰⵙⵙ %d ⵓⵙⵙⴰⵏ @@ -85,11 +85,48 @@ ⵔⵏⵓ ⵖⵔ ⵙⵜⵉ ⴰⵙⴽⵙⵍ ⴰⵙⴽⵙⵍ ⴰⵎⴰⵢⵏⵓ - ⵔⵣⵓ ⵙ + ⴱⴹⵓ ⵙ ⵜⵉⵙⵖⴰⵍ ⵔⵣⵓ ⴰⴳⵎ ⴱⴹⵓ ⵙⵔⵙ ⵙⵔ + ⵙ %s + ⵔⵏⵏⵓ ⵜ %s + ⵉⵙ ⵜⵅⵙⴷ ⴰⴷ ⵜⴽⴽⵙⴷ ⵜⵔⴰⴱⴱⵓⵜ ⴰ\? + ⴱⴷⴷ + ⵉⵏⵉⴳⵍ + ⴰⵥⵟⵟⴰ + ⵜⴰⵍⴳⴰⵎⵜ + ⵜⵓⵙⴷⵖⵉⵏ + ⴰⴳⵉ + ⵜⴰⵢⵢⵉⵀⵜ + ⴽⵜⵔ + ⵙⴰⵙⵜⵡⴰ + ⴽⴽⵙ ⴰⵙⵓⵔⵎ + ⴰⵎⵖⵔⵉ ⴷⴼⴼⵉⵔ + ⴰⵎⵖⵔⵉ ⵏ ⵓⴼⵉⴷⵢⵓ + ⵖⵔ ⵙⴰ + ⵙⵙⵎⵔⵙ ⵟⵓⵕ + ⵖⵔ ⴰⴼⵉⴷⵢⵓ,ⴰⵣⵎⵣ: + ⵉⵅⴼⴰⵡⴰⵍ ⵏⵏⴽ (ⵙ ⵜⵏⴳⵍⵉⵣⵜ): + ⴰⵏⵖⵎⵉⵙ: + ⵎⵍ + ⴰⵙⴷⴰⵡ ⵏ ⵓⴳⴰⵎ ⵓⴼⵉⴷⵢⵓ + ⵜⵉⵙⵓⵔⴰ + ⴰⵙⵏⵓⴱⴳ + ⵙⵎⴰⵍ ⴰⵏⵖⵎⵉⵙ + ⴽⴽⵙ ⵜⴰⵙⵓⵔⵉ ⵉ ⵓⵙⴰⵔⵓ + ⴽⴽⵙ ⵜⴰⵙⵓⵔⵉ + ⵉⵙⵙⵓⵔ + ⵙⵙⵓⵔ + ⵙⵎⵔⵙ ⵉⵎⵖⵔⵉ ⵏ ⵉⵎⵙⵍⵉ ⴰⴱⵕⵕⴰⵏⵉ + ⵙⵎⵔⵙ ⵉⵎⵖⵔⵉ ⵏ ⵓⴼⵉⴷⵢⵓ ⴰⴱⵕⵕⴰⵏⵉ + ⵓⵜⵓⵢ + ⵙⵜⵉ ⵉⵎⵉⵏⵉⴳ + ⴰⵙⵎⴰⵍ ⵏ ⵜⴰⵢⴰⴼⵓⵜ ⵉ: %s + ⵎⵉⵏ ⵜⵅⵙⴷ ⴰⴷ ⵜⵜ ⵜⵉⵏⵉⴷ: %1$s\? + %1$s ⵏ ⵜⴰⵏⵏⴰⵢⵉⵏ + ⴰⴷⵔ ⵅ \"ⵔⵣⵓ\"ⴰⴼⴰⴷ ⴰⴷ ⵜⵜⴰⵡⵍⴷ \ No newline at end of file From 18c32863649d5c9ca2edefdde9ca4e7534db8099 Mon Sep 17 00:00:00 2001 From: zeritti Date: Sun, 23 Aug 2020 10:54:34 +0000 Subject: [PATCH 081/137] Translated using Weblate (Czech) Currently translated at 100.0% (584 of 584 strings) --- app/src/main/res/values-cs/strings.xml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 905039622..2adbdec6e 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -108,7 +108,7 @@ Kontrolní součet Určete prosím složku pro stahování později v nastavení Hlášení uživatele - Co:\\nŽádost:\\nJazyk obsahu:\\nSlužba:\\nČas GMT:\\nBalíček:\\nVerze:\\nVerze OS: + Co:\\nŽádost:\\nJazyk obsahu\\nZemě obsahu:\\nJazyk aplikace:\\nSlužba:\\nČas GMT:\\nBalíček:\\nVerze:\\nVerze OS: Vše Kanál Ano @@ -626,4 +626,12 @@ otevření ve vyskakovacím okně %s Založil %s Miniatura avatara kanálu + Strana playlistů + Ukázat jen neseskupené objednávky + Zatím žádné záložky playlistů + Vybrat playlist + Prosím, ověřte, zda chyba již existuje. Pokud založíte duplikovaný tiket, obíráte nás o čas, který bychom mohli věnovat řešení skutečných chyb. + Podat hlášení na GitHubu + Zkopírovat formátované hlášení + Ukazuji výsledky pro: %s \ No newline at end of file From e10c7beedbdc33e7b1dc5c43af09a5442cffa40e Mon Sep 17 00:00:00 2001 From: Kahina Messaoudi Date: Sat, 22 Aug 2020 23:55:50 +0000 Subject: [PATCH 082/137] Translated using Weblate (Kabyle) Currently translated at 31.8% (186 of 584 strings) --- app/src/main/res/values-kab/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-kab/strings.xml b/app/src/main/res/values-kab/strings.xml index b0195ec9c..243103b2a 100644 --- a/app/src/main/res/values-kab/strings.xml +++ b/app/src/main/res/values-kab/strings.xml @@ -165,4 +165,6 @@ Tividyutin Ldi deg uminig %1$s n tmeẓriyin + Yeffeɣ-d deg %1$s + Senned ɣef\"Nadi\" akken ad tebduḍ \ No newline at end of file From c79997ebe36a8ef46d5e402e2f649ae16347e883 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sat, 15 Aug 2020 23:45:23 +0200 Subject: [PATCH 083/137] Show hourglass icon when buffering --- .../newpipe/player/NotificationUtil.java | 72 +++++++++--------- .../ic_hourglass_top_white_24dp.png | Bin 0 -> 302 bytes .../ic_hourglass_top_white_24dp.png | Bin 0 -> 246 bytes .../ic_hourglass_top_white_24dp.png | Bin 0 -> 413 bytes .../ic_hourglass_top_white_24dp.png | Bin 0 -> 614 bytes .../ic_hourglass_top_white_24dp.png | Bin 0 -> 777 bytes 6 files changed, 36 insertions(+), 36 deletions(-) create mode 100644 app/src/main/res/drawable-hdpi/ic_hourglass_top_white_24dp.png create mode 100644 app/src/main/res/drawable-mdpi/ic_hourglass_top_white_24dp.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_hourglass_top_white_24dp.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_hourglass_top_white_24dp.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_hourglass_top_white_24dp.png diff --git a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java index 32dd93bd4..3b7e2ac3d 100644 --- a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java +++ b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java @@ -94,12 +94,7 @@ public final class NotificationUtil { } else { notificationBuilder.setLargeIcon(player.getThumbnail()); } - - setAction(player, notificationSlot0, 0); - setAction(player, notificationSlot1, 1); - setAction(player, notificationSlot2, 2); - setAction(player, notificationSlot3, 3); - setAction(player, notificationSlot4, 4); + updateActions(notificationBuilder, player); notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build()); } @@ -122,7 +117,7 @@ public final class NotificationUtil { private NotificationCompat.Builder createNotification(final VideoPlayerImpl player) { notificationManager = (NotificationManager) player.context.getSystemService(NOTIFICATION_SERVICE); - NotificationCompat.Builder builder = new NotificationCompat.Builder(player.context, + final NotificationCompat.Builder builder = new NotificationCompat.Builder(player.context, player.context.getString(R.string.notification_channel_id)); final String compactView = player.sharedPreferences.getString(player.context.getString( @@ -165,6 +160,7 @@ public final class NotificationUtil { new Intent(ACTION_CLOSE), FLAG_UPDATE_CURRENT)) .setColor(ContextCompat.getColor(player.context, R.color.gray)) .setPriority(NotificationCompat.PRIORITY_HIGH); + final boolean scaleImageToSquareAspectRatio = player.sharedPreferences.getBoolean( player.context.getString(R.string.scale_to_square_image_in_notifications_key), false); @@ -174,22 +170,8 @@ public final class NotificationUtil { builder.setLargeIcon(player.getThumbnail()); } - notificationSlot0 = player.sharedPreferences.getString( - player.context.getString(R.string.notification_slot_0_key), notificationSlot0); - notificationSlot1 = player.sharedPreferences.getString( - player.context.getString(R.string.notification_slot_1_key), notificationSlot1); - notificationSlot2 = player.sharedPreferences.getString( - player.context.getString(R.string.notification_slot_2_key), notificationSlot2); - notificationSlot3 = player.sharedPreferences.getString( - player.context.getString(R.string.notification_slot_3_key), notificationSlot3); - notificationSlot4 = player.sharedPreferences.getString( - player.context.getString(R.string.notification_slot_4_key), notificationSlot4); - - addAction(builder, player, notificationSlot0); - addAction(builder, player, notificationSlot1); - addAction(builder, player, notificationSlot2); - addAction(builder, player, notificationSlot3); - addAction(builder, player, notificationSlot4); + initializeNotificationSlots(player); + updateActions(builder, player); return builder; } @@ -224,32 +206,50 @@ public final class NotificationUtil { // ACTIONS ///////////////////////////////////////////////////// - private void addAction(final NotificationCompat.Builder builder, - final VideoPlayerImpl player, - final String slot) { - builder.addAction(getAction(builder, player, slot)); + private void initializeNotificationSlots(final VideoPlayerImpl player) { + notificationSlot0 = player.sharedPreferences.getString( + player.context.getString(R.string.notification_slot_0_key), notificationSlot0); + notificationSlot1 = player.sharedPreferences.getString( + player.context.getString(R.string.notification_slot_1_key), notificationSlot1); + notificationSlot2 = player.sharedPreferences.getString( + player.context.getString(R.string.notification_slot_2_key), notificationSlot2); + notificationSlot3 = player.sharedPreferences.getString( + player.context.getString(R.string.notification_slot_3_key), notificationSlot3); + notificationSlot4 = player.sharedPreferences.getString( + player.context.getString(R.string.notification_slot_4_key), notificationSlot4); } @SuppressLint("RestrictedApi") - private void setAction(final VideoPlayerImpl player, - final String slot, - final int slotNumber) { - notificationBuilder.mActions.set(slotNumber, getAction(notificationBuilder, player, slot)); + private void updateActions(final NotificationCompat.Builder builder, + final VideoPlayerImpl player) { + builder.mActions.clear(); + addAction(builder, player, notificationSlot0); + addAction(builder, player, notificationSlot1); + addAction(builder, player, notificationSlot2); + addAction(builder, player, notificationSlot3); + addAction(builder, player, notificationSlot4); } - private NotificationCompat.Action getAction(final NotificationCompat.Builder builder, - final VideoPlayerImpl player, + private void addAction(final NotificationCompat.Builder builder, + final VideoPlayerImpl player, + final String slot) { + final NotificationCompat.Action action = getAction(player, slot); + if (action != null) { + builder.addAction(action); + } + } + + @Nullable + private NotificationCompat.Action getAction(final VideoPlayerImpl player, final String slot) { switch (slot) { case "play_pause_buffering": if (player.getCurrentState() == BasePlayer.STATE_PREFLIGHT || player.getCurrentState() == BasePlayer.STATE_BLOCKED || player.getCurrentState() == BasePlayer.STATE_BUFFERING) { - builder.setSmallIcon(android.R.drawable.stat_sys_download); - return getAction(player, R.drawable.ic_file_download_white_24dp, + return getAction(player, R.drawable.ic_hourglass_top_white_24dp, "Buffering", ACTION_BUFFERING); } else { - builder.setSmallIcon(R.drawable.ic_newpipe_triangle_white); return getAction(player, player.isPlaying() ? R.drawable.exo_notification_pause : R.drawable.exo_notification_play, diff --git a/app/src/main/res/drawable-hdpi/ic_hourglass_top_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_hourglass_top_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..13050da089b68bb561b1b88c72a2f23b7a018abf GIT binary patch literal 302 zcmV+}0nz@6P)Nkl%kOb+SFg8yf4J1JA4k(RzB1HQTxKi^J_m z=)PuW{QLo9{cWs9n}O7q&!^F!#XbS_4xm0ZND8`wMg+KnZum6#-uly6KMrp1a^B9PMKK<0)2JsR0Z$Rg|+q0d;Uf;&U3R@|(^8f$<07*qoM6N<$f{e0+ Ak^lez literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_hourglass_top_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_hourglass_top_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..2343e8cb9e297af98a685569a634ee2fe2a422d7 GIT binary patch literal 246 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`Gjdp%toLn>}1CrE62@c;k+MGk9x zRm4<}H?{pg(%crv-L{PNpTnQ29ETmV{+!&{AlPxa;Rm% zW05+kz--6#(N*D^)1=EyU9~N%5><{f@hkk}G4+t{-eVTRx8zv!q#m(ucV8XTq9P4B u(}m85nvxy%aIxE&t>Cu46*kiu=!^C3ukHU_nkEbM2!p4qpUXO@geCyZ!C@@` literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_hourglass_top_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_hourglass_top_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..bdf88fb3b6228c30f5d7dec80785280edab4f951 GIT binary patch literal 413 zcmV;O0b>4%P)O7Aq9@TonZ1cVp_@8>K<>;J^DzwVmC38< z1LtD=zN+(ktciUv|18=ma~ILOXrb~JICfEaJFJaew~aP`7QKnmj{Fqo&IW}2cEZ4# zZF7RbWzV`La!wuX6xsyHjDc;h{A$43RmYuZYGpP73Zv(HuYAv)&@)lE+R%J;_56Su zDb_mQk!?oQ*${vL1aJ?q9r00P%lASAcu;`H{>aB*F#L%hbZ+LFA=;ok00000NkvXX Hu0mjf8wtON literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_hourglass_top_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_hourglass_top_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..f9a097f4de3976b2b71e70580fdd791fd281ca8d GIT binary patch literal 614 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@Zgyv2VAAz;aSW-r^>(&l-XRAOmz5he zHZbu%=U~#364rK-|KAp?`=@>T(7mG}{@|2&8;jy! zt+OoKd@en>*HJFnbaUY|h3_+qRabOY=-Q<+Ja35-zCCXy?@>p#hAqb~9Bc0?ed1d1 z*vBey&9xQNb3_z)KMLMldS;I4v0I$SCwR^lX)wE%>c_NTV#QRZ3Gb|b@h7Z$B$xMY zn<0n&4Y@~Omu|bUE_t=t;g=oHA2ll`PuubP+efQ;f$TkRBRDzJ>+8-gwSG9wA^S_t znK>5>iu-=-`k+^)_pN+GZe#5uW6do}lb<$aDNG*)EF|P6HvpDckwDj1G?-?tMo%@Rf87m*1*9rS46sEPcJ$%c|$BODohp%cm z?AxK4wM#-+VqKnKRprk4o+sv*oy$tuaX#`9*V8)zw-4S}`p{0(>3rEbW6p(^)lW{v zAM#rIE$^x1h4}tjyCY|Lewzedp7lJb${}C!TcxwFHG}O2d6WqHD4zC*Qw}V2VQ<5a i{D+`ebq$>MLi|jkkK9kjrLMsA!{F)a=d#Wzp$Pz@f(ADL literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_hourglass_top_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_hourglass_top_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..7a099dabfe78a342fb0ab8821a1344cbdc805c18 GIT binary patch literal 777 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7Ro>V7lPx;uunK>+RhASxk-s?e7_N zm@+RdHCocWv|r(6@F~$s21l0p3QN8Swk+`$R%+VntMfLOd843C^VFNF`zO?|+v$9M z_wB!R1`6}cH=EzT^Uji6%9TU0MZgJ6{L9=MXFug+4NHI)BhXHwK!6&9bMj-MC-?da zUnn=s+qheZVMFqppBxX4+-TJ+h`DfT|78h(C3#g2TVHqA%K^!sjeqWUxKgrlGLuT( zqK#J;1*GVGyAyH!#(^7$ZfLb1Suaw(VB;M3g(qW5oUfXnW<21tQ95wNr4SM6>L8~u z_EmpoCLMG1wT*T-vg+7TMg|=b?Y;~B)(aQ@teEt%$vQwstDd=I-6~`4$osKId;h*% zG0pLIlFt0C3iHdjE^Pa-d2c||w$}e|Tbs7)9?H~DVR&#O;&enkJ45YH3$?{BC)cOF zxprf*@=kBt%lcocCd)m2%){}LVat>q_2SoBxVL@1s_64X!O8i3mh~%MZR51N z_2|9F{LI&Le6tVDPP(gIW}3oK8v3|ozO*{0dDXJ6SpKh>%UAxac(>xu(!TO7C&Ge$ ztbZ}5uSQ3<{7}sC*^aidnXfW)BMZK7Dx6fXIDN^+5ND5?OWzK~{r<-JUGh&}^pYI? z8!fT#4Zm%zX}i76<8s`I0-lH4bT4fYHzBe6Gzc(!aL+@ex1X Date: Sun, 16 Aug 2020 00:01:43 +0200 Subject: [PATCH 084/137] Extract hardcoded strings into strings.xml and improve them --- .../newpipe/player/NotificationUtil.java | 10 +- app/src/main/res/values/settings_keys.xml | 172 +++++++++--------- app/src/main/res/values/strings.xml | 33 +++- app/src/main/res/xml/appearance_settings.xml | 58 +++--- 4 files changed, 144 insertions(+), 129 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java index 3b7e2ac3d..96ade4d7e 100644 --- a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java +++ b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java @@ -208,15 +208,15 @@ public final class NotificationUtil { private void initializeNotificationSlots(final VideoPlayerImpl player) { notificationSlot0 = player.sharedPreferences.getString( - player.context.getString(R.string.notification_slot_0_key), notificationSlot0); + player.context.getString(R.string.notification_action_0_key), notificationSlot0); notificationSlot1 = player.sharedPreferences.getString( - player.context.getString(R.string.notification_slot_1_key), notificationSlot1); + player.context.getString(R.string.notification_action_1_key), notificationSlot1); notificationSlot2 = player.sharedPreferences.getString( - player.context.getString(R.string.notification_slot_2_key), notificationSlot2); + player.context.getString(R.string.notification_action_2_key), notificationSlot2); notificationSlot3 = player.sharedPreferences.getString( - player.context.getString(R.string.notification_slot_3_key), notificationSlot3); + player.context.getString(R.string.notification_action_3_key), notificationSlot3); notificationSlot4 = player.sharedPreferences.getString( - player.context.getString(R.string.notification_slot_4_key), notificationSlot4); + player.context.getString(R.string.notification_action_4_key), notificationSlot4); } @SuppressLint("RestrictedApi") diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index 36dde583c..6099c6ecf 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -118,107 +118,107 @@ 0,1,2 scale_to_square_image_in_notifications - prev - next - rewind - forward - smart_rewind_prev - smart_forward_next - play_pause_buffering - play_pause - repeat - shuffle - close - n/a + prev + next + rewind + forward + smart_rewind_prev + smart_forward_next + play_pause_buffering + play_pause + repeat + shuffle + close + n/a - notification_slot_0_key - @string/notification_slot_smart_rewind_prev_key - - Rewind / Previous - Previous - Rewind + notification_action_0_key + @string/notification_action_smart_rewind_prev_key + + @string/notification_action_smart_rewind_prev_value + @string/notification_action_prev_value + @string/notification_action_rewind_value - - @string/notification_slot_smart_rewind_prev_key - @string/notification_slot_prev_key - @string/notification_slot_rewind_key + + @string/notification_action_smart_rewind_prev_key + @string/notification_action_prev_key + @string/notification_action_rewind_key - notification_slot_1_key - @string/notification_slot_play_pause_buffering_key - - Play / Pause / Buffering - Play / Pause - Rewind + notification_action_1_key + @string/notification_action_play_pause_buffering_key + + @string/notification_action_play_pause_buffering_value + @string/notification_action_play_pause_value + @string/notification_action_rewind_value - - @string/notification_slot_play_pause_buffering_key - @string/notification_slot_play_pause_key - @string/notification_slot_rewind_key + + @string/notification_action_play_pause_buffering_key + @string/notification_action_play_pause_key + @string/notification_action_rewind_key - notification_slot_2_key - @string/notification_slot_smart_forward_next_key - - Forward / Next - Forward - Next - Play / Pause / Buffering - Play / Pause + notification_action_2_key + @string/notification_action_smart_forward_next_key + + @string/notification_action_smart_forward_next_value + @string/notification_action_forward_value + @string/notification_action_next_value + @string/notification_action_play_pause_buffering_value + @string/notification_action_play_pause_value - - @string/notification_slot_smart_forward_next_key - @string/notification_slot_forward_key - @string/notification_slot_next_key - @string/notification_slot_play_pause_buffering_key - @string/notification_slot_play_pause_key + + @string/notification_action_smart_forward_next_key + @string/notification_action_forward_key + @string/notification_action_next_key + @string/notification_action_play_pause_buffering_key + @string/notification_action_play_pause_key - notification_slot_3_key - @string/notification_slot_repeat_key - - Repeat - Shuffle - Previous - Forward - Forward / Next - Rewind - Rewind / Previous - Close - N/A + notification_action_3_key + @string/notification_action_repeat_key + + @string/notification_action_repeat_value + @string/notification_action_shuffle_value + @string/notification_action_prev_value + @string/notification_action_forward_value + @string/notification_action_smart_forward_next_value + @string/notification_action_rewind_value + @string/notification_action_smart_rewind_prev_value + @string/notification_action_close_value + @string/notification_action_n_a_value - - @string/notification_slot_repeat_key - @string/notification_slot_shuffle_key - @string/notification_slot_prev_key - @string/notification_slot_forward_key - @string/notification_slot_smart_forward_next_key - @string/notification_slot_rewind_key - @string/notification_slot_smart_rewind_prev_key - @string/notification_slot_close_key - @string/notification_slot_n_a_key + + @string/notification_action_repeat_key + @string/notification_action_shuffle_key + @string/notification_action_prev_key + @string/notification_action_forward_key + @string/notification_action_smart_forward_next_key + @string/notification_action_rewind_key + @string/notification_action_smart_rewind_prev_key + @string/notification_action_close_key + @string/notification_action_n_a_key - notification_slot_4_key - @string/notification_slot_close_key - - Close - Repeat - Shuffle - Next - Forward - Forward / Next - N/A + notification_action_4_key + @string/notification_action_close_key + + @string/notification_action_close_value + @string/notification_action_repeat_value + @string/notification_action_shuffle_value + @string/notification_action_next_value + @string/notification_action_forward_value + @string/notification_action_smart_forward_next_value + @string/notification_action_n_a_value - - @string/notification_slot_close_key - @string/notification_slot_repeat_key - @string/notification_slot_shuffle_key - @string/notification_slot_next_key - @string/notification_slot_forward_key - @string/notification_slot_smart_forward_next_key - @string/notification_slot_n_a_key + + @string/notification_action_close_key + @string/notification_action_repeat_key + @string/notification_action_shuffle_key + @string/notification_action_next_key + @string/notification_action_forward_key + @string/notification_action_smart_forward_next_key + @string/notification_action_n_a_key video_mp4 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 20b6b81f6..3f58d186a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -58,15 +58,30 @@ org.xbmc.kore Show \"Play with Kodi\" option Display an option to play a video via Kodi media center - Scale image to 1:1 aspect ratio - This will scale the notification image from 16:9 to 1:1 aspect ratio - Notification slot 0 - Notification slot 1 - Notification slot 2 - Notification slot 3 - Notification slot 4 - Notification compact view - Notification slots to show in compact view + + Scale image to 1:1 aspect ratio + This will scale the notification image from 16:9 to 1:1 aspect ratio + First action button + Second action button + Third action button + Fourth action button + Fifth action button + Notification compact view + Notification slots to show in compact view + + Previous + Next + Rewind + Forward + Rewind / Previous + Forward / Next + Play / Pause / Buffering + Play / Pause + Repeat + Shuffle + Close + Nothing + Audio Default audio format Default video format diff --git a/app/src/main/res/xml/appearance_settings.xml b/app/src/main/res/xml/appearance_settings.xml index 3cdaf8e9e..7b25a4ab5 100644 --- a/app/src/main/res/xml/appearance_settings.xml +++ b/app/src/main/res/xml/appearance_settings.xml @@ -42,60 +42,60 @@ From 8b3a09306bb65625b07b955f1312d3486203a167 Mon Sep 17 00:00:00 2001 From: Stypox Date: Thu, 3 Sep 2020 21:49:21 +0200 Subject: [PATCH 085/137] Various notification code improvements Improve builder parameters Reorder code and extract large icon function service.startForeground() now is also provided with service type in android versions >= Q --- .../newpipe/player/NotificationUtil.java | 102 +++++++++--------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java index 96ade4d7e..7c5854442 100644 --- a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java +++ b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java @@ -5,8 +5,10 @@ import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.Intent; +import android.content.pm.ServiceInfo; import android.graphics.Bitmap; import android.graphics.Matrix; +import android.os.Build; import android.util.Log; import androidx.annotation.DrawableRes; @@ -69,38 +71,7 @@ public final class NotificationUtil { ///////////////////////////////////////////////////// /** - * Updates the notification, and the button icons depending on the playback state. - * On old notifications used for changes on the remoteView - * - * @param player the player currently open, to take data from - */ - synchronized void updateNotification(final VideoPlayerImpl player) { - if (DEBUG) { - Log.d(TAG, "N_ updateNotification()"); - } - - if (notificationBuilder == null) { - return; - } - - notificationBuilder.setContentTitle(player.getVideoTitle()); - notificationBuilder.setContentText(player.getUploaderName()); - final boolean scaleImageToSquareAspectRatio = player.sharedPreferences.getBoolean( - player.context.getString(R.string.scale_to_square_image_in_notifications_key), - false); - if (scaleImageToSquareAspectRatio) { - notificationBuilder.setLargeIcon( - getBitmapWithSquareAspectRatio(player.getThumbnail())); - } else { - notificationBuilder.setLargeIcon(player.getThumbnail()); - } - updateActions(notificationBuilder, player); - - notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build()); - } - - /** - * Creates the notification, if it does not exist already or unless forceRecreate is true. + * Creates the notification if it does not exist already or unless forceRecreate is true. * @param player the player currently open, to take data from * @param forceRecreate whether to force the recreation of the notification even if it already * exists @@ -145,40 +116,57 @@ public final class NotificationUtil { e.printStackTrace(); } + builder.setStyle(new androidx.media.app.NotificationCompat.MediaStyle() - .setMediaSession(player.mediaSessionManager.getSessionToken()) - .setShowCancelButton(false) - .setShowActionsInCompactView(compactSlot0, compactSlot1, compactSlot2)) - .setOngoing(false) - .setContentIntent(PendingIntent.getActivity(player.context, NOTIFICATION_ID, - getIntentForNotification(player), FLAG_UPDATE_CURRENT)) + .setMediaSession(player.mediaSessionManager.getSessionToken()) + .setShowActionsInCompactView(compactSlot0, compactSlot1, compactSlot2)) + .setPriority(NotificationCompat.PRIORITY_HIGH) .setSmallIcon(R.drawable.ic_newpipe_triangle_white) .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) .setContentTitle(player.getVideoTitle()) .setContentText(player.getUploaderName()) - .setDeleteIntent(PendingIntent.getActivity(player.context, NOTIFICATION_ID, - new Intent(ACTION_CLOSE), FLAG_UPDATE_CURRENT)) .setColor(ContextCompat.getColor(player.context, R.color.gray)) - .setPriority(NotificationCompat.PRIORITY_HIGH); - - final boolean scaleImageToSquareAspectRatio = player.sharedPreferences.getBoolean( - player.context.getString(R.string.scale_to_square_image_in_notifications_key), - false); - if (scaleImageToSquareAspectRatio) { - builder.setLargeIcon(getBitmapWithSquareAspectRatio(player.getThumbnail())); - } else { - builder.setLargeIcon(player.getThumbnail()); - } + .setContentIntent(PendingIntent.getActivity(player.context, NOTIFICATION_ID, + getIntentForNotification(player), FLAG_UPDATE_CURRENT)) + .setDeleteIntent(PendingIntent.getBroadcast(player.context, NOTIFICATION_ID, + new Intent(ACTION_CLOSE), FLAG_UPDATE_CURRENT)); initializeNotificationSlots(player); updateActions(builder, player); + setLargeIcon(builder, player); return builder; } + /** + * Updates the notification and the button icons depending on the playback state. + * @param player the player currently open, to take data from + */ + synchronized void updateNotification(final VideoPlayerImpl player) { + if (DEBUG) { + Log.d(TAG, "N_ updateNotification()"); + } + + if (notificationBuilder == null) { + return; + } + + notificationBuilder.setContentTitle(player.getVideoTitle()); + notificationBuilder.setContentText(player.getUploaderName()); + updateActions(notificationBuilder, player); + setLargeIcon(notificationBuilder, player); + + notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build()); + } + void startForegroundServiceWithNotification(final Service service) { - service.startForeground(NOTIFICATION_ID, notificationBuilder.build()); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + service.startForeground(NOTIFICATION_ID, notificationBuilder.build(), + ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK); + } else { + service.startForeground(NOTIFICATION_ID, notificationBuilder.build()); + } } @@ -364,6 +352,18 @@ public final class NotificationUtil { // BITMAP ///////////////////////////////////////////////////// + private void setLargeIcon(final NotificationCompat.Builder builder, + final VideoPlayerImpl player) { + final boolean scaleImageToSquareAspectRatio = player.sharedPreferences.getBoolean( + player.context.getString(R.string.scale_to_square_image_in_notifications_key), + false); + if (scaleImageToSquareAspectRatio) { + builder.setLargeIcon(getBitmapWithSquareAspectRatio(player.getThumbnail())); + } else { + builder.setLargeIcon(player.getThumbnail()); + } + } + private Bitmap getBitmapWithSquareAspectRatio(final Bitmap bitmap) { return getResizedBitmap(bitmap, bitmap.getWidth(), bitmap.getWidth()); } From 628575dc5f35ed6f6675223ca79493a199bb3f03 Mon Sep 17 00:00:00 2001 From: Stypox Date: Thu, 3 Sep 2020 22:04:58 +0200 Subject: [PATCH 086/137] Clean up MediaSessionManager --- .../newpipe/player/NotificationUtil.java | 6 ++--- .../player/helper/MediaSessionManager.java | 27 +++++++++---------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java index 7c5854442..95c604472 100644 --- a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java +++ b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java @@ -112,7 +112,7 @@ public final class NotificationUtil { compactSlot2 = 2; } } - } catch (Exception e) { + } catch (final Exception e) { e.printStackTrace(); } @@ -184,8 +184,8 @@ public final class NotificationUtil { notificationManager.cancel(NOTIFICATION_ID); notificationManager = null; } - } catch (Exception e) { - Log.e("NotificationUtil", "Exception", e); + } catch (final Exception e) { + Log.e(TAG, "Could not cancel notification", e); } } diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/MediaSessionManager.java b/app/src/main/java/org/schabi/newpipe/player/helper/MediaSessionManager.java index 3bb2965a2..8d089c6ed 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/MediaSessionManager.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/MediaSessionManager.java @@ -29,10 +29,8 @@ public class MediaSessionManager { private final MediaSessionCompat mediaSession; @NonNull private final MediaSessionConnector sessionConnector; - @NonNull - private final PlaybackStateCompat.Builder playbackStateCompatBuilder; - private int tmpThumbHash; + private int lastAlbumArtHashCode; public MediaSessionManager(@NonNull final Context context, @NonNull final Player player, @@ -42,15 +40,16 @@ public class MediaSessionManager { | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); this.mediaSession.setActive(true); - this.playbackStateCompatBuilder = new PlaybackStateCompat.Builder(); - this.playbackStateCompatBuilder.setState(PlaybackStateCompat.STATE_NONE, -1, 1); - this.playbackStateCompatBuilder.setActions(PlaybackStateCompat.ACTION_SEEK_TO - | PlaybackStateCompat.ACTION_PLAY - | PlaybackStateCompat.ACTION_PAUSE // was play and pause now play/pause - | PlaybackStateCompat.ACTION_SKIP_TO_NEXT - | PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS - | PlaybackStateCompat.ACTION_SET_REPEAT_MODE | PlaybackStateCompat.ACTION_STOP); - this.mediaSession.setPlaybackState(playbackStateCompatBuilder.build()); + this.mediaSession.setPlaybackState(new PlaybackStateCompat.Builder() + .setState(PlaybackStateCompat.STATE_NONE, -1, 1) + .setActions(PlaybackStateCompat.ACTION_SEEK_TO + | PlaybackStateCompat.ACTION_PLAY + | PlaybackStateCompat.ACTION_PAUSE // was play and pause now play/pause + | PlaybackStateCompat.ACTION_SKIP_TO_NEXT + | PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS + | PlaybackStateCompat.ACTION_SET_REPEAT_MODE + | PlaybackStateCompat.ACTION_STOP) + .build()); this.sessionConnector = new MediaSessionConnector(mediaSession); this.sessionConnector.setControlDispatcher(new PlayQueuePlaybackController(callback)); @@ -91,7 +90,7 @@ public class MediaSessionManager { if (getMetadataAlbumArt() == null || getMetadataTitle() == null || getMetadataArtist() == null || getMetadataDuration() <= 1 - || albumArt.hashCode() != tmpThumbHash) { + || albumArt.hashCode() != lastAlbumArtHashCode) { if (DEBUG) { Log.d(TAG, "setMetadata: N_Metadata update: t: " + title + " a: " + artist + " thumb: " + albumArt.hashCode() + " d: " + duration); @@ -103,7 +102,7 @@ public class MediaSessionManager { .putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, albumArt) .putBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON, albumArt) .putLong(MediaMetadataCompat.METADATA_KEY_DURATION, duration).build()); - tmpThumbHash = albumArt.hashCode(); + lastAlbumArtHashCode = albumArt.hashCode(); } } From 00ce077758f8ff20649cb975e4be6107dd7a9382 Mon Sep 17 00:00:00 2001 From: TobiGr Date: Fri, 4 Sep 2020 19:57:28 +0000 Subject: [PATCH 087/137] Translated using Weblate (Korean) Currently translated at 87.3% (510 of 584 strings) --- app/src/main/res/values-ko/strings.xml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 78550ca5e..ef455c7f4 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -527,4 +527,28 @@ 다운로드 기록 삭제 다운로드된 파일 삭제 %1$d 다운로드 삭제 + + %d 선택 + + 이름 + 이 그룹을 삭제하시겠어요\? + 새로운 + 피드 + 피드를 프로세싱합니다… + 피드를 로딩하고 있습니다… + 로드 실패: %d + 마지막으로 업데이트 된 피드; %s + 채널 그룹 + 무음해제 + 무음 + 아직 재생목록 책갈피가 없습니다 + 재생목록 선택 + 해결 되었다면 \"완료\"를 누르세요 + ∞ 비디오 + 100+ 비디오 + 도움말 + 노래 + 이 비디오는 연령제한이 있습니다. +\n +\n만약, 시청을 원한다면 설정에 \"연령 제한 컨텐츠\"를 활성화 하세요. \ No newline at end of file From 0090256ded5df74120a9f3dd9cd4b99fdd89ab8e Mon Sep 17 00:00:00 2001 From: pitachips Date: Fri, 4 Sep 2020 19:53:37 +0000 Subject: [PATCH 088/137] Translated using Weblate (Korean) Currently translated at 87.3% (510 of 584 strings) --- app/src/main/res/values-ko/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index ef455c7f4..ce60b5887 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -551,4 +551,8 @@ 이 비디오는 연령제한이 있습니다. \n \n만약, 시청을 원한다면 설정에 \"연령 제한 컨텐츠\"를 활성화 하세요. + 완료 + 아티스트 + 앨범 + 비디오 \ No newline at end of file From 622676f9bce6a880442ac151c8ff0a3d7e1ff5e1 Mon Sep 17 00:00:00 2001 From: Antony Date: Sun, 6 Sep 2020 09:32:47 +0000 Subject: [PATCH 089/137] Translated using Weblate (Greek) Currently translated at 85.2% (498 of 584 strings) --- app/src/main/res/values-el/strings.xml | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 46133d24b..c3c002fbc 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -122,15 +122,15 @@ Αυτόματη πρόσθεση της επόμενης ροής στην ουρά Αυτόματη πρόσθεση μιας σχετικής ροής όταν αναπαράγεται η προηγούμενη ροή σε μια μη-επαναλαμβανόμενη ουρά Έλεγχος αναπαραγωγής με χειρονομίες - Χρήση χειρονομιών για τον έλεγχο της φωτεινότητας και της έντασης ήχου της εφαρμογής + Χρήση χειρονομιών για τον έλεγχο της φωτεινότητας και της έντασης ήχου Εμφάνιση υποδείξεων ενώ κάνετε αναζήτηση Αποθήκευση αναζητήσεων στη συσκευή Προβολή Ιστορικού Κρατήστε ιστορικό των βίντεο που έχετε δει - Συνέχεια όταν η εφαρμογή έρθει σε πρώτο πλάνο - Συνέχιση της αναπαραγωγής έπειτα από διακοπές (π.χ.: κλήσεις) + Συνέχεια αναπαραγωγής + Συνέχιση της αναπαραγωγής έπειτα από διακοπές (π.χ. κλήσεις) Εμφάνιση της βοήθειας \"Πιέστε παρατεταμένα για πρόσθεση\" - Εμφάνιση της βοήθειας όταν έχει πατηθεί το κουμπί Παρασκηνίου ή Αναδυόμενου παραθύρου στη σελίδα λεπτομερειών του βίντεο + Εμφάνιση υπόδειξης όταν πατηθεί το κουμπί Παρασκηνίου ή Αναδυόμενου παραθύρου στη σελίδα λεπτομερειών του βίντεο Προεπιλεγμένη χώρα περιεχομένου Υπηρεσία Συσκευή Αναπαραγωγής @@ -404,9 +404,9 @@ Νέα Καρτέλα Επιλογή Καρτέλας Ρυθμίσεις χειρονομιών ήχου - Χρησιμοποιήστε χειρονομίες για τον έλεγχο της έντασης του ήχου + Χρησιμοποιήστε χειρονομίες για τον έλεγχο έντασης του ήχου Ρυθμίσεις χειρονομιών φωτεινότητας - Χρησιμοποιήστε χειρονομίες για τον έλεγχο της φωτεινότητας + Χρησιμοποιήστε χειρονομίες για τον έλεγχο φωτεινότητας Ενημερώσεις Συμβάντα Το αρχείο διαγράφηκε @@ -522,4 +522,12 @@ Προεπιλογή συστήματος Βίντεο Εμφάνιση αποτελεσμάτων για: + Ενεργοποίηση γρήγορης λειτουργίας + Απενεργοποίηση γρήγορης λειτουργίας + Αυτό το περιεχόμενο δεν υποστηρίζεται ακόμη από το NewPipe. +\n +\nΕλπίζουμε ότι θα υποστηριχθεί σε μια μελλοντική έκδοση. + Μικρογραφία avatar του καναλιού + Δημιουργήθηκε από %s + Σελίδα λίστας αναπαραγωγής \ No newline at end of file From 408e819d321951a060dbafafa7dbfd94295bf4dd Mon Sep 17 00:00:00 2001 From: Stypox Date: Mon, 7 Sep 2020 15:25:26 +0200 Subject: [PATCH 090/137] Extract duplicate setActivityTitle code to own function --- .../settings/BasePreferenceFragment.java | 22 ++++++------------- .../PeertubeInstanceListFragment.java | 14 ++---------- .../settings/tabs/ChooseTabsFragment.java | 14 ++---------- .../org/schabi/newpipe/util/ThemeHelper.java | 20 +++++++++++++++++ 4 files changed, 31 insertions(+), 39 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/BasePreferenceFragment.java b/app/src/main/java/org/schabi/newpipe/settings/BasePreferenceFragment.java index d8b686297..911d27403 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/BasePreferenceFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/BasePreferenceFragment.java @@ -5,12 +5,12 @@ import android.os.Bundle; import android.preference.PreferenceManager; import android.view.View; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.appcompat.app.ActionBar; -import androidx.appcompat.app.AppCompatActivity; import androidx.preference.PreferenceFragmentCompat; import org.schabi.newpipe.MainActivity; +import org.schabi.newpipe.util.ThemeHelper; public abstract class BasePreferenceFragment extends PreferenceFragmentCompat { protected final String TAG = getClass().getSimpleName() + "@" + Integer.toHexString(hashCode()); @@ -25,24 +25,16 @@ public abstract class BasePreferenceFragment extends PreferenceFragmentCompat { } @Override - public void onViewCreated(final View view, @Nullable final Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); + public void onViewCreated(@NonNull final View rootView, + @Nullable final Bundle savedInstanceState) { + super.onViewCreated(rootView, savedInstanceState); setDivider(null); - updateTitle(); + ThemeHelper.setTitleToAppCompatActivity(getActivity(), getPreferenceScreen().getTitle()); } @Override public void onResume() { super.onResume(); - updateTitle(); - } - - private void updateTitle() { - if (getActivity() instanceof AppCompatActivity) { - final ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar(); - if (actionBar != null) { - actionBar.setTitle(getPreferenceScreen().getTitle()); - } - } + ThemeHelper.setTitleToAppCompatActivity(getActivity(), getPreferenceScreen().getTitle()); } } diff --git a/app/src/main/java/org/schabi/newpipe/settings/PeertubeInstanceListFragment.java b/app/src/main/java/org/schabi/newpipe/settings/PeertubeInstanceListFragment.java index dfa975eef..5dddb14fd 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/PeertubeInstanceListFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/PeertubeInstanceListFragment.java @@ -22,9 +22,7 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.content.res.AppCompatResources; import androidx.appcompat.widget.AppCompatImageView; import androidx.fragment.app.Fragment; @@ -117,7 +115,8 @@ public class PeertubeInstanceListFragment extends Fragment { @Override public void onResume() { super.onResume(); - updateTitle(); + ThemeHelper.setTitleToAppCompatActivity(getActivity(), + getString(R.string.peertube_instance_url_title)); } @Override @@ -176,15 +175,6 @@ public class PeertubeInstanceListFragment extends Fragment { sharedPreferences.edit().putBoolean(Constants.KEY_MAIN_PAGE_CHANGE, true).apply(); } - private void updateTitle() { - if (getActivity() instanceof AppCompatActivity) { - final ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar(); - if (actionBar != null) { - actionBar.setTitle(R.string.peertube_instance_url_title); - } - } - } - private void saveChanges() { final JsonStringWriter jsonWriter = JsonWriter.string().object().array("instances"); for (final PeertubeInstance instance : instanceList) { 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 44fe987ee..2554ecc5c 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 @@ -16,9 +16,7 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.content.res.AppCompatResources; import androidx.appcompat.widget.AppCompatImageView; import androidx.fragment.app.Fragment; @@ -92,7 +90,8 @@ public class ChooseTabsFragment extends Fragment { @Override public void onResume() { super.onResume(); - updateTitle(); + ThemeHelper.setTitleToAppCompatActivity(getActivity(), + getString(R.string.main_page_content)); } @Override @@ -137,15 +136,6 @@ public class ChooseTabsFragment extends Fragment { tabList.addAll(tabsManager.getTabs()); } - private void updateTitle() { - if (getActivity() instanceof AppCompatActivity) { - final ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar(); - if (actionBar != null) { - actionBar.setTitle(R.string.main_page_content); - } - } - } - private void saveChanges() { tabsManager.saveTabs(tabList); } diff --git a/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java b/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java index 88e1a31cd..6b8e884a2 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java @@ -19,6 +19,7 @@ package org.schabi.newpipe.util; +import android.app.Activity; import android.content.Context; import android.content.res.TypedArray; import android.preference.PreferenceManager; @@ -26,7 +27,10 @@ import android.util.TypedValue; import android.view.ContextThemeWrapper; import androidx.annotation.AttrRes; +import androidx.annotation.Nullable; import androidx.annotation.StyleRes; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; import androidx.core.content.ContextCompat; import org.schabi.newpipe.R; @@ -231,4 +235,20 @@ public final class ThemeHelper { return PreferenceManager.getDefaultSharedPreferences(context) .getString(themeKey, defaultTheme); } + + /** + * Sets the title to the activity, if the activity is an {@link AppCompatActivity} and has an + * action bar. + * @param activity the activity to set the title of + * @param title the title to set to the activity + */ + public static void setTitleToAppCompatActivity(@Nullable final Activity activity, + final CharSequence title) { + if (activity instanceof AppCompatActivity) { + final ActionBar actionBar = ((AppCompatActivity) activity).getSupportActionBar(); + if (actionBar != null) { + actionBar.setTitle(title); + } + } + } } From 31814b70dad2ff3e5aeefc4098495d60cbc2cbc7 Mon Sep 17 00:00:00 2001 From: Avently <7953703+avently@users.noreply.github.com> Date: Mon, 7 Sep 2020 19:34:10 +0300 Subject: [PATCH 091/137] Disabled preloading when switching streams --- .../newpipe/fragments/detail/VideoDetailFragment.java | 3 +++ .../java/org/schabi/newpipe/player/BasePlayer.java | 5 +++++ .../org/schabi/newpipe/player/VideoPlayerImpl.java | 4 ++++ .../schabi/newpipe/player/helper/LoadController.java | 11 +++++++++++ 4 files changed, 23 insertions(+) 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 b92becbd1..61a52bd69 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 @@ -958,6 +958,9 @@ public class VideoDetailFragment return; } setInitialData(sid, videoUrl, title, queue); + if (player != null) { + player.disablePreloadingOfCurrentTrack(); + } startLoading(false, true); } diff --git a/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java b/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java index 5e0f9ab94..f126e88a0 100644 --- a/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java @@ -1410,6 +1410,11 @@ public abstract class BasePlayer implements return currentMetadata; } + @NonNull + public LoadController getLoadController() { + return (LoadController) loadControl; + } + @NonNull public String getVideoUrl() { return currentMetadata == null diff --git a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java index 0e06c1aaf..080013ae4 100644 --- a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java +++ b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java @@ -1484,6 +1484,10 @@ public class VideoPlayerImpl extends VideoPlayer } } + public void disablePreloadingOfCurrentTrack() { + getLoadController().disablePreloadingOfCurrentTrack(); + } + /** * Measures width and height of controls visible on screen. * It ensures that controls will be side-by-side with NavigationBar and notches diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/LoadController.java b/app/src/main/java/org/schabi/newpipe/player/helper/LoadController.java index e164e0563..d123a263b 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/LoadController.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/LoadController.java @@ -13,6 +13,7 @@ public class LoadController implements LoadControl { private final long initialPlaybackBufferUs; private final LoadControl internalLoadControl; + private boolean preloadingEnabled = true; /*////////////////////////////////////////////////////////////////////////// // Default Load Control @@ -41,6 +42,7 @@ public class LoadController implements LoadControl { @Override public void onPrepared() { + preloadingEnabled = true; internalLoadControl.onPrepared(); } @@ -52,11 +54,13 @@ public class LoadController implements LoadControl { @Override public void onStopped() { + preloadingEnabled = true; internalLoadControl.onStopped(); } @Override public void onReleased() { + preloadingEnabled = true; internalLoadControl.onReleased(); } @@ -78,6 +82,9 @@ public class LoadController implements LoadControl { @Override public boolean shouldContinueLoading(final long bufferedDurationUs, final float playbackSpeed) { + if (!preloadingEnabled) { + return false; + } return internalLoadControl.shouldContinueLoading(bufferedDurationUs, playbackSpeed); } @@ -90,4 +97,8 @@ public class LoadController implements LoadControl { .shouldStartPlayback(bufferedDurationUs, playbackSpeed, rebuffering); return isInitialPlaybackBufferFilled || isInternalStartingPlayback; } + + public void disablePreloadingOfCurrentTrack() { + preloadingEnabled = false; + } } From 71b32fe64104eabd422b7aa4cea6b30e53c48d22 Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 8 Sep 2020 19:02:05 +0200 Subject: [PATCH 092/137] Add notification costumization settings menu --- .../org/schabi/newpipe/RouterActivity.java | 2 +- .../org/schabi/newpipe/player/MainPlayer.java | 8 +- .../newpipe/player/NotificationConstants.java | 141 +++++++++ .../newpipe/player/NotificationUtil.java | 189 ++++++------ .../newpipe/player/VideoPlayerImpl.java | 5 + .../NotificationSettingsFragment.java | 271 ++++++++++++++++++ .../drawable-hdpi/ic_close_white_24dp_png.png | Bin 0 -> 415 bytes ...ng => ic_hourglass_top_white_24dp_png.png} | Bin .../drawable-mdpi/ic_close_white_24dp_png.png | Bin 0 -> 285 bytes ...ng => ic_hourglass_top_white_24dp_png.png} | Bin .../ic_close_white_24dp_png.png | Bin 0 -> 602 bytes ...ng => ic_hourglass_top_white_24dp_png.png} | Bin .../ic_close_white_24dp_png.png | Bin 0 -> 1034 bytes ...ng => ic_hourglass_top_white_24dp_png.png} | Bin .../ic_close_white_24dp_png.png | Bin 0 -> 2068 bytes ...ng => ic_hourglass_top_white_24dp_png.png} | Bin .../drawable/ic_hourglass_top_white_24dp.xml | 9 + .../main/res/layout/list_radio_icon_item.xml | 4 +- .../main/res/layout/settings_notification.xml | 135 +++++++++ .../layout/settings_notification_action.xml | 88 ++++++ ...view.xml => single_choice_dialog_view.xml} | 0 app/src/main/res/values/settings_keys.xml | 109 +------ app/src/main/res/values/strings.xml | 31 +- app/src/main/res/xml/appearance_settings.xml | 66 ----- app/src/main/res/xml/main_settings.xml | 6 + 25 files changed, 774 insertions(+), 290 deletions(-) create mode 100644 app/src/main/java/org/schabi/newpipe/player/NotificationConstants.java create mode 100644 app/src/main/java/org/schabi/newpipe/settings/NotificationSettingsFragment.java create mode 100644 app/src/main/res/drawable-hdpi/ic_close_white_24dp_png.png rename app/src/main/res/drawable-hdpi/{ic_hourglass_top_white_24dp.png => ic_hourglass_top_white_24dp_png.png} (100%) create mode 100644 app/src/main/res/drawable-mdpi/ic_close_white_24dp_png.png rename app/src/main/res/drawable-mdpi/{ic_hourglass_top_white_24dp.png => ic_hourglass_top_white_24dp_png.png} (100%) create mode 100644 app/src/main/res/drawable-xhdpi/ic_close_white_24dp_png.png rename app/src/main/res/drawable-xhdpi/{ic_hourglass_top_white_24dp.png => ic_hourglass_top_white_24dp_png.png} (100%) create mode 100644 app/src/main/res/drawable-xxhdpi/ic_close_white_24dp_png.png rename app/src/main/res/drawable-xxhdpi/{ic_hourglass_top_white_24dp.png => ic_hourglass_top_white_24dp_png.png} (100%) create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_close_white_24dp_png.png rename app/src/main/res/drawable-xxxhdpi/{ic_hourglass_top_white_24dp.png => ic_hourglass_top_white_24dp_png.png} (100%) create mode 100644 app/src/main/res/drawable/ic_hourglass_top_white_24dp.xml create mode 100644 app/src/main/res/layout/settings_notification.xml create mode 100644 app/src/main/res/layout/settings_notification_action.xml rename app/src/main/res/layout/{preferred_player_dialog_view.xml => single_choice_dialog_view.xml} (100%) diff --git a/app/src/main/java/org/schabi/newpipe/RouterActivity.java b/app/src/main/java/org/schabi/newpipe/RouterActivity.java index 70fceaf07..0d658f3a1 100644 --- a/app/src/main/java/org/schabi/newpipe/RouterActivity.java +++ b/app/src/main/java/org/schabi/newpipe/RouterActivity.java @@ -258,7 +258,7 @@ public class RouterActivity extends AppCompatActivity { final LayoutInflater inflater = LayoutInflater.from(themeWrapperContext); final LinearLayout rootLayout = (LinearLayout) inflater.inflate( - R.layout.preferred_player_dialog_view, null, false); + R.layout.single_choice_dialog_view, null, false); final RadioGroup radioGroup = rootLayout.findViewById(android.R.id.list); final DialogInterface.OnClickListener dialogButtonsClickListener = (dialog, which) -> { diff --git a/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java b/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java index 065efca02..a16fc3cbf 100644 --- a/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java @@ -77,11 +77,11 @@ public final class MainPlayer extends Service { static final String ACTION_FAST_FORWARD = "org.schabi.newpipe.player.MainPlayer.ACTION_FAST_FORWARD"; static final String ACTION_BUFFERING - = "org.schabi.newpipe.player.BackgroundPlayer.ACTION_BUFFERING"; + = "org.schabi.newpipe.player.MainPlayer.ACTION_BUFFERING"; static final String ACTION_SHUFFLE - = "org.schabi.newpipe.player.BackgroundPlayer.ACTION_SHUFFLE"; - - static final String SET_IMAGE_RESOURCE_METHOD = "setImageResource"; + = "org.schabi.newpipe.player.MainPlayer.ACTION_SHUFFLE"; + public static final String ACTION_RECREATE_NOTIFICATION + = "org.schabi.newpipe.player.MainPlayer.ACTION_RECREATE_NOTIFICATION"; /*////////////////////////////////////////////////////////////////////////// // Service's LifeCycle diff --git a/app/src/main/java/org/schabi/newpipe/player/NotificationConstants.java b/app/src/main/java/org/schabi/newpipe/player/NotificationConstants.java new file mode 100644 index 000000000..599e18e65 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/player/NotificationConstants.java @@ -0,0 +1,141 @@ +package org.schabi.newpipe.player; + +import android.content.Context; +import android.content.SharedPreferences; + +import androidx.annotation.DrawableRes; +import androidx.annotation.IntDef; +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; + +import org.schabi.newpipe.R; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.SortedSet; +import java.util.TreeSet; + +public final class NotificationConstants { + + private NotificationConstants() { } + + + public static final int NOTHING = 0; + public static final int PREVIOUS = 1; + public static final int NEXT = 2; + public static final int REWIND = 3; + public static final int FORWARD = 4; + public static final int SMART_REWIND_PREVIOUS = 5; + public static final int SMART_FORWARD_NEXT = 6; + public static final int PLAY_PAUSE = 7; + public static final int PLAY_PAUSE_BUFFERING = 8; + public static final int REPEAT = 9; + public static final int SHUFFLE = 10; + public static final int CLOSE = 11; + + @Retention(RetentionPolicy.SOURCE) + @IntDef({NOTHING, PREVIOUS, NEXT, REWIND, FORWARD, SMART_REWIND_PREVIOUS, SMART_FORWARD_NEXT, + PLAY_PAUSE, PLAY_PAUSE_BUFFERING, REPEAT, SHUFFLE, CLOSE}) + public @interface Action { } + + @StringRes + public static final int[] ACTION_SUMMARIES = { + R.string.notification_action_nothing, + R.string.notification_action_previous, + R.string.notification_action_next, + R.string.notification_action_rewind, + R.string.notification_action_forward, + R.string.notification_action_smart_rewind_previous, + R.string.notification_action_smart_forward_next, + R.string.notification_action_play_pause, + R.string.notification_action_play_pause_buffering, + R.string.notification_action_repeat, + R.string.notification_action_shuffle, + R.string.close, + }; + + @DrawableRes + public static final int[] ACTION_ICONS = { + 0, + R.drawable.exo_icon_previous, + R.drawable.exo_icon_next, + R.drawable.exo_icon_rewind, + R.drawable.exo_icon_fastforward, + R.drawable.exo_icon_previous, + R.drawable.exo_icon_next, + R.drawable.ic_pause_white_24dp, + R.drawable.ic_hourglass_top_white_24dp, + R.drawable.exo_icon_repeat_all, + R.drawable.exo_icon_shuffle_on, + R.drawable.ic_close_white_24dp, + }; + + + @Action + public static final int[] SLOT_DEFAULTS = { + SMART_REWIND_PREVIOUS, + PLAY_PAUSE_BUFFERING, + SMART_FORWARD_NEXT, + REPEAT, + CLOSE, + }; + + @Action + public static final int[][] SLOT_ALLOWED_ACTIONS = { + new int[] {PREVIOUS, REWIND, SMART_REWIND_PREVIOUS}, + new int[] {REWIND, PLAY_PAUSE, PLAY_PAUSE_BUFFERING}, + new int[] {NEXT, FORWARD, SMART_FORWARD_NEXT, PLAY_PAUSE, PLAY_PAUSE_BUFFERING}, + new int[] {NOTHING, PREVIOUS, NEXT, REWIND, FORWARD, SMART_REWIND_PREVIOUS, + SMART_FORWARD_NEXT, REPEAT, SHUFFLE, CLOSE}, + new int[] {NOTHING, NEXT, FORWARD, SMART_FORWARD_NEXT, REPEAT, SHUFFLE, CLOSE}, + }; + + public static final int[] SLOT_PREF_KEYS = { + R.string.notification_slot_0_key, + R.string.notification_slot_1_key, + R.string.notification_slot_2_key, + R.string.notification_slot_3_key, + R.string.notification_slot_4_key, + }; + + + public static final Integer[] SLOT_COMPACT_DEFAULTS = {0, 1, 2}; + + public static final int[] SLOT_COMPACT_PREF_KEYS = { + R.string.notification_slot_compact_0_key, + R.string.notification_slot_compact_1_key, + R.string.notification_slot_compact_2_key, + }; + + /** + * @param context the context to use + * @param sharedPreferences the shared preferences to query values from + * @param slotCount remove indices >= than this value (set to {@code 5} to do nothing, or make + * it lower if there are slots with empty actions) + * @return a sorted list of the indices of the slots to use as compact slots + */ + public static List getCompactSlotsFromPreferences( + @NonNull final Context context, + final SharedPreferences sharedPreferences, + final int slotCount) { + final SortedSet compactSlots = new TreeSet<>(); + for (int i = 0; i < 3; i++) { + final int compactSlot = sharedPreferences.getInt( + context.getString(SLOT_COMPACT_PREF_KEYS[i]), Integer.MAX_VALUE); + + if (compactSlot == Integer.MAX_VALUE) { + // settings not yet populated, return default values + return new ArrayList<>(Arrays.asList(SLOT_COMPACT_DEFAULTS)); + } + + // a negative value (-1) is set when the user does not want a particular compact slot + if (compactSlot >= 0 && compactSlot < slotCount) { + compactSlots.add(compactSlot); + } + } + return new ArrayList<>(compactSlots); + } +} diff --git a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java index 95c604472..2c5e882bb 100644 --- a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java +++ b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java @@ -20,6 +20,8 @@ import org.schabi.newpipe.MainActivity; import org.schabi.newpipe.R; import org.schabi.newpipe.util.NavigationHelper; +import java.util.List; + import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; import static android.content.Context.NOTIFICATION_SERVICE; import static com.google.android.exoplayer2.Player.REPEAT_MODE_ALL; @@ -46,11 +48,8 @@ public final class NotificationUtil { @Nullable private static NotificationUtil instance = null; - private String notificationSlot0 = "smart_rewind_prev"; - private String notificationSlot1 = "play_pause_buffering"; - private String notificationSlot2 = "smart_forward_next"; - private String notificationSlot3 = "repeat"; - private String notificationSlot4 = "close"; + @NotificationConstants.Action + private int[] notificationSlots = NotificationConstants.SLOT_DEFAULTS.clone(); private NotificationManager notificationManager; private NotificationCompat.Builder notificationBuilder; @@ -91,35 +90,28 @@ public final class NotificationUtil { final NotificationCompat.Builder builder = new NotificationCompat.Builder(player.context, player.context.getString(R.string.notification_channel_id)); - final String compactView = player.sharedPreferences.getString(player.context.getString( - R.string.settings_notifications_compact_view_key), "0,1,2"); - int compactSlot0 = 0; - int compactSlot1 = 1; - int compactSlot2 = 2; - try { - if (compactView != null) { - final String[] parts = compactView.split(","); - compactSlot0 = Integer.parseInt(parts[0]); - compactSlot1 = Integer.parseInt(parts[1]); - compactSlot2 = Integer.parseInt(parts[2]); - if (compactSlot0 > 4) { - compactSlot0 = 0; - } - if (compactSlot1 > 4) { - compactSlot1 = 1; - } - if (compactSlot2 > 4) { - compactSlot2 = 2; - } - } - } catch (final Exception e) { - e.printStackTrace(); + initializeNotificationSlots(player); + + // count the number of real slots, to make sure compact slots indices are not out of bound + int nonNothingSlotCount = 5; + if (notificationSlots[3] == NotificationConstants.NOTHING) { + --nonNothingSlotCount; + } + if (notificationSlots[4] == NotificationConstants.NOTHING) { + --nonNothingSlotCount; } + // build the compact slot indices array (need code to convert from Integer... because Java) + final List compactSlotList = NotificationConstants.getCompactSlotsFromPreferences( + player.context, player.sharedPreferences, nonNothingSlotCount); + final int[] compactSlots = new int[compactSlotList.size()]; + for (int i = 0; i < compactSlotList.size(); i++) { + compactSlots[i] = compactSlotList.get(i); + } builder.setStyle(new androidx.media.app.NotificationCompat.MediaStyle() .setMediaSession(player.mediaSessionManager.getSessionToken()) - .setShowActionsInCompactView(compactSlot0, compactSlot1, compactSlot2)) + .setShowActionsInCompactView(compactSlots)) .setPriority(NotificationCompat.PRIORITY_HIGH) .setSmallIcon(R.drawable.ic_newpipe_triangle_white) .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) @@ -131,7 +123,6 @@ public final class NotificationUtil { .setDeleteIntent(PendingIntent.getBroadcast(player.context, NOTIFICATION_ID, new Intent(ACTION_CLOSE), FLAG_UPDATE_CURRENT)); - initializeNotificationSlots(player); updateActions(builder, player); setLargeIcon(builder, player); @@ -171,22 +162,20 @@ public final class NotificationUtil { boolean hasSlotWithBuffering() { - return notificationSlot0.equals("play_pause_buffering") - || notificationSlot1.equals("play_pause_buffering") - || notificationSlot2.equals("play_pause_buffering") - || notificationSlot3.equals("play_pause_buffering") - || notificationSlot4.equals("play_pause_buffering"); + return notificationSlots[1] == NotificationConstants.PLAY_PAUSE_BUFFERING + || notificationSlots[2] == NotificationConstants.PLAY_PAUSE_BUFFERING; } - public void cancelNotification() { + void cancelNotification() { try { if (notificationManager != null) { notificationManager.cancel(NOTIFICATION_ID); - notificationManager = null; } } catch (final Exception e) { Log.e(TAG, "Could not cancel notification", e); } + notificationManager = null; + notificationBuilder = null; } @@ -195,32 +184,25 @@ public final class NotificationUtil { ///////////////////////////////////////////////////// private void initializeNotificationSlots(final VideoPlayerImpl player) { - notificationSlot0 = player.sharedPreferences.getString( - player.context.getString(R.string.notification_action_0_key), notificationSlot0); - notificationSlot1 = player.sharedPreferences.getString( - player.context.getString(R.string.notification_action_1_key), notificationSlot1); - notificationSlot2 = player.sharedPreferences.getString( - player.context.getString(R.string.notification_action_2_key), notificationSlot2); - notificationSlot3 = player.sharedPreferences.getString( - player.context.getString(R.string.notification_action_3_key), notificationSlot3); - notificationSlot4 = player.sharedPreferences.getString( - player.context.getString(R.string.notification_action_4_key), notificationSlot4); + for (int i = 0; i < 5; ++i) { + notificationSlots[i] = player.sharedPreferences.getInt( + player.context.getString(NotificationConstants.SLOT_PREF_KEYS[i]), + NotificationConstants.SLOT_DEFAULTS[i]); + } } @SuppressLint("RestrictedApi") private void updateActions(final NotificationCompat.Builder builder, final VideoPlayerImpl player) { builder.mActions.clear(); - addAction(builder, player, notificationSlot0); - addAction(builder, player, notificationSlot1); - addAction(builder, player, notificationSlot2); - addAction(builder, player, notificationSlot3); - addAction(builder, player, notificationSlot4); + for (int i = 0; i < 5; ++i) { + addAction(builder, player, notificationSlots[i]); + } } private void addAction(final NotificationCompat.Builder builder, final VideoPlayerImpl player, - final String slot) { + @NotificationConstants.Action final int slot) { final NotificationCompat.Action action = getAction(player, slot); if (action != null) { builder.addAction(action); @@ -228,23 +210,42 @@ public final class NotificationUtil { } @Nullable - private NotificationCompat.Action getAction(final VideoPlayerImpl player, - final String slot) { - switch (slot) { - case "play_pause_buffering": - if (player.getCurrentState() == BasePlayer.STATE_PREFLIGHT - || player.getCurrentState() == BasePlayer.STATE_BLOCKED - || player.getCurrentState() == BasePlayer.STATE_BUFFERING) { - return getAction(player, R.drawable.ic_hourglass_top_white_24dp, - "Buffering", ACTION_BUFFERING); + private NotificationCompat.Action getAction( + final VideoPlayerImpl player, + @NotificationConstants.Action final int selectedAction) { + final int baseActionIcon = NotificationConstants.ACTION_ICONS[selectedAction]; + switch (selectedAction) { + case NotificationConstants.PREVIOUS: + return getAction(player, baseActionIcon, "Previous", ACTION_PLAY_PREVIOUS); + + case NotificationConstants.NEXT: + return getAction(player, baseActionIcon, "Next", ACTION_PLAY_NEXT); + + case NotificationConstants.REWIND: + return getAction(player, baseActionIcon, "Rewind", ACTION_FAST_REWIND); + + case NotificationConstants.FORWARD: + return getAction(player, baseActionIcon, "Forward", ACTION_FAST_FORWARD); + + case NotificationConstants.SMART_REWIND_PREVIOUS: + if (player.playQueue != null && player.playQueue.size() > 1) { + return getAction(player, R.drawable.exo_notification_previous, + "Previous", ACTION_PLAY_PREVIOUS); } else { - return getAction(player, - player.isPlaying() ? R.drawable.exo_notification_pause - : R.drawable.exo_notification_play, - player.isPlaying() ? "Pause" : "Play", - ACTION_PLAY_PAUSE); + return getAction(player, R.drawable.exo_controls_rewind, + "Rewind", ACTION_FAST_REWIND); } - case "play_pause": + + case NotificationConstants.SMART_FORWARD_NEXT: + if (player.playQueue != null && player.playQueue.size() > 1) { + return getAction(player, R.drawable.exo_notification_next, + "Next", ACTION_PLAY_NEXT); + } else { + return getAction(player, R.drawable.exo_controls_fastforward, + "Forward", ACTION_FAST_FORWARD); + } + + case NotificationConstants.PLAY_PAUSE: final boolean pauseOrPlay = player.isPlaying() || player.getCurrentState() == BasePlayer.STATE_PREFLIGHT || player.getCurrentState() == BasePlayer.STATE_BLOCKED @@ -254,48 +255,38 @@ public final class NotificationUtil { : R.drawable.exo_notification_play, pauseOrPlay ? "Pause" : "Play", ACTION_PLAY_PAUSE); - case "rewind": - return getAction(player, R.drawable.exo_controls_rewind, - "Rewind", ACTION_FAST_REWIND); - case "smart_rewind_prev": - if (player.playQueue != null && player.playQueue.size() > 1) { - return getAction(player, R.drawable.exo_notification_previous, - "Prev", ACTION_PLAY_PREVIOUS); + + case NotificationConstants.PLAY_PAUSE_BUFFERING: + if (player.getCurrentState() == BasePlayer.STATE_PREFLIGHT + || player.getCurrentState() == BasePlayer.STATE_BLOCKED + || player.getCurrentState() == BasePlayer.STATE_BUFFERING) { + return getAction(player, R.drawable.ic_hourglass_top_white_24dp_png, + "Buffering", ACTION_BUFFERING); } else { - return getAction(player, R.drawable.exo_controls_rewind, - "Rewind", ACTION_FAST_REWIND); + return getAction(player, + player.isPlaying() ? R.drawable.exo_notification_pause + : R.drawable.exo_notification_play, + player.isPlaying() ? "Pause" : "Play", + ACTION_PLAY_PAUSE); } - case "forward": - return getAction(player, R.drawable.exo_controls_fastforward, - "Forward", ACTION_FAST_FORWARD); - case "smart_forward_next": - if (player.playQueue != null && player.playQueue.size() > 1) { - return getAction(player, R.drawable.exo_notification_next, - "Next", ACTION_PLAY_NEXT); - } else { - return getAction(player, R.drawable.exo_controls_fastforward, - "Forward", ACTION_FAST_FORWARD); - } - case "next": - return getAction(player, R.drawable.exo_notification_next, - "Next", ACTION_PLAY_NEXT); - case "prev": - return getAction(player, R.drawable.exo_notification_previous, - "Prev", ACTION_PLAY_PREVIOUS); - case "repeat": + + case NotificationConstants.REPEAT: return getAction(player, getRepeatModeDrawable(player.getRepeatMode()), getRepeatModeTitle(player.getRepeatMode()), ACTION_REPEAT); - case "shuffle": + + case NotificationConstants.SHUFFLE: final boolean shuffled = player.playQueue != null && player.playQueue.isShuffled(); return getAction(player, shuffled ? R.drawable.exo_controls_shuffle_on : R.drawable.exo_controls_shuffle_off, shuffled ? "ShuffleOn" : "ShuffleOff", ACTION_SHUFFLE); - case "close": - return getAction(player, R.drawable.ic_close_white_24dp, + + case NotificationConstants.CLOSE: + return getAction(player, R.drawable.ic_close_white_24dp_png, "Close", ACTION_CLOSE); - case "n/a": + + case NotificationConstants.NOTHING: default: // do nothing return null; diff --git a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java index 024be26dc..c1171efb7 100644 --- a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java +++ b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java @@ -112,6 +112,7 @@ import static org.schabi.newpipe.player.MainPlayer.ACTION_OPEN_CONTROLS; import static org.schabi.newpipe.player.MainPlayer.ACTION_PLAY_NEXT; import static org.schabi.newpipe.player.MainPlayer.ACTION_PLAY_PAUSE; import static org.schabi.newpipe.player.MainPlayer.ACTION_PLAY_PREVIOUS; +import static org.schabi.newpipe.player.MainPlayer.ACTION_RECREATE_NOTIFICATION; import static org.schabi.newpipe.player.MainPlayer.ACTION_REPEAT; import static org.schabi.newpipe.player.MainPlayer.ACTION_SHUFFLE; import static org.schabi.newpipe.player.helper.PlayerHelper.MinimizeMode.MINIMIZE_ON_EXIT_MODE_BACKGROUND; @@ -1179,6 +1180,7 @@ public class VideoPlayerImpl extends VideoPlayer intentFilter.addAction(ACTION_FAST_FORWARD); intentFilter.addAction(ACTION_BUFFERING); intentFilter.addAction(ACTION_SHUFFLE); + intentFilter.addAction(ACTION_RECREATE_NOTIFICATION); intentFilter.addAction(VideoDetailFragment.ACTION_VIDEO_FRAGMENT_RESUMED); intentFilter.addAction(VideoDetailFragment.ACTION_VIDEO_FRAGMENT_STOPPED); @@ -1236,6 +1238,9 @@ public class VideoPlayerImpl extends VideoPlayer case ACTION_SHUFFLE: onShuffleClicked(); break; + case ACTION_RECREATE_NOTIFICATION: + resetNotification(true); + break; case Intent.ACTION_HEADSET_PLUG: //FIXME /*notificationManager.cancel(NOTIFICATION_ID); mediaSessionManager.dispose(); diff --git a/app/src/main/java/org/schabi/newpipe/settings/NotificationSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/NotificationSettingsFragment.java new file mode 100644 index 000000000..f4bbc96a7 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/settings/NotificationSettingsFragment.java @@ -0,0 +1,271 @@ +package org.schabi.newpipe.settings; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CheckBox; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.RadioButton; +import android.widget.RadioGroup; +import android.widget.Switch; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.content.res.AppCompatResources; +import androidx.fragment.app.Fragment; + +import org.schabi.newpipe.R; +import org.schabi.newpipe.player.MainPlayer; +import org.schabi.newpipe.player.NotificationConstants; +import org.schabi.newpipe.util.DeviceUtils; +import org.schabi.newpipe.util.ThemeHelper; +import org.schabi.newpipe.views.FocusOverlayView; + +import java.util.List; + +public class NotificationSettingsFragment extends Fragment { + + private Switch scaleSwitch; + private NotificationSlot[] notificationSlots; + + private SharedPreferences pref; + private List compactSlots; + private String scaleKey; + + //////////////////////////////////////////////////////////////////////////// + // Lifecycle + //////////////////////////////////////////////////////////////////////////// + + @Override + public void onCreate(@Nullable final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + pref = PreferenceManager.getDefaultSharedPreferences(requireContext()); + scaleKey = getString(R.string.scale_to_square_image_in_notifications_key); + } + + @Override + public View onCreateView(@NonNull final LayoutInflater inflater, + final ViewGroup container, + @Nullable final Bundle savedInstanceState) { + return inflater.inflate(R.layout.settings_notification, container, false); + } + + @Override + public void onViewCreated(@NonNull final View rootView, + @Nullable final Bundle savedInstanceState) { + super.onViewCreated(rootView, savedInstanceState); + + setupScaleSwitch(rootView); + setupActions(rootView); + } + + @Override + public void onResume() { + super.onResume(); + ThemeHelper.setTitleToAppCompatActivity(getActivity(), + getString(R.string.settings_category_notification_title)); + } + + @Override + public void onPause() { + super.onPause(); + saveChanges(); + requireContext().sendBroadcast(new Intent(MainPlayer.ACTION_RECREATE_NOTIFICATION)); + } + + + //////////////////////////////////////////////////////////////////////////// + // Setup + //////////////////////////////////////////////////////////////////////////// + + private void setupScaleSwitch(@NonNull final View view) { + scaleSwitch = view.findViewById(R.id.notificationScaleSwitch); + scaleSwitch.setChecked(pref.getBoolean(scaleKey, false)); + + view.findViewById(R.id.notificationScaleSwitchClickableArea) + .setOnClickListener(v -> scaleSwitch.toggle()); + } + + private void setupActions(@NonNull final View view) { + compactSlots = + NotificationConstants.getCompactSlotsFromPreferences(requireContext(), pref, 5); + notificationSlots = new NotificationSlot[5]; + for (int i = 0; i < 5; i++) { + notificationSlots[i] = new NotificationSlot(i, view); + } + } + + + //////////////////////////////////////////////////////////////////////////// + // Saving + //////////////////////////////////////////////////////////////////////////// + + private void saveChanges() { + final SharedPreferences.Editor editor = pref.edit(); + editor.putBoolean(scaleKey, scaleSwitch.isChecked()); + + for (int i = 0; i < 3; i++) { + editor.putInt(getString(NotificationConstants.SLOT_COMPACT_PREF_KEYS[i]), + (i < compactSlots.size() ? compactSlots.get(i) : -1)); + } + + for (int i = 0; i < 5; i++) { + editor.putInt(getString(NotificationConstants.SLOT_PREF_KEYS[i]), + notificationSlots[i].selectedAction); + } + + editor.apply(); + } + + + //////////////////////////////////////////////////////////////////////////// + // Notification action + //////////////////////////////////////////////////////////////////////////// + + private static final int[] SLOT_ITEMS = { + R.id.notificationAction0, + R.id.notificationAction1, + R.id.notificationAction2, + R.id.notificationAction3, + R.id.notificationAction4, + }; + + private static final int[] SLOT_TITLES = { + R.string.notification_action_0_title, + R.string.notification_action_1_title, + R.string.notification_action_2_title, + R.string.notification_action_3_title, + R.string.notification_action_4_title, + }; + + private class NotificationSlot { + + final int i; + @NotificationConstants.Action int selectedAction; + + ImageView icon; + TextView summary; + + NotificationSlot(final int actionIndex, final View parentView) { + this.i = actionIndex; + + final View view = parentView.findViewById(SLOT_ITEMS[i]); + setupSelectedAction(view); + setupTitle(view); + setupCheckbox(view); + } + + void setupTitle(final View view) { + ((TextView) view.findViewById(R.id.notificationActionTitle)) + .setText(SLOT_TITLES[i]); + view.findViewById(R.id.notificationActionClickableArea).setOnClickListener( + v -> openActionChooserDialog()); + } + + void setupCheckbox(final View view) { + final CheckBox compactSlotCheckBox = view.findViewById(R.id.notificationActionCheckBox); + compactSlotCheckBox.setChecked(compactSlots.contains(i)); + view.findViewById(R.id.notificationActionCheckBoxClickableArea).setOnClickListener( + v -> { + if (compactSlotCheckBox.isChecked()) { + compactSlots.remove((Integer) i); + } else if (compactSlots.size() < 3) { + compactSlots.add(i); + } else { + Toast.makeText(requireContext(), + R.string.notification_actions_at_most_three, + Toast.LENGTH_SHORT).show(); + return; + } + + compactSlotCheckBox.toggle(); + }); + } + + void setupSelectedAction(final View view) { + icon = view.findViewById(R.id.notificationActionIcon); + summary = view.findViewById(R.id.notificationActionSummary); + selectedAction = pref.getInt(getString(NotificationConstants.SLOT_PREF_KEYS[i]), + NotificationConstants.SLOT_DEFAULTS[i]); + updateInfo(); + } + + void updateInfo() { + if (NotificationConstants.ACTION_ICONS[selectedAction] == 0) { + icon.setImageDrawable(null); + } else { + icon.setImageDrawable(AppCompatResources.getDrawable(requireContext(), + NotificationConstants.ACTION_ICONS[selectedAction])); + } + + summary.setText(NotificationConstants.ACTION_SUMMARIES[selectedAction]); + } + + void openActionChooserDialog() { + final LayoutInflater inflater = LayoutInflater.from(requireContext()); + final LinearLayout rootLayout = (LinearLayout) inflater.inflate( + R.layout.single_choice_dialog_view, null, false); + final RadioGroup radioGroup = rootLayout.findViewById(android.R.id.list); + + final AlertDialog alertDialog = new AlertDialog.Builder(requireContext()) + .setTitle(SLOT_TITLES[i]) + .setView(radioGroup) + .setCancelable(true) + .create(); + + final View.OnClickListener radioButtonsClickListener = v -> { + final int id = ((RadioButton) v).getId(); + selectedAction = NotificationConstants.SLOT_ALLOWED_ACTIONS[i][id]; + updateInfo(); + alertDialog.dismiss(); + }; + + for (int id = 0; id < NotificationConstants.SLOT_ALLOWED_ACTIONS[i].length; ++id) { + final int action = NotificationConstants.SLOT_ALLOWED_ACTIONS[i][id]; + final RadioButton radioButton + = (RadioButton) inflater.inflate(R.layout.list_radio_icon_item, null); + + // if present set action icon with correct color + if (NotificationConstants.ACTION_ICONS[action] != 0) { + final Drawable drawable = AppCompatResources.getDrawable(requireContext(), + NotificationConstants.ACTION_ICONS[action]); + if (drawable != null) { + final int color = ThemeHelper.resolveColorFromAttr(requireContext(), + android.R.attr.textColorPrimary); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + drawable.setTint(color); + } else { + drawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN); + } + radioButton.setCompoundDrawablesWithIntrinsicBounds( + null, null, drawable, null); + } + } + + radioButton.setText(NotificationConstants.ACTION_SUMMARIES[action]); + radioButton.setChecked(action == selectedAction); + radioButton.setId(id); + radioButton.setLayoutParams(new RadioGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + radioButton.setOnClickListener(radioButtonsClickListener); + radioGroup.addView(radioButton); + } + alertDialog.show(); + + if (DeviceUtils.isTv(requireContext())) { + FocusOverlayView.setupFocusObserver(alertDialog); + } + } + } +} diff --git a/app/src/main/res/drawable-hdpi/ic_close_white_24dp_png.png b/app/src/main/res/drawable-hdpi/ic_close_white_24dp_png.png new file mode 100644 index 0000000000000000000000000000000000000000..2f73a04b16de2d72f6dde7b999d52c196a3d77ed GIT binary patch literal 415 zcmV;Q0bu@#P))B%|VoRJ~51*73|4$uU7wV=LfQ}Z6z>*ua= zz!a=!$bizDY7D3=LCrcgQ_)sin3`_iNWwV%t4_3`c2fu2KEo#SHr)s=ll~i65tRL) z|JmoTsohM)ks)MLjmtidO||%D0_>BqNzgtyn}qC>w~5hB=56xY_Xrr5O-}nB0pzo( zk?6iq7;iU8bYCdUzugqueVom7b`!VzVr}Z|roP=LWmB(i>gqm8o3em23Nia|(N3b9 zJoarlK<~&`Y&SXV(=QGs2WU!AyV!0r?Az1Z%s9Phrb+Xx`32$efF+z^MPdK|002ov JPDHLkV1i~e!B_wQ literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/ic_hourglass_top_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_hourglass_top_white_24dp_png.png similarity index 100% rename from app/src/main/res/drawable-hdpi/ic_hourglass_top_white_24dp.png rename to app/src/main/res/drawable-hdpi/ic_hourglass_top_white_24dp_png.png diff --git a/app/src/main/res/drawable-mdpi/ic_close_white_24dp_png.png b/app/src/main/res/drawable-mdpi/ic_close_white_24dp_png.png new file mode 100644 index 0000000000000000000000000000000000000000..d8aa2f7c4728f3b856ceb84edeb60832e79fcf23 GIT binary patch literal 285 zcmV+&0pk9NP)8bGvk?rMKCB{yZl|vD)G+ z##jL@;0!SyI09S7`2@Uy3qzvGufR)47=iTNaY121+M& z#z&Ih)F;r%lLUL11@0g20P(mp)0?=xB5iB0Yp6QBD7W zx1`g!JG;FZJ>=ZD}aQdPT4cF2JX< z=7`eifcqnhf_N9pnt~GwB5(NSrTLa(UeHeT+085IG!TC^rJX1ntPyJ7yrBO*wzP>c zum^56LColzs3d%_y%pwVP@#*aCi8b6+$biZ{MGh}g*rdcm~T;96#^H+gSIFLbtkla zLR06}H!sZ>U5^(pJ|>qJx_21&<3xz z=J}XDA+Is(906Q`A^5O0&ujX`obFV!Z literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_hourglass_top_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_hourglass_top_white_24dp_png.png similarity index 100% rename from app/src/main/res/drawable-xhdpi/ic_hourglass_top_white_24dp.png rename to app/src/main/res/drawable-xhdpi/ic_hourglass_top_white_24dp_png.png diff --git a/app/src/main/res/drawable-xxhdpi/ic_close_white_24dp_png.png b/app/src/main/res/drawable-xxhdpi/ic_close_white_24dp_png.png new file mode 100644 index 0000000000000000000000000000000000000000..2cd1a88659f07386e028e70877802dd38ecb7ecb GIT binary patch literal 1034 zcmV+l1oiugP)o$Qc;3T*Sj)DV%>Kg$kz!h*T4RN}_C*T|K3-}tG2D`z#DGJj87Qi`h3H-#r zAAxyWMYK?ykKn%hAAi6-@G1B(MS+UoGw=YcvbG=Kdn1yqB8*cODb5LtsDQt~E%2og z$)=O&oFbjP4W5D*tnG**%~@$TI_JB49S#fIqLaEU3RIwTw)xMx@TkwU+lq~1=D`iu z8xEbcN2d)~sAq)kIH+;XB`(-*W+qM85a>Dhj@CW%5UIkM^cEZk+rT>s)X{1NFE|6P zQv@$@PAQ%dam1FTAAqmGZ*F~@u{hIi{Rz}C$hN9n8OXKbRM>Xrx`NHSMGrUxE>k2g zC;bJ_dCd#37i^E=y*t4^umqOb)=nMgY;$m%0p5|uZFPuFI`VOnDfBCy)EmQl_R$eL zbch$KY%6nJG0hWe58KVmqz^vD9#JIYr2Z%~i8E)A&N1Q~d(0e%@3+pGQ%J=*bq4o> zkBh2w(lVXY7U4bebVS+bR_^e%8EXSM#0ThNyM6W%>YPH2hdBc9RzAZI@AwSlGDXbi zq`?eeb5iAbW0yjB4em1@0dCB0HQDO&R_-;BkJ)x5wqdK}r2m*s+Vyc#pzKyBTX~(k zc6eQ179NG%qex3W?dF@^ZpcHEIylf>byUEQ~Lb99OY$YVS$1k6Es_e&Th9spfK4gbauN91365#3YFcm zEKH=mm6W}k4S^!>tt9N-k`$)ly;YifHyZ-Qwzo=S@0Rq;iFI#fbMIzDpv3l8Hui35 zXRC(yR!Q#N(#}?~?5&d6yGhAbvF@$n+`CE1Rd7Xh0#ikSu1z(er2guT@b+3kd1dN)6t zn6!0b9_E+H4<+rb>SVWle)-+}e4@oh5zXLzinPXdTa~c4s>yB}{3k9_95c|HY!%W> zC(UvuO-b5Yad6MmIn(?BPE$^yP$(1%g+ifFC={8%Keh)tWYG$(asU7T07*qoM6N<$ Ef)k_jzyJUM literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_hourglass_top_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_hourglass_top_white_24dp_png.png similarity index 100% rename from app/src/main/res/drawable-xxhdpi/ic_hourglass_top_white_24dp.png rename to app/src/main/res/drawable-xxhdpi/ic_hourglass_top_white_24dp_png.png diff --git a/app/src/main/res/drawable-xxxhdpi/ic_close_white_24dp_png.png b/app/src/main/res/drawable-xxxhdpi/ic_close_white_24dp_png.png new file mode 100644 index 0000000000000000000000000000000000000000..4d278c5bfba91b997502367af09ec686afaf7584 GIT binary patch literal 2068 zcmV+v2elZDN|DP|FjR$7bbg?m#k)*mJjK_RVG z3=%PQgJxK(7)4QUd{bG0f+Mgu1*N5_znvSOyFD}Y_gqbX_owFz-#6v+yXQXVIro0g zdCq+T0fj=LP$(1%g+ifFC=?2XLZMJ76befOgTWYKtT0=6T399g7|x2&drA~;fCq(# zg-g`|>VS79-eI0_4-?-eY!x=buY?)GIT14PX~HaFiSPz&5k3?i;om>;i?OlLnfw~z z?cjfS0n3Pl^aydlQda$b;T!1U4`HR_1iu)&5}so69~;KLg1-nWg!#e*VZ2W#K1rA& z+{`3j5cWbB%{bu*j#?USqif*b!J*MbB-9WISw3~Z=dAootoq(z?&%@#gu~%Bx*E0* zW9%y&;H;?C!W>~Vj0&^;QO0}Bnfy({CJP6&@M1m~ZU^jy&B4&qbQL=Cb)loV!yq-CoTXTJ2lim& zP!r$FV{|`KG;zG`9`1(L6A5Q6BB9@qsNWI^Y2$3~5>{}V#!doF6@EV>G9zdcxD=J}(?MxP?3QL8@g>^h~hI;I{|JQ^%+Kl{63-}RY*a9Nq z`=A|MiTW#%uzZZ|TgM9i-9qW~8!LYk<5K*dMSdvUCfqLUguNjo>PvEjwN8p}WY7ECL)M_ZC8SlxK*@n{TuuwXE{LLL> zTuh`@64e1d$S{+jBTd7U+^;98GTvzT$Ifr$vYvH7g7 z?}X3c8w-hgo|46NiBfXZ%LF@iOhVkeXGD%Lz>?mP)CL22@a!mmhGMKHIeY!2psSRb>yu2RXUp^b3iWbAJriw=0LpW zC4G`SAxmd-WDZ!x3O-{YH3yTZM@iO}=xlm>2e{AcLZ0CbA*AL|67?Jzvs1R12BUPA zhj+kKL$TbqD5}{M@$MQ$yf~d@b$~A?K7|amz{px{s+xTvN)UZKj#{9zsk6*>dvh{5 zAe~je)v~JD>mfRNjVfv$kuX9$Zh7g0wAM(gd+bu)%eY0Oxb9B+j=V_J14P2YNSB&!Z+$WS_H~w0)9vLiB2P#i zp$(Zhu#678N0t)x3}0{N8I{?nNOM4pp;+#CP&ysPxY_T?mPA7#J@=rHt{Ms{S{YP95&qcMSmB^ua$8S;jFNq2x%ym8y2l2uF`pCj7tc!{Yi#G>a^^* zc!6kmtB}+IliUGKu){*>G#RIkxaYL_;mkPqaFFes@^Z_<5v|mzs>1C6_vEXm77n=N zo;u=FCAW=8xM|^lHckjW9d4s@p(D{AkhBbT%vU86HN~$-zHrpe0wn6$AtdT!&PT06 zJYaqn3?eo6v-16U@b$a*w3!$d{IH88eQHOEr zNeOvET7)=YG5w_FMrF30!)Z@3`FZYp%r8byArf+VCo~yKCn7gC=o@ksQZr4!Dba8$F0000 + + diff --git a/app/src/main/res/layout/list_radio_icon_item.xml b/app/src/main/res/layout/list_radio_icon_item.xml index 947747c16..3446e351c 100644 --- a/app/src/main/res/layout/list_radio_icon_item.xml +++ b/app/src/main/res/layout/list_radio_icon_item.xml @@ -10,10 +10,8 @@ android:maxLines="2" android:minHeight="?attr/listPreferredItemHeightSmall" android:paddingEnd="?attr/listPreferredItemPaddingRight" - android:paddingLeft="?attr/listPreferredItemPaddingLeft" - android:paddingRight="?attr/listPreferredItemPaddingRight" android:paddingStart="?attr/listPreferredItemPaddingLeft" android:background="?attr/checked_selector" android:textColor="?attr/textColorAlertDialogListItem" - tools:drawableLeft="?attr/ic_play" + tools:drawableLeft="?attr/ic_play_arrow" tools:text="Lorem ipsum dolor sit amet" /> diff --git a/app/src/main/res/layout/settings_notification.xml b/app/src/main/res/layout/settings_notification.xml new file mode 100644 index 000000000..61b7f1aad --- /dev/null +++ b/app/src/main/res/layout/settings_notification.xml @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/settings_notification_action.xml b/app/src/main/res/layout/settings_notification_action.xml new file mode 100644 index 000000000..8ef2d8ab2 --- /dev/null +++ b/app/src/main/res/layout/settings_notification_action.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/preferred_player_dialog_view.xml b/app/src/main/res/layout/single_choice_dialog_view.xml similarity index 100% rename from app/src/main/res/layout/preferred_player_dialog_view.xml rename to app/src/main/res/layout/single_choice_dialog_view.xml diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index 52b43002d..0aa1435c1 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -118,108 +118,15 @@ 0,1,2 scale_to_square_image_in_notifications - prev - next - rewind - forward - smart_rewind_prev - smart_forward_next - play_pause_buffering - play_pause - repeat - shuffle - close - n/a + notification_slot_0_key + notification_slot_1_key + notification_slot_2_key + notification_slot_3_key + notification_slot_4_key - notification_action_0_key - @string/notification_action_smart_rewind_prev_key - - @string/notification_action_smart_rewind_prev_value - @string/notification_action_prev_value - @string/notification_action_rewind_value - - - @string/notification_action_smart_rewind_prev_key - @string/notification_action_prev_key - @string/notification_action_rewind_key - - - notification_action_1_key - @string/notification_action_play_pause_buffering_key - - @string/notification_action_play_pause_buffering_value - @string/notification_action_play_pause_value - @string/notification_action_rewind_value - - - @string/notification_action_play_pause_buffering_key - @string/notification_action_play_pause_key - @string/notification_action_rewind_key - - - - notification_action_2_key - @string/notification_action_smart_forward_next_key - - @string/notification_action_smart_forward_next_value - @string/notification_action_forward_value - @string/notification_action_next_value - @string/notification_action_play_pause_buffering_value - @string/notification_action_play_pause_value - - - @string/notification_action_smart_forward_next_key - @string/notification_action_forward_key - @string/notification_action_next_key - @string/notification_action_play_pause_buffering_key - @string/notification_action_play_pause_key - - - notification_action_3_key - @string/notification_action_repeat_key - - @string/notification_action_repeat_value - @string/notification_action_shuffle_value - @string/notification_action_prev_value - @string/notification_action_forward_value - @string/notification_action_smart_forward_next_value - @string/notification_action_rewind_value - @string/notification_action_smart_rewind_prev_value - @string/notification_action_close_value - @string/notification_action_n_a_value - - - @string/notification_action_repeat_key - @string/notification_action_shuffle_key - @string/notification_action_prev_key - @string/notification_action_forward_key - @string/notification_action_smart_forward_next_key - @string/notification_action_rewind_key - @string/notification_action_smart_rewind_prev_key - @string/notification_action_close_key - @string/notification_action_n_a_key - - - notification_action_4_key - @string/notification_action_close_key - - @string/notification_action_close_value - @string/notification_action_repeat_value - @string/notification_action_shuffle_value - @string/notification_action_next_value - @string/notification_action_forward_value - @string/notification_action_smart_forward_next_value - @string/notification_action_n_a_value - - - @string/notification_action_close_key - @string/notification_action_repeat_key - @string/notification_action_shuffle_key - @string/notification_action_next_key - @string/notification_action_forward_key - @string/notification_action_smart_forward_next_key - @string/notification_action_n_a_key - + notification_slot_compact_0_key + notification_slot_compact_1_key + notification_slot_compact_2_key video_mp4 video_webm diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 45d806728..21c734741 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -66,21 +66,20 @@ Third action button Fourth action button Fifth action button - Notification compact view - Notification slots to show in compact view - - Previous - Next - Rewind - Forward - Rewind / Previous - Forward / Next - Play / Pause / Buffering - Play / Pause - Repeat - Shuffle - Close - Nothing + Edit each notification action below by tapping on it.\nSelect up to three of them to be shown in the compact notification by using the checkboxes on the right. + You can select at most three actions to show in the compact notification! + + Previous + Next + Rewind + Forward + Rewind / Previous + Forward / Next + Play / Pause / Buffering + Play / Pause + Repeat + Shuffle + Nothing Audio Default audio format @@ -154,7 +153,7 @@ Other Debug Updates - Notifications + Notification Playing in background Playing in popup mode Queued on background player diff --git a/app/src/main/res/xml/appearance_settings.xml b/app/src/main/res/xml/appearance_settings.xml index 7b25a4ab5..e45641f91 100644 --- a/app/src/main/res/xml/appearance_settings.xml +++ b/app/src/main/res/xml/appearance_settings.xml @@ -34,70 +34,4 @@ android:title="@string/caption_setting_title" app:iconSpaceReserved="false" /> - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/xml/main_settings.xml b/app/src/main/res/xml/main_settings.xml index 604f3bb05..af093a757 100644 --- a/app/src/main/res/xml/main_settings.xml +++ b/app/src/main/res/xml/main_settings.xml @@ -35,6 +35,12 @@ android:icon="?attr/ic_language" android:title="@string/content"/> + + Date: Tue, 8 Sep 2020 21:19:43 +0200 Subject: [PATCH 093/137] Make notification creation and cancelling more consistent --- .../org/schabi/newpipe/player/MainPlayer.java | 12 ++---- .../newpipe/player/NotificationUtil.java | 41 ++++++++++--------- .../newpipe/player/VideoPlayerImpl.java | 41 +++++++------------ 3 files changed, 39 insertions(+), 55 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java b/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java index a16fc3cbf..b885d105b 100644 --- a/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java @@ -121,7 +121,7 @@ public final class MainPlayer extends Service { if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction()) || intent.getStringExtra(VideoPlayer.PLAY_QUEUE_KEY) != null) { - showNotificationAndStartForeground(); + NotificationUtil.getInstance().createNotificationAndStartForeground(playerImpl, this); } playerImpl.handleIntent(intent); @@ -154,7 +154,7 @@ public final class MainPlayer extends Service { // So we should hide the notification at all. // When autoplay enabled such notification flashing is annoying so skip this case if (!autoplayEnabled) { - stopForeground(true); + NotificationUtil.getInstance().cancelNotificationAndStopForeground(this); } } } @@ -202,9 +202,8 @@ public final class MainPlayer extends Service { playerImpl.removePopupFromView(); playerImpl.destroy(); } - NotificationUtil.getInstance().cancelNotification(); - stopForeground(true); + NotificationUtil.getInstance().cancelNotificationAndStopForeground(this); stopSelf(); } @@ -243,11 +242,6 @@ public final class MainPlayer extends Service { } } - private void showNotificationAndStartForeground() { - NotificationUtil.getInstance().createNotificationIfNeeded(playerImpl, true); - NotificationUtil.getInstance().startForegroundServiceWithNotification(this); - } - public class LocalBinder extends Binder { diff --git a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java index 2c5e882bb..e05d7d19d 100644 --- a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java +++ b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java @@ -42,7 +42,7 @@ import static org.schabi.newpipe.player.MainPlayer.ACTION_SHUFFLE; * @author cool-student */ public final class NotificationUtil { - private static final String TAG = "NotificationUtil"; + private static final String TAG = NotificationUtil.class.getSimpleName(); private static final boolean DEBUG = BasePlayer.DEBUG; private static final int NOTIFICATION_ID = 123789; @@ -70,21 +70,25 @@ public final class NotificationUtil { ///////////////////////////////////////////////////// /** - * Creates the notification if it does not exist already or unless forceRecreate is true. + * Creates the notification if it does not exist already and recreates it if forceRecreate is + * true. Updates the notification with the data in the player. * @param player the player currently open, to take data from * @param forceRecreate whether to force the recreation of the notification even if it already * exists */ - void createNotificationIfNeeded(final VideoPlayerImpl player, final boolean forceRecreate) { + synchronized void createNotificationIfNeededAndUpdate(final VideoPlayerImpl player, + final boolean forceRecreate) { if (notificationBuilder == null || forceRecreate) { if (DEBUG) { - Log.d(TAG, "N_ createNotificationIfNeeded(true)"); + Log.d(TAG, "N_ createNotificationIfNeededAndUpdate(true)"); } notificationBuilder = createNotification(player); } + updateNotification(player); } - private NotificationCompat.Builder createNotification(final VideoPlayerImpl player) { + private synchronized NotificationCompat.Builder createNotification( + final VideoPlayerImpl player) { notificationManager = (NotificationManager) player.context.getSystemService(NOTIFICATION_SERVICE); final NotificationCompat.Builder builder = new NotificationCompat.Builder(player.context, @@ -115,17 +119,12 @@ public final class NotificationUtil { .setPriority(NotificationCompat.PRIORITY_HIGH) .setSmallIcon(R.drawable.ic_newpipe_triangle_white) .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) - .setContentTitle(player.getVideoTitle()) - .setContentText(player.getUploaderName()) .setColor(ContextCompat.getColor(player.context, R.color.gray)) .setContentIntent(PendingIntent.getActivity(player.context, NOTIFICATION_ID, getIntentForNotification(player), FLAG_UPDATE_CURRENT)) .setDeleteIntent(PendingIntent.getBroadcast(player.context, NOTIFICATION_ID, new Intent(ACTION_CLOSE), FLAG_UPDATE_CURRENT)); - updateActions(builder, player); - setLargeIcon(builder, player); - return builder; } @@ -133,7 +132,7 @@ public final class NotificationUtil { * Updates the notification and the button icons depending on the playback state. * @param player the player currently open, to take data from */ - synchronized void updateNotification(final VideoPlayerImpl player) { + private synchronized void updateNotification(final VideoPlayerImpl player) { if (DEBUG) { Log.d(TAG, "N_ updateNotification()"); } @@ -151,7 +150,15 @@ public final class NotificationUtil { } - void startForegroundServiceWithNotification(final Service service) { + boolean hasSlotWithBuffering() { + return notificationSlots[1] == NotificationConstants.PLAY_PAUSE_BUFFERING + || notificationSlots[2] == NotificationConstants.PLAY_PAUSE_BUFFERING; + } + + + void createNotificationAndStartForeground(final VideoPlayerImpl player, final Service service) { + createNotificationIfNeededAndUpdate(player, true); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { service.startForeground(NOTIFICATION_ID, notificationBuilder.build(), ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK); @@ -160,13 +167,7 @@ public final class NotificationUtil { } } - - boolean hasSlotWithBuffering() { - return notificationSlots[1] == NotificationConstants.PLAY_PAUSE_BUFFERING - || notificationSlots[2] == NotificationConstants.PLAY_PAUSE_BUFFERING; - } - - void cancelNotification() { + void cancelNotificationAndStopForeground(final Service service) { try { if (notificationManager != null) { notificationManager.cancel(NOTIFICATION_ID); @@ -176,6 +177,8 @@ public final class NotificationUtil { } notificationManager = null; notificationBuilder = null; + + service.stopForeground(true); } diff --git a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java index c1171efb7..e2e382bb2 100644 --- a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java +++ b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java @@ -575,7 +575,7 @@ public class VideoPlayerImpl extends VideoPlayer void onShuffleOrRepeatModeChanged() { updatePlaybackButtons(); updatePlayback(); - resetNotification(false); + NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false); } @Override @@ -612,7 +612,7 @@ public class VideoPlayerImpl extends VideoPlayer titleTextView.setText(tag.getMetadata().getName()); channelTextView.setText(tag.getMetadata().getUploaderName()); - resetNotification(false); + NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false); updateMetadata(); } @@ -1059,9 +1059,7 @@ public class VideoPlayerImpl extends VideoPlayer animatePlayButtons(false, 100); getRootView().setKeepScreenOn(false); - NotificationUtil.getInstance().createNotificationIfNeeded(this, false); - NotificationUtil.getInstance().updateNotification( - this); + NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false); } @Override @@ -1077,7 +1075,7 @@ public class VideoPlayerImpl extends VideoPlayer isForwardPressed = false; isRewindPressed = false; } else { - NotificationUtil.getInstance().updateNotification(this); + NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false); } } } @@ -1097,7 +1095,7 @@ public class VideoPlayerImpl extends VideoPlayer checkLandscape(); getRootView().setKeepScreenOn(true); - resetNotification(false); + NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false); } @Override @@ -1113,12 +1111,12 @@ public class VideoPlayerImpl extends VideoPlayer updateWindowFlags(IDLE_WINDOW_FLAGS); - resetNotification(false); - // Remove running notification when user don't want music (or video in popup) // to be played in background if (!minimizeOnPopupEnabled() && !backgroundPlaybackEnabled() && videoPlayerSelected()) { - service.stopForeground(true); + NotificationUtil.getInstance().cancelNotificationAndStopForeground(service); + } else { + NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false); } getRootView().setKeepScreenOn(false); @@ -1130,9 +1128,7 @@ public class VideoPlayerImpl extends VideoPlayer animatePlayButtons(false, 100); getRootView().setKeepScreenOn(true); - NotificationUtil.getInstance().createNotificationIfNeeded(this, false); - NotificationUtil.getInstance().updateNotification( - this); + NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false); } @@ -1146,9 +1142,7 @@ public class VideoPlayerImpl extends VideoPlayer getRootView().setKeepScreenOn(false); updateWindowFlags(IDLE_WINDOW_FLAGS); - NotificationUtil.getInstance().createNotificationIfNeeded(this, false); - NotificationUtil.getInstance().updateNotification(this); - + NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false); super.onCompleted(); } @@ -1239,7 +1233,7 @@ public class VideoPlayerImpl extends VideoPlayer onShuffleClicked(); break; case ACTION_RECREATE_NOTIFICATION: - resetNotification(true); + NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, true); break; case Intent.ACTION_HEADSET_PLUG: //FIXME /*notificationManager.cancel(NOTIFICATION_ID); @@ -1309,19 +1303,12 @@ public class VideoPlayerImpl extends VideoPlayer // Thumbnail Loading //////////////////////////////////////////////////////////////////////////*/ - void resetNotification(final boolean recreate) { - NotificationUtil.getInstance().createNotificationIfNeeded(this, recreate); - NotificationUtil.getInstance().updateNotification(this); - } - @Override public void onLoadingComplete(final String imageUri, final View view, final Bitmap loadedImage) { - // rebuild OLD notification here since remote view does not release bitmaps, - // causing memory leaks super.onLoadingComplete(imageUri, view, loadedImage); - resetNotification(true); + NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false); } @Override @@ -1329,13 +1316,13 @@ public class VideoPlayerImpl extends VideoPlayer final View view, final FailReason failReason) { super.onLoadingFailed(imageUri, view, failReason); - resetNotification(true); + NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false); } @Override public void onLoadingCancelled(final String imageUri, final View view) { super.onLoadingCancelled(imageUri, view); - resetNotification(true); + NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false); } /*////////////////////////////////////////////////////////////////////////// From bc8954fbbafc737cd950a2b86fe89694d87f0120 Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 8 Sep 2020 21:42:25 +0200 Subject: [PATCH 094/137] Fix notification content intent not being updated when needed --- .../newpipe/player/NotificationUtil.java | 14 +-- .../schabi/newpipe/util/NavigationHelper.java | 86 +++++++++---------- 2 files changed, 48 insertions(+), 52 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java index e05d7d19d..e01b0ec49 100644 --- a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java +++ b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java @@ -120,8 +120,6 @@ public final class NotificationUtil { .setSmallIcon(R.drawable.ic_newpipe_triangle_white) .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) .setColor(ContextCompat.getColor(player.context, R.color.gray)) - .setContentIntent(PendingIntent.getActivity(player.context, NOTIFICATION_ID, - getIntentForNotification(player), FLAG_UPDATE_CURRENT)) .setDeleteIntent(PendingIntent.getBroadcast(player.context, NOTIFICATION_ID, new Intent(ACTION_CLOSE), FLAG_UPDATE_CURRENT)); @@ -141,6 +139,9 @@ public final class NotificationUtil { return; } + // also update content intent, in case the user switched players + notificationBuilder.setContentIntent(PendingIntent.getActivity(player.context, + NOTIFICATION_ID, getIntentForNotification(player), FLAG_UPDATE_CURRENT)); notificationBuilder.setContentTitle(player.getVideoTitle()); notificationBuilder.setContentText(player.getUploaderName()); updateActions(notificationBuilder, player); @@ -326,19 +327,18 @@ public final class NotificationUtil { } private Intent getIntentForNotification(final VideoPlayerImpl player) { - final Intent intent; if (player.audioPlayerSelected() || player.popupPlayerSelected()) { - // Means we play in popup or audio only. Let's show BackgroundPlayerActivity - intent = NavigationHelper.getBackgroundPlayerActivityIntent(player.context); + // Means we play in popup or audio only. Let's show the play queue + return NavigationHelper.getPlayQueueActivityIntent(player.context); } else { // We are playing in fragment. Don't open another activity just show fragment. That's it - intent = NavigationHelper.getPlayerIntent( + final Intent intent = NavigationHelper.getPlayerIntent( player.context, MainActivity.class, null, true); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setAction(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_LAUNCHER); + return intent; } - return intent; } 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 96dfc1925..fb1469802 100644 --- a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java @@ -57,7 +57,7 @@ import org.schabi.newpipe.settings.SettingsActivity; import java.util.ArrayList; -@SuppressWarnings({"unused", "WeakerAccess"}) +@SuppressWarnings({"unused"}) public final class NavigationHelper { public static final String MAIN_FRAGMENT_TAG = "main_fragment_tag"; public static final String SEARCH_FRAGMENT_TAG = "search_fragment_tag"; @@ -69,16 +69,18 @@ public final class NavigationHelper { //////////////////////////////////////////////////////////////////////////*/ @NonNull - public static Intent getPlayerIntent(@NonNull final Context context, - @NonNull final Class targetClazz, - @NonNull final PlayQueue playQueue, - @Nullable final String quality, - final boolean resumePlayback) { + public static Intent getPlayerIntent(@NonNull final Context context, + @NonNull final Class targetClazz, + @Nullable final PlayQueue playQueue, + @Nullable final String quality, + final boolean resumePlayback) { final Intent intent = new Intent(context, targetClazz); - final String cacheKey = SerializedCache.getInstance().put(playQueue, PlayQueue.class); - if (cacheKey != null) { - intent.putExtra(VideoPlayer.PLAY_QUEUE_KEY, cacheKey); + if (playQueue != null) { + final String cacheKey = SerializedCache.getInstance().put(playQueue, PlayQueue.class); + if (cacheKey != null) { + intent.putExtra(VideoPlayer.PLAY_QUEUE_KEY, cacheKey); + } } if (quality != null) { intent.putExtra(VideoPlayer.PLAYBACK_QUALITY, quality); @@ -90,53 +92,51 @@ public final class NavigationHelper { } @NonNull - public static Intent getPlayerIntent(@NonNull final Context context, - @NonNull final Class targetClazz, - @NonNull final PlayQueue playQueue, - final boolean resumePlayback) { + public static Intent getPlayerIntent(@NonNull final Context context, + @NonNull final Class targetClazz, + @Nullable final PlayQueue playQueue, + final boolean resumePlayback) { return getPlayerIntent(context, targetClazz, playQueue, null, resumePlayback); } @NonNull - public static Intent getPlayerEnqueueIntent(@NonNull final Context context, - @NonNull final Class targetClazz, - @NonNull final PlayQueue playQueue, - final boolean selectOnAppend, - final boolean resumePlayback) { + public static Intent getPlayerEnqueueIntent(@NonNull final Context context, + @NonNull final Class targetClazz, + @Nullable final PlayQueue playQueue, + final boolean selectOnAppend, + final boolean resumePlayback) { return getPlayerIntent(context, targetClazz, playQueue, resumePlayback) .putExtra(BasePlayer.APPEND_ONLY, true) .putExtra(BasePlayer.SELECT_ON_APPEND, selectOnAppend); } @NonNull - public static Intent getPlayerIntent(@NonNull final Context context, - @NonNull final Class targetClazz, - @NonNull final PlayQueue playQueue, - final int repeatMode, - final float playbackSpeed, - final float playbackPitch, - final boolean playbackSkipSilence, - @Nullable final String playbackQuality, - final boolean resumePlayback, - final boolean startPaused, - final boolean isMuted) { + public static Intent getPlayerIntent(@NonNull final Context context, + @NonNull final Class targetClazz, + @Nullable final PlayQueue playQueue, + final int repeatMode, + final float playbackSpeed, + final float playbackPitch, + final boolean playbackSkipSilence, + @Nullable final String playbackQuality, + final boolean resumePlayback, + final boolean startPaused, + final boolean isMuted) { return getPlayerIntent(context, targetClazz, playQueue, playbackQuality, resumePlayback) .putExtra(BasePlayer.REPEAT_MODE, repeatMode) .putExtra(BasePlayer.START_PAUSED, startPaused) .putExtra(BasePlayer.IS_MUTED, isMuted); } - public static void playOnMainPlayer( - final AppCompatActivity activity, - final PlayQueue queue, - final boolean autoPlay) { + public static void playOnMainPlayer(final AppCompatActivity activity, + final PlayQueue queue, + final boolean autoPlay) { playOnMainPlayer(activity.getSupportFragmentManager(), queue, autoPlay); } - public static void playOnMainPlayer( - final FragmentManager fragmentManager, - final PlayQueue queue, - final boolean autoPlay) { + public static void playOnMainPlayer(final FragmentManager fragmentManager, + final PlayQueue queue, + final boolean autoPlay) { final PlayQueueItem currentStream = queue.getItem(); openVideoDetailFragment( fragmentManager, @@ -148,7 +148,7 @@ public final class NavigationHelper { } public static void playOnMainPlayer(@NonNull final Context context, - @NonNull final PlayQueue queue, + @Nullable final PlayQueue queue, @NonNull final StreamingService.LinkType linkType, @NonNull final String url, @NonNull final String title, @@ -553,18 +553,14 @@ public final class NavigationHelper { return true; } - public static Intent getBackgroundPlayerActivityIntent(final Context context) { - return getServicePlayerActivityIntent(context, BackgroundPlayerActivity.class); - } - - private static Intent getServicePlayerActivityIntent(final Context context, - final Class activityClass) { - final Intent intent = new Intent(context, activityClass); + public static Intent getPlayQueueActivityIntent(final Context context) { + final Intent intent = new Intent(context, BackgroundPlayerActivity.class); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); } return intent; } + /*////////////////////////////////////////////////////////////////////////// // Link handling //////////////////////////////////////////////////////////////////////////*/ From bd34c7ede3a7e01b19e6f5a1a8f9944db231826f Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 8 Sep 2020 21:59:39 +0200 Subject: [PATCH 095/137] Make player foreground playback-specific in manifest --- app/src/main/AndroidManifest.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1b3b80d88..6fd62aebe 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -44,8 +44,9 @@ + android:name=".player.MainPlayer" + android:exported="false" + android:foregroundServiceType="mediaPlayback"> From 1d6370e11c2f11191e9cc6de7123dd8b141f1413 Mon Sep 17 00:00:00 2001 From: Stjepan Date: Tue, 8 Sep 2020 09:07:06 +0000 Subject: [PATCH 096/137] Translated using Weblate (Croatian) Currently translated at 86.9% (508 of 584 strings) --- app/src/main/res/values-hr/strings.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 4512e265b..03c74e364 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -512,4 +512,13 @@ Omogući brz način Onemogući brz način Memorija uređaja je popunjena + Najomiljenije + Pritisnite \"Gotovo\" kad riješeno + Gotovo + ∞ videozapisa + 100+ videozapisa + Prijavite grešku na GitHub + Umjetnici + Albumi + Pjesme \ No newline at end of file From 1605e50cef85e54a7ff6faee6519ba13c45c0b74 Mon Sep 17 00:00:00 2001 From: Stypox Date: Wed, 9 Sep 2020 20:30:57 +0200 Subject: [PATCH 097/137] Update notification when play queue is edited --- .../schabi/newpipe/player/VideoPlayerImpl.java | 6 ++++++ .../player/playback/MediaSourceManager.java | 16 ++++++++-------- .../player/playback/PlaybackListener.java | 11 ++++++++++- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java index dd23b47e6..7e02549f1 100644 --- a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java +++ b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java @@ -642,6 +642,12 @@ public class VideoPlayerImpl extends VideoPlayer duration); } + @Override + public void onPlayQueueEdited() { + updatePlayback(); + NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false); + } + @Override @Nullable public MediaSource sourceOf(final PlayQueueItem item, final StreamInfo info) { diff --git a/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java b/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java index 23e813c4b..1b8c62e64 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java +++ b/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java @@ -255,21 +255,21 @@ public class MediaSourceManager { // Loading and Syncing switch (event.type()) { - case INIT: - case REORDER: - case ERROR: - case SELECT: + case INIT: case REORDER: case ERROR: case SELECT: loadImmediate(); // low frequency, critical events break; - case APPEND: - case REMOVE: - case MOVE: - case RECOVERY: + case APPEND: case REMOVE: case MOVE: case RECOVERY: default: loadDebounced(); // high frequency or noncritical events break; } + // update ui and notification + switch (event.type()) { + case APPEND: case REMOVE: case MOVE: case REORDER: + playbackListener.onPlayQueueEdited(); + } + if (!isPlayQueueReady()) { maybeBlock(); playQueue.fetch(); diff --git a/app/src/main/java/org/schabi/newpipe/player/playback/PlaybackListener.java b/app/src/main/java/org/schabi/newpipe/player/playback/PlaybackListener.java index 0755bdd7a..811f82b3b 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playback/PlaybackListener.java +++ b/app/src/main/java/org/schabi/newpipe/player/playback/PlaybackListener.java @@ -69,7 +69,7 @@ public interface PlaybackListener { MediaSource sourceOf(PlayQueueItem item, StreamInfo info); /** - * Called when the play queue can no longer to played or used. + * Called when the play queue can no longer be played or used. * Currently, this means the play queue is empty and complete. * Signals to the listener that it should shutdown. *

@@ -77,4 +77,13 @@ public interface PlaybackListener { *

*/ void onPlaybackShutdown(); + + /** + * Called whenever the play queue was edited (items were added, deleted or moved), + * use this to e.g. update notification buttons or fragment ui. + *

+ * May be called at any time. + *

+ */ + void onPlayQueueEdited(); } From 52e89c1d1cea4226ec25c0708ecd0dea75794108 Mon Sep 17 00:00:00 2001 From: Stypox Date: Wed, 9 Sep 2020 20:41:30 +0200 Subject: [PATCH 098/137] Prevent seeking out of video duration in player --- .../java/org/schabi/newpipe/player/BasePlayer.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java b/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java index a26ec6ccb..5a60095ae 100644 --- a/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java @@ -1242,7 +1242,15 @@ public abstract class BasePlayer implements Log.d(TAG, "seekBy() called with: position = [" + positionMillis + "]"); } if (simpleExoPlayer != null) { - simpleExoPlayer.seekTo(positionMillis); + // prevent invalid positions when fast-forwarding/-rewinding + long normalizedPositionMillis = positionMillis; + if (normalizedPositionMillis < 0) { + normalizedPositionMillis = 0; + } else if (normalizedPositionMillis > simpleExoPlayer.getDuration()) { + normalizedPositionMillis = simpleExoPlayer.getDuration(); + } + + simpleExoPlayer.seekTo(normalizedPositionMillis); } } From 5846fbabce47554d5596433c80c77f55d1e86ed0 Mon Sep 17 00:00:00 2001 From: Stypox Date: Wed, 9 Sep 2020 20:44:27 +0200 Subject: [PATCH 099/137] Change "image" to "thumbnail" --- app/src/main/res/values/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 21c734741..1f4be4c83 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -59,8 +59,8 @@ Show \"Play with Kodi\" option Display an option to play a video via Kodi media center - Scale image to 1:1 aspect ratio - This will scale the notification image from 16:9 to 1:1 aspect ratio + Scale thumbnail to 1:1 aspect ratio + Scale the video thumbnail shown in the notification from 16:9 to 1:1 aspect ratio (may introduce distortions) First action button Second action button Third action button From bccfe500b39de8416f1deac9cc4a9468d8bf01cd Mon Sep 17 00:00:00 2001 From: Stypox Date: Thu, 10 Sep 2020 18:47:22 +0200 Subject: [PATCH 100/137] Fix seekbar invisible or not updating Have the notification recreate only when strictly necessary, and recreate it if there was a timeline change, fixing the seekbar not updating at all sometimes --- .../org/schabi/newpipe/player/NotificationUtil.java | 12 ++++++------ .../org/schabi/newpipe/player/VideoPlayerImpl.java | 8 ++++++++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java index e01b0ec49..b0bfcb6e1 100644 --- a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java +++ b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java @@ -78,10 +78,7 @@ public final class NotificationUtil { */ synchronized void createNotificationIfNeededAndUpdate(final VideoPlayerImpl player, final boolean forceRecreate) { - if (notificationBuilder == null || forceRecreate) { - if (DEBUG) { - Log.d(TAG, "N_ createNotificationIfNeededAndUpdate(true)"); - } + if (forceRecreate || notificationBuilder == null) { notificationBuilder = createNotification(player); } updateNotification(player); @@ -89,6 +86,9 @@ public final class NotificationUtil { private synchronized NotificationCompat.Builder createNotification( final VideoPlayerImpl player) { + if (DEBUG) { + Log.d(TAG, "createNotification()"); + } notificationManager = (NotificationManager) player.context.getSystemService(NOTIFICATION_SERVICE); final NotificationCompat.Builder builder = new NotificationCompat.Builder(player.context, @@ -132,7 +132,7 @@ public final class NotificationUtil { */ private synchronized void updateNotification(final VideoPlayerImpl player) { if (DEBUG) { - Log.d(TAG, "N_ updateNotification()"); + Log.d(TAG, "updateNotification()"); } if (notificationBuilder == null) { @@ -158,7 +158,7 @@ public final class NotificationUtil { void createNotificationAndStartForeground(final VideoPlayerImpl player, final Service service) { - createNotificationIfNeededAndUpdate(player, true); + createNotificationIfNeededAndUpdate(player, false); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { service.startForeground(NOTIFICATION_ID, notificationBuilder.build(), diff --git a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java index 7e02549f1..f30330e4d 100644 --- a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java +++ b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java @@ -66,6 +66,7 @@ import androidx.recyclerview.widget.RecyclerView; import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.SimpleExoPlayer; +import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.text.CaptionStyleCompat; import com.google.android.exoplayer2.ui.AspectRatioFrameLayout; @@ -604,6 +605,13 @@ public class VideoPlayerImpl extends VideoPlayer } } + @Override + public void onTimelineChanged(final Timeline timeline, final int reason) { + super.onTimelineChanged(timeline, reason); + // force recreate notification to ensure seek bar is shown when preparation finishes + NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, true); + } + protected void onMetadataChanged(@NonNull final MediaSourceTag tag) { super.onMetadataChanged(tag); From 2017e6a3e31d2a03a399c82f712001a8e3c01a05 Mon Sep 17 00:00:00 2001 From: Stypox Date: Thu, 10 Sep 2020 20:36:52 +0200 Subject: [PATCH 101/137] Refactor MediaSessionManager --- .../player/helper/MediaSessionManager.java | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/MediaSessionManager.java b/app/src/main/java/org/schabi/newpipe/player/helper/MediaSessionManager.java index 8d089c6ed..b0c641433 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/MediaSessionManager.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/MediaSessionManager.java @@ -16,14 +16,14 @@ import androidx.media.session.MediaButtonReceiver; import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector; -import org.schabi.newpipe.BuildConfig; +import org.schabi.newpipe.MainActivity; import org.schabi.newpipe.player.mediasession.MediaSessionCallback; import org.schabi.newpipe.player.mediasession.PlayQueueNavigator; import org.schabi.newpipe.player.mediasession.PlayQueuePlaybackController; public class MediaSessionManager { - private static final String TAG = "MediaSessionManager"; - public static final boolean DEBUG = !BuildConfig.BUILD_TYPE.equals("release"); + private static final String TAG = MediaSessionManager.class.getSimpleName(); + public static final boolean DEBUG = MainActivity.DEBUG; @NonNull private final MediaSessionCompat mediaSession; @@ -35,12 +35,12 @@ public class MediaSessionManager { public MediaSessionManager(@NonNull final Context context, @NonNull final Player player, @NonNull final MediaSessionCallback callback) { - this.mediaSession = new MediaSessionCompat(context, TAG); - this.mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS + mediaSession = new MediaSessionCompat(context, TAG); + mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); - this.mediaSession.setActive(true); + mediaSession.setActive(true); - this.mediaSession.setPlaybackState(new PlaybackStateCompat.Builder() + mediaSession.setPlaybackState(new PlaybackStateCompat.Builder() .setState(PlaybackStateCompat.STATE_NONE, -1, 1) .setActions(PlaybackStateCompat.ACTION_SEEK_TO | PlaybackStateCompat.ACTION_PLAY @@ -51,10 +51,10 @@ public class MediaSessionManager { | PlaybackStateCompat.ACTION_STOP) .build()); - this.sessionConnector = new MediaSessionConnector(mediaSession); - this.sessionConnector.setControlDispatcher(new PlayQueuePlaybackController(callback)); - this.sessionConnector.setQueueNavigator(new PlayQueueNavigator(mediaSession, callback)); - this.sessionConnector.setPlayer(player); + sessionConnector = new MediaSessionConnector(mediaSession); + sessionConnector.setControlDispatcher(new PlayQueuePlaybackController(callback)); + sessionConnector.setQueueNavigator(new PlayQueueNavigator(mediaSession, callback)); + sessionConnector.setPlayer(player); } @Nullable @@ -64,10 +64,12 @@ public class MediaSessionManager { } public MediaSessionCompat.Token getSessionToken() { - return this.mediaSession.getSessionToken(); + return mediaSession.getSessionToken(); } - public void setMetadata(final String title, final String artist, final Bitmap albumArt, + public void setMetadata(final String title, + final String artist, + final Bitmap albumArt, final long duration) { if (albumArt == null || !mediaSession.isActive()) { return; @@ -130,9 +132,9 @@ public class MediaSessionManager { * Should be called on player destruction to prevent leakage. */ public void dispose() { - this.sessionConnector.setPlayer(null); - this.sessionConnector.setQueueNavigator(null); - this.mediaSession.setActive(false); - this.mediaSession.release(); + sessionConnector.setPlayer(null); + sessionConnector.setQueueNavigator(null); + mediaSession.setActive(false); + mediaSession.release(); } } From 883e4fcd7c2827ea5fc778447bed966842aa1a0e Mon Sep 17 00:00:00 2001 From: Avently <7953703+avently@users.noreply.github.com> Date: Fri, 11 Sep 2020 20:52:38 +0300 Subject: [PATCH 102/137] Small fixes of issues with old devices support, brightness, etc --- .../fragments/detail/VideoDetailFragment.java | 57 ++++++++++++------- .../org/schabi/newpipe/player/MainPlayer.java | 1 + .../newpipe/player/VideoPlayerImpl.java | 1 + .../player/event/PlayerGestureListener.java | 14 +++-- app/src/main/res/layout-large-land/player.xml | 6 +- app/src/main/res/layout/player.xml | 6 +- 6 files changed, 55 insertions(+), 30 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 b731d0270..319523ab7 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 @@ -102,13 +102,12 @@ import org.schabi.newpipe.util.ListHelper; import org.schabi.newpipe.util.Localization; import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.PermissionHelper; +import org.schabi.newpipe.util.SerializedCache; import org.schabi.newpipe.util.ShareUtils; import org.schabi.newpipe.util.ThemeHelper; import org.schabi.newpipe.views.AnimatedProgressBar; import org.schabi.newpipe.views.LargeTextMovementMethod; -import java.io.Serializable; -import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; import java.util.List; @@ -337,7 +336,7 @@ public class VideoDetailFragment stopPlayerListener(); playerService = null; player = null; - saveCurrentAndRestoreDefaultBrightness(); + restoreDefaultBrightness(); } } @@ -426,7 +425,7 @@ public class VideoDetailFragment if (currentWorker != null) { currentWorker.dispose(); } - saveCurrentAndRestoreDefaultBrightness(); + restoreDefaultBrightness(); PreferenceManager.getDefaultSharedPreferences(requireContext()) .edit() .putString(getString(R.string.stream_info_selected_tab_key), @@ -538,31 +537,51 @@ public class VideoDetailFragment super.onSaveInstanceState(outState); if (!isLoading.get() && currentInfo != null && isVisible()) { - outState.putSerializable(INFO_KEY, currentInfo); + final String infoCacheKey = SerializedCache.getInstance() + .put(currentInfo, StreamInfo.class); + if (infoCacheKey != null) { + outState.putString(INFO_KEY, infoCacheKey); + } } if (playQueue != null) { - outState.putSerializable(VideoPlayer.PLAY_QUEUE_KEY, playQueue); + final String queueCacheKey = SerializedCache.getInstance() + .put(playQueue, PlayQueue.class); + if (queueCacheKey != null) { + outState.putString(VideoPlayer.PLAY_QUEUE_KEY, queueCacheKey); + } + } + final String stackCacheKey = SerializedCache.getInstance().put(stack, LinkedList.class); + if (stackCacheKey != null) { + outState.putString(STACK_KEY, stackCacheKey); } - outState.putSerializable(STACK_KEY, stack); } @Override protected void onRestoreInstanceState(@NonNull final Bundle savedState) { super.onRestoreInstanceState(savedState); - Serializable serializable = savedState.getSerializable(INFO_KEY); - if (serializable instanceof StreamInfo) { - currentInfo = (StreamInfo) serializable; - InfoCache.getInstance().putInfo(serviceId, url, currentInfo, InfoItem.InfoType.STREAM); + final String infoCacheKey = savedState.getString(INFO_KEY); + if (infoCacheKey != null) { + currentInfo = SerializedCache.getInstance().take(infoCacheKey, StreamInfo.class); + if (currentInfo != null) { + InfoCache.getInstance() + .putInfo(serviceId, url, currentInfo, InfoItem.InfoType.STREAM); + } } - serializable = savedState.getSerializable(STACK_KEY); - if (serializable instanceof Collection) { - //noinspection unchecked - stack.addAll((Collection) serializable); + final String stackCacheKey = savedState.getString(STACK_KEY); + if (stackCacheKey != null) { + final LinkedList cachedStack = + SerializedCache.getInstance().take(stackCacheKey, LinkedList.class); + if (cachedStack != null) { + stack.addAll(cachedStack); + } + } + final String queueCacheKey = savedState.getString(VideoPlayer.PLAY_QUEUE_KEY); + if (queueCacheKey != null) { + playQueue = SerializedCache.getInstance().take(queueCacheKey, PlayQueue.class); } - playQueue = (PlayQueue) savedState.getSerializable(VideoPlayer.PLAY_QUEUE_KEY); } /*////////////////////////////////////////////////////////////////////////// @@ -2027,13 +2046,11 @@ public class VideoDetailFragment && player.getPlayer().getPlaybackState() != Player.STATE_IDLE; } - private void saveCurrentAndRestoreDefaultBrightness() { + private void restoreDefaultBrightness() { final WindowManager.LayoutParams lp = activity.getWindow().getAttributes(); if (lp.screenBrightness == -1) { return; } - // Save current brightness level - PlayerHelper.setScreenBrightness(activity, lp.screenBrightness); // Restore the old brightness when fragment.onPause() called or // when a player is in portrait @@ -2052,7 +2069,7 @@ public class VideoDetailFragment || !player.isFullscreen() || bottomSheetState != BottomSheetBehavior.STATE_EXPANDED) { // Apply system brightness when the player is not in fullscreen - saveCurrentAndRestoreDefaultBrightness(); + restoreDefaultBrightness(); } else { // Restore already saved brightness level final float brightnessLevel = PlayerHelper.getScreenBrightness(activity); diff --git a/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java b/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java index 273f37cc8..c78ddf036 100644 --- a/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java @@ -171,6 +171,7 @@ public final class MainPlayer extends Service { // Android TV will handle back button in case controls will be visible // (one more additional unneeded click while the player is hidden) playerImpl.hideControls(0, 0); + playerImpl.onQueueClosed(); // Notification shows information about old stream but if a user selects // a stream from backStack it's not actual anymore // So we should hide the notification at all. diff --git a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java index a5758301c..52df3d956 100644 --- a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java +++ b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java @@ -257,6 +257,7 @@ public class VideoPlayerImpl extends VideoPlayer } else { getRootView().setVisibility(View.VISIBLE); initVideoPlayer(); + onQueueClosed(); // Android TV: without it focus will frame the whole player playPauseButton.requestFocus(); } diff --git a/app/src/main/java/org/schabi/newpipe/player/event/PlayerGestureListener.java b/app/src/main/java/org/schabi/newpipe/player/event/PlayerGestureListener.java index 4aa6070eb..a2def2a64 100644 --- a/app/src/main/java/org/schabi/newpipe/player/event/PlayerGestureListener.java +++ b/app/src/main/java/org/schabi/newpipe/player/event/PlayerGestureListener.java @@ -9,6 +9,7 @@ import android.view.View; import android.view.ViewConfiguration; import android.view.Window; import android.view.WindowManager; +import android.widget.ProgressBar; import androidx.appcompat.content.res.AppCompatResources; import org.schabi.newpipe.R; import org.schabi.newpipe.player.BasePlayer; @@ -264,14 +265,19 @@ public class PlayerGestureListener } final Window window = parent.getWindow(); - - playerImpl.getBrightnessProgressBar().incrementProgressBy((int) distanceY); - final float currentProgressPercent = (float) playerImpl.getBrightnessProgressBar() - .getProgress() / playerImpl.getMaxGestureLength(); final WindowManager.LayoutParams layoutParams = window.getAttributes(); + final ProgressBar bar = playerImpl.getBrightnessProgressBar(); + final float oldBrightness = layoutParams.screenBrightness; + bar.setProgress((int) (bar.getMax() * Math.max(0, Math.min(1, oldBrightness)))); + bar.incrementProgressBy((int) distanceY); + + final float currentProgressPercent = (float) bar.getProgress() / bar.getMax(); layoutParams.screenBrightness = currentProgressPercent; window.setAttributes(layoutParams); + // Save current brightness level + PlayerHelper.setScreenBrightness(parent, currentProgressPercent); + if (DEBUG) { Log.d(TAG, "onScroll().brightnessControl, " + "currentBrightness = " + currentProgressPercent); diff --git a/app/src/main/res/layout-large-land/player.xml b/app/src/main/res/layout-large-land/player.xml index 46edda8b7..3c410801e 100644 --- a/app/src/main/res/layout-large-land/player.xml +++ b/app/src/main/res/layout-large-land/player.xml @@ -353,10 +353,10 @@ android:id="@+id/playbackSeekBar" style="@style/Widget.AppCompat.SeekBar" android:layout_width="0dp" - android:layout_height="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="center" android:layout_weight="1" - android:paddingBottom="4dp" - android:paddingTop="8dp" + android:layout_marginTop="2dp" tools:progress="25" android:nextFocusDown="@id/screenRotationButton" tools:secondaryProgress="50"/> diff --git a/app/src/main/res/layout/player.xml b/app/src/main/res/layout/player.xml index 88489d8d5..ec95bd8c3 100644 --- a/app/src/main/res/layout/player.xml +++ b/app/src/main/res/layout/player.xml @@ -352,10 +352,10 @@ android:id="@+id/playbackSeekBar" style="@style/Widget.AppCompat.SeekBar" android:layout_width="0dp" - android:layout_height="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="center" android:layout_weight="1" - android:paddingBottom="4dp" - android:paddingTop="8dp" + android:layout_marginTop="2dp" tools:progress="25" tools:secondaryProgress="50"/> From b747d0983613e2f06f34a86eace635717c4a1224 Mon Sep 17 00:00:00 2001 From: bopol Date: Sun, 13 Sep 2020 14:01:01 +0200 Subject: [PATCH 103/137] change default quality --- app/src/main/res/values/settings_keys.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index 7fb7d4f4d..fbeddc6db 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -85,10 +85,10 @@
default_resolution - 360p + 720p60 show_higher_resolutions default_popup_resolution - 360p + 480p best_resolution From 011cc7d3376f14d4f92e3bac9ef5bf2c8483b789 Mon Sep 17 00:00:00 2001 From: Avently <7953703+avently@users.noreply.github.com> Date: Mon, 14 Sep 2020 02:46:00 +0300 Subject: [PATCH 104/137] Android 11 initial support --- app/src/main/res/layout-large-land/fragment_video_detail.xml | 1 - app/src/main/res/layout-large-land/player.xml | 3 +-- app/src/main/res/layout/activity_main.xml | 3 +-- app/src/main/res/layout/fragment_video_detail.xml | 1 - app/src/main/res/layout/player.xml | 3 +-- 5 files changed, 3 insertions(+), 8 deletions(-) diff --git a/app/src/main/res/layout-large-land/fragment_video_detail.xml b/app/src/main/res/layout-large-land/fragment_video_detail.xml index f69832b81..3c64be3b5 100644 --- a/app/src/main/res/layout-large-land/fragment_video_detail.xml +++ b/app/src/main/res/layout-large-land/fragment_video_detail.xml @@ -28,7 +28,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@android:color/transparent" - android:fitsSystemWindows="true" android:touchscreenBlocksFocus="false" app:elevation="0dp" app:layout_behavior="com.google.android.material.appbar.FlingBehavior"> diff --git a/app/src/main/res/layout-large-land/player.xml b/app/src/main/res/layout-large-land/player.xml index 3c410801e..7163964fc 100644 --- a/app/src/main/res/layout-large-land/player.xml +++ b/app/src/main/res/layout-large-land/player.xml @@ -62,8 +62,7 @@ + android:layout_height="match_parent"> + android:layout_height="match_parent"> diff --git a/app/src/main/res/layout/player.xml b/app/src/main/res/layout/player.xml index ec95bd8c3..ae445bbb2 100644 --- a/app/src/main/res/layout/player.xml +++ b/app/src/main/res/layout/player.xml @@ -62,8 +62,7 @@ + android:layout_height="match_parent"> Date: Mon, 14 Sep 2020 11:30:41 +0300 Subject: [PATCH 105/137] Android 11: transparent navigation and status bars --- .../fragments/detail/VideoDetailFragment.java | 4 ++++ .../newpipe/player/VideoPlayerImpl.java | 4 ++++ app/src/main/res/values-v29/themes.xml | 20 +++++++++++++++++++ app/src/main/res/values/styles.xml | 4 ++-- 4 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 app/src/main/res/values-v29/themes.xml 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 319523ab7..eddefaa8c 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 @@ -2003,6 +2003,10 @@ public class VideoDetailFragment } activity.getWindow().getDecorView().setSystemUiVisibility(0); activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + if (Build.VERSION.SDK_INT >= 30 /*Android 11*/) { + activity.getWindow().setStatusBarColor(ThemeHelper.resolveColorFromAttr( + requireContext(), android.R.attr.colorPrimary)); + } } private void hideSystemUi() { diff --git a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java index 52df3d956..ede476653 100644 --- a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java +++ b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java @@ -27,6 +27,7 @@ import android.content.IntentFilter; import android.content.SharedPreferences; import android.database.ContentObserver; import android.graphics.Bitmap; +import android.graphics.Color; import android.graphics.PixelFormat; import android.graphics.Point; import android.net.Uri; @@ -1475,6 +1476,9 @@ public class VideoPlayerImpl extends VideoPlayer | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; getParentActivity().getWindow().getDecorView().setSystemUiVisibility(visibility); + if (Build.VERSION.SDK_INT >= 30 /*Android 11*/) { + getParentActivity().getWindow().setStatusBarColor(Color.TRANSPARENT); + } } } diff --git a/app/src/main/res/values-v29/themes.xml b/app/src/main/res/values-v29/themes.xml new file mode 100644 index 000000000..63494d0ae --- /dev/null +++ b/app/src/main/res/values-v29/themes.xml @@ -0,0 +1,20 @@ + + + + + + - -