diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 2787e2238b5..845d57d908b 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -13,8 +13,8 @@ - take over the world #### Fixes the following issue(s) - -- + +- Fixes # #### Relies on the following changes diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a3ea00e03d3..427da73915d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,25 +5,27 @@ on: branches: - dev push: - branches: + branches: - dev - master jobs: - build-and-test: + build-and-test-jvm: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + - uses: gradle/wrapper-validation-action@v1 - name: create and checkout branch # push events already checked out the branch if: github.event_name == 'pull_request' run: git checkout -B ${{ github.head_ref }} - - name: set up JDK 1.8 - uses: actions/setup-java@v1.4.3 + - name: set up JDK 8 + uses: actions/setup-java@v2 with: - java-version: 1.8 + java-version: 8 + distribution: "zulu" - name: Cache Gradle dependencies uses: actions/cache@v2 @@ -32,7 +34,7 @@ jobs: key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} restore-keys: ${{ runner.os }}-gradle - - name: Build debug APK and run Tests + - name: Build debug APK and run jvm tests run: ./gradlew assembleDebug lintDebug testDebugUnitTest --stacktrace - name: Upload APK @@ -40,6 +42,32 @@ jobs: with: name: app path: app/build/outputs/apk/debug/*.apk + test-android: + runs-on: macos-latest + strategy: + matrix: + api-level: [21, 29] + steps: + - uses: actions/checkout@v2 + + - name: set up JDK 8 + uses: actions/setup-java@v2 + with: + java-version: 8 + distribution: "zulu" + + - name: Cache Gradle dependencies + uses: actions/cache@v2 + with: + path: ~/.gradle/caches + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} + restore-keys: ${{ runner.os }}-gradle + + - name: Run android tests + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: ${{ matrix.api-level }} + script: ./gradlew connectedCheck # sonar: # runs-on: ubuntu-latest # steps: @@ -48,9 +76,10 @@ jobs: # fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis # - name: Set up JDK 11 -# uses: actions/setup-java@v1.4.3 +# uses: actions/setup-java@v2 # with: # java-version: 11 # Sonar requires JDK 11 +# distribution: "zulu" # - name: Cache SonarCloud packages # uses: actions/cache@v2 diff --git a/README.es.md b/README.es.md index 0aa198d2c03..c894dd43f0f 100644 --- a/README.es.md +++ b/README.es.md @@ -9,7 +9,7 @@ - +


@@ -85,7 +85,7 @@ NewPipe apoya varios servicios. Nuestras [documentaciones](https://teamnewpipe.g ## Installación y actualizaciones Se puede instalar NewPipe usando uno de los métodos siguientes: - 1. Agregar nuestro repositorio personalizado a F-Droid e instalarlo desde allí. Las instrucciones están aquí: https://newpipe.schabi.org/FAQ/tutorials/install-add-fdroid-repo/ + 1. Agregar nuestro repositorio personalizado a F-Droid e instalarlo desde allí. Las instrucciones están aquí: https://newpipe.net/FAQ/tutorials/install-add-fdroid-repo/ 2. Descargar el archivo APK del enlace [Github Releases](https://github.com/TeamNewPipe/NewPipe/releases) e instalarlo. 3. Actualizar a través de F-Droid. Este es el método más lento para obtener la actualización, como F-Droid debe reconocer cambios, construir el APK aparte, firmarlo con una clave, y finalmente empujar la actualización a los usuarios. 4. Construir un APK de depuración por si mismo. Este es el modo más rápido para realizar nuevas características en su dispositivo, pero es mucho más complicado, asi que recomendamos uno de los otros métodos. @@ -135,6 +135,6 @@ El proyecto NewPipe tiene como objetivo proveer una experience privada y anónim Por lo tanto, la app no colecciona ningunos datos sin su consentimiento. La politica de privacidad de NewPipe explica en detalle los datos enviados y almacenados cuando envia un informe de error, o comentario en nuestro blog. Puede encontrar el documento [aqui](https://newpipe.net/legal/privacy/). ## Licencia -[![GNU GPLv3 Image](https://www.gnu.org/graphics/gplv3-127x51.png)](http://www.gnu.org/licenses/gpl-3.0.en.html) +[![GNU GPLv3 Image](https://www.gnu.org/graphics/gplv3-127x51.png)](https://www.gnu.org/licenses/gpl-3.0.en.html) NewPipe es Software Libre: Puede usar, estudiar, compartir, y mejorarlo a su voluntad. Especificamente puede redistribuir y/o modificarlo bajo los términos de la [GNU General Public License](https://www.gnu.org/licenses/gpl.html) como publicado por la Free Software Foundation, o versión 3 de la licencia, o (en su opción) cualquier versión posterior. diff --git a/README.ja.md b/README.ja.md index 685202bf37a..fabafbfd177 100644 --- a/README.ja.md +++ b/README.ja.md @@ -9,7 +9,7 @@ - +


@@ -143,7 +143,7 @@ NewPipe プロジェクトはメディアウェブサービスを使用する上 ## ライセンス -[![GNU GPLv3 のロゴ](https://www.gnu.org/graphics/gplv3-127x51.png)](http://www.gnu.org/licenses/gpl-3.0.en.html) +[![GNU GPLv3 のロゴ](https://www.gnu.org/graphics/gplv3-127x51.png)](https://www.gnu.org/licenses/gpl-3.0.en.html) NewPipe はフリーソフトウェアなので、あなたはあなたの望むように使用、習得、共有、改善を行えます。 具体的には、フリーソフトウェア財団により公開された [GNU General Public License](https://www.gnu.org/licenses/gpl.html) のバージョン3のライセンスもしくは、(あなたの選択で) いずれかの後継バージョンの規約の元で配布または改変を行うことができます。 diff --git a/README.ko.md b/README.ko.md index 8bbda9b5daf..3ee9ae63151 100644 --- a/README.ko.md +++ b/README.ko.md @@ -9,7 +9,7 @@ - +


@@ -139,7 +139,7 @@ NewPipe 프로젝트는 미디어 웹 서비스를 사용하는 것에 대한 그러므로, 앱은 당신의 동의 없이 어떤 데이터도 수집하지 않습니다. NewPipe의 개인정보보호정책은 당신이 충돌 리포트를 보내거나, 또는 우리의 블로그에 글을 남길 때 어떤 데이터가 보내지고 저장되는지에 대해 상세히 설명합니다. 이 문서는 [여기](https://newpipe.net/legal/privacy/)에서 확인할 수 있습니다. ## License -[![GNU GPLv3 Image](https://www.gnu.org/graphics/gplv3-127x51.png)](http://www.gnu.org/licenses/gpl-3.0.en.html) +[![GNU GPLv3 Image](https://www.gnu.org/graphics/gplv3-127x51.png)](https://www.gnu.org/licenses/gpl-3.0.en.html) NewPipe는 자유 소프트웨어입니다: 당신의 마음대로 이것을 사용하고, 연구하고, 공유하고, 개선할 수 있습니다. 구체적으로 당신은 자유 소프트웨어 재단에서 발행되는, 버전 3 또는 (당신의 선택에 따라)이후 버전의, diff --git a/README.md b/README.md index 27ede1c0309..9eec4569343 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ - +


@@ -87,7 +87,7 @@ NewPipe supports multiple services. Our [docs](https://teamnewpipe.github.io/doc ## Installation and updates You can install NewPipe using one of the following methods: - 1. Add our custom repo to F-Droid and install it from there. The instructions are here: https://newpipe.schabi.org/FAQ/tutorials/install-add-fdroid-repo/ + 1. Add our custom repo to F-Droid and install it from there. The instructions are here: https://newpipe.net/FAQ/tutorials/install-add-fdroid-repo/ 2. Download the APK from [Github Releases](https://github.com/TeamNewPipe/NewPipe/releases) and install it. 3. Update via F-Droid. This is the slowest method of getting updates, as F-Droid must recognize changes, build the APK itself, sign it, then push the update to users. 4. Build a debug APK yourself. This is the fastest way to get new features on your device, but is much more complicated, so we recommend using one of the other methods. @@ -137,7 +137,7 @@ The NewPipe project aims to provide a private, anonymous experience for using me Therefore, the app does not collect any data without your consent. NewPipe's privacy policy explains in detail what data is sent and stored when you send a crash report, or comment in our blog. You can find the document [here](https://newpipe.net/legal/privacy/). ## License -[![GNU GPLv3 Image](https://www.gnu.org/graphics/gplv3-127x51.png)](http://www.gnu.org/licenses/gpl-3.0.en.html) +[![GNU GPLv3 Image](https://www.gnu.org/graphics/gplv3-127x51.png)](https://www.gnu.org/licenses/gpl-3.0.en.html) NewPipe is Free Software: You can use, study share and improve it at your will. Specifically you can redistribute and/or modify it under the terms of the diff --git a/README.pt_BR.md b/README.pt_BR.md index 033b6f0f741..251c904b731 100644 --- a/README.pt_BR.md +++ b/README.pt_BR.md @@ -10,7 +10,7 @@ - +


@@ -135,7 +135,7 @@ O projeto NewPipe tem como objetivo proporcionar uma experiência privada e anô Portanto, o aplicativo não coleta nenhum dado sem o seu consentimento. A política de privacidade da NewPipe explica em detalhes quais dados são enviados e armazenados quando você envia um relatório de erro ou comenta em nosso blog. Você pode encontrar o documento [aqui](https://newpipe.net/legal/privacy/). ## Licença -[![GNU GPLv3 Image](https://www.gnu.org/graphics/gplv3-127x51.png)](http://www.gnu.org/licenses/gpl-3.0.en.html) +[![GNU GPLv3 Image](https://www.gnu.org/graphics/gplv3-127x51.png)](https://www.gnu.org/licenses/gpl-3.0.en.html) NewPipe é Software Livre: Você pode usar, estudar compartilhamento e melhorá-lo à sua vontade. Especificamente, você pode redistribuir e/ou modificá-lo sob os termos do diff --git a/README.ro.md b/README.ro.md index e28cd8cd635..1d39422fc8b 100644 --- a/README.ro.md +++ b/README.ro.md @@ -9,7 +9,7 @@ - +


@@ -87,9 +87,9 @@ NewPipe suportă servicii multiple. [Documentele](https://teamnewpipe.github.io/ ## Instalare şi actualizări Puteţi instala NewPipe folosind una dintre următoarele metode: - 1. Adăugaţi depozitul nostru F-droid personalizat. Instrucţiunile sunt aici: https://newpipe.schabi.org/FAQ/tutorials/install-add-fdroid-repo/ + 1. Adăugaţi depozitul nostru F-droid personalizat. Instrucţiunile sunt aici: https://newpipe.net/FAQ/tutorials/install-add-fdroid-repo/ 2. Descărcaţi APK-ul din [Github Releases](https://github.com/TeamNewPipe/NewPipe/releases) şi instalaţi-l. - 3. Actualizaţi via F-Droid. Aceasta este cea mai lentă metodă de a obţine actualizări, deoarece F-Droid trebuie să recunoască schimbările, să constriască APK-ul, să îl semneze, iar apoi să îl trimită utilizatorilor. (**IMPORTANT**: în momentul scrierii, o problemă împiedică versiunile mai noi de 0.20.1 să fie publicate. Aşa că, dacă doriţi să folosiţi F-droid, până această problemă este rezolvată, vă recomandăm metoda 1.) + 3. Actualizaţi via F-Droid. Aceasta este cea mai lentă metodă de a obţine actualizări, deoarece F-Droid trebuie să recunoască schimbările, să constriască APK-ul, să îl semneze, iar apoi să îl trimită utilizatorilor. 4. Construiţi un APK de depanare. Aceasta este cea mai rapidă metodă de a primi funcţii noi, dar este mult mai complicată, aşa că vă recomandăm să folosiţi una dintre celelalte metode. Recomandăm metoda 1 pentru majoritatea utilizatorilor. APK-urile din metodele 1 şi 2 suntcompatibile una cu cealaltă, dar nu cu cele din metoda 3. Acest lucru se datorează faptului că aceeași cheie de semnare (a noastră) este utilizată pentru 1 și 2, dar o altă cheie de semnare (F-Droid) este utilizată pentru 3. Construirea unui APK de depanare folosind metoda 4 exclude o cheie în întregime. Cheile de semnare vă asigură că un utilizator nu este păcălit să instaleze o actualizare rău intenționată a unei aplicații. @@ -137,7 +137,7 @@ Proiectul NewPipe îşi propune să furnizeze o experienţă privată şi anonim Prin urmare, aplicaţia nu colectează niciun fel de informaţii fără acordul dumneavoastră. Politica de confidențialitate a NewPipe explică în detaliu ce date sunt trimise și stocate atunci când trimiteți un raport de blocare sau comentați pe blogul nostru. Puteți găsi documentul [aici](https://newpipe.net/legal/privacy/). ## Licenţă -[![GNU GPLv3 Image](https://www.gnu.org/graphics/gplv3-127x51.png)](http://www.gnu.org/licenses/gpl-3.0.en.html) +[![GNU GPLv3 Image](https://www.gnu.org/graphics/gplv3-127x51.png)](https://www.gnu.org/licenses/gpl-3.0.en.html) NewPipe este Software Gratuit: Îl puteţi folosi şi împărtăşi cum doriţi. Mai exact, îl puteți redistribui și / sau modifica în conformitate cu termenii [GNU General Public License](https://www.gnu.org/licenses/gpl.html) aşa cum a fost publicat de Free Software Foundation, fie versiunea 3 a Licenței, fie diff --git a/README.so.md b/README.so.md index f0bba8b791d..703886f127d 100644 --- a/README.so.md +++ b/README.so.md @@ -9,7 +9,7 @@ - +


@@ -133,6 +133,6 @@ Mashruuca NewPipe waxay ujeedadiisu tahay inuu bixiyo wax kuu gaar ah, oo adoon Sidaa darteed, app-ku wax xog ah ma uruuriyo fasaxaaga la'aantii. Siyaasada Sirdhawrka NewPipe ayaa si faahfaahsan u sharaxda waxii xog ah ee la diro markaad cillad wariso, ama aad bogganaga faallo ka dhiibato. Warqada waxaad ka heli kartaa [halkan](https://newpipe.net/legal/privacy/). ## Laysinka -[![GNU GPLv3 Image](https://www.gnu.org/graphics/gplv3-127x51.png)](http://www.gnu.org/licenses/gpl-3.0.en.html) +[![GNU GPLv3 Image](https://www.gnu.org/graphics/gplv3-127x51.png)](https://www.gnu.org/licenses/gpl-3.0.en.html) NewPipe waa barnaamij bilaash ah oon lahayn xuquuqda daabacaada: Waad isticmaali kartaa, waad wadaagi kartaa waadna hormarin kartaa hadaad rabto. Gaar ahaan waad sii daabici kartaa ama wax baad ka badali kartaa ayadoo la raacayo shuruudaha sharciga guud ee [GNU](https://www.gnu.org/licenses/gpl.html) sida ay soosaareen Ururka Barnaamijyada Bilaashka ah, soosaarista 3aad ee laysinka, ama (hadaad doonto) nooc walba oo kasii dambeeyay laysinkii 3aad. diff --git a/app/build.gradle b/app/build.gradle index 6143587e66e..36ad7912118 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -17,8 +17,8 @@ android { resValue "string", "app_name", "NewPipe" minSdkVersion 19 targetSdkVersion 29 - versionCode 967 - versionName "0.21.1" + versionCode 968 + versionName "0.21.2" multiDexEnabled true @@ -96,16 +96,19 @@ android { } ext { - icepickVersion = '3.2.0' checkstyleVersion = '8.38' - stethoVersion = '1.5.1' - leakCanaryVersion = '2.5' - exoPlayerVersion = '2.12.3' + androidxLifecycleVersion = '2.2.0' androidxRoomVersion = '2.3.0-alpha03' + + icepickVersion = '3.2.0' + exoPlayerVersion = '2.13.2' + googleAutoServiceVersion = '1.0-rc7' groupieVersion = '2.8.1' markwonVersion = '4.6.0' - googleAutoServiceVersion = '1.0-rc7' + + leakCanaryVersion = '2.5' + stethoVersion = '1.5.1' mockitoVersion = '3.6.0' } @@ -171,82 +174,99 @@ sonarqube { } dependencies { +/** Desugaring **/ coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.1' - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlin_version}" - - implementation "frankiesardo:icepick:${icepickVersion}" - kapt "frankiesardo:icepick-processor:${icepickVersion}" +/** NewPipe libraries **/ + // You can use a local version by uncommenting a few lines in settings.gradle + implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751' + implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.21.2' +/** Checkstyle **/ checkstyle "com.puppycrawl.tools:checkstyle:${checkstyleVersion}" - ktlint "com.pinterest:ktlint:0.40.0" - - debugImplementation "com.facebook.stetho:stetho:${stethoVersion}" - debugImplementation "com.facebook.stetho:stetho-okhttp3:${stethoVersion}" + ktlint 'com.pinterest:ktlint:0.40.0' - debugImplementation "com.squareup.leakcanary:leakcanary-android:${leakCanaryVersion}" - implementation "com.squareup.leakcanary:leakcanary-object-watcher-android:${leakCanaryVersion}" - implementation "com.squareup.leakcanary:plumber-android:${leakCanaryVersion}" +/** Kotlin **/ + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlin_version}" - implementation "androidx.multidex:multidex:2.0.1" +/** AndroidX **/ + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'androidx.cardview:cardview:1.0.0' + implementation 'androidx.constraintlayout:constraintlayout:2.0.4' + implementation 'androidx.core:core-ktx:1.3.2' + implementation 'androidx.documentfile:documentfile:1.0.1' + implementation "androidx.lifecycle:lifecycle-livedata:${androidxLifecycleVersion}" + implementation "androidx.lifecycle:lifecycle-viewmodel:${androidxLifecycleVersion}" + implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0' + implementation 'androidx.media:media:1.2.1' + implementation 'androidx.multidex:multidex:2.0.1' + implementation 'androidx.preference:preference:1.1.1' + implementation 'androidx.recyclerview:recyclerview:1.1.0' + implementation "androidx.room:room-runtime:${androidxRoomVersion}" + implementation "androidx.room:room-rxjava3:${androidxRoomVersion}" + kapt "androidx.room:room-compiler:${androidxRoomVersion}" + implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' + implementation 'androidx.webkit:webkit:1.4.0' + implementation 'com.google.android.material:material:1.2.1' - // NewPipe dependencies - // You can use a local version by uncommenting a few lines in settings.gradle - implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.21.1' - implementation "com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751" +/** Third-party libraries **/ + // Instance state boilerplate elimination + implementation "frankiesardo:icepick:${icepickVersion}" + kapt "frankiesardo:icepick-processor:${icepickVersion}" + // HTML parser implementation "org.jsoup:jsoup:1.13.1" + // HTTP client //noinspection GradleDependency --> do not update okhttp to keep supporting Android 4.4 users implementation "com.squareup.okhttp3:okhttp:3.12.13" + // Media player implementation "com.google.android.exoplayer:exoplayer:${exoPlayerVersion}" implementation "com.google.android.exoplayer:extension-mediasession:${exoPlayerVersion}" - implementation "com.google.android.material:material:1.2.1" - + // Metadata generator for service descriptors compileOnly "com.google.auto.service:auto-service-annotations:${googleAutoServiceVersion}" kapt "com.google.auto.service:auto-service:${googleAutoServiceVersion}" - implementation "androidx.appcompat:appcompat:1.2.0" - implementation "androidx.preference:preference:1.1.1" - implementation "androidx.recyclerview:recyclerview:1.1.0" - implementation "androidx.cardview:cardview:1.0.0" - implementation "androidx.constraintlayout:constraintlayout:2.0.4" - implementation 'androidx.core:core-ktx:1.3.2' - implementation 'androidx.documentfile:documentfile:1.0.1' - implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0' - implementation 'androidx.media:media:1.2.1' - implementation 'androidx.webkit:webkit:1.4.0' - - implementation "androidx.lifecycle:lifecycle-livedata:${androidxLifecycleVersion}" - implementation "androidx.lifecycle:lifecycle-viewmodel:${androidxLifecycleVersion}" - - implementation "androidx.room:room-runtime:${androidxRoomVersion}" - implementation "androidx.room:room-rxjava3:${androidxRoomVersion}" - kapt "androidx.room:room-compiler:${androidxRoomVersion}" - - implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" - + // Manager for complex RecyclerView layouts implementation "com.xwray:groupie:${groupieVersion}" implementation "com.xwray:groupie-viewbinding:${groupieVersion}" + // Circular ImageView implementation "de.hdodenhof:circleimageview:3.1.0" + // Image loading implementation "com.nostra13.universalimageloader:universal-image-loader:1.9.5" + // Markdown library for Android implementation "io.noties.markwon:core:${markwonVersion}" implementation "io.noties.markwon:linkify:${markwonVersion}" + // File picker implementation "com.nononsenseapps:filepicker:4.2.1" + // Crash reporting implementation "ch.acra:acra-core:5.7.0" + // Reactive extensions for Java VM implementation "io.reactivex.rxjava3:rxjava:3.0.7" implementation "io.reactivex.rxjava3:rxandroid:3.0.0" + // RxJava binding APIs for Android UI widgets implementation "com.jakewharton.rxbinding4:rxbinding:4.0.0" + // Date and time formatting implementation "org.ocpsoft.prettytime:prettytime:5.0.0.Final" +/** Debugging **/ + // Memory leak detection + implementation "com.squareup.leakcanary:leakcanary-object-watcher-android:${leakCanaryVersion}" + implementation "com.squareup.leakcanary:plumber-android:${leakCanaryVersion}" + debugImplementation "com.squareup.leakcanary:leakcanary-android:${leakCanaryVersion}" + // Debug bridge for Android + debugImplementation "com.facebook.stetho:stetho:${stethoVersion}" + debugImplementation "com.facebook.stetho:stetho-okhttp3:${stethoVersion}" + +/** Testing **/ testImplementation 'junit:junit:4.13.1' testImplementation "org.mockito:mockito-core:${mockitoVersion}" testImplementation "org.mockito:mockito-inline:${mockitoVersion}" diff --git a/app/src/debug/java/org/schabi/newpipe/settings/DebugSettingsFragment.java b/app/src/debug/java/org/schabi/newpipe/settings/DebugSettingsFragment.java index 7e2ff69b82e..d5d223ff245 100644 --- a/app/src/debug/java/org/schabi/newpipe/settings/DebugSettingsFragment.java +++ b/app/src/debug/java/org/schabi/newpipe/settings/DebugSettingsFragment.java @@ -2,7 +2,6 @@ import android.os.Bundle; -import androidx.annotation.Nullable; import androidx.preference.Preference; import org.schabi.newpipe.R; @@ -11,8 +10,8 @@ public class DebugSettingsFragment extends BasePreferenceFragment { @Override - public void onCreate(@Nullable final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) { + addPreferencesFromResource(R.xml.debug_settings); final Preference showMemoryLeaksPreference = findPreference(getString(R.string.show_memory_leaks_key)); @@ -31,9 +30,4 @@ public void onCreate(@Nullable final Bundle savedInstanceState) { throw new RuntimeException(); }); } - - @Override - public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) { - addPreferencesFromResource(R.xml.debug_settings); - } } diff --git a/app/src/debug/res/xml/main_settings.xml b/app/src/debug/res/xml/main_settings.xml index dfb8ffa34d0..d482d033c03 100644 --- a/app/src/debug/res/xml/main_settings.xml +++ b/app/src/debug/res/xml/main_settings.xml @@ -6,50 +6,50 @@ diff --git a/app/src/main/java/org/schabi/newpipe/MainActivity.java b/app/src/main/java/org/schabi/newpipe/MainActivity.java index 1b8f3190e63..90db7bead28 100644 --- a/app/src/main/java/org/schabi/newpipe/MainActivity.java +++ b/app/src/main/java/org/schabi/newpipe/MainActivity.java @@ -133,6 +133,8 @@ protected void onCreate(final Bundle savedInstanceState) { if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) { TLSSocketFactoryCompat.setAsDefault(); } + + ThemeHelper.setDayNightMode(this); ThemeHelper.setTheme(this, ServiceHelper.getSelectedServiceId(this)); assureCorrectAppLanguage(this); @@ -180,27 +182,27 @@ private void setupDrawer() throws Exception { drawerLayoutBinding.navigation.getMenu() .add(R.id.menu_tabs_group, ITEM_ID_SUBSCRIPTIONS, ORDER, R.string.tab_subscriptions) - .setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_channel)); + .setIcon(R.drawable.ic_tv); drawerLayoutBinding.navigation.getMenu() .add(R.id.menu_tabs_group, ITEM_ID_FEED, ORDER, R.string.fragment_feed_title) - .setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_rss)); + .setIcon(R.drawable.ic_rss_feed); drawerLayoutBinding.navigation.getMenu() .add(R.id.menu_tabs_group, ITEM_ID_BOOKMARKS, ORDER, R.string.tab_bookmarks) - .setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_bookmark)); + .setIcon(R.drawable.ic_bookmark); drawerLayoutBinding.navigation.getMenu() .add(R.id.menu_tabs_group, ITEM_ID_DOWNLOADS, ORDER, R.string.downloads) - .setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_file_download)); + .setIcon(R.drawable.ic_file_download); drawerLayoutBinding.navigation.getMenu() .add(R.id.menu_tabs_group, ITEM_ID_HISTORY, ORDER, R.string.action_history) - .setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_history)); + .setIcon(R.drawable.ic_history); //Settings and About drawerLayoutBinding.navigation.getMenu() .add(R.id.menu_options_about_group, ITEM_ID_SETTINGS, ORDER, R.string.settings) - .setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_settings)); + .setIcon(R.drawable.ic_settings); drawerLayoutBinding.navigation.getMenu() .add(R.id.menu_options_about_group, ITEM_ID_ABOUT, ORDER, R.string.tab_about) - .setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_info_outline)); + .setIcon(R.drawable.ic_info_outline); toggle = new ActionBarDrawerToggle(this, mainBinding.getRoot(), toolbarLayoutBinding.toolbar, R.string.drawer_open, R.string.drawer_close); @@ -346,7 +348,7 @@ private void toggleServices() { } private void showServices() { - drawerHeaderBinding.drawerArrow.setImageResource(R.drawable.ic_arrow_drop_up_white_24dp); + drawerHeaderBinding.drawerArrow.setImageResource(R.drawable.ic_arrow_drop_up); for (final StreamingService s : NewPipe.getServices()) { final String title = s.getServiceInfo().getName() @@ -412,7 +414,7 @@ public void onNothingSelected(final AdapterView parent) { } private void showTabs() throws ExtractionException { - drawerHeaderBinding.drawerArrow.setImageResource(R.drawable.ic_arrow_drop_down_white_24dp); + drawerHeaderBinding.drawerArrow.setImageResource(R.drawable.ic_arrow_drop_down); //Tabs final int currentServiceId = ServiceHelper.getSelectedServiceId(this); @@ -430,27 +432,27 @@ private void showTabs() throws ExtractionException { drawerLayoutBinding.navigation.getMenu() .add(R.id.menu_tabs_group, ITEM_ID_SUBSCRIPTIONS, ORDER, R.string.tab_subscriptions) - .setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_channel)); + .setIcon(R.drawable.ic_tv); drawerLayoutBinding.navigation.getMenu() .add(R.id.menu_tabs_group, ITEM_ID_FEED, ORDER, R.string.fragment_feed_title) - .setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_rss)); + .setIcon(R.drawable.ic_rss_feed); drawerLayoutBinding.navigation.getMenu() .add(R.id.menu_tabs_group, ITEM_ID_BOOKMARKS, ORDER, R.string.tab_bookmarks) - .setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_bookmark)); + .setIcon(R.drawable.ic_bookmark); drawerLayoutBinding.navigation.getMenu() .add(R.id.menu_tabs_group, ITEM_ID_DOWNLOADS, ORDER, R.string.downloads) - .setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_file_download)); + .setIcon(R.drawable.ic_file_download); drawerLayoutBinding.navigation.getMenu() .add(R.id.menu_tabs_group, ITEM_ID_HISTORY, ORDER, R.string.action_history) - .setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_history)); + .setIcon(R.drawable.ic_history); //Settings and About drawerLayoutBinding.navigation.getMenu() .add(R.id.menu_options_about_group, ITEM_ID_SETTINGS, ORDER, R.string.settings) - .setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_settings)); + .setIcon(R.drawable.ic_settings); drawerLayoutBinding.navigation.getMenu() .add(R.id.menu_options_about_group, ITEM_ID_ABOUT, ORDER, R.string.tab_about) - .setIcon(ThemeHelper.resolveResourceIdFromAttr(this, R.attr.ic_info_outline)); + .setIcon(R.drawable.ic_info_outline); } @Override diff --git a/app/src/main/java/org/schabi/newpipe/RouterActivity.java b/app/src/main/java/org/schabi/newpipe/RouterActivity.java index 179fab8dc4d..3b3ca6083a0 100644 --- a/app/src/main/java/org/schabi/newpipe/RouterActivity.java +++ b/app/src/main/java/org/schabi/newpipe/RouterActivity.java @@ -91,7 +91,6 @@ import static org.schabi.newpipe.extractor.StreamingService.ServiceInfo.MediaCapability.AUDIO; import static org.schabi.newpipe.extractor.StreamingService.ServiceInfo.MediaCapability.VIDEO; -import static org.schabi.newpipe.util.ThemeHelper.resolveResourceIdFromAttr; /** * Get the url from the intent and open it in the chosen preferred player. @@ -231,7 +230,7 @@ private void showUnsupportedUrlDialog(final String url) { new AlertDialog.Builder(context) .setTitle(R.string.unsupported_url) .setMessage(R.string.unsupported_url_dialog_message) - .setIcon(ThemeHelper.resolveResourceIdFromAttr(context, R.attr.ic_share)) + .setIcon(R.drawable.ic_share) .setPositiveButton(R.string.open_in_browser, (dialog, which) -> ShareUtils.openUrlInBrowser(this, url)) .setNegativeButton(R.string.share, @@ -373,7 +372,7 @@ private void showDialog(final List choices) { final RadioButton radioButton = ListRadioIconItemBinding.inflate(inflater).getRoot(); radioButton.setText(item.description); TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(radioButton, - AppCompatResources.getDrawable(getApplicationContext(), item.icon), + AppCompatResources.getDrawable(themeWrapperContext, item.icon), null, null, null); radioButton.setChecked(false); radioButton.setId(id++); @@ -427,16 +426,16 @@ private List getChoicesForService(final StreamingService serv final AdapterChoiceItem videoPlayer = new AdapterChoiceItem( getString(R.string.video_player_key), getString(R.string.video_player), - resolveResourceIdFromAttr(context, R.attr.ic_play_arrow)); + R.drawable.ic_play_arrow); final AdapterChoiceItem showInfo = new AdapterChoiceItem( getString(R.string.show_info_key), getString(R.string.show_info), - resolveResourceIdFromAttr(context, R.attr.ic_info_outline)); + R.drawable.ic_info_outline); final AdapterChoiceItem popupPlayer = new AdapterChoiceItem( getString(R.string.popup_player_key), getString(R.string.popup_player), - resolveResourceIdFromAttr(context, R.attr.ic_popup)); + R.drawable.ic_picture_in_picture); final AdapterChoiceItem backgroundPlayer = new AdapterChoiceItem( getString(R.string.background_player_key), getString(R.string.background_player), - resolveResourceIdFromAttr(context, R.attr.ic_headset)); + R.drawable.ic_headset); if (linkType == LinkType.STREAM) { if (isExtVideoEnabled) { @@ -481,7 +480,7 @@ private List getChoicesForService(final StreamingService serv returnList.add(new AdapterChoiceItem(getString(R.string.download_key), getString(R.string.download), - resolveResourceIdFromAttr(context, R.attr.ic_file_download))); + R.drawable.ic_file_download)); return returnList; } diff --git a/app/src/main/java/org/schabi/newpipe/about/AboutActivity.java b/app/src/main/java/org/schabi/newpipe/about/AboutActivity.java deleted file mode 100644 index ec28be237ef..00000000000 --- a/app/src/main/java/org/schabi/newpipe/about/AboutActivity.java +++ /dev/null @@ -1,192 +0,0 @@ -package org.schabi.newpipe.about; - -import android.content.Context; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentActivity; -import androidx.viewpager2.adapter.FragmentStateAdapter; - -import com.google.android.material.tabs.TabLayoutMediator; - -import org.schabi.newpipe.BuildConfig; -import org.schabi.newpipe.R; -import org.schabi.newpipe.databinding.ActivityAboutBinding; -import org.schabi.newpipe.databinding.FragmentAboutBinding; -import org.schabi.newpipe.util.ThemeHelper; - -import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage; -import static org.schabi.newpipe.util.ShareUtils.openUrlInBrowser; - -public class AboutActivity extends AppCompatActivity { - /** - * List of all software components. - */ - private static final SoftwareComponent[] SOFTWARE_COMPONENTS = { - new SoftwareComponent("ACRA", "2013", "Kevin Gaudin", - "https://github.com/ACRA/acra", StandardLicenses.APACHE2), - new SoftwareComponent("AndroidX", "2005 - 2011", "The Android Open Source Project", - "https://developer.android.com/jetpack", StandardLicenses.APACHE2), - new SoftwareComponent("CircleImageView", "2014 - 2020", "Henning Dodenhof", - "https://github.com/hdodenhof/CircleImageView", - StandardLicenses.APACHE2), - new SoftwareComponent("ExoPlayer", "2014 - 2020", "Google, Inc.", - "https://github.com/google/ExoPlayer", StandardLicenses.APACHE2), - new SoftwareComponent("GigaGet", "2014 - 2015", "Peter Cai", - "https://github.com/PaperAirplane-Dev-Team/GigaGet", StandardLicenses.GPL3), - new SoftwareComponent("Groupie", "2016", "Lisa Wray", - "https://github.com/lisawray/groupie", StandardLicenses.MIT), - new SoftwareComponent("Icepick", "2015", "Frankie Sardo", - "https://github.com/frankiesardo/icepick", StandardLicenses.EPL1), - new SoftwareComponent("Jsoup", "2009 - 2020", "Jonathan Hedley", - "https://github.com/jhy/jsoup", StandardLicenses.MIT), - new SoftwareComponent("Markwon", "2019", "Dimitry Ivanov", - "https://github.com/noties/Markwon", StandardLicenses.APACHE2), - new SoftwareComponent("Material Components for Android", "2016 - 2020", "Google, Inc.", - "https://github.com/material-components/material-components-android", - StandardLicenses.APACHE2), - new SoftwareComponent("NewPipe Extractor", "2017 - 2020", "Christian Schabesberger", - "https://github.com/TeamNewPipe/NewPipeExtractor", StandardLicenses.GPL3), - new SoftwareComponent("NoNonsense-FilePicker", "2016", "Jonas Kalderstam", - "https://github.com/spacecowboy/NoNonsense-FilePicker", - StandardLicenses.MPL2), - new SoftwareComponent("OkHttp", "2019", "Square, Inc.", - "https://square.github.io/okhttp/", StandardLicenses.APACHE2), - new SoftwareComponent("PrettyTime", "2012 - 2020", "Lincoln Baxter, III", - "https://github.com/ocpsoft/prettytime", StandardLicenses.APACHE2), - new SoftwareComponent("RxAndroid", "2015", "The RxAndroid authors", - "https://github.com/ReactiveX/RxAndroid", StandardLicenses.APACHE2), - new SoftwareComponent("RxBinding", "2015", "Jake Wharton", - "https://github.com/JakeWharton/RxBinding", StandardLicenses.APACHE2), - new SoftwareComponent("RxJava", "2016 - 2020", "RxJava Contributors", - "https://github.com/ReactiveX/RxJava", StandardLicenses.APACHE2), - new SoftwareComponent("Universal Image Loader", "2011 - 2015", "Sergey Tarasevich", - "https://github.com/nostra13/Android-Universal-Image-Loader", - StandardLicenses.APACHE2), - }; - - private static final int POS_ABOUT = 0; - private static final int POS_LICENSE = 1; - private static final int TOTAL_COUNT = 2; - - @Override - protected void onCreate(final Bundle savedInstanceState) { - assureCorrectAppLanguage(this); - super.onCreate(savedInstanceState); - ThemeHelper.setTheme(this); - setTitle(getString(R.string.title_activity_about)); - - final ActivityAboutBinding aboutBinding = ActivityAboutBinding.inflate(getLayoutInflater()); - setContentView(aboutBinding.getRoot()); - - setSupportActionBar(aboutBinding.toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - // Create the adapter that will return a fragment for each of the three - // primary sections of the activity. - final SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(this); - - // Set up the ViewPager with the sections adapter. - aboutBinding.container.setAdapter(mSectionsPagerAdapter); - - new TabLayoutMediator(aboutBinding.tabs, aboutBinding.container, (tab, position) -> { - switch (position) { - default: - case POS_ABOUT: - tab.setText(R.string.tab_about); - break; - case POS_LICENSE: - tab.setText(R.string.tab_licenses); - break; - } - }).attach(); - } - - @Override - public boolean onOptionsItemSelected(final MenuItem item) { - final int id = item.getItemId(); - - switch (id) { - case android.R.id.home: - finish(); - return true; - } - - return super.onOptionsItemSelected(item); - } - - /** - * A placeholder fragment containing a simple view. - */ - public static class AboutFragment extends Fragment { - public AboutFragment() { - } - - /** - * Created a new instance of this fragment for the given section number. - * - * @return New instance of {@link AboutFragment} - */ - public static AboutFragment newInstance() { - return new AboutFragment(); - } - - @Override - public View onCreateView(@NonNull final LayoutInflater inflater, final ViewGroup container, - final Bundle savedInstanceState) { - final FragmentAboutBinding aboutBinding = - FragmentAboutBinding.inflate(inflater, container, false); - final Context context = getContext(); - - aboutBinding.appVersion.setText(BuildConfig.VERSION_NAME); - - aboutBinding.githubLink.setOnClickListener(nv -> - openUrlInBrowser(context, context.getString(R.string.github_url), false)); - - aboutBinding.donationLink.setOnClickListener(v -> - openUrlInBrowser(context, context.getString(R.string.donation_url), false)); - - aboutBinding.websiteLink.setOnClickListener(nv -> - openUrlInBrowser(context, context.getString(R.string.website_url), false)); - - aboutBinding.privacyPolicyLink.setOnClickListener(v -> - openUrlInBrowser(context, context.getString(R.string.privacy_policy_url), - false)); - - return aboutBinding.getRoot(); - } - } - - /** - * A {@link FragmentStateAdapter} that returns a fragment corresponding to - * one of the sections/tabs/pages. - */ - public static class SectionsPagerAdapter extends FragmentStateAdapter { - public SectionsPagerAdapter(final FragmentActivity fa) { - super(fa); - } - - @NonNull - @Override - public Fragment createFragment(final int position) { - switch (position) { - default: - case POS_ABOUT: - return AboutFragment.newInstance(); - case POS_LICENSE: - return LicenseFragment.newInstance(SOFTWARE_COMPONENTS); - } - } - - @Override - public int getItemCount() { - // Show 2 total pages. - return TOTAL_COUNT; - } - } -} diff --git a/app/src/main/java/org/schabi/newpipe/about/AboutActivity.kt b/app/src/main/java/org/schabi/newpipe/about/AboutActivity.kt new file mode 100644 index 00000000000..2f015a049ec --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/about/AboutActivity.kt @@ -0,0 +1,191 @@ +package org.schabi.newpipe.about + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.MenuItem +import android.view.View +import android.view.ViewGroup +import android.widget.Button +import androidx.appcompat.app.AppCompatActivity +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentActivity +import androidx.viewpager2.adapter.FragmentStateAdapter +import com.google.android.material.tabs.TabLayout +import com.google.android.material.tabs.TabLayoutMediator +import org.schabi.newpipe.BuildConfig +import org.schabi.newpipe.R +import org.schabi.newpipe.databinding.ActivityAboutBinding +import org.schabi.newpipe.databinding.FragmentAboutBinding +import org.schabi.newpipe.util.Localization +import org.schabi.newpipe.util.ShareUtils +import org.schabi.newpipe.util.ThemeHelper + +class AboutActivity : AppCompatActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + Localization.assureCorrectAppLanguage(this) + super.onCreate(savedInstanceState) + ThemeHelper.setTheme(this) + title = getString(R.string.title_activity_about) + val aboutBinding = ActivityAboutBinding.inflate(layoutInflater) + setContentView(aboutBinding.root) + setSupportActionBar(aboutBinding.aboutToolbar) + supportActionBar!!.setDisplayHomeAsUpEnabled(true) + // Create the adapter that will return a fragment for each of the three + // primary sections of the activity. + val mAboutStateAdapter = AboutStateAdapter(this) + + // Set up the ViewPager with the sections adapter. + aboutBinding.aboutViewPager2.adapter = mAboutStateAdapter + TabLayoutMediator( + aboutBinding.aboutTabLayout, + aboutBinding.aboutViewPager2 + ) { tab: TabLayout.Tab, position: Int -> + when (position) { + POS_ABOUT -> tab.setText(R.string.tab_about) + POS_LICENSE -> tab.setText(R.string.tab_licenses) + else -> throw IllegalArgumentException("Unknown position for ViewPager2") + } + }.attach() + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (item.itemId == android.R.id.home) { + finish() + return true + } + return super.onOptionsItemSelected(item) + } + + /** + * A placeholder fragment containing a simple view. + */ + class AboutFragment : Fragment() { + private fun Button.openLink(url: Int) { + setOnClickListener { + ShareUtils.openUrlInBrowser( + context, + requireContext().getString(url), + false + ) + } + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + val aboutBinding = FragmentAboutBinding.inflate(inflater, container, false) + aboutBinding.aboutAppVersion.text = BuildConfig.VERSION_NAME + aboutBinding.aboutGithubLink.openLink(R.string.github_url) + aboutBinding.aboutDonationLink.openLink(R.string.donation_url) + aboutBinding.aboutWebsiteLink.openLink(R.string.website_url) + aboutBinding.aboutPrivacyPolicyLink.openLink(R.string.privacy_policy_url) + return aboutBinding.root + } + } + + /** + * A [FragmentStateAdapter] that returns a fragment corresponding to + * one of the sections/tabs/pages. + */ + private class AboutStateAdapter(fa: FragmentActivity) : FragmentStateAdapter(fa) { + override fun createFragment(position: Int): Fragment { + return when (position) { + POS_ABOUT -> AboutFragment() + POS_LICENSE -> LicenseFragment.newInstance(SOFTWARE_COMPONENTS) + else -> throw IllegalArgumentException("Unknown position for ViewPager2") + } + } + + override fun getItemCount(): Int { + // Show 2 total pages. + return TOTAL_COUNT + } + } + + companion object { + /** + * List of all software components. + */ + private val SOFTWARE_COMPONENTS = arrayOf( + SoftwareComponent( + "ACRA", "2013", "Kevin Gaudin", + "https://github.com/ACRA/acra", StandardLicenses.APACHE2 + ), + SoftwareComponent( + "AndroidX", "2005 - 2011", "The Android Open Source Project", + "https://developer.android.com/jetpack", StandardLicenses.APACHE2 + ), + SoftwareComponent( + "CircleImageView", "2014 - 2020", "Henning Dodenhof", + "https://github.com/hdodenhof/CircleImageView", StandardLicenses.APACHE2 + ), + SoftwareComponent( + "ExoPlayer", "2014 - 2020", "Google, Inc.", + "https://github.com/google/ExoPlayer", StandardLicenses.APACHE2 + ), + SoftwareComponent( + "GigaGet", "2014 - 2015", "Peter Cai", + "https://github.com/PaperAirplane-Dev-Team/GigaGet", StandardLicenses.GPL3 + ), + SoftwareComponent( + "Groupie", "2016", "Lisa Wray", + "https://github.com/lisawray/groupie", StandardLicenses.MIT + ), + SoftwareComponent( + "Icepick", "2015", "Frankie Sardo", + "https://github.com/frankiesardo/icepick", StandardLicenses.EPL1 + ), + SoftwareComponent( + "Jsoup", "2009 - 2020", "Jonathan Hedley", + "https://github.com/jhy/jsoup", StandardLicenses.MIT + ), + SoftwareComponent( + "Markwon", "2019", "Dimitry Ivanov", + "https://github.com/noties/Markwon", StandardLicenses.APACHE2 + ), + SoftwareComponent( + "Material Components for Android", "2016 - 2020", "Google, Inc.", + "https://github.com/material-components/material-components-android", + StandardLicenses.APACHE2 + ), + SoftwareComponent( + "NewPipe Extractor", "2017 - 2020", "Christian Schabesberger", + "https://github.com/TeamNewPipe/NewPipeExtractor", StandardLicenses.GPL3 + ), + SoftwareComponent( + "NoNonsense-FilePicker", "2016", "Jonas Kalderstam", + "https://github.com/spacecowboy/NoNonsense-FilePicker", StandardLicenses.MPL2 + ), + SoftwareComponent( + "OkHttp", "2019", "Square, Inc.", + "https://square.github.io/okhttp/", StandardLicenses.APACHE2 + ), + SoftwareComponent( + "PrettyTime", "2012 - 2020", "Lincoln Baxter, III", + "https://github.com/ocpsoft/prettytime", StandardLicenses.APACHE2 + ), + SoftwareComponent( + "RxAndroid", "2015", "The RxAndroid authors", + "https://github.com/ReactiveX/RxAndroid", StandardLicenses.APACHE2 + ), + SoftwareComponent( + "RxBinding", "2015", "Jake Wharton", + "https://github.com/JakeWharton/RxBinding", StandardLicenses.APACHE2 + ), + SoftwareComponent( + "RxJava", "2016 - 2020", "RxJava Contributors", + "https://github.com/ReactiveX/RxJava", StandardLicenses.APACHE2 + ), + SoftwareComponent( + "Universal Image Loader", "2011 - 2015", "Sergey Tarasevich", + "https://github.com/nostra13/Android-Universal-Image-Loader", + StandardLicenses.APACHE2 + ) + ) + private const val POS_ABOUT = 0 + private const val POS_LICENSE = 1 + private const val TOTAL_COUNT = 2 + } +} diff --git a/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.java b/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.java deleted file mode 100644 index f5bf4df19e9..00000000000 --- a/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.java +++ /dev/null @@ -1,145 +0,0 @@ -package org.schabi.newpipe.about; - -import android.os.Bundle; -import android.view.ContextMenu; -import android.view.LayoutInflater; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; - -import org.schabi.newpipe.R; -import org.schabi.newpipe.databinding.FragmentLicensesBinding; -import org.schabi.newpipe.databinding.ItemSoftwareComponentBinding; -import org.schabi.newpipe.util.ShareUtils; - -import java.io.Serializable; -import java.util.Arrays; -import java.util.Comparator; -import java.util.Objects; - -import io.reactivex.rxjava3.disposables.CompositeDisposable; - -/** - * Fragment containing the software licenses. - */ -public class LicenseFragment extends Fragment { - private static final String ARG_COMPONENTS = "components"; - private static final String LICENSE_KEY = "ACTIVE_LICENSE"; - - private SoftwareComponent[] softwareComponents; - private SoftwareComponent componentForContextMenu; - private License activeLicense; - private final CompositeDisposable compositeDisposable = new CompositeDisposable(); - - public static LicenseFragment newInstance(final SoftwareComponent[] softwareComponents) { - final Bundle bundle = new Bundle(); - bundle.putParcelableArray(ARG_COMPONENTS, Objects.requireNonNull(softwareComponents)); - final LicenseFragment fragment = new LicenseFragment(); - fragment.setArguments(bundle); - return fragment; - } - - @Override - public void onCreate(@Nullable final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - softwareComponents = (SoftwareComponent[]) getArguments() - .getParcelableArray(ARG_COMPONENTS); - - if (savedInstanceState != null) { - final Serializable license = savedInstanceState.getSerializable(LICENSE_KEY); - if (license != null) { - activeLicense = (License) license; - } - } - // Sort components by name - Arrays.sort(softwareComponents, Comparator.comparing(SoftwareComponent::getName)); - } - - @Override - public void onDestroy() { - compositeDisposable.dispose(); - super.onDestroy(); - } - - @Nullable - @Override - public View onCreateView(@NonNull final LayoutInflater inflater, - @Nullable final ViewGroup container, - @Nullable final Bundle savedInstanceState) { - final FragmentLicensesBinding binding = FragmentLicensesBinding - .inflate(inflater, container, false); - - binding.appReadLicense.setOnClickListener(v -> { - activeLicense = StandardLicenses.GPL3; - compositeDisposable.add(LicenseFragmentHelper.showLicense(getActivity(), - StandardLicenses.GPL3)); - }); - - for (final SoftwareComponent component : softwareComponents) { - final ItemSoftwareComponentBinding componentBinding = ItemSoftwareComponentBinding - .inflate(inflater, container, false); - componentBinding.name.setText(component.getName()); - componentBinding.copyright.setText(getString(R.string.copyright, - component.getYears(), - component.getCopyrightOwner(), - component.getLicense().getAbbreviation())); - - final View root = componentBinding.getRoot(); - root.setTag(component); - root.setOnClickListener(v -> { - activeLicense = component.getLicense(); - compositeDisposable.add(LicenseFragmentHelper.showLicense(getActivity(), - component.getLicense())); - }); - binding.softwareComponents.addView(root); - registerForContextMenu(root); - } - if (activeLicense != null) { - compositeDisposable.add(LicenseFragmentHelper.showLicense(getActivity(), - activeLicense)); - } - return binding.getRoot(); - } - - @Override - public void onCreateContextMenu(final ContextMenu menu, final View v, - final ContextMenu.ContextMenuInfo menuInfo) { - final MenuInflater inflater = getActivity().getMenuInflater(); - final SoftwareComponent component = (SoftwareComponent) v.getTag(); - menu.setHeaderTitle(component.getName()); - inflater.inflate(R.menu.software_component, menu); - super.onCreateContextMenu(menu, v, menuInfo); - componentForContextMenu = (SoftwareComponent) v.getTag(); - } - - @Override - public boolean onContextItemSelected(@NonNull final MenuItem item) { - // item.getMenuInfo() is null so we use the tag of the view - final SoftwareComponent component = componentForContextMenu; - if (component == null) { - return false; - } - switch (item.getItemId()) { - case R.id.action_website: - ShareUtils.openUrlInBrowser(getActivity(), component.getLink()); - return true; - case R.id.action_show_license: - compositeDisposable.add(LicenseFragmentHelper.showLicense(getActivity(), - component.getLicense())); - } - return false; - } - - @Override - public void onSaveInstanceState(@NonNull final Bundle savedInstanceState) { - super.onSaveInstanceState(savedInstanceState); - if (activeLicense != null) { - savedInstanceState.putSerializable(LICENSE_KEY, activeLicense); - } - } -} diff --git a/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.kt b/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.kt new file mode 100644 index 00000000000..d72ecf8948c --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.kt @@ -0,0 +1,131 @@ +package org.schabi.newpipe.about + +import android.os.Bundle +import android.view.ContextMenu +import android.view.ContextMenu.ContextMenuInfo +import android.view.LayoutInflater +import android.view.MenuItem +import android.view.View +import android.view.ViewGroup +import androidx.core.os.bundleOf +import androidx.fragment.app.Fragment +import io.reactivex.rxjava3.disposables.CompositeDisposable +import org.schabi.newpipe.R +import org.schabi.newpipe.about.LicenseFragmentHelper.showLicense +import org.schabi.newpipe.databinding.FragmentLicensesBinding +import org.schabi.newpipe.databinding.ItemSoftwareComponentBinding +import org.schabi.newpipe.util.ShareUtils +import java.util.Arrays +import java.util.Objects + +/** + * Fragment containing the software licenses. + */ +class LicenseFragment : Fragment() { + private lateinit var softwareComponents: Array + private var componentForContextMenu: SoftwareComponent? = null + private var activeLicense: License? = null + private val compositeDisposable = CompositeDisposable() + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + softwareComponents = + arguments?.getParcelableArray(ARG_COMPONENTS) as Array + if (savedInstanceState != null) { + val license = savedInstanceState.getSerializable(LICENSE_KEY) + if (license != null) { + activeLicense = license as License? + } + } + // Sort components by name + Arrays.sort(softwareComponents, Comparator.comparing(SoftwareComponent::name)) + } + + override fun onDestroy() { + compositeDisposable.dispose() + super.onDestroy() + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + val binding = FragmentLicensesBinding.inflate(inflater, container, false) + binding.licensesAppReadLicense.setOnClickListener { + activeLicense = StandardLicenses.GPL3 + compositeDisposable.add( + showLicense(activity, StandardLicenses.GPL3) + ) + } + for (component in softwareComponents) { + val componentBinding = ItemSoftwareComponentBinding + .inflate(inflater, container, false) + componentBinding.name.text = component.name + componentBinding.copyright.text = getString( + R.string.copyright, + component.years, + component.copyrightOwner, + component.license.abbreviation + ) + val root: View = componentBinding.root + root.tag = component + root.setOnClickListener { + activeLicense = component.license + compositeDisposable.add( + showLicense(activity, component.license) + ) + } + binding.licensesSoftwareComponents.addView(root) + registerForContextMenu(root) + } + if (activeLicense != null) { + compositeDisposable.add( + showLicense(activity, activeLicense!!) + ) + } + return binding.root + } + + override fun onCreateContextMenu(menu: ContextMenu, v: View, menuInfo: ContextMenuInfo?) { + val inflater = requireActivity().menuInflater + val component = v.tag as SoftwareComponent + menu.setHeaderTitle(component.name) + inflater.inflate(R.menu.software_component, menu) + super.onCreateContextMenu(menu, v, menuInfo) + componentForContextMenu = component + } + + override fun onContextItemSelected(item: MenuItem): Boolean { + // item.getMenuInfo() is null so we use the tag of the view + val component = componentForContextMenu ?: return false + when (item.itemId) { + R.id.menu_software_website -> { + ShareUtils.openUrlInBrowser(activity, component.link) + return true + } + R.id.menu_software_show_license -> compositeDisposable.add( + showLicense(activity, component.license) + ) + } + return false + } + + override fun onSaveInstanceState(savedInstanceState: Bundle) { + super.onSaveInstanceState(savedInstanceState) + if (activeLicense != null) { + savedInstanceState.putSerializable(LICENSE_KEY, activeLicense) + } + } + + companion object { + private const val ARG_COMPONENTS = "components" + private const val LICENSE_KEY = "ACTIVE_LICENSE" + fun newInstance(softwareComponents: Array): LicenseFragment { + val fragment = LicenseFragment() + fragment.arguments = + bundleOf(ARG_COMPONENTS to Objects.requireNonNull(softwareComponents)) + return fragment + } + } +} diff --git a/app/src/main/java/org/schabi/newpipe/about/LicenseFragmentHelper.java b/app/src/main/java/org/schabi/newpipe/about/LicenseFragmentHelper.java deleted file mode 100644 index b0241049d29..00000000000 --- a/app/src/main/java/org/schabi/newpipe/about/LicenseFragmentHelper.java +++ /dev/null @@ -1,109 +0,0 @@ -package org.schabi.newpipe.about; - -import android.content.Context; -import android.util.Base64; -import android.webkit.WebView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; - -import org.schabi.newpipe.R; -import org.schabi.newpipe.util.ThemeHelper; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; - -import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; -import io.reactivex.rxjava3.core.Observable; -import io.reactivex.rxjava3.disposables.Disposable; -import io.reactivex.rxjava3.schedulers.Schedulers; - -import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage; - -public final class LicenseFragmentHelper { - private LicenseFragmentHelper() { } - - /** - * @param context the context to use - * @param license the license - * @return String which contains a HTML formatted license page - * styled according to the context's theme - */ - private static String getFormattedLicense(@NonNull final Context context, - @NonNull final License license) { - final StringBuilder licenseContent = new StringBuilder(); - final String webViewData; - try (BufferedReader in = new BufferedReader(new InputStreamReader( - context.getAssets().open(license.getFilename()), StandardCharsets.UTF_8))) { - String str; - while ((str = in.readLine()) != null) { - licenseContent.append(str); - } - - // split the HTML file and insert the stylesheet into the HEAD of the file - webViewData = licenseContent.toString().replace("", - ""); - } catch (final IOException e) { - throw new IllegalArgumentException( - "Could not get license file: " + license.getFilename(), e); - } - return webViewData; - } - - /** - * @param context the Android context - * @return String which is a CSS stylesheet according to the context's theme - */ - private static String getLicenseStylesheet(@NonNull final Context context) { - final boolean isLightTheme = ThemeHelper.isLightThemeSelected(context); - return "body{padding:12px 15px;margin:0;" - + "background:#" + getHexRGBColor(context, isLightTheme - ? R.color.light_license_background_color - : R.color.dark_license_background_color) + ";" - + "color:#" + getHexRGBColor(context, isLightTheme - ? R.color.light_license_text_color - : R.color.dark_license_text_color) + "}" - + "a[href]{color:#" + getHexRGBColor(context, isLightTheme - ? R.color.light_youtube_primary_color - : R.color.dark_youtube_primary_color) + "}" - + "pre{white-space:pre-wrap}"; - } - - /** - * Cast R.color to a hexadecimal color value. - * - * @param context the context to use - * @param color the color number from R.color - * @return a six characters long String with hexadecimal RGB values - */ - private static String getHexRGBColor(@NonNull final Context context, final int color) { - return context.getResources().getString(color).substring(3); - } - - static Disposable showLicense(@Nullable final Context context, @NonNull final License license) { - if (context == null) { - return Disposable.empty(); - } - - return Observable.fromCallable(() -> getFormattedLicense(context, license)) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(formattedLicense -> { - final String webViewData = Base64.encodeToString(formattedLicense - .getBytes(StandardCharsets.UTF_8), Base64.NO_PADDING); - final WebView webView = new WebView(context); - webView.loadData(webViewData, "text/html; charset=UTF-8", "base64"); - - final AlertDialog.Builder alert = new AlertDialog.Builder(context); - alert.setTitle(license.getName()); - alert.setView(webView); - assureCorrectAppLanguage(context); - alert.setNegativeButton(context.getString(R.string.finish), - (dialog, which) -> dialog.dismiss()); - alert.show(); - }); - } -} diff --git a/app/src/main/java/org/schabi/newpipe/about/LicenseFragmentHelper.kt b/app/src/main/java/org/schabi/newpipe/about/LicenseFragmentHelper.kt new file mode 100644 index 00000000000..bdb3edabdc5 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/about/LicenseFragmentHelper.kt @@ -0,0 +1,116 @@ +package org.schabi.newpipe.about + +import android.content.Context +import android.util.Base64 +import android.webkit.WebView +import androidx.appcompat.app.AlertDialog +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers +import io.reactivex.rxjava3.core.Observable +import io.reactivex.rxjava3.disposables.Disposable +import io.reactivex.rxjava3.schedulers.Schedulers +import org.schabi.newpipe.R +import org.schabi.newpipe.util.Localization +import org.schabi.newpipe.util.ThemeHelper +import java.io.BufferedReader +import java.io.IOException +import java.io.InputStreamReader +import java.nio.charset.StandardCharsets + +object LicenseFragmentHelper { + /** + * @param context the context to use + * @param license the license + * @return String which contains a HTML formatted license page + * styled according to the context's theme + */ + private fun getFormattedLicense(context: Context, license: License): String { + val licenseContent = StringBuilder() + val webViewData: String + try { + BufferedReader( + InputStreamReader( + context.assets.open(license.filename), + StandardCharsets.UTF_8 + ) + ).use { `in` -> + var str: String? + while (`in`.readLine().also { str = it } != null) { + licenseContent.append(str) + } + + // split the HTML file and insert the stylesheet into the HEAD of the file + webViewData = "$licenseContent".replace( + "", + "" + ) + } + } catch (e: IOException) { + throw IllegalArgumentException( + "Could not get license file: " + license.filename, e + ) + } + return webViewData + } + + /** + * @param context the Android context + * @return String which is a CSS stylesheet according to the context's theme + */ + private fun getLicenseStylesheet(context: Context): String { + val isLightTheme = ThemeHelper.isLightThemeSelected(context) + return ( + "body{padding:12px 15px;margin:0;" + "background:#" + getHexRGBColor( + context, + if (isLightTheme) R.color.light_license_background_color + else R.color.dark_license_background_color + ) + ";" + "color:#" + getHexRGBColor( + context, + if (isLightTheme) R.color.light_license_text_color + else R.color.dark_license_text_color + ) + "}" + "a[href]{color:#" + getHexRGBColor( + context, + if (isLightTheme) R.color.light_youtube_primary_color + else R.color.dark_youtube_primary_color + ) + "}" + "pre{white-space:pre-wrap}" + ) + } + + /** + * Cast R.color to a hexadecimal color value. + * + * @param context the context to use + * @param color the color number from R.color + * @return a six characters long String with hexadecimal RGB values + */ + private fun getHexRGBColor(context: Context, color: Int): String { + return context.getString(color).substring(3) + } + + @JvmStatic + fun showLicense(context: Context?, license: License): Disposable { + return if (context == null) { + Disposable.empty() + } else { + Observable.fromCallable { getFormattedLicense(context, license) } + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { formattedLicense: String -> + val webViewData = Base64.encodeToString( + formattedLicense + .toByteArray(StandardCharsets.UTF_8), + Base64.NO_PADDING + ) + val webView = WebView(context) + webView.loadData(webViewData, "text/html; charset=UTF-8", "base64") + val alert = AlertDialog.Builder(context) + alert.setTitle(license.name) + alert.setView(webView) + Localization.assureCorrectAppLanguage(context) + alert.setNegativeButton( + context.getString(R.string.finish) + ) { dialog, _ -> dialog.dismiss() } + alert.show() + } + } + } +} diff --git a/app/src/main/java/org/schabi/newpipe/about/StandardLicenses.java b/app/src/main/java/org/schabi/newpipe/about/StandardLicenses.java deleted file mode 100644 index 60b1e168c6f..00000000000 --- a/app/src/main/java/org/schabi/newpipe/about/StandardLicenses.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.schabi.newpipe.about; - -/** - * Class containing information about standard software licenses. - */ -public final class StandardLicenses { - public static final License GPL3 - = new License("GNU General Public License, Version 3.0", "GPLv3", "gpl_3.html"); - public static final License APACHE2 - = new License("Apache License, Version 2.0", "ALv2", "apache2.html"); - public static final License MPL2 - = new License("Mozilla Public License, Version 2.0", "MPL 2.0", "mpl2.html"); - public static final License MIT - = new License("MIT License", "MIT", "mit.html"); - public static final License EPL1 - = new License("Eclipse Public License, Version 1.0", "EPL 1.0", "epl1.html"); - - private StandardLicenses() { } -} diff --git a/app/src/main/java/org/schabi/newpipe/about/StandardLicenses.kt b/app/src/main/java/org/schabi/newpipe/about/StandardLicenses.kt new file mode 100644 index 00000000000..c5b9618fe1e --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/about/StandardLicenses.kt @@ -0,0 +1,21 @@ +package org.schabi.newpipe.about + +/** + * Class containing information about standard software licenses. + */ +object StandardLicenses { + @JvmField + val GPL3 = License("GNU General Public License, Version 3.0", "GPLv3", "gpl_3.html") + + @JvmField + val APACHE2 = License("Apache License, Version 2.0", "ALv2", "apache2.html") + + @JvmField + val MPL2 = License("Mozilla Public License, Version 2.0", "MPL 2.0", "mpl2.html") + + @JvmField + val MIT = License("MIT License", "MIT", "mit.html") + + @JvmField + val EPL1 = License("Eclipse Public License, Version 1.0", "EPL 1.0", "epl1.html") +} diff --git a/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java b/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java index 484a4649774..4d3726c3888 100644 --- a/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java +++ b/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java @@ -394,8 +394,7 @@ private void initToolbar(final Toolbar toolbar) { } toolbar.setTitle(R.string.download_dialog_title); - toolbar.setNavigationIcon( - ThemeHelper.resolveResourceIdFromAttr(requireContext(), R.attr.ic_arrow_back)); + toolbar.setNavigationIcon(R.drawable.ic_arrow_back); toolbar.inflateMenu(R.menu.dialog_url); toolbar.setNavigationOnClickListener(v -> requireDialog().dismiss()); toolbar.setNavigationContentDescription(R.string.cancel); diff --git a/app/src/main/java/org/schabi/newpipe/error/ErrorActivity.java b/app/src/main/java/org/schabi/newpipe/error/ErrorActivity.java index c39d616e6a4..2fcba0e1a94 100644 --- a/app/src/main/java/org/schabi/newpipe/error/ErrorActivity.java +++ b/app/src/main/java/org/schabi/newpipe/error/ErrorActivity.java @@ -1,7 +1,6 @@ package org.schabi.newpipe.error; import android.app.Activity; -import android.app.AlertDialog; import android.content.Context; import android.content.Intent; import android.graphics.Color; @@ -16,6 +15,7 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.Fragment; @@ -137,6 +137,8 @@ private static void reportErrorInSnackbar(final Context context, protected void onCreate(final Bundle savedInstanceState) { assureCorrectAppLanguage(this); super.onCreate(savedInstanceState); + + ThemeHelper.setDayNightMode(this); ThemeHelper.setTheme(this); activityErrorBinding = ActivityErrorBinding.inflate(getLayoutInflater()); diff --git a/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java index 5fb68ba305c..88d7e757e1b 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java @@ -1,7 +1,6 @@ package org.schabi.newpipe.fragments; import android.content.Context; -import android.content.res.ColorStateList; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; @@ -30,7 +29,6 @@ import org.schabi.newpipe.settings.tabs.TabsManager; import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.ServiceHelper; -import org.schabi.newpipe.util.ThemeHelper; import java.util.ArrayList; import java.util.List; @@ -87,10 +85,10 @@ protected void initViews(final View rootView, final Bundle savedInstanceState) { binding = FragmentMainBinding.bind(rootView); - binding.mainTabLayout.setTabIconTint(ColorStateList.valueOf( - ThemeHelper.resolveColorFromAttr(requireContext(), R.attr.colorAccent))); binding.mainTabLayout.setupWithViewPager(binding.pager); binding.mainTabLayout.addOnTabSelectedListener(this); + binding.mainTabLayout.setTabRippleColor(binding.mainTabLayout.getTabRippleColor() + .withAlpha(32)); setupTabs(); } 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 a5dfe205761..71739ba3d45 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 @@ -73,7 +73,7 @@ import org.schabi.newpipe.fragments.BaseStateFragment; import org.schabi.newpipe.fragments.EmptyFragment; import org.schabi.newpipe.fragments.list.comments.CommentsFragment; -import org.schabi.newpipe.fragments.list.videos.RelatedVideosFragment; +import org.schabi.newpipe.fragments.list.videos.RelatedItemsFragment; import org.schabi.newpipe.ktx.AnimationType; import org.schabi.newpipe.local.dialog.PlaylistAppendDialog; import org.schabi.newpipe.local.dialog.PlaylistCreationDialog; @@ -153,7 +153,7 @@ public final class VideoDetailFragment // tabs private boolean showComments; - private boolean showRelatedStreams; + private boolean showRelatedItems; private boolean showDescription; private String selectedTabTag; @AttrRes @NonNull final List tabIcons = new ArrayList<>(); @@ -280,7 +280,7 @@ public void onCreate(final Bundle savedInstanceState) { final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); showComments = prefs.getBoolean(getString(R.string.show_comments_key), true); - showRelatedStreams = prefs.getBoolean(getString(R.string.show_next_video_key), true); + showRelatedItems = prefs.getBoolean(getString(R.string.show_next_video_key), true); showDescription = prefs.getBoolean(getString(R.string.show_description_key), true); selectedTabTag = prefs.getString( getString(R.string.stream_info_selected_tab_key), COMMENTS_TAB_TAG); @@ -413,7 +413,7 @@ public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, showComments = sharedPreferences.getBoolean(key, true); tabSettingsChanged = true; } else if (key.equals(getString(R.string.show_next_video_key))) { - showRelatedStreams = sharedPreferences.getBoolean(key, true); + showRelatedItems = sharedPreferences.getBoolean(key, true); tabSettingsChanged = true; } else if (key.equals(getString(R.string.show_description_key))) { showComments = sharedPreferences.getBoolean(key, true); @@ -923,21 +923,21 @@ private void initTabs() { if (shouldShowComments()) { pageAdapter.addFragment( CommentsFragment.getInstance(serviceId, url, title), COMMENTS_TAB_TAG); - tabIcons.add(R.drawable.ic_comment_white_24dp); + tabIcons.add(R.drawable.ic_comment); tabContentDescriptions.add(R.string.comments_tab_description); } - if (showRelatedStreams && binding.relatedStreamsLayout == null) { + if (showRelatedItems && binding.relatedItemsLayout == null) { // temp empty fragment. will be updated in handleResult pageAdapter.addFragment(new EmptyFragment(false), RELATED_TAB_TAG); - tabIcons.add(R.drawable.ic_art_track_white_24dp); - tabContentDescriptions.add(R.string.related_streams_tab_description); + tabIcons.add(R.drawable.ic_art_track); + tabContentDescriptions.add(R.string.related_items_tab_description); } if (showDescription) { // temp empty fragment. will be updated in handleResult pageAdapter.addFragment(new EmptyFragment(false), DESCRIPTION_TAB_TAG); - tabIcons.add(R.drawable.ic_description_white_24dp); + tabIcons.add(R.drawable.ic_description); tabContentDescriptions.add(R.string.description_tab_description); } @@ -974,14 +974,14 @@ private void updateTabIconsAndContentDescriptions() { } private void updateTabs(@NonNull final StreamInfo info) { - if (showRelatedStreams) { - if (binding.relatedStreamsLayout == null) { // phone - pageAdapter.updateItem(RELATED_TAB_TAG, RelatedVideosFragment.getInstance(info)); + if (showRelatedItems) { + if (binding.relatedItemsLayout == null) { // phone + pageAdapter.updateItem(RELATED_TAB_TAG, RelatedItemsFragment.getInstance(info)); } else { // tablet + TV getChildFragmentManager().beginTransaction() - .replace(R.id.relatedStreamsLayout, RelatedVideosFragment.getInstance(info)) + .replace(R.id.relatedItemsLayout, RelatedItemsFragment.getInstance(info)) .commitAllowingStateLoss(); - binding.relatedStreamsLayout.setVisibility( + binding.relatedItemsLayout.setVisibility( player != null && player.isFullscreen() ? View.GONE : View.VISIBLE); } } @@ -1009,6 +1009,12 @@ private boolean shouldShowComments() { } public void updateTabLayoutVisibility() { + + if (binding == null) { + //If binding is null we do not need to and should not do anything with its object(s) + return; + } + if (pageAdapter.getCount() < 2 || binding.viewPager.getVisibility() != View.VISIBLE) { // hide tab layout if there is only one tab or if the view pager is also hidden binding.tabLayout.setVisibility(View.GONE); @@ -1331,8 +1337,8 @@ public void handleError() { super.handleError(); setErrorImage(R.drawable.not_available_monkey); - if (binding.relatedStreamsLayout != null) { // hide related streams for tablets - binding.relatedStreamsLayout.setVisibility(View.INVISIBLE); + if (binding.relatedItemsLayout != null) { // hide related streams for tablets + binding.relatedItemsLayout.setVisibility(View.INVISIBLE); } // hide comments / related streams / description tabs @@ -1426,12 +1432,12 @@ public void showLoading() { binding.detailTitleRootLayout.setClickable(false); binding.detailSecondaryControlPanel.setVisibility(View.GONE); - if (binding.relatedStreamsLayout != null) { - if (showRelatedStreams) { - binding.relatedStreamsLayout.setVisibility( + if (binding.relatedItemsLayout != null) { + if (showRelatedItems) { + binding.relatedItemsLayout.setVisibility( player != null && player.isFullscreen() ? View.GONE : View.INVISIBLE); } else { - binding.relatedStreamsLayout.setVisibility(View.GONE); + binding.relatedItemsLayout.setVisibility(View.GONE); } } @@ -1843,8 +1849,8 @@ public void onFullscreenStateChanged(final boolean fullscreen) { showSystemUi(); } - if (binding.relatedStreamsLayout != null) { - binding.relatedStreamsLayout.setVisibility(fullscreen ? View.GONE : View.VISIBLE); + if (binding.relatedItemsLayout != null) { + binding.relatedItemsLayout.setVisibility(fullscreen ? View.GONE : View.VISIBLE); } scrollToTop(); @@ -2274,11 +2280,10 @@ private void updateOverlayData(@Nullable final String overlayTitle, } private void setOverlayPlayPauseImage(final boolean playerIsPlaying) { - final int attr = playerIsPlaying - ? R.attr.ic_pause - : R.attr.ic_play_arrow; - binding.overlayPlayPauseButton.setImageResource( - ThemeHelper.resolveResourceIdFromAttr(activity, attr)); + final int drawable = playerIsPlaying + ? R.drawable.ic_pause + : R.drawable.ic_play_arrow; + binding.overlayPlayPauseButton.setImageResource(drawable); } private void setOverlayLook(final AppBarLayout appBar, diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java index 3c37bd1287b..38fdbccab38 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java @@ -45,6 +45,7 @@ import java.util.List; import java.util.Queue; +import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; import static org.schabi.newpipe.ktx.ViewUtils.animate; import static org.schabi.newpipe.ktx.ViewUtils.animateHideRecyclerViewAllowingScrolling; @@ -124,8 +125,8 @@ public void onResume() { /** * If the default implementation of {@link StateSaver.WriteRead} should be used. * - * @see StateSaver * @param useDefaultStateSaving Whether the default implementation should be used + * @see StateSaver */ public void setUseDefaultStateSaving(final boolean useDefaultStateSaving) { this.useDefaultStateSaving = useDefaultStateSaving; @@ -350,7 +351,7 @@ protected void showStreamDialog(final StreamInfoItem item) { return; } - final ArrayList entries = new ArrayList<>(); + final List entries = new ArrayList<>(); if (PlayerHolder.getType() != null) { entries.add(StreamDialogEntry.enqueue); @@ -361,7 +362,7 @@ protected void showStreamDialog(final StreamInfoItem item) { StreamDialogEntry.append_playlist, StreamDialogEntry.share )); - } else { + } else { entries.addAll(Arrays.asList( StreamDialogEntry.start_here_on_background, StreamDialogEntry.start_here_on_popup, @@ -372,6 +373,11 @@ protected void showStreamDialog(final StreamInfoItem item) { if (KoreUtil.shouldShowPlayWithKodi(context, item.getServiceId())) { entries.add(StreamDialogEntry.play_with_kodi); } + + if (!isNullOrEmpty(item.getUploaderUrl())) { + entries.add(StreamDialogEntry.show_channel_details); + } + StreamDialogEntry.setEnabledEntries(entries); new InfoItemDialog(activity, item, StreamDialogEntry.getCommands(context), diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java index 6874f80d5e6..e98dc9fdadf 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java @@ -12,6 +12,7 @@ import org.schabi.newpipe.extractor.ListExtractor; import org.schabi.newpipe.extractor.ListInfo; import org.schabi.newpipe.extractor.Page; +import org.schabi.newpipe.extractor.channel.ChannelInfo; import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException; import org.schabi.newpipe.util.Constants; import org.schabi.newpipe.views.NewPipeRecyclerView; @@ -227,7 +228,11 @@ public void handleResult(@NonNull final I result) { showListFooter(hasMoreItems()); } else { infoListAdapter.clearStreamItemList(); - showEmptyState(); + // showEmptyState should be called only if there is no item as + // well as no header in infoListAdapter + if (!(result instanceof ChannelInfo && infoListAdapter.getItemCount() == 1)) { + showEmptyState(); + } } } diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index a94581cfd53..e02e18a8636 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -449,8 +449,8 @@ public void handleResult(@NonNull final ChannelInfo result) { if (!TextUtils.isEmpty(currentInfo.getParentChannelName())) { headerBinding.subChannelTitleView.setText(String.format( - getString(R.string.channel_created_by), - currentInfo.getParentChannelName()) + getString(R.string.channel_created_by), + currentInfo.getParentChannelName()) ); headerBinding.subChannelTitleView.setVisibility(View.VISIBLE); headerBinding.subChannelAvatarView.setVisibility(View.VISIBLE); @@ -462,7 +462,13 @@ public void handleResult(@NonNull final ChannelInfo result) { menuRssButton.setVisible(!TextUtils.isEmpty(result.getFeedUrl())); } - playlistControlBinding.getRoot().setVisibility(View.VISIBLE); + // PlaylistControls should be visible only if there is some item in + // infoListAdapter other than header + if (infoListAdapter.getItemCount() != 1) { + playlistControlBinding.getRoot().setVisibility(View.VISIBLE); + } else { + playlistControlBinding.getRoot().setVisibility(View.GONE); + } for (final Throwable throwable : result.getErrors()) { if (throwable instanceof ContentNotSupportedException) { diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java index 11494792319..a729b7cc9bf 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java @@ -61,7 +61,6 @@ import static org.schabi.newpipe.ktx.ViewUtils.animate; import static org.schabi.newpipe.ktx.ViewUtils.animateHideRecyclerViewAllowingScrolling; -import static org.schabi.newpipe.util.ThemeHelper.resolveResourceIdFromAttr; public class PlaylistFragment extends BaseListInfoFragment { private CompositeDisposable disposables; @@ -307,7 +306,7 @@ public void handleResult(@NonNull final PlaylistInfo result) { getResources().getColor(R.color.transparent_background_color)); headerBinding.uploaderAvatarView.setImageDrawable( AppCompatResources.getDrawable(requireContext(), - resolveResourceIdFromAttr(requireContext(), R.attr.ic_radio)) + R.drawable.ic_radio) ); } else { IMAGE_LOADER.displayImage(avatarUrl, headerBinding.uploaderAvatarView, @@ -423,7 +422,9 @@ public void onComplete() { } @Override public void setTitle(final String title) { super.setTitle(title); - headerBinding.playlistTitleView.setText(title); + if (headerBinding != null) { + headerBinding.playlistTitleView.setText(title); + } } private void onBookmarkClicked() { @@ -459,13 +460,13 @@ private void updateBookmarkButtons() { return; } - final int iconAttr = playlistEntity == null - ? R.attr.ic_playlist_add : R.attr.ic_playlist_check; + final int drawable = playlistEntity == null + ? R.drawable.ic_playlist_add : R.drawable.ic_playlist_add_check; final int titleRes = playlistEntity == null ? R.string.bookmark_playlist : R.string.unbookmark_playlist; - playlistBookmarkButton.setIcon(resolveResourceIdFromAttr(activity, iconAttr)); + playlistBookmarkButton.setIcon(drawable); playlistBookmarkButton.setTitle(titleRes); } } diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java index 26360137e9c..b52aaf2f878 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java @@ -139,7 +139,7 @@ public class SearchFragment extends BaseListFragment menuItemToFilterName; + @Nullable private Map menuItemToFilterName = null; private StreamingService service; private Page nextPage; private boolean isSuggestionsEnabled = true; @@ -455,11 +455,12 @@ public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) { } @Override - public boolean onOptionsItemSelected(final MenuItem item) { - final List cf = new ArrayList<>(1); - cf.add(menuItemToFilterName.get(item.getItemId())); - changeContentFilter(item, cf); - + public boolean onOptionsItemSelected(@NonNull final MenuItem item) { + if (menuItemToFilterName != null) { + final List cf = new ArrayList<>(1); + cf.add(menuItemToFilterName.get(item.getItemId())); + changeContentFilter(item, cf); + } return true; } @@ -486,6 +487,9 @@ private void showSearchOnStart() { + lastSearchedString); } searchEditText.setText(searchString); + if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) { + searchEditText.setHintTextColor(searchEditText.getTextColors().withAlpha(128)); + } if (TextUtils.isEmpty(searchString) || TextUtils.isEmpty(searchEditText.getText())) { searchToolbarContainer.setTranslationX(100); diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SuggestionListAdapter.java b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SuggestionListAdapter.java index d4bb4eebde8..95231679672 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SuggestionListAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SuggestionListAdapter.java @@ -1,14 +1,12 @@ package org.schabi.newpipe.fragments.list.search; import android.content.Context; -import android.content.res.TypedArray; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; -import androidx.annotation.AttrRes; import androidx.recyclerview.widget.RecyclerView; import org.schabi.newpipe.R; @@ -117,16 +115,8 @@ private SuggestionItemHolder(final View rootView) { queryView = rootView.findViewById(R.id.suggestion_search); insertView = rootView.findViewById(R.id.suggestion_insert); - historyResId = resolveResourceIdFromAttr(rootView.getContext(), R.attr.ic_history); - searchResId = resolveResourceIdFromAttr(rootView.getContext(), R.attr.ic_search); - } - - private static int resolveResourceIdFromAttr(final Context context, - @AttrRes final int attr) { - final TypedArray a = context.getTheme().obtainStyledAttributes(new int[]{attr}); - final int attributeResourceId = a.getResourceId(0, 0); - a.recycle(); - return attributeResourceId; + historyResId = R.drawable.ic_history; + searchResId = R.drawable.ic_search; } private void updateFrom(final SuggestionItem item) { diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/videos/RelatedVideosFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/videos/RelatedItemsFragment.java similarity index 80% rename from app/src/main/java/org/schabi/newpipe/fragments/list/videos/RelatedVideosFragment.java rename to app/src/main/java/org/schabi/newpipe/fragments/list/videos/RelatedItemsFragment.java index 902df94bc1d..a66b7d56974 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/videos/RelatedVideosFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/videos/RelatedItemsFragment.java @@ -15,38 +15,38 @@ import androidx.viewbinding.ViewBinding; import org.schabi.newpipe.R; -import org.schabi.newpipe.databinding.RelatedStreamsHeaderBinding; +import org.schabi.newpipe.databinding.RelatedItemsHeaderBinding; import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.extractor.ListExtractor; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.fragments.list.BaseListInfoFragment; import org.schabi.newpipe.ktx.ViewUtils; -import org.schabi.newpipe.util.RelatedStreamInfo; +import org.schabi.newpipe.util.RelatedItemInfo; import java.io.Serializable; import io.reactivex.rxjava3.core.Single; import io.reactivex.rxjava3.disposables.CompositeDisposable; -public class RelatedVideosFragment extends BaseListInfoFragment +public class RelatedItemsFragment extends BaseListInfoFragment implements SharedPreferences.OnSharedPreferenceChangeListener { private static final String INFO_KEY = "related_info_key"; private final CompositeDisposable disposables = new CompositeDisposable(); - private RelatedStreamInfo relatedStreamInfo; + private RelatedItemInfo relatedItemInfo; /*////////////////////////////////////////////////////////////////////////// // Views //////////////////////////////////////////////////////////////////////////*/ - private RelatedStreamsHeaderBinding headerBinding; + private RelatedItemsHeaderBinding headerBinding; - public static RelatedVideosFragment getInstance(final StreamInfo info) { - final RelatedVideosFragment instance = new RelatedVideosFragment(); + public static RelatedItemsFragment getInstance(final StreamInfo info) { + final RelatedItemsFragment instance = new RelatedItemsFragment(); instance.setInitialData(info); return instance; } - public RelatedVideosFragment() { + public RelatedItemsFragment() { super(UserAction.REQUESTED_STREAM); } @@ -63,7 +63,7 @@ public void onAttach(@NonNull final Context context) { public View onCreateView(@NonNull final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) { - return inflater.inflate(R.layout.fragment_related_streams, container, false); + return inflater.inflate(R.layout.fragment_related_items, container, false); } @Override @@ -80,8 +80,8 @@ public void onDestroyView() { @Override protected ViewBinding getListHeader() { - if (relatedStreamInfo != null && relatedStreamInfo.getRelatedItems() != null) { - headerBinding = RelatedStreamsHeaderBinding + if (relatedItemInfo != null && relatedItemInfo.getRelatedItems() != null) { + headerBinding = RelatedItemsHeaderBinding .inflate(activity.getLayoutInflater(), itemsList, false); final SharedPreferences pref = PreferenceManager @@ -107,8 +107,8 @@ protected Single loadMoreItemsLogic() { //////////////////////////////////////////////////////////////////////////*/ @Override - protected Single loadResult(final boolean forceLoad) { - return Single.fromCallable(() -> relatedStreamInfo); + protected Single loadResult(final boolean forceLoad) { + return Single.fromCallable(() -> relatedItemInfo); } @Override @@ -120,7 +120,7 @@ public void showLoading() { } @Override - public void handleResult(@NonNull final RelatedStreamInfo result) { + public void handleResult(@NonNull final RelatedItemInfo result) { super.handleResult(result); if (headerBinding != null) { @@ -145,23 +145,23 @@ public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) { private void setInitialData(final StreamInfo info) { super.setInitialData(info.getServiceId(), info.getUrl(), info.getName()); - if (this.relatedStreamInfo == null) { - this.relatedStreamInfo = RelatedStreamInfo.getInfo(info); + if (this.relatedItemInfo == null) { + this.relatedItemInfo = RelatedItemInfo.getInfo(info); } } @Override public void onSaveInstanceState(@NonNull final Bundle outState) { super.onSaveInstanceState(outState); - outState.putSerializable(INFO_KEY, relatedStreamInfo); + outState.putSerializable(INFO_KEY, relatedItemInfo); } @Override protected void onRestoreInstanceState(@NonNull final Bundle savedState) { super.onRestoreInstanceState(savedState); final Serializable serializable = savedState.getSerializable(INFO_KEY); - if (serializable instanceof RelatedStreamInfo) { - this.relatedStreamInfo = (RelatedStreamInfo) serializable; + if (serializable instanceof RelatedItemInfo) { + this.relatedItemInfo = (RelatedItemInfo) serializable; } } diff --git a/app/src/main/java/org/schabi/newpipe/info_list/InfoItemDialog.java b/app/src/main/java/org/schabi/newpipe/info_list/InfoItemDialog.java index 8f00e50fde7..c485337f0fc 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/InfoItemDialog.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/InfoItemDialog.java @@ -1,13 +1,13 @@ package org.schabi.newpipe.info_list; import android.app.Activity; -import android.app.AlertDialog; import android.content.DialogInterface; import android.view.View; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.stream.StreamInfoItem; diff --git a/app/src/main/java/org/schabi/newpipe/info_list/StreamSegmentItem.kt b/app/src/main/java/org/schabi/newpipe/info_list/StreamSegmentItem.kt index 798b9b287b7..f6d3587d6a0 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/StreamSegmentItem.kt +++ b/app/src/main/java/org/schabi/newpipe/info_list/StreamSegmentItem.kt @@ -1,5 +1,6 @@ package org.schabi.newpipe.info_list +import android.view.View import android.widget.ImageView import android.widget.TextView import com.nostra13.universalimageloader.core.ImageLoader @@ -29,6 +30,17 @@ class StreamSegmentItem( ) } viewHolder.root.findViewById(R.id.textViewTitle).text = item.title + if (item.channelName == null) { + viewHolder.root.findViewById(R.id.textViewChannel).visibility = View.GONE + // When the channel name is displayed there is less space + // and thus the segment title needs to be only one line height. + // But when there is no channel name displayed, the title can be two lines long. + // The default maxLines value is set to 1 to display all elements in the AS preview, + viewHolder.root.findViewById(R.id.textViewTitle).maxLines = 2 + } else { + viewHolder.root.findViewById(R.id.textViewChannel).text = item.channelName + viewHolder.root.findViewById(R.id.textViewChannel).visibility = View.VISIBLE + } viewHolder.root.findViewById(R.id.textViewStartSeconds).text = Localization.getDurationString(item.startTimeSeconds.toLong()) viewHolder.root.setOnClickListener { onClick.onItemClick(this, item.startTimeSeconds) } diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamInfoItemHolder.java index 1915ff28323..a84c9840416 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/StreamInfoItemHolder.java @@ -4,8 +4,6 @@ import android.view.ViewGroup; import android.widget.TextView; -import androidx.preference.PreferenceManager; - import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.stream.StreamInfoItem; @@ -14,6 +12,8 @@ import org.schabi.newpipe.local.history.HistoryRecordManager; import org.schabi.newpipe.util.Localization; +import androidx.preference.PreferenceManager; + import static org.schabi.newpipe.MainActivity.DEBUG; /* diff --git a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java index e9032a1c661..a58bb4cd5f4 100644 --- a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java @@ -1,7 +1,5 @@ package org.schabi.newpipe.local.bookmark; -import android.app.AlertDialog; -import android.app.AlertDialog.Builder; import android.os.Bundle; import android.os.Parcelable; import android.util.Log; @@ -12,6 +10,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.FragmentManager; import org.reactivestreams.Subscriber; @@ -260,7 +259,7 @@ private void showLocalDialog(final PlaylistMetadataEntry selectedItem) { final EditText editText = dialogView.findViewById(R.id.playlist_name_edit_text); editText.setText(selectedItem.name); - final Builder builder = new AlertDialog.Builder(activity); + final AlertDialog.Builder builder = new AlertDialog.Builder(activity); builder.setView(dialogView) .setPositiveButton(R.string.rename_playlist, (dialog, which) -> changeLocalPlaylistName(selectedItem.uid, editText.getText().toString())) diff --git a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistCreationDialog.java b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistCreationDialog.java index 4d19f0dd91f..40ea27e8c9a 100644 --- a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistCreationDialog.java +++ b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistCreationDialog.java @@ -1,6 +1,5 @@ package org.schabi.newpipe.local.dialog; -import android.app.AlertDialog; import android.app.Dialog; import android.os.Bundle; import android.view.View; @@ -9,6 +8,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; import org.schabi.newpipe.NewPipeDatabase; import org.schabi.newpipe.R; @@ -46,7 +46,7 @@ public Dialog onCreateDialog(@Nullable final Bundle savedInstanceState) { final View dialogView = View.inflate(getContext(), R.layout.dialog_playlist_name, null); final EditText nameInput = dialogView.findViewById(R.id.playlist_name); - final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getContext()) + final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(requireContext()) .setTitle(R.string.create_playlist) .setView(dialogView) .setCancelable(true) @@ -54,7 +54,7 @@ public Dialog onCreateDialog(@Nullable final Bundle savedInstanceState) { .setPositiveButton(R.string.create, (dialogInterface, i) -> { final String name = nameInput.getText().toString(); final LocalPlaylistManager playlistManager = - new LocalPlaylistManager(NewPipeDatabase.getInstance(getContext())); + new LocalPlaylistManager(NewPipeDatabase.getInstance(requireContext())); final Toast successToast = Toast.makeText(getActivity(), R.string.playlist_creation_success, Toast.LENGTH_SHORT); diff --git a/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java index 1bece369b73..a2107d5e56d 100644 --- a/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java @@ -40,7 +40,6 @@ import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.OnClickGesture; import org.schabi.newpipe.util.StreamDialogEntry; -import org.schabi.newpipe.util.ThemeHelper; import java.util.ArrayList; import java.util.Arrays; @@ -312,14 +311,13 @@ private void toggleSortMode() { if (sortMode == StatisticSortMode.LAST_PLAYED) { sortMode = StatisticSortMode.MOST_PLAYED; setTitle(getString(R.string.title_most_played)); - headerBinding.sortButtonIcon.setImageResource( - ThemeHelper.resolveResourceIdFromAttr(requireContext(), R.attr.ic_history)); + headerBinding.sortButtonIcon.setImageResource(R.drawable.ic_history); headerBinding.sortButtonText.setText(R.string.title_last_played); } else { sortMode = StatisticSortMode.LAST_PLAYED; setTitle(getString(R.string.title_last_played)); headerBinding.sortButtonIcon.setImageResource( - ThemeHelper.resolveResourceIdFromAttr(requireContext(), R.attr.ic_filter_list)); + R.drawable.ic_filter_list); headerBinding.sortButtonText.setText(R.string.title_most_played); } startLoading(true); diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java index 5dbb67cd1d0..66bd341429f 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java @@ -72,7 +72,6 @@ public class LocalPlaylistFragment extends BaseLocalListFragment() { feedGroupsCarousel = FeedGroupCarouselItem(requireContext(), carouselAdapter) feedGroupsSortMenuItem = HeaderWithMenuItem( getString(R.string.feed_groups_header_title), - ThemeHelper.resolveResourceIdFromAttr(requireContext(), R.attr.ic_sort), + R.drawable.ic_sort, menuItemOnClickListener = ::openReorderDialog ) add(Section(feedGroupsSortMenuItem, listOf(feedGroupsCarousel))) diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupDialog.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupDialog.kt index 5bd13356d1d..2918bcd66b9 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupDialog.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupDialog.kt @@ -1,6 +1,7 @@ package org.schabi.newpipe.local.subscription.dialog import android.app.Dialog +import android.content.res.ColorStateList import android.os.Bundle import android.os.Parcelable import android.view.LayoutInflater @@ -12,6 +13,7 @@ import androidx.core.content.getSystemService import androidx.core.os.bundleOf import androidx.core.view.isGone import androidx.core.view.isVisible +import androidx.core.widget.ImageViewCompat import androidx.core.widget.doOnTextChanged import androidx.fragment.app.DialogFragment import androidx.lifecycle.Observer @@ -123,6 +125,14 @@ class FeedGroupDialog : DialogFragment(), BackPressable { _feedGroupCreateBinding = DialogFeedGroupCreateBinding.bind(view) _searchLayoutBinding = feedGroupCreateBinding.subscriptionsHeaderSearchContainer + if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) { + // KitKat doesn't apply container's theme to content + val contrastColor = ColorStateList.valueOf(resources.getColor(R.color.contrastColor)) + searchLayoutBinding.toolbarSearchEditText.setTextColor(contrastColor) + searchLayoutBinding.toolbarSearchEditText.setHintTextColor(contrastColor.withAlpha(128)) + ImageViewCompat.setImageTintList(searchLayoutBinding.toolbarSearchClearIcon, contrastColor) + } + viewModel = ViewModelProvider( this, FeedGroupDialogViewModel.Factory( @@ -306,7 +316,7 @@ class FeedGroupDialog : DialogFragment(), BackPressable { groupSortOrder = feedGroupEntity?.sortOrder ?: -1 val feedGroupIcon = if (selectedIcon == null) icon else selectedIcon!! - feedGroupCreateBinding.iconPreview.setImageResource(feedGroupIcon.getDrawableRes(requireContext())) + feedGroupCreateBinding.iconPreview.setImageResource(feedGroupIcon.getDrawableRes()) if (feedGroupCreateBinding.groupNameInput.text.isNullOrBlank()) { feedGroupCreateBinding.groupNameInput.setText(name) @@ -404,7 +414,7 @@ class FeedGroupDialog : DialogFragment(), BackPressable { if (groupId == NO_GROUP_SELECTED) { val icon = selectedIcon ?: FeedGroupIcon.ALL - feedGroupCreateBinding.iconPreview.setImageResource(icon.getDrawableRes(requireContext())) + feedGroupCreateBinding.iconPreview.setImageResource(icon.getDrawableRes()) } } diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/item/FeedGroupCardItem.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/item/FeedGroupCardItem.kt index a9731df8a7b..7b78b3d955a 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/item/FeedGroupCardItem.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/item/FeedGroupCardItem.kt @@ -25,7 +25,7 @@ data class FeedGroupCardItem( override fun bind(viewBinding: FeedGroupCardItemBinding, position: Int) { viewBinding.title.text = name - viewBinding.icon.setImageResource(icon.getDrawableRes(viewBinding.root.context)) + viewBinding.icon.setImageResource(icon.getDrawableRes()) } override fun initializeViewBinding(view: View) = FeedGroupCardItemBinding.bind(view) diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/item/FeedGroupReorderItem.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/item/FeedGroupReorderItem.kt index 74e481c4fe3..9a33de54df3 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/item/FeedGroupReorderItem.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/item/FeedGroupReorderItem.kt @@ -32,7 +32,7 @@ data class FeedGroupReorderItem( override fun bind(viewBinding: FeedGroupReorderItemBinding, position: Int) { viewBinding.groupName.text = name - viewBinding.groupIcon.setImageResource(icon.getDrawableRes(viewBinding.root.context)) + viewBinding.groupIcon.setImageResource(icon.getDrawableRes()) } override fun bind(viewHolder: GroupieViewHolder, position: Int, payloads: MutableList) { diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/item/FeedImportExportItem.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/item/FeedImportExportItem.kt index afca7064f98..aacfc77adc4 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/item/FeedImportExportItem.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/item/FeedImportExportItem.kt @@ -86,7 +86,7 @@ class FeedImportExportItem( private fun setupImportFromItems(listHolder: ViewGroup) { val previousBackupItem = addItemView( listHolder.context.getString(R.string.previous_export), - ThemeHelper.resolveResourceIdFromAttr(listHolder.context, R.attr.ic_backup), listHolder + R.drawable.ic_backup, listHolder ) previousBackupItem.setOnClickListener { onImportPreviousSelected() } @@ -115,8 +115,7 @@ class FeedImportExportItem( private fun setupExportToItems(listHolder: ViewGroup) { val previousBackupItem = addItemView( listHolder.context.getString(R.string.file), - ThemeHelper.resolveResourceIdFromAttr(listHolder.context, R.attr.ic_save), - listHolder + R.drawable.ic_save, listHolder ) previousBackupItem.setOnClickListener { onExportSelected() } } diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/item/PickerIconItem.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/item/PickerIconItem.kt index 11fc4833a51..1b55d2e85f3 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/item/PickerIconItem.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/item/PickerIconItem.kt @@ -13,7 +13,7 @@ class PickerIconItem( val icon: FeedGroupIcon ) : BindableItem() { @DrawableRes - val iconRes: Int = icon.getDrawableRes(context) + val iconRes: Int = icon.getDrawableRes() override fun getLayout(): Int = R.layout.picker_icon_item diff --git a/app/src/main/java/org/schabi/newpipe/player/NotificationConstants.java b/app/src/main/java/org/schabi/newpipe/player/NotificationConstants.java index cf58c8f76da..6c9858d1bdf 100644 --- a/app/src/main/java/org/schabi/newpipe/player/NotificationConstants.java +++ b/app/src/main/java/org/schabi/newpipe/player/NotificationConstants.java @@ -50,11 +50,11 @@ private NotificationConstants() { } 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.ic_pause, + R.drawable.ic_hourglass_top, R.drawable.exo_icon_repeat_all, R.drawable.exo_icon_shuffle_on, - R.drawable.ic_close_white_24dp, + R.drawable.ic_close, }; 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 43c1b4405fa..948343be2ba 100644 --- a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java +++ b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java @@ -273,14 +273,14 @@ private NotificationCompat.Action getAction( || player.getCurrentState() == Player.STATE_BLOCKED || player.getCurrentState() == Player.STATE_BUFFERING) { // null intent -> show hourglass icon that does nothing when clicked - return new NotificationCompat.Action(R.drawable.ic_hourglass_top_white_24dp_png, + return new NotificationCompat.Action(R.drawable.ic_hourglass_top, player.getContext().getString(R.string.notification_action_buffering), null); } case NotificationConstants.PLAY_PAUSE: if (player.getCurrentState() == Player.STATE_COMPLETED) { - return getAction(player, R.drawable.ic_replay_white_24dp_png, + return getAction(player, R.drawable.ic_replay, R.string.exo_controls_pause_description, ACTION_PLAY_PAUSE); } else if (player.isPlaying() || player.getCurrentState() == Player.STATE_PREFLIGHT @@ -315,7 +315,7 @@ private NotificationCompat.Action getAction( } case NotificationConstants.CLOSE: - return getAction(player, R.drawable.ic_close_white_24dp_png, + return getAction(player, R.drawable.ic_close, R.string.close, ACTION_CLOSE); case NotificationConstants.NOTHING: diff --git a/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java b/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java index d757a926844..08a2762a979 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java +++ b/app/src/main/java/org/schabi/newpipe/player/PlayQueueActivity.java @@ -589,15 +589,15 @@ private void onStateChanged(final int state) { switch (state) { case Player.STATE_PAUSED: queueControlBinding.controlPlayPause - .setImageResource(R.drawable.ic_play_arrow_white_24dp); + .setImageResource(R.drawable.ic_play_arrow); break; case Player.STATE_PLAYING: queueControlBinding.controlPlayPause - .setImageResource(R.drawable.ic_pause_white_24dp); + .setImageResource(R.drawable.ic_pause); break; case Player.STATE_COMPLETED: queueControlBinding.controlPlayPause - .setImageResource(R.drawable.ic_replay_white_24dp); + .setImageResource(R.drawable.ic_replay); break; default: break; @@ -670,8 +670,7 @@ private void onMaybeMuteChanged() { //2) Icon change accordingly to current App Theme // using rootView.getContext() because getApplicationContext() didn't work final Context context = queueControlBinding.getRoot().getContext(); - item.setIcon(ThemeHelper.resolveResourceIdFromAttr(context, - player.isMuted() ? R.attr.ic_volume_off : R.attr.ic_volume_up)); + item.setIcon(player.isMuted() ? R.drawable.ic_volume_off : R.drawable.ic_volume_up); } } } diff --git a/app/src/main/java/org/schabi/newpipe/player/Player.java b/app/src/main/java/org/schabi/newpipe/player/Player.java index f8e0732b3b8..21276b4c0f5 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -26,6 +26,7 @@ import android.util.DisplayMetrics; import android.util.Log; import android.util.TypedValue; +import android.view.ContextThemeWrapper; import android.view.GestureDetector; import android.view.KeyEvent; import android.view.LayoutInflater; @@ -51,6 +52,7 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.content.res.AppCompatResources; +import androidx.appcompat.widget.AppCompatImageButton; import androidx.core.content.ContextCompat; import androidx.core.view.DisplayCutoutCompat; import androidx.core.view.ViewCompat; @@ -74,6 +76,7 @@ import com.google.android.exoplayer2.ui.AspectRatioFrameLayout; import com.google.android.exoplayer2.ui.SubtitleView; import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter; +import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.video.VideoListener; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.nostra13.universalimageloader.core.ImageLoader; @@ -446,9 +449,12 @@ private void initViews(@NonNull final PlayerBinding playerBinding) { binding.playbackSeekBar.getProgressDrawable() .setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY)); - qualityPopupMenu = new PopupMenu(context, binding.qualityTextView); + final ContextThemeWrapper themeWrapper = new ContextThemeWrapper(getContext(), + R.style.DarkPopupMenu); + + qualityPopupMenu = new PopupMenu(themeWrapper, binding.qualityTextView); playbackSpeedPopupMenu = new PopupMenu(context, binding.playbackSpeed); - captionPopupMenu = new PopupMenu(context, binding.captionTextView); + captionPopupMenu = new PopupMenu(themeWrapper, binding.captionTextView); binding.progressBarLoadingPanel.getIndeterminateDrawable() .setColorFilter(new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.MULTIPLY)); @@ -488,10 +494,12 @@ private void initPlayer(final boolean playOnReady) { // Setup subtitle view simpleExoPlayer.addTextOutput(binding.subtitleView); - // Setup audio session with onboard equalizer - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - trackSelector.setParameters(trackSelector.buildUponParameters() - .setTunnelingAudioSessionId(C.generateAudioSessionIdV21(context))); + // enable media tunneling + if (DeviceUtils.shouldSupportMediaTunneling()) { + trackSelector.setParameters( + trackSelector.buildUponParameters().setTunnelingEnabled(true)); + } else if (DEBUG) { + Log.d(TAG, "[" + Util.DEVICE_DEBUG_INFO + "] does not support media tunneling"); } } @@ -624,10 +632,10 @@ public void handleIntent(@NonNull final Intent intent) { && newQueue.getItem().getUrl().equals(playQueue.getItem().getUrl()) && newQueue.getItem().getRecoveryPosition() != PlayQueueItem.RECOVERY_UNSET) { // Player can have state = IDLE when playback is stopped or failed - // and we should retry() in this case + // and we should retry in this case if (simpleExoPlayer.getPlaybackState() == com.google.android.exoplayer2.Player.STATE_IDLE) { - simpleExoPlayer.retry(); + simpleExoPlayer.prepare(); } simpleExoPlayer.seekTo(playQueue.getIndex(), newQueue.getItem().getRecoveryPosition()); simpleExoPlayer.setPlayWhenReady(playWhenReady); @@ -638,10 +646,10 @@ public void handleIntent(@NonNull final Intent intent) { && !playQueue.isDisposed()) { // Do not re-init the same PlayQueue. Save time // Player can have state = IDLE when playback is stopped or failed - // and we should retry() in this case + // and we should retry in this case if (simpleExoPlayer.getPlaybackState() == com.google.android.exoplayer2.Player.STATE_IDLE) { - simpleExoPlayer.retry(); + simpleExoPlayer.prepare(); } simpleExoPlayer.setPlayWhenReady(playWhenReady); @@ -706,11 +714,7 @@ && isPlaybackResumeEnabled(this) // Android TV: without it focus will frame the whole player binding.playPauseButton.requestFocus(); - if (simpleExoPlayer.getPlayWhenReady()) { - play(); - } else { - pause(); - } + playPause(); } NavigationHelper.sendPlayerStartedEvent(context); } @@ -957,7 +961,7 @@ private void setupElementsVisibility() { = LinearLayout.LayoutParams.MATCH_PARENT; binding.secondaryControls.setVisibility(View.INVISIBLE); binding.moreOptionsButton.setImageDrawable(AppCompatResources.getDrawable(context, - R.drawable.ic_expand_more_white_24dp)); + R.drawable.ic_expand_more)); binding.share.setVisibility(View.VISIBLE); binding.openInBrowser.setVisibility(View.VISIBLE); binding.switchMute.setVisibility(View.VISIBLE); @@ -1592,6 +1596,10 @@ private void onUpdateProgress(final int currentProgress, segmentAdapter.selectSegmentAt(getNearestStreamSegmentPosition(currentProgress)); } + if (isQueueVisible) { + updateQueueTime(currentProgress); + } + final boolean showThumbnail = prefs.getBoolean( context.getString(R.string.show_thumbnail_key), true); // setMetadata only updates the metadata when any of the metadata keys are null @@ -1653,7 +1661,7 @@ public void onStartTrackingTouch(final SeekBar seekBar) { saveWasPlaying(); if (isPlaying()) { - simpleExoPlayer.setPlayWhenReady(false); + simpleExoPlayer.pause(); } showControls(0); @@ -1669,7 +1677,7 @@ public void onStopTrackingTouch(final SeekBar seekBar) { seekTo(seekBar.getProgress()); if (wasPlaying || simpleExoPlayer.getDuration() == seekBar.getProgress()) { - simpleExoPlayer.setPlayWhenReady(true); + simpleExoPlayer.play(); } binding.playbackCurrentTime.setText(getTimeString(seekBar.getProgress())); @@ -1687,7 +1695,7 @@ public void onStopTrackingTouch(final SeekBar seekBar) { } public void saveWasPlaying() { - this.wasPlaying = simpleExoPlayer.getPlayWhenReady(); + this.wasPlaying = getPlayWhenReady(); } //endregion @@ -1912,7 +1920,7 @@ public void onPlayerStateChanged(final boolean playWhenReady, final int playback } @Override // exoplayer listener - public void onLoadingChanged(final boolean isLoading) { + public void onIsLoadingChanged(final boolean isLoading) { if (DEBUG) { Log.d(TAG, "ExoPlayer - onLoadingChanged() called with: " + "isLoading = [" + isLoading + "]"); @@ -1956,7 +1964,8 @@ public void onPlaybackUnblock(final MediaSource mediaSource) { if (currentState == STATE_BLOCKED) { changeState(STATE_BUFFERING); } - simpleExoPlayer.prepare(mediaSource); + simpleExoPlayer.setMediaSource(mediaSource); + simpleExoPlayer.prepare(); } public void changeState(final int state) { @@ -2020,7 +2029,7 @@ private void onBlocked() { animate(binding.loadingPanel, true, 0); animate(binding.surfaceForeground, true, 100); - binding.playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_24dp); + binding.playPauseButton.setImageResource(R.drawable.ic_play_arrow); animatePlayButtons(false, 100); binding.getRoot().setKeepScreenOn(false); @@ -2049,7 +2058,7 @@ private void onPlaying() { animate(binding.playPauseButton, false, 80, AnimationType.SCALE_AND_ALPHA, 0, () -> { - binding.playPauseButton.setImageResource(R.drawable.ic_pause_white_24dp); + binding.playPauseButton.setImageResource(R.drawable.ic_pause); animatePlayButtons(true, 200); if (!isQueueVisible) { binding.playPauseButton.requestFocus(); @@ -2068,6 +2077,7 @@ private void onBuffering() { Log.d(TAG, "onBuffering() called"); } binding.loadingPanel.setBackgroundColor(Color.TRANSPARENT); + binding.loadingPanel.setVisibility(View.VISIBLE); binding.getRoot().setKeepScreenOn(true); @@ -2090,7 +2100,7 @@ private void onPaused() { animate(binding.playPauseButton, false, 80, AnimationType.SCALE_AND_ALPHA, 0, () -> { - binding.playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_24dp); + binding.playPauseButton.setImageResource(R.drawable.ic_play_arrow); animatePlayButtons(true, 200); if (!isQueueVisible) { binding.playPauseButton.requestFocus(); @@ -2129,7 +2139,7 @@ private void onCompleted() { animate(binding.playPauseButton, false, 0, AnimationType.SCALE_AND_ALPHA, 0, () -> { - binding.playPauseButton.setImageResource(R.drawable.ic_replay_white_24dp); + binding.playPauseButton.setImageResource(R.drawable.ic_replay); animatePlayButtons(true, DEFAULT_CONTROLS_DURATION); }); @@ -2221,7 +2231,7 @@ public void onRepeatModeChanged(@RepeatMode final int repeatMode) { Log.d(TAG, "ExoPlayer - onRepeatModeChanged() called with: " + "repeatMode = [" + repeatMode + "]"); } - setRepeatModeButton(binding.repeatButton, repeatMode); + setRepeatModeButton(((AppCompatImageButton) binding.repeatButton), repeatMode); onShuffleOrRepeatModeChanged(); } @@ -2249,7 +2259,7 @@ private void onShuffleOrRepeatModeChanged() { NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false); } - private void setRepeatModeButton(final ImageButton imageButton, final int repeatMode) { + private void setRepeatModeButton(final AppCompatImageButton imageButton, final int repeatMode) { switch (repeatMode) { case REPEAT_MODE_OFF: imageButton.setImageResource(R.drawable.exo_controls_repeat_off); @@ -2290,7 +2300,7 @@ boolean isMuted() { private void setMuteButton(final ImageButton button, final boolean isMuted) { button.setImageDrawable(AppCompatResources.getDrawable(context, isMuted - ? R.drawable.ic_volume_off_white_24dp : R.drawable.ic_volume_up_white_24dp)); + ? R.drawable.ic_volume_off : R.drawable.ic_volume_up)); } //endregion @@ -2355,6 +2365,12 @@ public void onPositionDiscontinuity(@DiscontinuityReason final int discontinuity break; } case DISCONTINUITY_REASON_SEEK: + if (DEBUG) { + Log.d(TAG, "ExoPlayer - onSeekProcessed() called"); + } + if (isPrepared) { + saveStreamProgressState(); + } case DISCONTINUITY_REASON_SEEK_ADJUSTMENT: case DISCONTINUITY_REASON_INTERNAL: if (playQueue.getIndex() != newWindowIndex) { @@ -2419,10 +2435,8 @@ public void onPlayerError(@NonNull final ExoPlaybackException error) { setRecovery(); reloadPlayQueueManager(); break; - case ExoPlaybackException.TYPE_OUT_OF_MEMORY: case ExoPlaybackException.TYPE_REMOTE: case ExoPlaybackException.TYPE_RENDERER: - case ExoPlaybackException.TYPE_TIMEOUT: default: showUnrecoverableError(error); onPlaybackShutdown(); @@ -2627,16 +2641,6 @@ public void seekToDefault() { simpleExoPlayer.seekToDefaultPosition(); } } - - @Override // exoplayer override - public void onSeekProcessed() { - if (DEBUG) { - Log.d(TAG, "ExoPlayer - onSeekProcessed() called"); - } - if (isPrepared) { - saveStreamProgressState(); - } - } //endregion @@ -2664,7 +2668,7 @@ public void play() { } } - simpleExoPlayer.setPlayWhenReady(true); + simpleExoPlayer.play(); saveStreamProgressState(); } @@ -2677,7 +2681,7 @@ public void pause() { } audioReactor.abandonAudioFocus(); - simpleExoPlayer.setPlayWhenReady(false); + simpleExoPlayer.pause(); saveStreamProgressState(); } @@ -2686,7 +2690,7 @@ public void playPause() { Log.d(TAG, "onPlayPause() called"); } - if (isPlaying()) { + if (getPlayWhenReady()) { pause(); } else { play(); @@ -2734,7 +2738,7 @@ public void fastForward() { } seekBy(retrieveSeekDurationFromPreferences(this)); triggerProgressUpdate(); - showAndAnimateControl(R.drawable.ic_fast_forward_white_24dp, true); + showAndAnimateControl(R.drawable.ic_fast_forward, true); } public void fastRewind() { @@ -2743,7 +2747,7 @@ public void fastRewind() { } seekBy(-retrieveSeekDurationFromPreferences(this)); triggerProgressUpdate(); - showAndAnimateControl(R.drawable.ic_fast_rewind_white_24dp, true); + showAndAnimateControl(R.drawable.ic_fast_rewind, true); } //endregion @@ -2965,6 +2969,7 @@ private void onQueueClicked() { buildQueue(); binding.itemsListHeaderTitle.setVisibility(View.GONE); + binding.itemsListHeaderDuration.setVisibility(View.VISIBLE); binding.shuffleButton.setVisibility(View.VISIBLE); binding.repeatButton.setVisibility(View.VISIBLE); @@ -2974,6 +2979,8 @@ private void onQueueClicked() { AnimationType.SLIDE_AND_ALPHA); binding.itemsList.scrollToPosition(playQueue.getIndex()); + + updateQueueTime((int) simpleExoPlayer.getCurrentPosition()); } private void buildQueue() { @@ -3196,6 +3203,32 @@ private void updateStreamRelatedViews() { buildPlaybackSpeedMenu(); binding.playbackSpeed.setVisibility(View.VISIBLE); } + + private void updateQueueTime(final int currentTime) { + final int currentStream = playQueue.getIndex(); + int before = 0; + int after = 0; + + final List streams = playQueue.getStreams(); + final int nStreams = streams.size(); + + for (int i = 0; i < nStreams; i++) { + if (i < currentStream) { + before += streams.get(i).getDuration(); + } else { + after += streams.get(i).getDuration(); + } + } + + before *= 1000; + after *= 1000; + + binding.itemsListHeaderDuration.setText( + String.format("%s/%s", + getTimeString(currentTime + before), + getTimeString(before + after) + )); + } //endregion @@ -3691,8 +3724,8 @@ private void setupScreenRotationButton() { || DeviceUtils.isTablet(context)) ? View.VISIBLE : View.GONE); binding.screenRotationButton.setImageDrawable(AppCompatResources.getDrawable(context, - isFullscreen ? R.drawable.ic_fullscreen_exit_white_24dp - : R.drawable.ic_fullscreen_white_24dp)); + isFullscreen ? R.drawable.ic_fullscreen_exit + : R.drawable.ic_fullscreen)); } private void setResizeMode(@AspectRatioFrameLayout.ResizeMode final int resizeMode) { @@ -4012,6 +4045,10 @@ public boolean isPlaying() { return !exoPlayerIsNull() && simpleExoPlayer.isPlaying(); } + public boolean getPlayWhenReady() { + return !exoPlayerIsNull() && simpleExoPlayer.getPlayWhenReady(); + } + private boolean isLoading() { return !exoPlayerIsNull() && simpleExoPlayer.isLoading(); } diff --git a/app/src/main/java/org/schabi/newpipe/player/event/BasePlayerGestureListener.kt b/app/src/main/java/org/schabi/newpipe/player/event/BasePlayerGestureListener.kt index 989c78c57cb..29ae7c5c318 100644 --- a/app/src/main/java/org/schabi/newpipe/player/event/BasePlayerGestureListener.kt +++ b/app/src/main/java/org/schabi/newpipe/player/event/BasePlayerGestureListener.kt @@ -229,8 +229,10 @@ abstract class BasePlayerGestureListener( // because the soft input is visible (the draggable area is currently resized). player.updateScreenSize() player.checkPopupPositionBounds() - initialPopupX = player.popupLayoutParams!!.x - initialPopupY = player.popupLayoutParams!!.y + player.popupLayoutParams?.let { + initialPopupX = it.x + initialPopupY = it.y + } return super.onDown(e) } @@ -466,7 +468,7 @@ abstract class BasePlayerGestureListener( // /////////////////////////////////////////////////////////////////// private fun getDisplayPortion(e: MotionEvent): DisplayPortion { - return if (player.playerType == MainPlayer.PlayerType.POPUP) { + return if (player.playerType == MainPlayer.PlayerType.POPUP && player.popupLayoutParams != null) { when { e.x < player.popupLayoutParams!!.width / 3.0 -> DisplayPortion.LEFT e.x > player.popupLayoutParams!!.width * 2.0 / 3.0 -> DisplayPortion.RIGHT diff --git a/app/src/main/java/org/schabi/newpipe/player/event/CustomBottomSheetBehavior.java b/app/src/main/java/org/schabi/newpipe/player/event/CustomBottomSheetBehavior.java index 61023875cda..a5de56e7569 100644 --- a/app/src/main/java/org/schabi/newpipe/player/event/CustomBottomSheetBehavior.java +++ b/app/src/main/java/org/schabi/newpipe/player/event/CustomBottomSheetBehavior.java @@ -26,7 +26,7 @@ public CustomBottomSheetBehavior(final Context context, final AttributeSet attrs Rect globalRect = new Rect(); private boolean skippingInterception = false; private final List skipInterceptionOfElements = Arrays.asList( - R.id.detail_content_root_layout, R.id.relatedStreamsLayout, + R.id.detail_content_root_layout, R.id.relatedItemsLayout, R.id.itemsListPanel, R.id.view_pager, R.id.tab_layout, R.id.bottomControls, R.id.playPauseButton, R.id.playPreviousButton, R.id.playNextButton); 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 a0b2e7eba72..998324c9c66 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 @@ -147,10 +147,10 @@ private void onScrollMainVolume(final float distanceX, final float distanceY) { player.getVolumeImageView().setImageDrawable( AppCompatResources.getDrawable(service, currentProgressPercent <= 0 - ? R.drawable.ic_volume_off_white_24dp - : currentProgressPercent < 0.25 ? R.drawable.ic_volume_mute_white_24dp - : currentProgressPercent < 0.75 ? R.drawable.ic_volume_down_white_24dp - : R.drawable.ic_volume_up_white_24dp) + ? R.drawable.ic_volume_off + : currentProgressPercent < 0.25 ? R.drawable.ic_volume_mute + : currentProgressPercent < 0.75 ? R.drawable.ic_volume_down + : R.drawable.ic_volume_up) ); if (player.getVolumeRelativeLayout().getVisibility() != View.VISIBLE) { @@ -189,10 +189,10 @@ private void onScrollMainBrightness(final float distanceX, final float distanceY player.getBrightnessImageView().setImageDrawable( AppCompatResources.getDrawable(service, currentProgressPercent < 0.25 - ? R.drawable.ic_brightness_low_white_24dp + ? R.drawable.ic_brightness_low : currentProgressPercent < 0.75 - ? R.drawable.ic_brightness_medium_white_24dp - : R.drawable.ic_brightness_high_white_24dp) + ? R.drawable.ic_brightness_medium + : R.drawable.ic_brightness_high) ); if (player.getBrightnessRelativeLayout().getVisibility() != View.VISIBLE) { diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/AudioReactor.java b/app/src/main/java/org/schabi/newpipe/player/helper/AudioReactor.java index 13ee24e16cf..c4b21f203a1 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/AudioReactor.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/AudioReactor.java @@ -103,13 +103,13 @@ private void onAudioFocusGain() { animateAudio(DUCK_AUDIO_TO, 1.0f); if (PlayerHelper.isResumeAfterAudioFocusGain(context)) { - player.setPlayWhenReady(true); + player.play(); } } private void onAudioFocusLoss() { Log.d(TAG, "onAudioFocusLoss() called"); - player.setPlayWhenReady(false); + player.pause(); } private void onAudioFocusLossCanDuck() { @@ -148,7 +148,7 @@ public void onAnimationEnd(final Animator animation) { //////////////////////////////////////////////////////////////////////////*/ @Override - public void onAudioSessionId(final EventTime eventTime, final int audioSessionId) { + public void onAudioSessionIdChanged(final EventTime eventTime, final int audioSessionId) { if (!PlayerHelper.isUsingDSP()) { return; } 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 ba9a2f1ec4c..fe0233508fc 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 @@ -4,7 +4,7 @@ import com.google.android.exoplayer2.LoadControl; import com.google.android.exoplayer2.Renderer; import com.google.android.exoplayer2.source.TrackGroupArray; -import com.google.android.exoplayer2.trackselection.TrackSelectionArray; +import com.google.android.exoplayer2.trackselection.ExoTrackSelection; import com.google.android.exoplayer2.upstream.Allocator; public class LoadController implements LoadControl { @@ -33,7 +33,7 @@ private LoadController(final int initialPlaybackBufferMs, final DefaultLoadControl.Builder builder = new DefaultLoadControl.Builder(); builder.setBufferDurationsMs(minimumPlaybackBufferMs, optimalPlaybackBufferMs, initialPlaybackBufferMs, initialPlaybackBufferMs); - internalLoadControl = builder.createDefaultLoadControl(); + internalLoadControl = builder.build(); } /*////////////////////////////////////////////////////////////////////////// @@ -47,9 +47,9 @@ public void onPrepared() { } @Override - public void onTracksSelected(final Renderer[] renderers, final TrackGroupArray trackGroupArray, - final TrackSelectionArray trackSelectionArray) { - internalLoadControl.onTracksSelected(renderers, trackGroupArray, trackSelectionArray); + public void onTracksSelected(final Renderer[] renderers, final TrackGroupArray trackGroups, + final ExoTrackSelection[] trackSelections) { + internalLoadControl.onTracksSelected(renderers, trackGroups, trackSelections); } @Override @@ -92,11 +92,12 @@ public boolean shouldContinueLoading(final long playbackPositionUs, @Override public boolean shouldStartPlayback(final long bufferedDurationUs, final float playbackSpeed, - final boolean rebuffering) { + final boolean rebuffering, final long targetLiveOffsetUs) { final boolean isInitialPlaybackBufferFilled = bufferedDurationUs >= this.initialPlaybackBufferUs * playbackSpeed; final boolean isInternalStartingPlayback = internalLoadControl - .shouldStartPlayback(bufferedDurationUs, playbackSpeed, rebuffering); + .shouldStartPlayback(bufferedDurationUs, playbackSpeed, rebuffering, + targetLiveOffsetUs); return isInitialPlaybackBufferFilled || isInternalStartingPlayback; } 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 b0c64143393..c7f1f9c8c84 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 @@ -36,8 +36,6 @@ public MediaSessionManager(@NonNull final Context context, @NonNull final Player player, @NonNull final MediaSessionCallback callback) { mediaSession = new MediaSessionCompat(context, TAG); - mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS - | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); mediaSession.setActive(true); mediaSession.setPlaybackState(new PlaybackStateCompat.Builder() diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java index 4324fcd0a0b..0a3ea908a72 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java @@ -23,7 +23,7 @@ import com.google.android.exoplayer2.SeekParameters; import com.google.android.exoplayer2.text.CaptionStyleCompat; import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection; -import com.google.android.exoplayer2.trackselection.TrackSelection; +import com.google.android.exoplayer2.trackselection.ExoTrackSelection; import com.google.android.exoplayer2.ui.AspectRatioFrameLayout; import com.google.android.exoplayer2.ui.AspectRatioFrameLayout.ResizeMode; import com.google.android.exoplayer2.util.MimeTypes; @@ -180,10 +180,10 @@ public static String cacheKeyOf(@NonNull final StreamInfo info, * if a candidate next video's url already exists in the existing items. *

*

- * The first item in {@link StreamInfo#getRelatedStreams()} is checked first. + * The first item in {@link StreamInfo#getRelatedItems()} is checked first. * If it is non-null and is not part of the existing items, it will be used as the next stream. - * Otherwise, a random item with non-repeating url will be selected - * from the {@link StreamInfo#getRelatedStreams()}. + * Otherwise, a random stream with non-repeating url will be selected + * from the {@link StreamInfo#getRelatedItems()}. Non-stream items are ignored. *

* * @param info currently playing stream @@ -198,7 +198,7 @@ public static PlayQueue autoQueueOf(@NonNull final StreamInfo info, urls.add(item.getUrl()); } - final List relatedItems = info.getRelatedStreams(); + final List relatedItems = info.getRelatedItems(); if (Utils.isNullOrEmpty(relatedItems)) { return null; } @@ -323,7 +323,7 @@ public static int getPlaybackOptimalBufferMs() { return 60000; } - public static TrackSelection.Factory getQualitySelector() { + public static ExoTrackSelection.Factory getQualitySelector() { return new AdaptiveTrackSelection.Factory( 1000, AdaptiveTrackSelection.DEFAULT_MAX_DURATION_FOR_QUALITY_DECREASE_MS, diff --git a/app/src/main/java/org/schabi/newpipe/player/playback/CustomTrackSelector.java b/app/src/main/java/org/schabi/newpipe/player/playback/CustomTrackSelector.java index d70707fdbf1..389be70628e 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playback/CustomTrackSelector.java +++ b/app/src/main/java/org/schabi/newpipe/player/playback/CustomTrackSelector.java @@ -13,7 +13,7 @@ import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; -import com.google.android.exoplayer2.trackselection.TrackSelection; +import com.google.android.exoplayer2.trackselection.ExoTrackSelection; import com.google.android.exoplayer2.util.Assertions; /** @@ -28,7 +28,7 @@ public class CustomTrackSelector extends DefaultTrackSelector { private String preferredTextLanguage; public CustomTrackSelector(final Context context, - final TrackSelection.Factory adaptiveTrackSelectionFactory) { + final ExoTrackSelection.Factory adaptiveTrackSelectionFactory) { super(context, adaptiveTrackSelectionFactory); } @@ -50,7 +50,7 @@ public void setPreferredTextLanguage(@NonNull final String label) { @Override @Nullable - protected Pair selectTextTrack( + protected Pair selectTextTrack( final TrackGroupArray groups, @NonNull final int[][] formatSupport, @NonNull final Parameters params, @@ -86,7 +86,7 @@ protected Pair selectTextTrack( } } return selectedGroup == null ? null - : Pair.create(new TrackSelection.Definition(selectedGroup, selectedTrackIndex), + : Pair.create(new ExoTrackSelection.Definition(selectedGroup, selectedTrackIndex), Assertions.checkNotNull(selectedTrackScore)); } } diff --git a/app/src/main/java/org/schabi/newpipe/player/resolver/PlaybackResolver.java b/app/src/main/java/org/schabi/newpipe/player/resolver/PlaybackResolver.java index e06c0ff82f6..a6dcadd5eeb 100644 --- a/app/src/main/java/org/schabi/newpipe/player/resolver/PlaybackResolver.java +++ b/app/src/main/java/org/schabi/newpipe/player/resolver/PlaybackResolver.java @@ -7,6 +7,7 @@ import androidx.annotation.Nullable; import com.google.android.exoplayer2.C; +import com.google.android.exoplayer2.MediaItem; import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.util.Util; @@ -43,13 +44,13 @@ default MediaSource buildLiveMediaSource(@NonNull final PlayerDataSource dataSou switch (type) { case C.TYPE_SS: return dataSource.getLiveSsMediaSourceFactory().setTag(metadata) - .createMediaSource(uri); + .createMediaSource(MediaItem.fromUri(uri)); case C.TYPE_DASH: return dataSource.getLiveDashMediaSourceFactory().setTag(metadata) - .createMediaSource(uri); + .createMediaSource(MediaItem.fromUri(uri)); case C.TYPE_HLS: return dataSource.getLiveHlsMediaSourceFactory().setTag(metadata) - .createMediaSource(uri); + .createMediaSource(MediaItem.fromUri(uri)); default: throw new IllegalStateException("Unsupported type: " + type); } @@ -68,16 +69,16 @@ default MediaSource buildMediaSource(@NonNull final PlayerDataSource dataSource, switch (type) { case C.TYPE_SS: return dataSource.getLiveSsMediaSourceFactory().setTag(metadata) - .createMediaSource(uri); + .createMediaSource(MediaItem.fromUri(uri)); case C.TYPE_DASH: return dataSource.getDashMediaSourceFactory().setTag(metadata) - .createMediaSource(uri); + .createMediaSource(MediaItem.fromUri(uri)); case C.TYPE_HLS: return dataSource.getHlsMediaSourceFactory().setTag(metadata) - .createMediaSource(uri); + .createMediaSource(MediaItem.fromUri(uri)); case C.TYPE_OTHER: return dataSource.getExtractorMediaSourceFactory(cacheKey).setTag(metadata) - .createMediaSource(uri); + .createMediaSource(MediaItem.fromUri(uri)); default: throw new IllegalStateException("Unsupported type: " + type); } diff --git a/app/src/main/java/org/schabi/newpipe/player/resolver/VideoPlaybackResolver.java b/app/src/main/java/org/schabi/newpipe/player/resolver/VideoPlaybackResolver.java index a2b3a1d3de9..245a85e7101 100644 --- a/app/src/main/java/org/schabi/newpipe/player/resolver/VideoPlaybackResolver.java +++ b/app/src/main/java/org/schabi/newpipe/player/resolver/VideoPlaybackResolver.java @@ -6,7 +6,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.google.android.exoplayer2.Format; +import com.google.android.exoplayer2.MediaItem; import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.source.MergingMediaSource; @@ -22,7 +22,6 @@ import java.util.ArrayList; import java.util.List; -import static com.google.android.exoplayer2.C.SELECTION_FLAG_AUTOSELECT; import static com.google.android.exoplayer2.C.TIME_UNSET; public class VideoPlaybackResolver implements PlaybackResolver { @@ -101,12 +100,12 @@ public MediaSource resolve(@NonNull final StreamInfo info) { if (mimeType == null) { continue; } - - final Format textFormat = Format.createTextSampleFormat(null, mimeType, - SELECTION_FLAG_AUTOSELECT, - PlayerHelper.captionLanguageOf(context, subtitle)); final MediaSource textSource = dataSource.getSampleMediaSourceFactory() - .createMediaSource(Uri.parse(subtitle.getUrl()), textFormat, TIME_UNSET); + .createMediaSource( + new MediaItem.Subtitle(Uri.parse(subtitle.getUrl()), + mimeType, + PlayerHelper.captionLanguageOf(context, subtitle)), + TIME_UNSET); mediaSources.add(textSource); } } 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 e2ac2c20d97..1e1b03b4f81 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java @@ -7,12 +7,12 @@ import android.provider.Settings; import android.widget.Toast; -import androidx.annotation.Nullable; import androidx.core.app.ActivityCompat; import androidx.preference.Preference; import org.schabi.newpipe.R; import org.schabi.newpipe.util.Constants; +import org.schabi.newpipe.util.ThemeHelper; public class AppearanceSettingsFragment extends BasePreferenceFragment { private static final boolean CAPTIONING_SETTINGS_ACCESSIBLE = @@ -21,8 +21,8 @@ public class AppearanceSettingsFragment extends BasePreferenceFragment { private String captionSettingsKey; @Override - public void onCreate(@Nullable final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) { + addPreferencesFromResource(R.xml.appearance_settings); final String themeKey = getString(R.string.theme_key); // the key of the active theme when settings were opened (or recreated after theme change) @@ -58,11 +58,6 @@ public void onCreate(@Nullable final Bundle savedInstanceState) { } } - @Override - public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) { - addPreferencesFromResource(R.xml.appearance_settings); - } - @Override public boolean onPreferenceTreeClick(final Preference preference) { if (preference.getKey().equals(captionSettingsKey) && CAPTIONING_SETTINGS_ACCESSIBLE) { @@ -89,6 +84,8 @@ private void applyThemeChange(final String beginningThemeKey, defaultPreferences.edit().putBoolean(Constants.KEY_THEME_CHANGE, true).apply(); defaultPreferences.edit().putString(themeKey, newValue.toString()).apply(); + ThemeHelper.setDayNightMode(getContext(), newValue.toString()); + if (!newValue.equals(beginningThemeKey) && getActivity() != null) { // if it's not the current theme ActivityCompat.recreate(getActivity()); diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java index dbe05bbd2f0..3fd44c4d521 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java @@ -1,7 +1,6 @@ package org.schabi.newpipe.settings; import android.app.Activity; -import android.app.AlertDialog; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; @@ -10,7 +9,7 @@ import android.widget.Toast; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; import androidx.core.content.ContextCompat; import androidx.preference.Preference; import androidx.preference.PreferenceManager; @@ -50,8 +49,35 @@ public class ContentSettingsFragment extends BasePreferenceFragment { private String initialLanguage; @Override - public void onCreate(@Nullable final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) { + final File homeDir = ContextCompat.getDataDir(requireContext()); + manager = new ContentSettingsManager(new NewPipeFileLocator(homeDir)); + manager.deleteSettingsFile(); + + addPreferencesFromResource(R.xml.content_settings); + + final Preference importDataPreference = findPreference(getString(R.string.import_data)); + importDataPreference.setOnPreferenceClickListener(p -> { + final Intent i = new Intent(getActivity(), FilePickerActivityHelper.class) + .putExtra(FilePickerActivityHelper.EXTRA_ALLOW_MULTIPLE, false) + .putExtra(FilePickerActivityHelper.EXTRA_ALLOW_CREATE_DIR, false) + .putExtra(FilePickerActivityHelper.EXTRA_MODE, + FilePickerActivityHelper.MODE_FILE); + startActivityForResult(i, REQUEST_IMPORT_PATH); + return true; + }); + + final Preference exportDataPreference = findPreference(getString(R.string.export_data)); + exportDataPreference.setOnPreferenceClickListener(p -> { + final Intent i = new Intent(getActivity(), FilePickerActivityHelper.class) + .putExtra(FilePickerActivityHelper.EXTRA_ALLOW_MULTIPLE, false) + .putExtra(FilePickerActivityHelper.EXTRA_ALLOW_CREATE_DIR, true) + .putExtra(FilePickerActivityHelper.EXTRA_MODE, + FilePickerActivityHelper.MODE_DIR); + startActivityForResult(i, REQUEST_EXPORT_PATH); + return true; + }); + thumbnailLoadToggleKey = getString(R.string.download_thumbnail_key); youtubeRestrictedModeEnabledKey = getString(R.string.youtube_restricted_mode_enabled); @@ -103,37 +129,6 @@ public boolean onPreferenceTreeClick(final Preference preference) { return super.onPreferenceTreeClick(preference); } - @Override - public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) { - final File homeDir = ContextCompat.getDataDir(requireContext()); - manager = new ContentSettingsManager(new NewPipeFileLocator(homeDir)); - manager.deleteSettingsFile(); - - addPreferencesFromResource(R.xml.content_settings); - - final Preference importDataPreference = findPreference(getString(R.string.import_data)); - importDataPreference.setOnPreferenceClickListener(p -> { - final Intent i = new Intent(getActivity(), FilePickerActivityHelper.class) - .putExtra(FilePickerActivityHelper.EXTRA_ALLOW_MULTIPLE, false) - .putExtra(FilePickerActivityHelper.EXTRA_ALLOW_CREATE_DIR, false) - .putExtra(FilePickerActivityHelper.EXTRA_MODE, - FilePickerActivityHelper.MODE_FILE); - startActivityForResult(i, REQUEST_IMPORT_PATH); - return true; - }); - - final Preference exportDataPreference = findPreference(getString(R.string.export_data)); - exportDataPreference.setOnPreferenceClickListener(p -> { - final Intent i = new Intent(getActivity(), FilePickerActivityHelper.class) - .putExtra(FilePickerActivityHelper.EXTRA_ALLOW_MULTIPLE, false) - .putExtra(FilePickerActivityHelper.EXTRA_ALLOW_CREATE_DIR, true) - .putExtra(FilePickerActivityHelper.EXTRA_MODE, - FilePickerActivityHelper.MODE_DIR); - startActivityForResult(i, REQUEST_EXPORT_PATH); - return true; - }); - } - @Override public void onDestroy() { super.onDestroy(); @@ -174,7 +169,7 @@ public void onActivityResult(final int requestCode, final int resultCode, final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US); exportDatabase(path + "/NewPipeData-" + sdf.format(new Date()) + ".zip"); } else { - final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + final AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity()); builder.setMessage(R.string.override_current_data) .setPositiveButton(getString(R.string.finish), (d, id) -> importDatabase(path)) @@ -220,7 +215,7 @@ private void importDatabase(final String filePath) { //If settings file exist, ask if it should be imported. if (manager.extractSettings(filePath)) { - final AlertDialog.Builder alert = new AlertDialog.Builder(getContext()); + final AlertDialog.Builder alert = new AlertDialog.Builder(requireContext()); alert.setTitle(R.string.import_settings); alert.setNegativeButton(android.R.string.no, (dialog, which) -> { diff --git a/app/src/main/java/org/schabi/newpipe/settings/DownloadSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/DownloadSettingsFragment.java index 8742f093767..91351264466 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/DownloadSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/DownloadSettingsFragment.java @@ -1,7 +1,6 @@ package org.schabi.newpipe.settings; import android.app.Activity; -import android.app.AlertDialog; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; @@ -11,8 +10,8 @@ import android.util.Log; import android.widget.Toast; -import androidx.annotation.Nullable; import androidx.annotation.StringRes; +import androidx.appcompat.app.AlertDialog; import androidx.preference.Preference; import com.nononsenseapps.filepicker.Utils; @@ -46,8 +45,8 @@ public class DownloadSettingsFragment extends BasePreferenceFragment { private Context ctx; @Override - public void onCreate(@Nullable final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) { + addPreferencesFromResource(R.xml.download_settings); downloadPathVideoPreference = getString(R.string.download_path_video_key); downloadPathAudioPreference = getString(R.string.download_path_audio_key); @@ -76,11 +75,6 @@ public void onCreate(@Nullable final Bundle savedInstanceState) { }); } - @Override - public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) { - addPreferencesFromResource(R.xml.download_settings); - } - @Override public void onAttach(final Context context) { super.onAttach(context); diff --git a/app/src/main/java/org/schabi/newpipe/settings/HistorySettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/HistorySettingsFragment.java index 89fabbdde3b..cb6ce263dce 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/HistorySettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/HistorySettingsFragment.java @@ -5,7 +5,6 @@ import android.widget.Toast; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.preference.Preference; @@ -29,8 +28,9 @@ public class HistorySettingsFragment extends BasePreferenceFragment { private CompositeDisposable disposables; @Override - public void onCreate(@Nullable final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) { + addPreferencesFromResource(R.xml.history_settings); + cacheWipeKey = getString(R.string.metadata_cache_wipe_key); viewsHistoryClearKey = getString(R.string.clear_views_history_key); playbackStatesClearKey = getString(R.string.clear_playback_states_key); @@ -39,11 +39,6 @@ public void onCreate(@Nullable final Bundle savedInstanceState) { disposables = new CompositeDisposable(); } - @Override - public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) { - addPreferencesFromResource(R.xml.history_settings); - } - @Override public boolean onPreferenceTreeClick(final Preference preference) { if (preference.getKey().equals(cacheWipeKey)) { 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 bd3cbf79d69..550e9be3fc4 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/PeertubeInstanceListFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/PeertubeInstanceListFragment.java @@ -145,10 +145,8 @@ public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) { final MenuItem restoreItem = menu .add(Menu.NONE, MENU_ITEM_RESTORE_ID, Menu.NONE, R.string.restore_defaults); restoreItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); - - final int restoreIcon = ThemeHelper - .resolveResourceIdFromAttr(requireContext(), R.attr.ic_restore_defaults); - restoreItem.setIcon(AppCompatResources.getDrawable(requireContext(), restoreIcon)); + restoreItem.setIcon(AppCompatResources.getDrawable(requireContext(), + R.drawable.ic_settings_backup_restore)); } @Override @@ -188,7 +186,7 @@ private void saveChanges() { } private void restoreDefaults() { - new AlertDialog.Builder(requireContext(), ThemeHelper.getDialogTheme(requireContext())) + new AlertDialog.Builder(requireContext()) .setTitle(R.string.restore_defaults) .setMessage(R.string.restore_defaults_confirmation) .setNegativeButton(R.string.cancel, null) diff --git a/app/src/main/java/org/schabi/newpipe/settings/SettingsActivity.java b/app/src/main/java/org/schabi/newpipe/settings/SettingsActivity.java index 4de166a5599..68908fc9248 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SettingsActivity.java +++ b/app/src/main/java/org/schabi/newpipe/settings/SettingsActivity.java @@ -56,11 +56,11 @@ protected void onCreate(final Bundle savedInstanceBundle) { SettingsLayoutBinding.inflate(getLayoutInflater()); setContentView(settingsLayoutBinding.getRoot()); - setSupportActionBar(settingsLayoutBinding.toolbarLayout.toolbar); + setSupportActionBar(settingsLayoutBinding.settingsToolbarLayout.toolbar); if (savedInstanceBundle == null) { getSupportFragmentManager().beginTransaction() - .replace(R.id.fragment_holder, new MainSettingsFragment()) + .replace(R.id.settings_fragment_holder, new MainSettingsFragment()) .commit(); } @@ -102,7 +102,7 @@ public boolean onPreferenceStartFragment(final PreferenceFragmentCompat caller, getSupportFragmentManager().beginTransaction() .setCustomAnimations(R.animator.custom_fade_in, R.animator.custom_fade_out, R.animator.custom_fade_in, R.animator.custom_fade_out) - .replace(R.id.fragment_holder, fragment) + .replace(R.id.settings_fragment_holder, fragment) .addToBackStack(null) .commit(); return true; diff --git a/app/src/main/java/org/schabi/newpipe/settings/UpdateSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/UpdateSettingsFragment.java index f25b25df2f1..0ca15e24592 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/UpdateSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/UpdateSettingsFragment.java @@ -2,7 +2,6 @@ import android.os.Bundle; -import androidx.annotation.Nullable; import androidx.preference.Preference; import org.schabi.newpipe.R; @@ -16,15 +15,10 @@ public class UpdateSettingsFragment extends BasePreferenceFragment { }; @Override - public void onCreate(@Nullable final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) { + addPreferencesFromResource(R.xml.update_settings); final String updateToggleKey = getString(R.string.update_app_key); findPreference(updateToggleKey).setOnPreferenceChangeListener(updatePreferenceChange); } - - @Override - public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) { - addPreferencesFromResource(R.xml.update_settings); - } } diff --git a/app/src/main/java/org/schabi/newpipe/settings/VideoAudioSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/VideoAudioSettingsFragment.java index 5eca99822f6..c0d274fe035 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/VideoAudioSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/VideoAudioSettingsFragment.java @@ -8,7 +8,6 @@ import android.text.format.DateUtils; import android.widget.Toast; -import androidx.annotation.Nullable; import androidx.preference.ListPreference; import com.google.android.material.snackbar.Snackbar; @@ -23,8 +22,8 @@ public class VideoAudioSettingsFragment extends BasePreferenceFragment { private SharedPreferences.OnSharedPreferenceChangeListener listener; @Override - public void onCreate(@Nullable final Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) { + addPreferencesFromResource(R.xml.video_audio_settings); updateSeekOptions(); @@ -104,11 +103,6 @@ private void updateSeekOptions() { } } - @Override - public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) { - addPreferencesFromResource(R.xml.video_audio_settings); - } - @Override public void onResume() { super.onResume(); diff --git a/app/src/main/java/org/schabi/newpipe/settings/custom/NotificationActionsPreference.java b/app/src/main/java/org/schabi/newpipe/settings/custom/NotificationActionsPreference.java index e50c858caf1..045e574be0a 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/custom/NotificationActionsPreference.java +++ b/app/src/main/java/org/schabi/newpipe/settings/custom/NotificationActionsPreference.java @@ -17,6 +17,7 @@ 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.core.graphics.drawable.DrawableCompat; @@ -41,9 +42,8 @@ public NotificationActionsPreference(final Context context, final AttributeSet a } - private NotificationSlot[] notificationSlots; - - private List compactSlots; + @Nullable private NotificationSlot[] notificationSlots = null; + @Nullable private List compactSlots = null; //////////////////////////////////////////////////////////////////////////// // Lifecycle @@ -85,19 +85,22 @@ private void setupActions(@NonNull final View view) { //////////////////////////////////////////////////////////////////////////// private void saveChanges() { - final SharedPreferences.Editor editor = getSharedPreferences().edit(); + if (compactSlots != null && notificationSlots != null) { + final SharedPreferences.Editor editor = getSharedPreferences().edit(); - for (int i = 0; i < 3; i++) { - editor.putInt(getContext().getString(NotificationConstants.SLOT_COMPACT_PREF_KEYS[i]), - (i < compactSlots.size() ? compactSlots.get(i) : -1)); - } + for (int i = 0; i < 3; i++) { + editor.putInt(getContext().getString( + NotificationConstants.SLOT_COMPACT_PREF_KEYS[i]), + (i < compactSlots.size() ? compactSlots.get(i) : -1)); + } - for (int i = 0; i < 5; i++) { - editor.putInt(getContext().getString(NotificationConstants.SLOT_PREF_KEYS[i]), - notificationSlots[i].selectedAction); - } + for (int i = 0; i < 5; i++) { + editor.putInt(getContext().getString(NotificationConstants.SLOT_PREF_KEYS[i]), + notificationSlots[i].selectedAction); + } - editor.apply(); + editor.apply(); + } } diff --git a/app/src/main/java/org/schabi/newpipe/settings/tabs/AddTabDialog.java b/app/src/main/java/org/schabi/newpipe/settings/tabs/AddTabDialog.java index 52e50fbbae5..e2e833feed2 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/tabs/AddTabDialog.java +++ b/app/src/main/java/org/schabi/newpipe/settings/tabs/AddTabDialog.java @@ -1,6 +1,5 @@ package org.schabi.newpipe.settings.tabs; -import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.view.LayoutInflater; @@ -11,10 +10,10 @@ import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.AppCompatImageView; import org.schabi.newpipe.R; -import org.schabi.newpipe.util.ThemeHelper; public final class AddTabDialog { private final AlertDialog dialog; @@ -60,7 +59,7 @@ private static final class DialogListAdapter extends BaseAdapter { private DialogListAdapter(final Context context, final ChooseTabListItem[] items) { this.inflater = LayoutInflater.from(context); this.items = items; - this.fallbackIcon = ThemeHelper.resolveResourceIdFromAttr(context, R.attr.ic_kiosk_hot); + this.fallbackIcon = R.drawable.ic_whatshot; } @Override 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 572741d03a8..9c1a9bdd71f 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 @@ -112,10 +112,8 @@ public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) { final MenuItem restoreItem = menu.add(Menu.NONE, MENU_ITEM_RESTORE_ID, Menu.NONE, R.string.restore_defaults); restoreItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); - - final int restoreIcon = ThemeHelper.resolveResourceIdFromAttr(requireContext(), - R.attr.ic_restore_defaults); - restoreItem.setIcon(AppCompatResources.getDrawable(requireContext(), restoreIcon)); + restoreItem.setIcon(AppCompatResources.getDrawable(requireContext(), + R.drawable.ic_settings_backup_restore)); } @Override @@ -142,7 +140,7 @@ private void saveChanges() { } private void restoreDefaults() { - new AlertDialog.Builder(requireContext(), ThemeHelper.getDialogTheme(requireContext())) + new AlertDialog.Builder(requireContext()) .setTitle(R.string.restore_defaults) .setMessage(R.string.restore_defaults_confirmation) .setNegativeButton(R.string.cancel, null) @@ -241,7 +239,7 @@ private ChooseTabListItem[] getAvailableTabs(final Context context) { case KIOSK: returnList.add(new ChooseTabListItem(tab.getTabId(), getString(R.string.kiosk_page_summary), - ThemeHelper.resolveResourceIdFromAttr(context, R.attr.ic_kiosk_hot))); + R.drawable.ic_whatshot)); break; case CHANNEL: returnList.add(new ChooseTabListItem(tab.getTabId(), @@ -252,8 +250,7 @@ private ChooseTabListItem[] getAvailableTabs(final Context context) { if (!tabList.contains(tab)) { returnList.add(new ChooseTabListItem(tab.getTabId(), getString(R.string.default_kiosk_page_summary), - ThemeHelper.resolveResourceIdFromAttr(context, - R.attr.ic_kiosk_hot))); + R.drawable.ic_whatshot)); } break; case PLAYLIST: diff --git a/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java b/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java index 0ffda2261c1..b289009ceba 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java +++ b/app/src/main/java/org/schabi/newpipe/settings/tabs/Tab.java @@ -30,7 +30,6 @@ import org.schabi.newpipe.local.subscription.SubscriptionFragment; import org.schabi.newpipe.util.KioskTranslator; import org.schabi.newpipe.util.ServiceHelper; -import org.schabi.newpipe.util.ThemeHelper; import java.util.Objects; @@ -188,7 +187,7 @@ public String getTabName(final Context context) { @DrawableRes @Override public int getTabIconRes(final Context context) { - return ThemeHelper.resolveResourceIdFromAttr(context, R.attr.ic_blank_page); + return R.drawable.ic_crop_portrait; } @Override @@ -213,7 +212,7 @@ public String getTabName(final Context context) { @DrawableRes @Override public int getTabIconRes(final Context context) { - return ThemeHelper.resolveResourceIdFromAttr(context, R.attr.ic_channel); + return R.drawable.ic_tv; } @Override @@ -239,7 +238,7 @@ public String getTabName(final Context context) { @DrawableRes @Override public int getTabIconRes(final Context context) { - return ThemeHelper.resolveResourceIdFromAttr(context, R.attr.ic_rss); + return R.drawable.ic_rss_feed; } @Override @@ -264,7 +263,7 @@ public String getTabName(final Context context) { @DrawableRes @Override public int getTabIconRes(final Context context) { - return ThemeHelper.resolveResourceIdFromAttr(context, R.attr.ic_bookmark); + return R.drawable.ic_bookmark; } @Override @@ -289,7 +288,7 @@ public String getTabName(final Context context) { @DrawableRes @Override public int getTabIconRes(final Context context) { - return ThemeHelper.resolveResourceIdFromAttr(context, R.attr.ic_history); + return R.drawable.ic_history; } @Override @@ -409,7 +408,7 @@ public String getTabName(final Context context) { @DrawableRes @Override public int getTabIconRes(final Context context) { - return ThemeHelper.resolveResourceIdFromAttr(context, R.attr.ic_channel); + return R.drawable.ic_tv; } @Override @@ -541,7 +540,7 @@ public String getTabName(final Context context) { @DrawableRes @Override public int getTabIconRes(final Context context) { - return ThemeHelper.resolveResourceIdFromAttr(context, R.attr.ic_bookmark); + return R.drawable.ic_bookmark; } @Override diff --git a/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java b/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java index 52069fd0e7d..91578f27ee2 100644 --- a/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java +++ b/app/src/main/java/org/schabi/newpipe/util/DeviceUtils.java @@ -20,6 +20,16 @@ public final class DeviceUtils { private static final String AMAZON_FEATURE_FIRE_TV = "amazon.hardware.fire_tv"; private static Boolean isTV = null; + /* + * Devices that do not support media tunneling + */ + // Formuler Z8 Pro, Z8, CC, Z Alpha, Z+ Neo + private static final boolean HI3798MV200 = Build.VERSION.SDK_INT == 24 + && Build.DEVICE.equals("Hi3798MV200"); + // Zephir TS43UHD-2 + private static final boolean CVT_MT5886_EU_1G = Build.VERSION.SDK_INT == 24 + && Build.DEVICE.equals("cvt_mt5886_eu_1g"); + private DeviceUtils() { } @@ -88,4 +98,15 @@ public static int spToPx(@Dimension(unit = Dimension.SP) final int sp, sp, context.getResources().getDisplayMetrics()); } + + /** + * Some devices have broken tunneled video playback but claim to support it. + * See https://github.com/TeamNewPipe/NewPipe/issues/5911 + * @return false if Kitkat (does not support tunneling) or affected device + */ + public static boolean shouldSupportMediaTunneling() { + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP + && !HI3798MV200 + && !CVT_MT5886_EU_1G; + } } diff --git a/app/src/main/java/org/schabi/newpipe/util/KioskTranslator.java b/app/src/main/java/org/schabi/newpipe/util/KioskTranslator.java index 2f0b3e1324b..f77aa0fdab9 100644 --- a/app/src/main/java/org/schabi/newpipe/util/KioskTranslator.java +++ b/app/src/main/java/org/schabi/newpipe/util/KioskTranslator.java @@ -63,20 +63,20 @@ public static int getKioskIcon(final String kioskId, final Context c) { case "Top 50": case "New & hot": case "conferences": - return ThemeHelper.resolveResourceIdFromAttr(c, R.attr.ic_kiosk_hot); + return R.drawable.ic_whatshot; case "Local": - return ThemeHelper.resolveResourceIdFromAttr(c, R.attr.ic_kiosk_local); + return R.drawable.ic_home; case "Recently added": case "recent": - return ThemeHelper.resolveResourceIdFromAttr(c, R.attr.ic_kiosk_recent); + return R.drawable.ic_add_circle_outline; case "Most liked": - return ThemeHelper.resolveResourceIdFromAttr(c, R.attr.ic_thumb_up); + return R.drawable.ic_thumb_up; case "live": - return ThemeHelper.resolveResourceIdFromAttr(c, R.attr.ic_live_tv); + return R.drawable.ic_live_tv; case "Featured": - return ThemeHelper.resolveResourceIdFromAttr(c, R.attr.ic_stars); + return R.drawable.ic_stars; case "Radio": - return ThemeHelper.resolveResourceIdFromAttr(c, R.attr.ic_radio); + return R.drawable.ic_radio; default: return 0; } 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 4f4fd528360..df804136a20 100644 --- a/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java @@ -62,7 +62,8 @@ public final class NavigationHelper { public static final String MAIN_FRAGMENT_TAG = "main_fragment_tag"; public static final String SEARCH_FRAGMENT_TAG = "search_fragment_tag"; - private NavigationHelper() { } + private NavigationHelper() { + } /*////////////////////////////////////////////////////////////////////////// // Players @@ -111,18 +112,22 @@ public static Intent getPlayerEnqueueIntent(@NonNull final Context context, public static void playOnMainPlayer(final AppCompatActivity activity, @NonNull final PlayQueue playQueue) { final PlayQueueItem item = playQueue.getItem(); - assert item != null; - openVideoDetailFragment(activity, activity.getSupportFragmentManager(), - item.getServiceId(), item.getUrl(), item.getTitle(), playQueue, false); + if (item != null) { + openVideoDetailFragment(activity, activity.getSupportFragmentManager(), + item.getServiceId(), item.getUrl(), item.getTitle(), playQueue, + false); + } } public static void playOnMainPlayer(final Context context, @NonNull final PlayQueue playQueue, final boolean switchingPlayers) { final PlayQueueItem item = playQueue.getItem(); - assert item != null; - openVideoDetail(context, - item.getServiceId(), item.getUrl(), item.getTitle(), playQueue, switchingPlayers); + if (item != null) { + openVideoDetail(context, + item.getServiceId(), item.getUrl(), item.getTitle(), playQueue, + switchingPlayers); + } } public static void playOnPopupPlayer(final Context context, diff --git a/app/src/main/java/org/schabi/newpipe/util/RelatedStreamInfo.java b/app/src/main/java/org/schabi/newpipe/util/RelatedItemInfo.java similarity index 54% rename from app/src/main/java/org/schabi/newpipe/util/RelatedStreamInfo.java rename to app/src/main/java/org/schabi/newpipe/util/RelatedItemInfo.java index 81e203b1f3b..f96bb0d549f 100644 --- a/app/src/main/java/org/schabi/newpipe/util/RelatedStreamInfo.java +++ b/app/src/main/java/org/schabi/newpipe/util/RelatedItemInfo.java @@ -9,19 +9,19 @@ import java.util.Collections; import java.util.List; -public class RelatedStreamInfo extends ListInfo { - public RelatedStreamInfo(final int serviceId, final ListLinkHandler listUrlIdHandler, - final String name) { +public class RelatedItemInfo extends ListInfo { + public RelatedItemInfo(final int serviceId, final ListLinkHandler listUrlIdHandler, + final String name) { super(serviceId, listUrlIdHandler, name); } - public static RelatedStreamInfo getInfo(final StreamInfo info) { + public static RelatedItemInfo getInfo(final StreamInfo info) { final ListLinkHandler handler = new ListLinkHandler( info.getOriginalUrl(), info.getUrl(), info.getId(), Collections.emptyList(), null); - final RelatedStreamInfo relatedStreamInfo = new RelatedStreamInfo( + final RelatedItemInfo relatedItemInfo = new RelatedItemInfo( info.getServiceId(), handler, info.getName()); - final List streams = new ArrayList<>(info.getRelatedStreams()); - relatedStreamInfo.setRelatedItems(streams); - return relatedStreamInfo; + final List relatedItems = new ArrayList<>(info.getRelatedItems()); + relatedItemInfo.setRelatedItems(relatedItems); + return relatedItemInfo; } } diff --git a/app/src/main/java/org/schabi/newpipe/util/StateSaver.java b/app/src/main/java/org/schabi/newpipe/util/StateSaver.java index ab28205fc7d..6ebdaee0234 100644 --- a/app/src/main/java/org/schabi/newpipe/util/StateSaver.java +++ b/app/src/main/java/org/schabi/newpipe/util/StateSaver.java @@ -72,10 +72,10 @@ public static void init(final Context context) { } /** - * @see #tryToRestore(SavedState, WriteRead) * @param outState * @param writeRead * @return the saved state + * @see #tryToRestore(SavedState, WriteRead) */ public static SavedState tryToRestore(final Bundle outState, final WriteRead writeRead) { if (outState == null || writeRead == null) { @@ -93,6 +93,7 @@ public static SavedState tryToRestore(final Bundle outState, final WriteRead wri /** * Try to restore the state from memory and disk, * using the {@link StateSaver.WriteRead#readFrom(Queue)} from the writeRead. + * * @param savedState * @param writeRead * @return the saved state @@ -143,19 +144,18 @@ private static SavedState tryToRestore(@NonNull final SavedState savedState, } /** - * @see #tryToSave(boolean, String, String, WriteRead) * @param isChangingConfig * @param savedState * @param outState * @param writeRead * @return the saved state or {@code null} + * @see #tryToSave(boolean, String, String, WriteRead) */ @Nullable public static SavedState tryToSave(final boolean isChangingConfig, @Nullable final SavedState savedState, final Bundle outState, final WriteRead writeRead) { - @NonNull - final String currentSavedPrefix; + @NonNull final String currentSavedPrefix; if (savedState == null || TextUtils.isEmpty(savedState.getPrefixFileSaved())) { // Generate unique prefix currentSavedPrefix = System.nanoTime() - writeRead.hashCode() + ""; @@ -299,8 +299,11 @@ public static void clearStateFiles() { cacheDir = new File(cacheDir, CACHE_DIR_NAME); if (cacheDir.exists()) { - for (final File file : cacheDir.listFiles()) { - file.delete(); + final File[] list = cacheDir.listFiles(); + if (list != null) { + for (final File file : list) { + file.delete(); + } } } } diff --git a/app/src/main/java/org/schabi/newpipe/util/StreamDialogEntry.java b/app/src/main/java/org/schabi/newpipe/util/StreamDialogEntry.java index 73fee32f7f5..2d59febc22e 100644 --- a/app/src/main/java/org/schabi/newpipe/util/StreamDialogEntry.java +++ b/app/src/main/java/org/schabi/newpipe/util/StreamDialogEntry.java @@ -24,6 +24,12 @@ public enum StreamDialogEntry { // enum values with DEFAULT actions // ////////////////////////////////////// + show_channel_details(R.string.show_channel_details, (fragment, item) -> + // For some reason `getParentFragmentManager()` doesn't work, but this does. + NavigationHelper.openChannelFragment(fragment.getActivity().getSupportFragmentManager(), + item.getServiceId(), item.getUploaderUrl(), item.getUploaderName()) + ), + /** * Enqueues the stream automatically to the current PlayerType.
*
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 dcfb7ed1907..907bcf0ba8b 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java @@ -23,7 +23,6 @@ import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; -import android.content.res.TypedArray; import android.util.TypedValue; import androidx.annotation.AttrRes; @@ -31,6 +30,7 @@ import androidx.annotation.StyleRes; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.app.AppCompatDelegate; import androidx.core.content.ContextCompat; import androidx.preference.PreferenceManager; @@ -47,6 +47,9 @@ private ThemeHelper() { * Apply the selected theme (on NewPipe settings) in the context * with the default style (see {@link #setTheme(Context, int)}). * + * ThemeHelper.setDayNightMode should be called before + * the applying theme for the first time in session + * * @param context context that the theme will be applied */ public static void setTheme(final Context context) { @@ -57,6 +60,9 @@ public static void setTheme(final Context context) { * Apply the selected theme (on NewPipe settings) in the context, * themed according with the styles defined for the service . * + * ThemeHelper.setDayNightMode should be called before + * the applying theme for the first time in session + * * @param context context that the theme will be applied * @param serviceId the theme will be styled to the service with this id, * pass -1 to get the default style @@ -120,6 +126,7 @@ public static int getThemeForService(final Context context, final int serviceId) final String selectedThemeKey = getSelectedThemeKey(context); + int baseTheme = R.style.DarkTheme; // default to dark theme if (selectedThemeKey.equals(lightThemeKey)) { baseTheme = R.style.LightTheme; @@ -202,20 +209,6 @@ public static int getSettingsThemeStyle(final Context context) { } } - /** - * Get a resource id from a resource styled according to the context's theme. - * - * @param context Android app context - * @param attr attribute reference of the resource - * @return resource ID - */ - public static int resolveResourceIdFromAttr(final Context context, @AttrRes final int attr) { - final TypedArray a = context.getTheme().obtainStyledAttributes(new int[]{attr}); - final int attributeResourceId = a.getResourceId(0, 0); - a.recycle(); - return attributeResourceId; - } - /** * Get a color from an attr styled according to the context's theme. * @@ -288,4 +281,21 @@ public static boolean isDeviceDarkThemeEnabled(final Context context) { return false; } } + + public static void setDayNightMode(final Context context) { + setDayNightMode(context, ThemeHelper.getSelectedThemeKey(context)); + } + + public static void setDayNightMode(final Context context, final String selectedThemeKey) { + final Resources res = context.getResources(); + + if (selectedThemeKey.equals(res.getString(R.string.light_theme_key))) { + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); + } else if (selectedThemeKey.equals(res.getString(R.string.dark_theme_key)) + || selectedThemeKey.equals(res.getString(R.string.black_theme_key))) { + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); + } else { + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM); + } + } } diff --git a/app/src/main/java/us/shandian/giga/ui/fragment/MissionsFragment.java b/app/src/main/java/us/shandian/giga/ui/fragment/MissionsFragment.java index 3270b2b6f72..c83eec819af 100644 --- a/app/src/main/java/us/shandian/giga/ui/fragment/MissionsFragment.java +++ b/app/src/main/java/us/shandian/giga/ui/fragment/MissionsFragment.java @@ -1,7 +1,6 @@ package us.shandian.giga.ui.fragment; import android.app.Activity; -import android.app.AlertDialog; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -19,6 +18,7 @@ import android.widget.Toast; import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.Fragment; import androidx.preference.PreferenceManager; import androidx.recyclerview.widget.GridLayoutManager; @@ -224,10 +224,9 @@ private void updateList() { mList.setAdapter(mAdapter); if (mSwitch != null) { - mSwitch.setIcon(ThemeHelper.resolveResourceIdFromAttr( - requireContext(), mLinear - ? R.attr.ic_grid - : R.attr.ic_list)); + mSwitch.setIcon(mLinear + ? R.drawable.ic_apps + : R.drawable.ic_list); mSwitch.setTitle(mLinear ? R.string.grid : R.string.list); mPrefs.edit().putBoolean("linear", mLinear).apply(); } diff --git a/app/src/main/java/us/shandian/giga/util/Utility.java b/app/src/main/java/us/shandian/giga/util/Utility.java index c090c72118a..ab584f0e6c7 100644 --- a/app/src/main/java/us/shandian/giga/util/Utility.java +++ b/app/src/main/java/us/shandian/giga/util/Utility.java @@ -182,12 +182,12 @@ public static int getForegroundForFileType(Context ctx, FileType type) { public static int getIconForFileType(FileType type) { switch (type) { case MUSIC: - return R.drawable.ic_headset_white_24dp; + return R.drawable.ic_headset; default: case VIDEO: - return R.drawable.ic_movie_white_24dp; + return R.drawable.ic_movie; case SUBTITLE: - return R.drawable.ic_subtitles_white_24dp; + return R.drawable.ic_subtitles; } } 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.png similarity index 100% rename from app/src/main/res/drawable-hdpi/ic_close_white_24dp_png.png rename to app/src/main/res/drawable-hdpi/ic_close_white.png diff --git a/app/src/main/res/drawable-hdpi/ic_hourglass_top_white_24dp_png.png b/app/src/main/res/drawable-hdpi/ic_hourglass_top_white.png similarity index 100% rename from app/src/main/res/drawable-hdpi/ic_hourglass_top_white_24dp_png.png rename to app/src/main/res/drawable-hdpi/ic_hourglass_top_white.png diff --git a/app/src/main/res/drawable-hdpi/ic_replay_white_24dp_png.png b/app/src/main/res/drawable-hdpi/ic_replay_white.png similarity index 100% rename from app/src/main/res/drawable-hdpi/ic_replay_white_24dp_png.png rename to app/src/main/res/drawable-hdpi/ic_replay_white.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.png similarity index 100% rename from app/src/main/res/drawable-mdpi/ic_close_white_24dp_png.png rename to app/src/main/res/drawable-mdpi/ic_close_white.png diff --git a/app/src/main/res/drawable-mdpi/ic_hourglass_top_white_24dp_png.png b/app/src/main/res/drawable-mdpi/ic_hourglass_top_white.png similarity index 100% rename from app/src/main/res/drawable-mdpi/ic_hourglass_top_white_24dp_png.png rename to app/src/main/res/drawable-mdpi/ic_hourglass_top_white.png diff --git a/app/src/main/res/drawable-mdpi/ic_replay_white_24dp_png.png b/app/src/main/res/drawable-mdpi/ic_replay_white.png similarity index 100% rename from app/src/main/res/drawable-mdpi/ic_replay_white_24dp_png.png rename to app/src/main/res/drawable-mdpi/ic_replay_white.png diff --git a/app/src/main/res/drawable/ic_add_white_24dp.xml b/app/src/main/res/drawable-night/ic_add.xml similarity index 100% rename from app/src/main/res/drawable/ic_add_white_24dp.xml rename to app/src/main/res/drawable-night/ic_add.xml diff --git a/app/src/main/res/drawable/ic_add_circle_outline_white_24dp.xml b/app/src/main/res/drawable-night/ic_add_circle_outline.xml similarity index 100% rename from app/src/main/res/drawable/ic_add_circle_outline_white_24dp.xml rename to app/src/main/res/drawable-night/ic_add_circle_outline.xml diff --git a/app/src/main/res/drawable/ic_apps_white_24dp.xml b/app/src/main/res/drawable-night/ic_apps.xml similarity index 100% rename from app/src/main/res/drawable/ic_apps_white_24dp.xml rename to app/src/main/res/drawable-night/ic_apps.xml diff --git a/app/src/main/res/drawable/ic_arrow_back_white_24dp.xml b/app/src/main/res/drawable-night/ic_arrow_back.xml similarity index 100% rename from app/src/main/res/drawable/ic_arrow_back_white_24dp.xml rename to app/src/main/res/drawable-night/ic_arrow_back.xml diff --git a/app/src/main/res/drawable/ic_asterisk_white_24dp.xml b/app/src/main/res/drawable-night/ic_asterisk.xml similarity index 100% rename from app/src/main/res/drawable/ic_asterisk_white_24dp.xml rename to app/src/main/res/drawable-night/ic_asterisk.xml diff --git a/app/src/main/res/drawable/ic_attach_money_white_24dp.xml b/app/src/main/res/drawable-night/ic_attach_money.xml similarity index 100% rename from app/src/main/res/drawable/ic_attach_money_white_24dp.xml rename to app/src/main/res/drawable-night/ic_attach_money.xml diff --git a/app/src/main/res/drawable/ic_backup_white_24dp.xml b/app/src/main/res/drawable-night/ic_backup.xml similarity index 100% rename from app/src/main/res/drawable/ic_backup_white_24dp.xml rename to app/src/main/res/drawable-night/ic_backup.xml diff --git a/app/src/main/res/drawable/ic_bookmark_white_24dp.xml b/app/src/main/res/drawable-night/ic_bookmark.xml similarity index 100% rename from app/src/main/res/drawable/ic_bookmark_white_24dp.xml rename to app/src/main/res/drawable-night/ic_bookmark.xml diff --git a/app/src/main/res/drawable/ic_bug_report_white_24dp.xml b/app/src/main/res/drawable-night/ic_bug_report.xml similarity index 100% rename from app/src/main/res/drawable/ic_bug_report_white_24dp.xml rename to app/src/main/res/drawable-night/ic_bug_report.xml diff --git a/app/src/main/res/drawable/ic_cast_white_24dp.xml b/app/src/main/res/drawable-night/ic_cast.xml similarity index 100% rename from app/src/main/res/drawable/ic_cast_white_24dp.xml rename to app/src/main/res/drawable-night/ic_cast.xml diff --git a/app/src/main/res/drawable/ic_child_care_white_24dp.xml b/app/src/main/res/drawable-night/ic_child_care.xml similarity index 100% rename from app/src/main/res/drawable/ic_child_care_white_24dp.xml rename to app/src/main/res/drawable-night/ic_child_care.xml diff --git a/app/src/main/res/drawable/ic_close_white_24dp.xml b/app/src/main/res/drawable-night/ic_close.xml similarity index 100% rename from app/src/main/res/drawable/ic_close_white_24dp.xml rename to app/src/main/res/drawable-night/ic_close.xml diff --git a/app/src/main/res/drawable/ic_cloud_download_white_24dp.xml b/app/src/main/res/drawable-night/ic_cloud_download.xml similarity index 100% rename from app/src/main/res/drawable/ic_cloud_download_white_24dp.xml rename to app/src/main/res/drawable-night/ic_cloud_download.xml diff --git a/app/src/main/res/drawable/ic_computer_white_24dp.xml b/app/src/main/res/drawable-night/ic_computer.xml similarity index 100% rename from app/src/main/res/drawable/ic_computer_white_24dp.xml rename to app/src/main/res/drawable-night/ic_computer.xml diff --git a/app/src/main/res/drawable/ic_crop_portrait_white_24dp.xml b/app/src/main/res/drawable-night/ic_crop_portrait.xml similarity index 100% rename from app/src/main/res/drawable/ic_crop_portrait_white_24dp.xml rename to app/src/main/res/drawable-night/ic_crop_portrait.xml diff --git a/app/src/main/res/drawable/ic_delete_white_24dp.xml b/app/src/main/res/drawable-night/ic_delete.xml similarity index 100% rename from app/src/main/res/drawable/ic_delete_white_24dp.xml rename to app/src/main/res/drawable-night/ic_delete.xml diff --git a/app/src/main/res/drawable/ic_directions_bike_white_24dp.xml b/app/src/main/res/drawable-night/ic_directions_bike.xml similarity index 100% rename from app/src/main/res/drawable/ic_directions_bike_white_24dp.xml rename to app/src/main/res/drawable-night/ic_directions_bike.xml diff --git a/app/src/main/res/drawable/ic_directions_car_white_24dp.xml b/app/src/main/res/drawable-night/ic_directions_car.xml similarity index 100% rename from app/src/main/res/drawable/ic_directions_car_white_24dp.xml rename to app/src/main/res/drawable-night/ic_directions_car.xml diff --git a/app/src/main/res/drawable/ic_done_white_24dp.xml b/app/src/main/res/drawable-night/ic_done.xml similarity index 100% rename from app/src/main/res/drawable/ic_done_white_24dp.xml rename to app/src/main/res/drawable-night/ic_done.xml diff --git a/app/src/main/res/drawable/ic_drag_handle_white_24dp.xml b/app/src/main/res/drawable-night/ic_drag_handle.xml similarity index 100% rename from app/src/main/res/drawable/ic_drag_handle_white_24dp.xml rename to app/src/main/res/drawable-night/ic_drag_handle.xml diff --git a/app/src/main/res/drawable/ic_edit_white_24dp.xml b/app/src/main/res/drawable-night/ic_edit.xml similarity index 100% rename from app/src/main/res/drawable/ic_edit_white_24dp.xml rename to app/src/main/res/drawable-night/ic_edit.xml diff --git a/app/src/main/res/drawable/ic_expand_less_white_24dp.xml b/app/src/main/res/drawable-night/ic_expand_less.xml similarity index 100% rename from app/src/main/res/drawable/ic_expand_less_white_24dp.xml rename to app/src/main/res/drawable-night/ic_expand_less.xml diff --git a/app/src/main/res/drawable/ic_expand_more_white_24dp.xml b/app/src/main/res/drawable-night/ic_expand_more.xml similarity index 100% rename from app/src/main/res/drawable/ic_expand_more_white_24dp.xml rename to app/src/main/res/drawable-night/ic_expand_more.xml diff --git a/app/src/main/res/drawable/ic_explore_white_24dp.xml b/app/src/main/res/drawable-night/ic_explore.xml similarity index 100% rename from app/src/main/res/drawable/ic_explore_white_24dp.xml rename to app/src/main/res/drawable-night/ic_explore.xml diff --git a/app/src/main/res/drawable/ic_fastfood_white_24dp.xml b/app/src/main/res/drawable-night/ic_fastfood.xml similarity index 100% rename from app/src/main/res/drawable/ic_fastfood_white_24dp.xml rename to app/src/main/res/drawable-night/ic_fastfood.xml diff --git a/app/src/main/res/drawable/ic_favorite_white_24dp.xml b/app/src/main/res/drawable-night/ic_favorite.xml similarity index 100% rename from app/src/main/res/drawable/ic_favorite_white_24dp.xml rename to app/src/main/res/drawable-night/ic_favorite.xml diff --git a/app/src/main/res/drawable/ic_file_download_white_24dp.xml b/app/src/main/res/drawable-night/ic_file_download.xml similarity index 100% rename from app/src/main/res/drawable/ic_file_download_white_24dp.xml rename to app/src/main/res/drawable-night/ic_file_download.xml diff --git a/app/src/main/res/drawable/ic_filter_list_white_24dp.xml b/app/src/main/res/drawable-night/ic_filter_list.xml similarity index 100% rename from app/src/main/res/drawable/ic_filter_list_white_24dp.xml rename to app/src/main/res/drawable-night/ic_filter_list.xml diff --git a/app/src/main/res/drawable/ic_fitness_center_white_24dp.xml b/app/src/main/res/drawable-night/ic_fitness_center.xml similarity index 100% rename from app/src/main/res/drawable/ic_fitness_center_white_24dp.xml rename to app/src/main/res/drawable-night/ic_fitness_center.xml diff --git a/app/src/main/res/drawable/ic_headset_white_24dp.xml b/app/src/main/res/drawable-night/ic_headset.xml similarity index 91% rename from app/src/main/res/drawable/ic_headset_white_24dp.xml rename to app/src/main/res/drawable-night/ic_headset.xml index 3ca2936b8cb..f2376476651 100644 --- a/app/src/main/res/drawable/ic_headset_white_24dp.xml +++ b/app/src/main/res/drawable-night/ic_headset.xml @@ -5,6 +5,6 @@ android:viewportWidth="24.0" android:viewportHeight="24.0"> diff --git a/app/src/main/res/drawable/ic_help_white_24dp.xml b/app/src/main/res/drawable-night/ic_help.xml similarity index 100% rename from app/src/main/res/drawable/ic_help_white_24dp.xml rename to app/src/main/res/drawable-night/ic_help.xml diff --git a/app/src/main/res/drawable/ic_history_white_24dp.xml b/app/src/main/res/drawable-night/ic_history.xml similarity index 100% rename from app/src/main/res/drawable/ic_history_white_24dp.xml rename to app/src/main/res/drawable-night/ic_history.xml diff --git a/app/src/main/res/drawable/ic_home_white_24dp.xml b/app/src/main/res/drawable-night/ic_home.xml similarity index 100% rename from app/src/main/res/drawable/ic_home_white_24dp.xml rename to app/src/main/res/drawable-night/ic_home.xml diff --git a/app/src/main/res/drawable/ic_import_export_white_24dp.xml b/app/src/main/res/drawable-night/ic_import_export.xml similarity index 100% rename from app/src/main/res/drawable/ic_import_export_white_24dp.xml rename to app/src/main/res/drawable-night/ic_import_export.xml diff --git a/app/src/main/res/drawable/ic_info_outline_white_24dp.xml b/app/src/main/res/drawable-night/ic_info_outline.xml similarity index 91% rename from app/src/main/res/drawable/ic_info_outline_white_24dp.xml rename to app/src/main/res/drawable-night/ic_info_outline.xml index 2465f780819..d772001dfba 100644 --- a/app/src/main/res/drawable/ic_info_outline_white_24dp.xml +++ b/app/src/main/res/drawable-night/ic_info_outline.xml @@ -5,6 +5,6 @@ android:viewportWidth="24.0" android:viewportHeight="24.0"> diff --git a/app/src/main/res/drawable/ic_insert_emoticon_white_24dp.xml b/app/src/main/res/drawable-night/ic_insert_emoticon.xml similarity index 100% rename from app/src/main/res/drawable/ic_insert_emoticon_white_24dp.xml rename to app/src/main/res/drawable-night/ic_insert_emoticon.xml diff --git a/app/src/main/res/drawable/ic_language_white_24dp.xml b/app/src/main/res/drawable-night/ic_language.xml similarity index 100% rename from app/src/main/res/drawable/ic_language_white_24dp.xml rename to app/src/main/res/drawable-night/ic_language.xml diff --git a/app/src/main/res/drawable/ic_list_white_24dp.xml b/app/src/main/res/drawable-night/ic_list.xml similarity index 100% rename from app/src/main/res/drawable/ic_list_white_24dp.xml rename to app/src/main/res/drawable-night/ic_list.xml diff --git a/app/src/main/res/drawable/ic_live_tv_white_24dp.xml b/app/src/main/res/drawable-night/ic_live_tv.xml similarity index 100% rename from app/src/main/res/drawable/ic_live_tv_white_24dp.xml rename to app/src/main/res/drawable-night/ic_live_tv.xml diff --git a/app/src/main/res/drawable/ic_megaphone_white_24dp.xml b/app/src/main/res/drawable-night/ic_megaphone.xml similarity index 100% rename from app/src/main/res/drawable/ic_megaphone_white_24dp.xml rename to app/src/main/res/drawable-night/ic_megaphone.xml diff --git a/app/src/main/res/drawable/ic_mic_white_24dp.xml b/app/src/main/res/drawable-night/ic_mic.xml similarity index 100% rename from app/src/main/res/drawable/ic_mic_white_24dp.xml rename to app/src/main/res/drawable-night/ic_mic.xml diff --git a/app/src/main/res/drawable/ic_more_vert_white_24dp.xml b/app/src/main/res/drawable-night/ic_more_vert.xml similarity index 100% rename from app/src/main/res/drawable/ic_more_vert_white_24dp.xml rename to app/src/main/res/drawable-night/ic_more_vert.xml diff --git a/app/src/main/res/drawable/ic_motorcycle_white_24dp.xml b/app/src/main/res/drawable-night/ic_motorcycle.xml similarity index 100% rename from app/src/main/res/drawable/ic_motorcycle_white_24dp.xml rename to app/src/main/res/drawable-night/ic_motorcycle.xml diff --git a/app/src/main/res/drawable/ic_movie_white_24dp.xml b/app/src/main/res/drawable-night/ic_movie.xml similarity index 100% rename from app/src/main/res/drawable/ic_movie_white_24dp.xml rename to app/src/main/res/drawable-night/ic_movie.xml diff --git a/app/src/main/res/drawable/ic_music_note_white_24dp.xml b/app/src/main/res/drawable-night/ic_music_note.xml similarity index 100% rename from app/src/main/res/drawable/ic_music_note_white_24dp.xml rename to app/src/main/res/drawable-night/ic_music_note.xml diff --git a/app/src/main/res/drawable/ic_palette_white_24dp.xml b/app/src/main/res/drawable-night/ic_palette.xml similarity index 100% rename from app/src/main/res/drawable/ic_palette_white_24dp.xml rename to app/src/main/res/drawable-night/ic_palette.xml diff --git a/app/src/main/res/drawable/ic_pause_white_24dp.xml b/app/src/main/res/drawable-night/ic_pause.xml similarity index 100% rename from app/src/main/res/drawable/ic_pause_white_24dp.xml rename to app/src/main/res/drawable-night/ic_pause.xml diff --git a/app/src/main/res/drawable/ic_people_white_24dp.xml b/app/src/main/res/drawable-night/ic_people.xml similarity index 100% rename from app/src/main/res/drawable/ic_people_white_24dp.xml rename to app/src/main/res/drawable-night/ic_people.xml diff --git a/app/src/main/res/drawable/ic_person_white_24dp.xml b/app/src/main/res/drawable-night/ic_person.xml similarity index 100% rename from app/src/main/res/drawable/ic_person_white_24dp.xml rename to app/src/main/res/drawable-night/ic_person.xml diff --git a/app/src/main/res/drawable/ic_pets_white_24dp.xml b/app/src/main/res/drawable-night/ic_pets.xml similarity index 100% rename from app/src/main/res/drawable/ic_pets_white_24dp.xml rename to app/src/main/res/drawable-night/ic_pets.xml diff --git a/app/src/main/res/drawable/ic_picture_in_picture_white_24dp.xml b/app/src/main/res/drawable-night/ic_picture_in_picture.xml similarity index 91% rename from app/src/main/res/drawable/ic_picture_in_picture_white_24dp.xml rename to app/src/main/res/drawable-night/ic_picture_in_picture.xml index f6b3205cc0c..1b01f323324 100644 --- a/app/src/main/res/drawable/ic_picture_in_picture_white_24dp.xml +++ b/app/src/main/res/drawable-night/ic_picture_in_picture.xml @@ -5,6 +5,6 @@ android:viewportWidth="24.0" android:viewportHeight="24.0"> diff --git a/app/src/main/res/drawable/ic_play_arrow_white_24dp.xml b/app/src/main/res/drawable-night/ic_play_arrow.xml similarity index 87% rename from app/src/main/res/drawable/ic_play_arrow_white_24dp.xml rename to app/src/main/res/drawable-night/ic_play_arrow.xml index 098b71d1fb1..95cace1c819 100644 --- a/app/src/main/res/drawable/ic_play_arrow_white_24dp.xml +++ b/app/src/main/res/drawable-night/ic_play_arrow.xml @@ -5,6 +5,6 @@ android:viewportWidth="24.0" android:viewportHeight="24.0"> diff --git a/app/src/main/res/drawable/ic_playlist_add_white_24dp.xml b/app/src/main/res/drawable-night/ic_playlist_add.xml similarity index 100% rename from app/src/main/res/drawable/ic_playlist_add_white_24dp.xml rename to app/src/main/res/drawable-night/ic_playlist_add.xml diff --git a/app/src/main/res/drawable/ic_playlist_add_check_white_24dp.xml b/app/src/main/res/drawable-night/ic_playlist_add_check.xml similarity index 100% rename from app/src/main/res/drawable/ic_playlist_add_check_white_24dp.xml rename to app/src/main/res/drawable-night/ic_playlist_add_check.xml diff --git a/app/src/main/res/drawable/ic_public_white_24dp.xml b/app/src/main/res/drawable-night/ic_public.xml similarity index 100% rename from app/src/main/res/drawable/ic_public_white_24dp.xml rename to app/src/main/res/drawable-night/ic_public.xml diff --git a/app/src/main/res/drawable/ic_radio_white_24dp.xml b/app/src/main/res/drawable-night/ic_radio.xml similarity index 100% rename from app/src/main/res/drawable/ic_radio_white_24dp.xml rename to app/src/main/res/drawable-night/ic_radio.xml diff --git a/app/src/main/res/drawable/ic_refresh_white_24dp.xml b/app/src/main/res/drawable-night/ic_refresh.xml similarity index 100% rename from app/src/main/res/drawable/ic_refresh_white_24dp.xml rename to app/src/main/res/drawable-night/ic_refresh.xml diff --git a/app/src/main/res/drawable/ic_restaurant_white_24dp.xml b/app/src/main/res/drawable-night/ic_restaurant.xml similarity index 100% rename from app/src/main/res/drawable/ic_restaurant_white_24dp.xml rename to app/src/main/res/drawable-night/ic_restaurant.xml diff --git a/app/src/main/res/drawable/ic_rss_feed_white_24dp.xml b/app/src/main/res/drawable-night/ic_rss_feed.xml similarity index 100% rename from app/src/main/res/drawable/ic_rss_feed_white_24dp.xml rename to app/src/main/res/drawable-night/ic_rss_feed.xml diff --git a/app/src/main/res/drawable/ic_save_white_24dp.xml b/app/src/main/res/drawable-night/ic_save.xml similarity index 100% rename from app/src/main/res/drawable/ic_save_white_24dp.xml rename to app/src/main/res/drawable-night/ic_save.xml diff --git a/app/src/main/res/drawable/ic_school_white_24dp.xml b/app/src/main/res/drawable-night/ic_school.xml similarity index 100% rename from app/src/main/res/drawable/ic_school_white_24dp.xml rename to app/src/main/res/drawable-night/ic_school.xml diff --git a/app/src/main/res/drawable/ic_search_white_24dp.xml b/app/src/main/res/drawable-night/ic_search.xml similarity index 100% rename from app/src/main/res/drawable/ic_search_white_24dp.xml rename to app/src/main/res/drawable-night/ic_search.xml diff --git a/app/src/main/res/drawable/ic_search_add_white_24dp.xml b/app/src/main/res/drawable-night/ic_search_add.xml similarity index 100% rename from app/src/main/res/drawable/ic_search_add_white_24dp.xml rename to app/src/main/res/drawable-night/ic_search_add.xml diff --git a/app/src/main/res/drawable/ic_settings_white_24dp.xml b/app/src/main/res/drawable-night/ic_settings.xml similarity index 100% rename from app/src/main/res/drawable/ic_settings_white_24dp.xml rename to app/src/main/res/drawable-night/ic_settings.xml diff --git a/app/src/main/res/drawable/ic_share_white_24dp.xml b/app/src/main/res/drawable-night/ic_share.xml similarity index 100% rename from app/src/main/res/drawable/ic_share_white_24dp.xml rename to app/src/main/res/drawable-night/ic_share.xml diff --git a/app/src/main/res/drawable/ic_shopping_cart_white_24dp.xml b/app/src/main/res/drawable-night/ic_shopping_cart.xml similarity index 100% rename from app/src/main/res/drawable/ic_shopping_cart_white_24dp.xml rename to app/src/main/res/drawable-night/ic_shopping_cart.xml diff --git a/app/src/main/res/drawable/ic_sort_white_24dp.xml b/app/src/main/res/drawable-night/ic_sort.xml similarity index 100% rename from app/src/main/res/drawable/ic_sort_white_24dp.xml rename to app/src/main/res/drawable-night/ic_sort.xml diff --git a/app/src/main/res/drawable/ic_stars_white_24dp.xml b/app/src/main/res/drawable-night/ic_stars.xml similarity index 100% rename from app/src/main/res/drawable/ic_stars_white_24dp.xml rename to app/src/main/res/drawable-night/ic_stars.xml diff --git a/app/src/main/res/drawable/ic_telescope_white_24dp.xml b/app/src/main/res/drawable-night/ic_telescope.xml similarity index 100% rename from app/src/main/res/drawable/ic_telescope_white_24dp.xml rename to app/src/main/res/drawable-night/ic_telescope.xml diff --git a/app/src/main/res/drawable/ic_thumb_down_white_24dp.xml b/app/src/main/res/drawable-night/ic_thumb_down.xml similarity index 100% rename from app/src/main/res/drawable/ic_thumb_down_white_24dp.xml rename to app/src/main/res/drawable-night/ic_thumb_down.xml diff --git a/app/src/main/res/drawable/ic_thumb_up_white_24dp.xml b/app/src/main/res/drawable-night/ic_thumb_up.xml similarity index 100% rename from app/src/main/res/drawable/ic_thumb_up_white_24dp.xml rename to app/src/main/res/drawable-night/ic_thumb_up.xml diff --git a/app/src/main/res/drawable/ic_trending_up_white_24dp.xml b/app/src/main/res/drawable-night/ic_trending_up.xml similarity index 100% rename from app/src/main/res/drawable/ic_trending_up_white_24dp.xml rename to app/src/main/res/drawable-night/ic_trending_up.xml diff --git a/app/src/main/res/drawable/ic_tv_white_24dp.xml b/app/src/main/res/drawable-night/ic_tv.xml similarity index 100% rename from app/src/main/res/drawable/ic_tv_white_24dp.xml rename to app/src/main/res/drawable-night/ic_tv.xml diff --git a/app/src/main/res/drawable/ic_videogame_asset_white_24dp.xml b/app/src/main/res/drawable-night/ic_videogame_asset.xml similarity index 100% rename from app/src/main/res/drawable/ic_videogame_asset_white_24dp.xml rename to app/src/main/res/drawable-night/ic_videogame_asset.xml diff --git a/app/src/main/res/drawable/ic_volume_off_black_24dp.xml b/app/src/main/res/drawable-night/ic_volume_off.xml similarity index 94% rename from app/src/main/res/drawable/ic_volume_off_black_24dp.xml rename to app/src/main/res/drawable-night/ic_volume_off.xml index 19f166ddce8..a2cabcee03d 100644 --- a/app/src/main/res/drawable/ic_volume_off_black_24dp.xml +++ b/app/src/main/res/drawable-night/ic_volume_off.xml @@ -4,6 +4,7 @@ android:viewportWidth="24.0" android:viewportHeight="24.0"> + diff --git a/app/src/main/res/drawable/ic_volume_up_white_24dp.xml b/app/src/main/res/drawable-night/ic_volume_up.xml similarity index 100% rename from app/src/main/res/drawable/ic_volume_up_white_24dp.xml rename to app/src/main/res/drawable-night/ic_volume_up.xml diff --git a/app/src/main/res/drawable/ic_watch_later_white_24dp.xml b/app/src/main/res/drawable-night/ic_watch_later.xml similarity index 100% rename from app/src/main/res/drawable/ic_watch_later_white_24dp.xml rename to app/src/main/res/drawable-night/ic_watch_later.xml diff --git a/app/src/main/res/drawable/ic_wb_sunny_white_24dp.xml b/app/src/main/res/drawable-night/ic_wb_sunny.xml similarity index 100% rename from app/src/main/res/drawable/ic_wb_sunny_white_24dp.xml rename to app/src/main/res/drawable-night/ic_wb_sunny.xml diff --git a/app/src/main/res/drawable/ic_whatshot_white_24dp.xml b/app/src/main/res/drawable-night/ic_whatshot.xml similarity index 100% rename from app/src/main/res/drawable/ic_whatshot_white_24dp.xml rename to app/src/main/res/drawable-night/ic_whatshot.xml diff --git a/app/src/main/res/drawable/ic_work_white_24dp.xml b/app/src/main/res/drawable-night/ic_work.xml similarity index 100% rename from app/src/main/res/drawable/ic_work_white_24dp.xml rename to app/src/main/res/drawable-night/ic_work.xml diff --git a/app/src/main/res/drawable-xhdpi/ic_close_white_24dp_png.png b/app/src/main/res/drawable-xhdpi/ic_close_white.png similarity index 100% rename from app/src/main/res/drawable-xhdpi/ic_close_white_24dp_png.png rename to app/src/main/res/drawable-xhdpi/ic_close_white.png diff --git a/app/src/main/res/drawable-xhdpi/ic_hourglass_top_white_24dp_png.png b/app/src/main/res/drawable-xhdpi/ic_hourglass_top_white.png similarity index 100% rename from app/src/main/res/drawable-xhdpi/ic_hourglass_top_white_24dp_png.png rename to app/src/main/res/drawable-xhdpi/ic_hourglass_top_white.png diff --git a/app/src/main/res/drawable-xhdpi/ic_replay_white_24dp_png.png b/app/src/main/res/drawable-xhdpi/ic_replay_white.png similarity index 100% rename from app/src/main/res/drawable-xhdpi/ic_replay_white_24dp_png.png rename to app/src/main/res/drawable-xhdpi/ic_replay_white.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.png similarity index 100% rename from app/src/main/res/drawable-xxhdpi/ic_close_white_24dp_png.png rename to app/src/main/res/drawable-xxhdpi/ic_close_white.png diff --git a/app/src/main/res/drawable-xxhdpi/ic_hourglass_top_white_24dp_png.png b/app/src/main/res/drawable-xxhdpi/ic_hourglass_top_white.png similarity index 100% rename from app/src/main/res/drawable-xxhdpi/ic_hourglass_top_white_24dp_png.png rename to app/src/main/res/drawable-xxhdpi/ic_hourglass_top_white.png diff --git a/app/src/main/res/drawable-xxhdpi/ic_replay_white_24dp_png.png b/app/src/main/res/drawable-xxhdpi/ic_replay_white.png similarity index 100% rename from app/src/main/res/drawable-xxhdpi/ic_replay_white_24dp_png.png rename to app/src/main/res/drawable-xxhdpi/ic_replay_white.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.png similarity index 100% rename from app/src/main/res/drawable-xxxhdpi/ic_close_white_24dp_png.png rename to app/src/main/res/drawable-xxxhdpi/ic_close_white.png diff --git a/app/src/main/res/drawable-xxxhdpi/ic_hourglass_top_white_24dp_png.png b/app/src/main/res/drawable-xxxhdpi/ic_hourglass_top_white.png similarity index 100% rename from app/src/main/res/drawable-xxxhdpi/ic_hourglass_top_white_24dp_png.png rename to app/src/main/res/drawable-xxxhdpi/ic_hourglass_top_white.png diff --git a/app/src/main/res/drawable-xxxhdpi/ic_replay_white_24dp_png.png b/app/src/main/res/drawable-xxxhdpi/ic_replay_white.png similarity index 100% rename from app/src/main/res/drawable-xxxhdpi/ic_replay_white_24dp_png.png rename to app/src/main/res/drawable-xxxhdpi/ic_replay_white.png diff --git a/app/src/main/res/drawable/ic_add_black_24dp.xml b/app/src/main/res/drawable/ic_add.xml similarity index 100% rename from app/src/main/res/drawable/ic_add_black_24dp.xml rename to app/src/main/res/drawable/ic_add.xml diff --git a/app/src/main/res/drawable/ic_add_circle_outline_black_24dp.xml b/app/src/main/res/drawable/ic_add_circle_outline.xml similarity index 100% rename from app/src/main/res/drawable/ic_add_circle_outline_black_24dp.xml rename to app/src/main/res/drawable/ic_add_circle_outline.xml diff --git a/app/src/main/res/drawable/ic_apps_black_24dp.xml b/app/src/main/res/drawable/ic_apps.xml similarity index 100% rename from app/src/main/res/drawable/ic_apps_black_24dp.xml rename to app/src/main/res/drawable/ic_apps.xml diff --git a/app/src/main/res/drawable/ic_arrow_back_black_24dp.xml b/app/src/main/res/drawable/ic_arrow_back.xml similarity index 100% rename from app/src/main/res/drawable/ic_arrow_back_black_24dp.xml rename to app/src/main/res/drawable/ic_arrow_back.xml diff --git a/app/src/main/res/drawable/ic_arrow_drop_down_white_24dp.xml b/app/src/main/res/drawable/ic_arrow_drop_down.xml similarity index 100% rename from app/src/main/res/drawable/ic_arrow_drop_down_white_24dp.xml rename to app/src/main/res/drawable/ic_arrow_drop_down.xml diff --git a/app/src/main/res/drawable/ic_arrow_drop_up_white_24dp.xml b/app/src/main/res/drawable/ic_arrow_drop_up.xml similarity index 100% rename from app/src/main/res/drawable/ic_arrow_drop_up_white_24dp.xml rename to app/src/main/res/drawable/ic_arrow_drop_up.xml diff --git a/app/src/main/res/drawable/ic_art_track_white_24dp.xml b/app/src/main/res/drawable/ic_art_track.xml similarity index 100% rename from app/src/main/res/drawable/ic_art_track_white_24dp.xml rename to app/src/main/res/drawable/ic_art_track.xml diff --git a/app/src/main/res/drawable/ic_asterisk_black_24dp.xml b/app/src/main/res/drawable/ic_asterisk.xml similarity index 100% rename from app/src/main/res/drawable/ic_asterisk_black_24dp.xml rename to app/src/main/res/drawable/ic_asterisk.xml diff --git a/app/src/main/res/drawable/ic_attach_money_black_24dp.xml b/app/src/main/res/drawable/ic_attach_money.xml similarity index 100% rename from app/src/main/res/drawable/ic_attach_money_black_24dp.xml rename to app/src/main/res/drawable/ic_attach_money.xml diff --git a/app/src/main/res/drawable/ic_backup_black_24dp.xml b/app/src/main/res/drawable/ic_backup.xml similarity index 100% rename from app/src/main/res/drawable/ic_backup_black_24dp.xml rename to app/src/main/res/drawable/ic_backup.xml diff --git a/app/src/main/res/drawable/ic_bookmark_black_24dp.xml b/app/src/main/res/drawable/ic_bookmark.xml similarity index 100% rename from app/src/main/res/drawable/ic_bookmark_black_24dp.xml rename to app/src/main/res/drawable/ic_bookmark.xml diff --git a/app/src/main/res/drawable/ic_brightness_high_white_24dp.xml b/app/src/main/res/drawable/ic_brightness_high.xml similarity index 100% rename from app/src/main/res/drawable/ic_brightness_high_white_24dp.xml rename to app/src/main/res/drawable/ic_brightness_high.xml diff --git a/app/src/main/res/drawable/ic_brightness_low_white_24dp.xml b/app/src/main/res/drawable/ic_brightness_low.xml similarity index 100% rename from app/src/main/res/drawable/ic_brightness_low_white_24dp.xml rename to app/src/main/res/drawable/ic_brightness_low.xml diff --git a/app/src/main/res/drawable/ic_brightness_medium_white_24dp.xml b/app/src/main/res/drawable/ic_brightness_medium.xml similarity index 100% rename from app/src/main/res/drawable/ic_brightness_medium_white_24dp.xml rename to app/src/main/res/drawable/ic_brightness_medium.xml diff --git a/app/src/main/res/drawable/ic_bug_report_black_24dp.xml b/app/src/main/res/drawable/ic_bug_report.xml similarity index 100% rename from app/src/main/res/drawable/ic_bug_report_black_24dp.xml rename to app/src/main/res/drawable/ic_bug_report.xml diff --git a/app/src/main/res/drawable/ic_cast_black_24dp.xml b/app/src/main/res/drawable/ic_cast.xml similarity index 100% rename from app/src/main/res/drawable/ic_cast_black_24dp.xml rename to app/src/main/res/drawable/ic_cast.xml diff --git a/app/src/main/res/drawable/ic_child_care_black_24dp.xml b/app/src/main/res/drawable/ic_child_care.xml similarity index 100% rename from app/src/main/res/drawable/ic_child_care_black_24dp.xml rename to app/src/main/res/drawable/ic_child_care.xml diff --git a/app/src/main/res/drawable/ic_close_black_24dp.xml b/app/src/main/res/drawable/ic_close.xml similarity index 100% rename from app/src/main/res/drawable/ic_close_black_24dp.xml rename to app/src/main/res/drawable/ic_close.xml diff --git a/app/src/main/res/drawable/ic_cloud_download_black_24dp.xml b/app/src/main/res/drawable/ic_cloud_download.xml similarity index 100% rename from app/src/main/res/drawable/ic_cloud_download_black_24dp.xml rename to app/src/main/res/drawable/ic_cloud_download.xml diff --git a/app/src/main/res/drawable/ic_comment_white_24dp.xml b/app/src/main/res/drawable/ic_comment.xml similarity index 100% rename from app/src/main/res/drawable/ic_comment_white_24dp.xml rename to app/src/main/res/drawable/ic_comment.xml diff --git a/app/src/main/res/drawable/ic_computer_black_24dp.xml b/app/src/main/res/drawable/ic_computer.xml similarity index 100% rename from app/src/main/res/drawable/ic_computer_black_24dp.xml rename to app/src/main/res/drawable/ic_computer.xml diff --git a/app/src/main/res/drawable/ic_crop_portrait_black_24dp.xml b/app/src/main/res/drawable/ic_crop_portrait.xml similarity index 100% rename from app/src/main/res/drawable/ic_crop_portrait_black_24dp.xml rename to app/src/main/res/drawable/ic_crop_portrait.xml diff --git a/app/src/main/res/drawable/ic_delete_black_24dp.xml b/app/src/main/res/drawable/ic_delete.xml similarity index 100% rename from app/src/main/res/drawable/ic_delete_black_24dp.xml rename to app/src/main/res/drawable/ic_delete.xml diff --git a/app/src/main/res/drawable/ic_description_white_24dp.xml b/app/src/main/res/drawable/ic_description.xml similarity index 100% rename from app/src/main/res/drawable/ic_description_white_24dp.xml rename to app/src/main/res/drawable/ic_description.xml diff --git a/app/src/main/res/drawable/ic_directions_bike_black_24dp.xml b/app/src/main/res/drawable/ic_directions_bike.xml similarity index 100% rename from app/src/main/res/drawable/ic_directions_bike_black_24dp.xml rename to app/src/main/res/drawable/ic_directions_bike.xml diff --git a/app/src/main/res/drawable/ic_directions_car_black_24dp.xml b/app/src/main/res/drawable/ic_directions_car.xml similarity index 100% rename from app/src/main/res/drawable/ic_directions_car_black_24dp.xml rename to app/src/main/res/drawable/ic_directions_car.xml diff --git a/app/src/main/res/drawable/ic_done_black_24dp.xml b/app/src/main/res/drawable/ic_done.xml similarity index 100% rename from app/src/main/res/drawable/ic_done_black_24dp.xml rename to app/src/main/res/drawable/ic_done.xml diff --git a/app/src/main/res/drawable/ic_drag_handle_black_24dp.xml b/app/src/main/res/drawable/ic_drag_handle.xml similarity index 100% rename from app/src/main/res/drawable/ic_drag_handle_black_24dp.xml rename to app/src/main/res/drawable/ic_drag_handle.xml diff --git a/app/src/main/res/drawable/ic_edit_black_24dp.xml b/app/src/main/res/drawable/ic_edit.xml similarity index 100% rename from app/src/main/res/drawable/ic_edit_black_24dp.xml rename to app/src/main/res/drawable/ic_edit.xml diff --git a/app/src/main/res/drawable/ic_expand_less_black_24dp.xml b/app/src/main/res/drawable/ic_expand_less.xml similarity index 100% rename from app/src/main/res/drawable/ic_expand_less_black_24dp.xml rename to app/src/main/res/drawable/ic_expand_less.xml diff --git a/app/src/main/res/drawable/ic_expand_more_black_24dp.xml b/app/src/main/res/drawable/ic_expand_more.xml similarity index 100% rename from app/src/main/res/drawable/ic_expand_more_black_24dp.xml rename to app/src/main/res/drawable/ic_expand_more.xml diff --git a/app/src/main/res/drawable/ic_explore_black_24dp.xml b/app/src/main/res/drawable/ic_explore.xml similarity index 100% rename from app/src/main/res/drawable/ic_explore_black_24dp.xml rename to app/src/main/res/drawable/ic_explore.xml diff --git a/app/src/main/res/drawable/ic_fast_forward_white_24dp.xml b/app/src/main/res/drawable/ic_fast_forward.xml similarity index 100% rename from app/src/main/res/drawable/ic_fast_forward_white_24dp.xml rename to app/src/main/res/drawable/ic_fast_forward.xml diff --git a/app/src/main/res/drawable/ic_fast_rewind_white_24dp.xml b/app/src/main/res/drawable/ic_fast_rewind.xml similarity index 100% rename from app/src/main/res/drawable/ic_fast_rewind_white_24dp.xml rename to app/src/main/res/drawable/ic_fast_rewind.xml diff --git a/app/src/main/res/drawable/ic_fastfood_black_24dp.xml b/app/src/main/res/drawable/ic_fastfood.xml similarity index 100% rename from app/src/main/res/drawable/ic_fastfood_black_24dp.xml rename to app/src/main/res/drawable/ic_fastfood.xml diff --git a/app/src/main/res/drawable/ic_favorite_black_24dp.xml b/app/src/main/res/drawable/ic_favorite.xml similarity index 100% rename from app/src/main/res/drawable/ic_favorite_black_24dp.xml rename to app/src/main/res/drawable/ic_favorite.xml diff --git a/app/src/main/res/drawable/ic_file_download_black_24dp.xml b/app/src/main/res/drawable/ic_file_download.xml similarity index 100% rename from app/src/main/res/drawable/ic_file_download_black_24dp.xml rename to app/src/main/res/drawable/ic_file_download.xml diff --git a/app/src/main/res/drawable/ic_filter_list_black_24dp.xml b/app/src/main/res/drawable/ic_filter_list.xml similarity index 100% rename from app/src/main/res/drawable/ic_filter_list_black_24dp.xml rename to app/src/main/res/drawable/ic_filter_list.xml diff --git a/app/src/main/res/drawable/ic_fitness_center_black_24dp.xml b/app/src/main/res/drawable/ic_fitness_center.xml similarity index 100% rename from app/src/main/res/drawable/ic_fitness_center_black_24dp.xml rename to app/src/main/res/drawable/ic_fitness_center.xml diff --git a/app/src/main/res/drawable/ic_format_list_numbered_white_24.xml b/app/src/main/res/drawable/ic_format_list_numbered.xml similarity index 100% rename from app/src/main/res/drawable/ic_format_list_numbered_white_24.xml rename to app/src/main/res/drawable/ic_format_list_numbered.xml diff --git a/app/src/main/res/drawable/ic_fullscreen_white_24dp.xml b/app/src/main/res/drawable/ic_fullscreen.xml similarity index 100% rename from app/src/main/res/drawable/ic_fullscreen_white_24dp.xml rename to app/src/main/res/drawable/ic_fullscreen.xml diff --git a/app/src/main/res/drawable/ic_fullscreen_exit_white_24dp.xml b/app/src/main/res/drawable/ic_fullscreen_exit.xml similarity index 100% rename from app/src/main/res/drawable/ic_fullscreen_exit_white_24dp.xml rename to app/src/main/res/drawable/ic_fullscreen_exit.xml diff --git a/app/src/main/res/drawable/ic_headset_black_24dp.xml b/app/src/main/res/drawable/ic_headset.xml similarity index 100% rename from app/src/main/res/drawable/ic_headset_black_24dp.xml rename to app/src/main/res/drawable/ic_headset.xml diff --git a/app/src/main/res/drawable/ic_help_black_24dp.xml b/app/src/main/res/drawable/ic_help.xml similarity index 100% rename from app/src/main/res/drawable/ic_help_black_24dp.xml rename to app/src/main/res/drawable/ic_help.xml diff --git a/app/src/main/res/drawable/ic_history_black_24dp.xml b/app/src/main/res/drawable/ic_history.xml similarity index 100% rename from app/src/main/res/drawable/ic_history_black_24dp.xml rename to app/src/main/res/drawable/ic_history.xml diff --git a/app/src/main/res/drawable/ic_home_black_24dp.xml b/app/src/main/res/drawable/ic_home.xml similarity index 100% rename from app/src/main/res/drawable/ic_home_black_24dp.xml rename to app/src/main/res/drawable/ic_home.xml diff --git a/app/src/main/res/drawable/ic_hourglass_top_white_24dp.xml b/app/src/main/res/drawable/ic_hourglass_top.xml similarity index 100% rename from app/src/main/res/drawable/ic_hourglass_top_white_24dp.xml rename to app/src/main/res/drawable/ic_hourglass_top.xml diff --git a/app/src/main/res/drawable/ic_import_export_black_24dp.xml b/app/src/main/res/drawable/ic_import_export.xml similarity index 100% rename from app/src/main/res/drawable/ic_import_export_black_24dp.xml rename to app/src/main/res/drawable/ic_import_export.xml diff --git a/app/src/main/res/drawable/ic_info_outline_black_24dp.xml b/app/src/main/res/drawable/ic_info_outline.xml similarity index 100% rename from app/src/main/res/drawable/ic_info_outline_black_24dp.xml rename to app/src/main/res/drawable/ic_info_outline.xml diff --git a/app/src/main/res/drawable/ic_insert_emoticon_black_24dp.xml b/app/src/main/res/drawable/ic_insert_emoticon.xml similarity index 100% rename from app/src/main/res/drawable/ic_insert_emoticon_black_24dp.xml rename to app/src/main/res/drawable/ic_insert_emoticon.xml diff --git a/app/src/main/res/drawable/ic_language_black_24dp.xml b/app/src/main/res/drawable/ic_language.xml similarity index 100% rename from app/src/main/res/drawable/ic_language_black_24dp.xml rename to app/src/main/res/drawable/ic_language.xml diff --git a/app/src/main/res/drawable/ic_list_black_24dp.xml b/app/src/main/res/drawable/ic_list.xml similarity index 100% rename from app/src/main/res/drawable/ic_list_black_24dp.xml rename to app/src/main/res/drawable/ic_list.xml diff --git a/app/src/main/res/drawable/ic_live_tv_black_24dp.xml b/app/src/main/res/drawable/ic_live_tv.xml similarity index 100% rename from app/src/main/res/drawable/ic_live_tv_black_24dp.xml rename to app/src/main/res/drawable/ic_live_tv.xml diff --git a/app/src/main/res/drawable/ic_megaphone_black_24dp.xml b/app/src/main/res/drawable/ic_megaphone.xml similarity index 100% rename from app/src/main/res/drawable/ic_megaphone_black_24dp.xml rename to app/src/main/res/drawable/ic_megaphone.xml diff --git a/app/src/main/res/drawable/ic_mic_black_24dp.xml b/app/src/main/res/drawable/ic_mic.xml similarity index 100% rename from app/src/main/res/drawable/ic_mic_black_24dp.xml rename to app/src/main/res/drawable/ic_mic.xml diff --git a/app/src/main/res/drawable/ic_more_vert_black_24dp.xml b/app/src/main/res/drawable/ic_more_vert.xml similarity index 100% rename from app/src/main/res/drawable/ic_more_vert_black_24dp.xml rename to app/src/main/res/drawable/ic_more_vert.xml diff --git a/app/src/main/res/drawable/ic_motorcycle_black_24dp.xml b/app/src/main/res/drawable/ic_motorcycle.xml similarity index 100% rename from app/src/main/res/drawable/ic_motorcycle_black_24dp.xml rename to app/src/main/res/drawable/ic_motorcycle.xml diff --git a/app/src/main/res/drawable/ic_movie_black_24dp.xml b/app/src/main/res/drawable/ic_movie.xml similarity index 100% rename from app/src/main/res/drawable/ic_movie_black_24dp.xml rename to app/src/main/res/drawable/ic_movie.xml diff --git a/app/src/main/res/drawable/ic_music_note_black_24dp.xml b/app/src/main/res/drawable/ic_music_note.xml similarity index 100% rename from app/src/main/res/drawable/ic_music_note_black_24dp.xml rename to app/src/main/res/drawable/ic_music_note.xml diff --git a/app/src/main/res/drawable/ic_next_white_24dp.xml b/app/src/main/res/drawable/ic_next.xml similarity index 100% rename from app/src/main/res/drawable/ic_next_white_24dp.xml rename to app/src/main/res/drawable/ic_next.xml diff --git a/app/src/main/res/drawable/ic_palette_black_24dp.xml b/app/src/main/res/drawable/ic_palette.xml similarity index 100% rename from app/src/main/res/drawable/ic_palette_black_24dp.xml rename to app/src/main/res/drawable/ic_palette.xml diff --git a/app/src/main/res/drawable/ic_pause_black_24dp.xml b/app/src/main/res/drawable/ic_pause.xml similarity index 100% rename from app/src/main/res/drawable/ic_pause_black_24dp.xml rename to app/src/main/res/drawable/ic_pause.xml diff --git a/app/src/main/res/drawable/ic_people_black_24dp.xml b/app/src/main/res/drawable/ic_people.xml similarity index 100% rename from app/src/main/res/drawable/ic_people_black_24dp.xml rename to app/src/main/res/drawable/ic_people.xml diff --git a/app/src/main/res/drawable/ic_person_black_24dp.xml b/app/src/main/res/drawable/ic_person.xml similarity index 100% rename from app/src/main/res/drawable/ic_person_black_24dp.xml rename to app/src/main/res/drawable/ic_person.xml diff --git a/app/src/main/res/drawable/ic_pets_black_24dp.xml b/app/src/main/res/drawable/ic_pets.xml similarity index 100% rename from app/src/main/res/drawable/ic_pets_black_24dp.xml rename to app/src/main/res/drawable/ic_pets.xml diff --git a/app/src/main/res/drawable/ic_picture_in_picture_black_24dp.xml b/app/src/main/res/drawable/ic_picture_in_picture.xml similarity index 100% rename from app/src/main/res/drawable/ic_picture_in_picture_black_24dp.xml rename to app/src/main/res/drawable/ic_picture_in_picture.xml diff --git a/app/src/main/res/drawable/ic_play_arrow_black_24dp.xml b/app/src/main/res/drawable/ic_play_arrow.xml similarity index 100% rename from app/src/main/res/drawable/ic_play_arrow_black_24dp.xml rename to app/src/main/res/drawable/ic_play_arrow.xml diff --git a/app/src/main/res/drawable/ic_playlist_add_black_24dp.xml b/app/src/main/res/drawable/ic_playlist_add.xml similarity index 100% rename from app/src/main/res/drawable/ic_playlist_add_black_24dp.xml rename to app/src/main/res/drawable/ic_playlist_add.xml diff --git a/app/src/main/res/drawable/ic_playlist_add_check_black_24dp.xml b/app/src/main/res/drawable/ic_playlist_add_check.xml similarity index 100% rename from app/src/main/res/drawable/ic_playlist_add_check_black_24dp.xml rename to app/src/main/res/drawable/ic_playlist_add_check.xml diff --git a/app/src/main/res/drawable/ic_playlist_play_white_24dp.xml b/app/src/main/res/drawable/ic_playlist_play.xml similarity index 100% rename from app/src/main/res/drawable/ic_playlist_play_white_24dp.xml rename to app/src/main/res/drawable/ic_playlist_play.xml diff --git a/app/src/main/res/drawable/ic_previous_white_24dp.xml b/app/src/main/res/drawable/ic_previous.xml similarity index 100% rename from app/src/main/res/drawable/ic_previous_white_24dp.xml rename to app/src/main/res/drawable/ic_previous.xml diff --git a/app/src/main/res/drawable/ic_public_black_24dp.xml b/app/src/main/res/drawable/ic_public.xml similarity index 100% rename from app/src/main/res/drawable/ic_public_black_24dp.xml rename to app/src/main/res/drawable/ic_public.xml diff --git a/app/src/main/res/drawable/ic_radio_black_24dp.xml b/app/src/main/res/drawable/ic_radio.xml similarity index 100% rename from app/src/main/res/drawable/ic_radio_black_24dp.xml rename to app/src/main/res/drawable/ic_radio.xml diff --git a/app/src/main/res/drawable/ic_refresh_black_24dp.xml b/app/src/main/res/drawable/ic_refresh.xml similarity index 100% rename from app/src/main/res/drawable/ic_refresh_black_24dp.xml rename to app/src/main/res/drawable/ic_refresh.xml diff --git a/app/src/main/res/drawable/ic_repeat_white_24dp.xml b/app/src/main/res/drawable/ic_repeat.xml similarity index 100% rename from app/src/main/res/drawable/ic_repeat_white_24dp.xml rename to app/src/main/res/drawable/ic_repeat.xml diff --git a/app/src/main/res/drawable/ic_replay_white_24dp.xml b/app/src/main/res/drawable/ic_replay.xml similarity index 100% rename from app/src/main/res/drawable/ic_replay_white_24dp.xml rename to app/src/main/res/drawable/ic_replay.xml diff --git a/app/src/main/res/drawable/ic_restaurant_black_24dp.xml b/app/src/main/res/drawable/ic_restaurant.xml similarity index 100% rename from app/src/main/res/drawable/ic_restaurant_black_24dp.xml rename to app/src/main/res/drawable/ic_restaurant.xml diff --git a/app/src/main/res/drawable/ic_rss_feed_black_24dp.xml b/app/src/main/res/drawable/ic_rss_feed.xml similarity index 100% rename from app/src/main/res/drawable/ic_rss_feed_black_24dp.xml rename to app/src/main/res/drawable/ic_rss_feed.xml diff --git a/app/src/main/res/drawable/ic_save_black_24dp.xml b/app/src/main/res/drawable/ic_save.xml similarity index 100% rename from app/src/main/res/drawable/ic_save_black_24dp.xml rename to app/src/main/res/drawable/ic_save.xml diff --git a/app/src/main/res/drawable/ic_school_black_24dp.xml b/app/src/main/res/drawable/ic_school.xml similarity index 100% rename from app/src/main/res/drawable/ic_school_black_24dp.xml rename to app/src/main/res/drawable/ic_school.xml diff --git a/app/src/main/res/drawable/ic_screen_rotation_white_24dp.xml b/app/src/main/res/drawable/ic_screen_rotation.xml similarity index 100% rename from app/src/main/res/drawable/ic_screen_rotation_white_24dp.xml rename to app/src/main/res/drawable/ic_screen_rotation.xml diff --git a/app/src/main/res/drawable/ic_search_black_24dp.xml b/app/src/main/res/drawable/ic_search.xml similarity index 100% rename from app/src/main/res/drawable/ic_search_black_24dp.xml rename to app/src/main/res/drawable/ic_search.xml diff --git a/app/src/main/res/drawable/ic_search_add_black_24dp.xml b/app/src/main/res/drawable/ic_search_add.xml similarity index 100% rename from app/src/main/res/drawable/ic_search_add_black_24dp.xml rename to app/src/main/res/drawable/ic_search_add.xml diff --git a/app/src/main/res/drawable/ic_settings_black_24dp.xml b/app/src/main/res/drawable/ic_settings.xml similarity index 100% rename from app/src/main/res/drawable/ic_settings_black_24dp.xml rename to app/src/main/res/drawable/ic_settings.xml diff --git a/app/src/main/res/drawable/ic_settings_backup_restore_white_24dp.xml b/app/src/main/res/drawable/ic_settings_backup_restore.xml similarity index 100% rename from app/src/main/res/drawable/ic_settings_backup_restore_white_24dp.xml rename to app/src/main/res/drawable/ic_settings_backup_restore.xml diff --git a/app/src/main/res/drawable/ic_settings_backup_restore_black_24dp.xml b/app/src/main/res/drawable/ic_settings_backup_restore_black_24dp.xml deleted file mode 100644 index 57f96653687..00000000000 --- a/app/src/main/res/drawable/ic_settings_backup_restore_black_24dp.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_share_black_24dp.xml b/app/src/main/res/drawable/ic_share.xml similarity index 100% rename from app/src/main/res/drawable/ic_share_black_24dp.xml rename to app/src/main/res/drawable/ic_share.xml diff --git a/app/src/main/res/drawable/ic_shopping_cart_black_24dp.xml b/app/src/main/res/drawable/ic_shopping_cart.xml similarity index 100% rename from app/src/main/res/drawable/ic_shopping_cart_black_24dp.xml rename to app/src/main/res/drawable/ic_shopping_cart.xml diff --git a/app/src/main/res/drawable/ic_shuffle_white_24dp.xml b/app/src/main/res/drawable/ic_shuffle.xml similarity index 100% rename from app/src/main/res/drawable/ic_shuffle_white_24dp.xml rename to app/src/main/res/drawable/ic_shuffle.xml diff --git a/app/src/main/res/drawable/ic_sort_black_24dp.xml b/app/src/main/res/drawable/ic_sort.xml similarity index 100% rename from app/src/main/res/drawable/ic_sort_black_24dp.xml rename to app/src/main/res/drawable/ic_sort.xml diff --git a/app/src/main/res/drawable/ic_stars_black_24dp.xml b/app/src/main/res/drawable/ic_stars.xml similarity index 100% rename from app/src/main/res/drawable/ic_stars_black_24dp.xml rename to app/src/main/res/drawable/ic_stars.xml diff --git a/app/src/main/res/drawable/ic_subtitles_white_24dp.xml b/app/src/main/res/drawable/ic_subtitles.xml similarity index 100% rename from app/src/main/res/drawable/ic_subtitles_white_24dp.xml rename to app/src/main/res/drawable/ic_subtitles.xml diff --git a/app/src/main/res/drawable/ic_telescope_black_24dp.xml b/app/src/main/res/drawable/ic_telescope.xml similarity index 100% rename from app/src/main/res/drawable/ic_telescope_black_24dp.xml rename to app/src/main/res/drawable/ic_telescope.xml diff --git a/app/src/main/res/drawable/ic_thumb_down_black_24dp.xml b/app/src/main/res/drawable/ic_thumb_down.xml similarity index 100% rename from app/src/main/res/drawable/ic_thumb_down_black_24dp.xml rename to app/src/main/res/drawable/ic_thumb_down.xml diff --git a/app/src/main/res/drawable/ic_thumb_up_black_24dp.xml b/app/src/main/res/drawable/ic_thumb_up.xml similarity index 100% rename from app/src/main/res/drawable/ic_thumb_up_black_24dp.xml rename to app/src/main/res/drawable/ic_thumb_up.xml diff --git a/app/src/main/res/drawable/ic_trending_up_black_24dp.xml b/app/src/main/res/drawable/ic_trending_up.xml similarity index 100% rename from app/src/main/res/drawable/ic_trending_up_black_24dp.xml rename to app/src/main/res/drawable/ic_trending_up.xml diff --git a/app/src/main/res/drawable/ic_tv_black_24dp.xml b/app/src/main/res/drawable/ic_tv.xml similarity index 100% rename from app/src/main/res/drawable/ic_tv_black_24dp.xml rename to app/src/main/res/drawable/ic_tv.xml diff --git a/app/src/main/res/drawable/ic_videogame_asset_black_24dp.xml b/app/src/main/res/drawable/ic_videogame_asset.xml similarity index 100% rename from app/src/main/res/drawable/ic_videogame_asset_black_24dp.xml rename to app/src/main/res/drawable/ic_videogame_asset.xml diff --git a/app/src/main/res/drawable/ic_volume_down_white_24dp.xml b/app/src/main/res/drawable/ic_volume_down.xml similarity index 100% rename from app/src/main/res/drawable/ic_volume_down_white_24dp.xml rename to app/src/main/res/drawable/ic_volume_down.xml diff --git a/app/src/main/res/drawable/ic_volume_mute_white_24dp.xml b/app/src/main/res/drawable/ic_volume_mute.xml similarity index 100% rename from app/src/main/res/drawable/ic_volume_mute_white_24dp.xml rename to app/src/main/res/drawable/ic_volume_mute.xml diff --git a/app/src/main/res/drawable/ic_volume_off_white_24dp.xml b/app/src/main/res/drawable/ic_volume_off.xml similarity index 98% rename from app/src/main/res/drawable/ic_volume_off_white_24dp.xml rename to app/src/main/res/drawable/ic_volume_off.xml index 2f8d6cfb430..7700239a377 100644 --- a/app/src/main/res/drawable/ic_volume_off_white_24dp.xml +++ b/app/src/main/res/drawable/ic_volume_off.xml @@ -7,4 +7,4 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_volume_up_black_24dp.xml b/app/src/main/res/drawable/ic_volume_up.xml similarity index 94% rename from app/src/main/res/drawable/ic_volume_up_black_24dp.xml rename to app/src/main/res/drawable/ic_volume_up.xml index 2ee5bce4333..aaaf8498333 100644 --- a/app/src/main/res/drawable/ic_volume_up_black_24dp.xml +++ b/app/src/main/res/drawable/ic_volume_up.xml @@ -1,6 +1,7 @@ - + - + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-land/activity_player_queue_control.xml b/app/src/main/res/layout-land/activity_player_queue_control.xml index b106e743788..4b79d92f60a 100644 --- a/app/src/main/res/layout-land/activity_player_queue_control.xml +++ b/app/src/main/res/layout-land/activity_player_queue_control.xml @@ -12,8 +12,8 @@ android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="wrap_content" - android:theme="@style/ThemeOverlay.AppCompat.ActionBar" - app:popupTheme="@style/ThemeOverlay.AppCompat.ActionBar"> + android:theme="@style/ThemeOverlay.AppCompat.DayNight.ActionBar" + app:popupTheme="@style/ThemeOverlay.AppCompat.DayNight.ActionBar"> @@ -138,7 +139,7 @@ android:focusable="true" android:scaleType="fitCenter" android:tint="?attr/colorAccent" - app:srcCompat="@drawable/ic_pause_white_24dp" + app:srcCompat="@drawable/ic_pause" tools:ignore="ContentDescription" /> @@ -263,7 +264,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" - android:background="@drawable/player_controls_background" android:gravity="center" android:orientation="horizontal" android:paddingLeft="16dp" 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 b037ca58449..d4f1ccc3d68 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 @@ -199,7 +199,7 @@ android:layout_gravity="top|end" android:layout_marginTop="11dp" android:layout_marginEnd="10dp" - app:srcCompat="@drawable/ic_expand_more_white_24dp" + app:srcCompat="@drawable/ic_expand_more" tools:ignore="ContentDescription" /> @@ -333,7 +333,7 @@ android:text="@string/rss_button_title" android:textSize="12sp" android:theme="@style/RedButton" - app:drawableLeftCompat="@drawable/ic_rss_feed_white_24dp" + app:drawableLeftCompat="@drawable/ic_rss_feed" tools:ignore="RtlHardcoded" android:visibility="gone"/>--> @@ -367,7 +367,7 @@ android:layout_height="@dimen/video_item_detail_like_image_height" android:layout_below="@id/detail_view_count_view" android:contentDescription="@string/detail_likes_img_view_description" - app:srcCompat="?attr/ic_thumb_up" /> + app:srcCompat="@drawable/ic_thumb_up" /> + app:drawableTopCompat="@drawable/ic_playlist_add" /> + app:drawableTopCompat="@drawable/ic_headset" /> + app:drawableTopCompat="@drawable/ic_picture_in_picture" /> + app:drawableTopCompat="@drawable/ic_file_download" /> @@ -529,7 +529,7 @@ android:paddingVertical="@dimen/detail_control_padding" android:text="@string/share" android:textSize="@dimen/detail_control_text_size" - app:drawableTopCompat="?attr/ic_share" /> + app:drawableTopCompat="@drawable/ic_share" /> + app:drawableTopCompat="@drawable/ic_language" /> + app:drawableTopCompat="@drawable/ic_cast" /> @@ -605,6 +605,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom|center" + app:tabIndicatorGravity="top" app:tabIconTint="?attr/colorAccent" app:tabBackground="?attr/windowBackground" app:tabGravity="fill" @@ -612,14 +613,12 @@ - - - + android:layout_weight="3" /> diff --git a/app/src/main/res/layout-large-land/player.xml b/app/src/main/res/layout-large-land/player.xml index 07f3ae755c4..de15b9da914 100644 --- a/app/src/main/res/layout-large-land/player.xml +++ b/app/src/main/res/layout-large-land/player.xml @@ -5,7 +5,8 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/black" - android:gravity="center"> + android:gravity="center" + android:theme="@style/WhiteTintTheme"> @@ -205,7 +208,8 @@ android:paddingBottom="3dp" android:scaleType="fitCenter" android:visibility="gone" - app:srcCompat="@drawable/ic_format_list_numbered_white_24" + app:tint="@color/white" + app:srcCompat="@drawable/ic_format_list_numbered" tools:ignore="ContentDescription,RtlHardcoded" tools:visibility="visible" /> @@ -218,7 +222,8 @@ android:focusable="true" android:padding="@dimen/player_main_buttons_padding" android:scaleType="fitXY" - app:srcCompat="@drawable/ic_expand_more_white_24dp" + app:tint="@color/white" + app:srcCompat="@drawable/ic_expand_more" tools:ignore="ContentDescription,RtlHardcoded" /> @@ -282,7 +287,8 @@ android:focusable="true" android:padding="@dimen/player_main_buttons_padding" android:scaleType="fitXY" - app:srcCompat="@drawable/ic_cast_white_24dp" + app:tint="@color/white" + app:srcCompat="@drawable/ic_cast" tools:ignore="RtlHardcoded" /> @@ -415,7 +425,8 @@ android:padding="@dimen/player_main_buttons_padding" android:scaleType="fitCenter" android:visibility="gone" - app:srcCompat="@drawable/ic_fullscreen_white_24dp" + app:tint="@color/white" + app:srcCompat="@drawable/ic_fullscreen" tools:ignore="ContentDescription,RtlHardcoded" tools:visibility="visible" /> @@ -438,7 +449,8 @@ android:clickable="true" android:focusable="true" android:scaleType="fitCenter" - app:srcCompat="@drawable/ic_previous_white_24dp" + app:tint="@color/white" + app:srcCompat="@drawable/ic_previous" tools:ignore="ContentDescription" /> @@ -449,7 +461,8 @@ android:layout_weight="1" android:background="?attr/selectableItemBackgroundBorderless" android:scaleType="fitCenter" - app:srcCompat="@drawable/ic_pause_white_24dp" + app:tint="@color/white" + app:srcCompat="@drawable/ic_pause" tools:ignore="ContentDescription" /> @@ -474,7 +488,7 @@ android:layout_width="380dp" android:layout_height="match_parent" android:layout_alignParentEnd="true" - android:background="?attr/queue_background_color" + android:background="@color/queue_background_color" android:visibility="gone" tools:visibility="visible"> @@ -514,7 +528,8 @@ android:focusable="true" android:padding="10dp" android:scaleType="fitXY" - app:srcCompat="?attr/ic_close" /> + app:tint="@color/white" + app:srcCompat="@drawable/ic_close" /> @@ -556,6 +571,7 @@ android:layout_height="match_parent" android:layout_below="@id/itemsListControl" android:scrollbars="vertical" + android:theme="@style/PlayQueueItemTextTheme" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" tools:listitem="@layout/play_queue_item" /> @@ -580,7 +596,7 @@ android:padding="15dp" android:visibility="gone" tools:ignore="ContentDescription" - tools:src="@drawable/ic_fast_rewind_white_24dp" + tools:src="@drawable/ic_fast_rewind" tools:visibility="visible" /> @@ -629,7 +645,7 @@ android:layout_height="70dp" android:layout_centerInParent="true" tools:ignore="ContentDescription" - tools:src="@drawable/ic_volume_up_white_24dp" /> + tools:src="@drawable/ic_volume_up" /> + tools:src="@drawable/ic_brightness_high" /> + android:theme="@style/ThemeOverlay.AppCompat.DayNight.ActionBar" + app:popupTheme="@style/ThemeOverlay.AppCompat.DayNight.ActionBar"> + android:layout_height="wrap_content" + app:tabTextColor="@color/white" + app:tabIndicatorColor="@color/white" /> diff --git a/app/src/main/res/layout/activity_downloader.xml b/app/src/main/res/layout/activity_downloader.xml index d91b943e7e5..e3b56e282b5 100644 --- a/app/src/main/res/layout/activity_downloader.xml +++ b/app/src/main/res/layout/activity_downloader.xml @@ -7,7 +7,7 @@ layout="@layout/toolbar_layout" android:id="@+id/toolbar_layout" /> - diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 6d25ed097a0..97ccd199ecb 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -8,7 +8,7 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - - + app:layout_behavior="org.schabi.newpipe.player.event.CustomBottomSheetBehavior" /> diff --git a/app/src/main/res/layout/activity_player_queue_control.xml b/app/src/main/res/layout/activity_player_queue_control.xml index c7c86a0699c..ec47992bb5b 100644 --- a/app/src/main/res/layout/activity_player_queue_control.xml +++ b/app/src/main/res/layout/activity_player_queue_control.xml @@ -12,8 +12,8 @@ android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="wrap_content" - android:theme="@style/ThemeOverlay.AppCompat.ActionBar" - app:popupTheme="@style/ThemeOverlay.AppCompat.ActionBar"> + android:theme="@style/ThemeOverlay.AppCompat.DayNight.ActionBar" + app:popupTheme="@style/ThemeOverlay.AppCompat.DayNight.ActionBar"> @@ -104,7 +105,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" - android:background="@drawable/player_controls_background" android:gravity="center" android:orientation="horizontal" android:paddingLeft="12dp" @@ -180,7 +180,7 @@ android:focusable="true" android:scaleType="fitXY" android:tint="?attr/colorAccent" - app:srcCompat="@drawable/ic_repeat_white_24dp" + app:srcCompat="@drawable/ic_repeat" tools:ignore="ContentDescription" /> diff --git a/app/src/main/res/layout/activity_recaptcha.xml b/app/src/main/res/layout/activity_recaptcha.xml index 65428d9f14a..12339d11995 100644 --- a/app/src/main/res/layout/activity_recaptcha.xml +++ b/app/src/main/res/layout/activity_recaptcha.xml @@ -11,10 +11,7 @@ android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" android:gravity="center_vertical" - android:minHeight="?attr/actionBarSize" - android:theme="@style/ThemeOverlay.AppCompat.ActionBar" - app:popupTheme="@style/ThemeOverlay.AppCompat.ActionBar" - app:titleTextAppearance="@style/Toolbar.Title" /> + android:minHeight="?attr/actionBarSize" /> + tools:src="@drawable/ic_asterisk" /> + android:theme="@style/ContrastToolbarTheme"> diff --git a/app/src/main/res/layout/dialog_playlists.xml b/app/src/main/res/layout/dialog_playlists.xml index 77b884f4f33..7564296b385 100644 --- a/app/src/main/res/layout/dialog_playlists.xml +++ b/app/src/main/res/layout/dialog_playlists.xml @@ -20,7 +20,7 @@ android:layout_centerVertical="true" android:layout_marginLeft="12dp" android:layout_marginRight="12dp" - app:srcCompat="?attr/ic_playlist_add" + app:srcCompat="@drawable/ic_playlist_add" tools:ignore="ContentDescription,RtlHardcoded" /> diff --git a/app/src/main/res/layout/feed_group_add_new_item.xml b/app/src/main/res/layout/feed_group_add_new_item.xml index 14ee19ad48c..882b38870f5 100644 --- a/app/src/main/res/layout/feed_group_add_new_item.xml +++ b/app/src/main/res/layout/feed_group_add_new_item.xml @@ -24,7 +24,7 @@ android:layout_height="14dp" android:layout_gravity="center" android:scaleType="centerInside" - app:srcCompat="?attr/ic_add" + app:srcCompat="@drawable/ic_add" tools:ignore="ContentDescription" /> + tools:src="@drawable/ic_fastfood" /> + tools:src="@drawable/ic_kiosk_hot" /> \ No newline at end of file diff --git a/app/src/main/res/layout/feed_import_export_group.xml b/app/src/main/res/layout/feed_import_export_group.xml index 33d50f59337..4a0b46692f2 100644 --- a/app/src/main/res/layout/feed_import_export_group.xml +++ b/app/src/main/res/layout/feed_import_export_group.xml @@ -53,7 +53,7 @@ android:layout_width="24dp" android:layout_height="24dp" android:layout_marginRight="16dp" - app:srcCompat="?attr/ic_expand_more" + app:srcCompat="@drawable/ic_expand_more" tools:ignore="ContentDescription,RtlHardcoded" /> diff --git a/app/src/main/res/layout/fragment_about.xml b/app/src/main/res/layout/fragment_about.xml index 77f94068531..3211f3bd968 100644 --- a/app/src/main/res/layout/fragment_about.xml +++ b/app/src/main/res/layout/fragment_about.xml @@ -15,16 +15,14 @@ android:paddingBottom="@dimen/activity_vertical_margin">