@@ -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
-[](http://www.gnu.org/licenses/gpl-3.0.en.html)
+[](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 685202bf3..fabafbfd1 100644
--- a/README.ja.md
+++ b/README.ja.md
@@ -9,7 +9,7 @@
-
+
@@ -143,7 +143,7 @@ NewPipe プロジェクトはメディアウェブサービスを使用する上
## ライセンス
-[](http://www.gnu.org/licenses/gpl-3.0.en.html)
+[](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 8bbda9b5d..3ee9ae631 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
-[](http://www.gnu.org/licenses/gpl-3.0.en.html)
+[](https://www.gnu.org/licenses/gpl-3.0.en.html)
NewPipe는 자유 소프트웨어입니다: 당신의 마음대로 이것을 사용하고, 연구하고, 공유하고, 개선할 수 있습니다.
구체적으로 당신은 자유 소프트웨어 재단에서 발행되는, 버전 3 또는 (당신의 선택에 따라)이후 버전의,
diff --git a/README.md b/README.md
index 27ede1c03..9eec45693 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
-[](http://www.gnu.org/licenses/gpl-3.0.en.html)
+[](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 033b6f0f7..251c904b7 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
-[](http://www.gnu.org/licenses/gpl-3.0.en.html)
+[](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 e28cd8cd6..1d39422fc 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ţă
-[](http://www.gnu.org/licenses/gpl-3.0.en.html)
+[](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 f0bba8b79..703886f12 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
-[](http://www.gnu.org/licenses/gpl-3.0.en.html)
+[](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 88ed8998e..500f5c052 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -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'
+/** 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.fynngodau:NewPipeExtractor:14f6f1b7c3d4a98ac0a74a9f6d16b05cb96c0c91'
+
+/** Checkstyle **/
+ checkstyle "com.puppycrawl.tools:checkstyle:${checkstyleVersion}"
+ ktlint 'com.pinterest:ktlint:0.40.0'
+
+/** Kotlin **/
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlin_version}"
- implementation "frankiesardo:icepick:${icepickVersion}"
- kapt "frankiesardo:icepick-processor:${icepickVersion}"
-
- 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}"
-
- debugImplementation "com.squareup.leakcanary:leakcanary-android:${leakCanaryVersion}"
- implementation "com.squareup.leakcanary:leakcanary-object-watcher-android:${leakCanaryVersion}"
- implementation "com.squareup.leakcanary:plumber-android:${leakCanaryVersion}"
-
- implementation "androidx.multidex:multidex:2.0.1"
-
- // NewPipe dependencies
- // You can use a local version by uncommenting a few lines in settings.gradle
- implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.21.0'
- implementation "com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751"
-
- implementation "org.jsoup:jsoup:1.13.1"
-
- //noinspection GradleDependency --> do not update okhttp to keep supporting Android 4.4 users
- implementation "com.squareup.okhttp3:okhttp:3.12.13"
-
- implementation "com.google.android.exoplayer:exoplayer:${exoPlayerVersion}"
- implementation "com.google.android.exoplayer:extension-mediasession:${exoPlayerVersion}"
-
- implementation "com.google.android.material:material:1.2.1"
-
- 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"
+/** 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.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.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'
- implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
+/** 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}"
+
+ // Metadata generator for service descriptors
+ compileOnly "com.google.auto.service:auto-service-annotations:${googleAutoServiceVersion}"
+ kapt "com.google.auto.service:auto-service:${googleAutoServiceVersion}"
+
+ // 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 7e2ff69b8..d5d223ff2 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 @@ package org.schabi.newpipe.settings;
import android.os.Bundle;
-import androidx.annotation.Nullable;
import androidx.preference.Preference;
import org.schabi.newpipe.R;
@@ -11,8 +10,8 @@ import leakcanary.LeakCanary;
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 class DebugSettingsFragment extends BasePreferenceFragment {
throw new RuntimeException();
});
}
-
- @Override
- public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) {
- addPreferencesFromResource(R.xml.debug_settings);
- }
}
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 ec28be237..000000000
--- 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 000000000..2f015a049
--- /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 f5bf4df19..000000000
--- 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 000000000..d72ecf894
--- /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 b0241049d..000000000
--- 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 000000000..bdb3edabd
--- /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 60b1e168c..000000000
--- 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 000000000..c5b9618fe
--- /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/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java
index 1e50a77f0..71739ba3d 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.BackPressable;
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 final class VideoDetailFragment
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 final class VideoDetailFragment
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);
@@ -927,11 +927,11 @@ public final class VideoDetailFragment
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);
- tabContentDescriptions.add(R.string.related_streams_tab_description);
+ tabContentDescriptions.add(R.string.related_items_tab_description);
}
if (showDescription) {
@@ -974,14 +974,14 @@ public final class VideoDetailFragment
}
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 @@ public final class VideoDetailFragment
}
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 final class VideoDetailFragment
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 final class VideoDetailFragment
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 final class VideoDetailFragment
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();
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 3c37bd128..38fdbccab 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.Arrays;
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 abstract class BaseListFragment extends BaseStateFragment
/**
* 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 @@ public abstract class BaseListFragment extends BaseStateFragment
return;
}
- final ArrayList entries = new ArrayList<>();
+ final List entries = new ArrayList<>();
if (PlayerHolder.getType() != null) {
entries.add(StreamDialogEntry.enqueue);
@@ -361,7 +362,7 @@ public abstract class BaseListFragment extends BaseStateFragment
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 @@ public abstract class BaseListFragment extends BaseStateFragment
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/playlist/PlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java
index d0f90ee6b..a729b7cc9 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
@@ -422,7 +422,9 @@ public class PlaylistFragment extends BaseListInfoFragment {
@Override
public void setTitle(final String title) {
super.setTitle(title);
- headerBinding.playlistTitleView.setText(title);
+ if (headerBinding != null) {
+ headerBinding.playlistTitleView.setText(title);
+ }
}
private void onBookmarkClicked() {
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 5f7baa358..b52aaf2f8 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 class SearchFragment extends BaseListFragment 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;
}
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 902df94bc..a66b7d569 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.preference.PreferenceManager;
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 class RelatedVideosFragment extends BaseListInfoFragment loadResult(final boolean forceLoad) {
- return Single.fromCallable(() -> relatedStreamInfo);
+ protected Single loadResult(final boolean forceLoad) {
+ return Single.fromCallable(() -> relatedItemInfo);
}
@Override
@@ -120,7 +120,7 @@ public class RelatedVideosFragment extends BaseListInfoFragment= 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");
}
}
@@ -629,10 +632,10 @@ public final class Player implements
&& 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);
@@ -643,10 +646,10 @@ public final class Player implements
&& !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);
@@ -711,11 +714,7 @@ public final class Player implements
// Android TV: without it focus will frame the whole player
binding.playPauseButton.requestFocus();
- if (simpleExoPlayer.getPlayWhenReady()) {
- play();
- } else {
- pause();
- }
+ playPause();
}
NavigationHelper.sendPlayerStartedEvent(context);
}
@@ -1658,7 +1657,7 @@ public final class Player implements
saveWasPlaying();
if (isPlaying()) {
- simpleExoPlayer.setPlayWhenReady(false);
+ simpleExoPlayer.pause();
}
showControls(0);
@@ -1674,7 +1673,7 @@ public final class Player implements
seekTo(seekBar.getProgress());
if (wasPlaying || simpleExoPlayer.getDuration() == seekBar.getProgress()) {
- simpleExoPlayer.setPlayWhenReady(true);
+ simpleExoPlayer.play();
}
binding.playbackCurrentTime.setText(getTimeString(seekBar.getProgress()));
@@ -1692,7 +1691,7 @@ public final class Player implements
}
public void saveWasPlaying() {
- this.wasPlaying = simpleExoPlayer.getPlayWhenReady();
+ this.wasPlaying = getPlayWhenReady();
}
//endregion
@@ -1917,7 +1916,7 @@ public final class Player implements
}
@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 + "]");
@@ -1961,7 +1960,8 @@ public final class Player implements
if (currentState == STATE_BLOCKED) {
changeState(STATE_BUFFERING);
}
- simpleExoPlayer.prepare(mediaSource);
+ simpleExoPlayer.setMediaSource(mediaSource);
+ simpleExoPlayer.prepare();
}
public void changeState(final int state) {
@@ -2360,6 +2360,12 @@ public final class Player implements
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) {
@@ -2424,10 +2430,8 @@ public final class Player implements
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();
@@ -2632,16 +2636,6 @@ public final class Player implements
simpleExoPlayer.seekToDefaultPosition();
}
}
-
- @Override // exoplayer override
- public void onSeekProcessed() {
- if (DEBUG) {
- Log.d(TAG, "ExoPlayer - onSeekProcessed() called");
- }
- if (isPrepared) {
- saveStreamProgressState();
- }
- }
//endregion
@@ -2669,7 +2663,7 @@ public final class Player implements
}
}
- simpleExoPlayer.setPlayWhenReady(true);
+ simpleExoPlayer.play();
saveStreamProgressState();
}
@@ -2682,7 +2676,7 @@ public final class Player implements
}
audioReactor.abandonAudioFocus();
- simpleExoPlayer.setPlayWhenReady(false);
+ simpleExoPlayer.pause();
saveStreamProgressState();
}
@@ -2691,7 +2685,7 @@ public final class Player implements
Log.d(TAG, "onPlayPause() called");
}
- if (isPlaying()) {
+ if (getPlayWhenReady()) {
pause();
} else {
play();
@@ -4017,6 +4011,10 @@ public final class Player implements
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 989c78c57..29ae7c5c3 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 61023875c..a5de56e75 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 class CustomBottomSheetBehavior extends BottomSheetBehavior
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/helper/AudioReactor.java b/app/src/main/java/org/schabi/newpipe/player/helper/AudioReactor.java
index 13ee24e16..c4b21f203 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 @@ public class AudioReactor implements AudioManager.OnAudioFocusChangeListener, An
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 class AudioReactor implements AudioManager.OnAudioFocusChangeListener, An
//////////////////////////////////////////////////////////////////////////*/
@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 ba9a2f1ec..fe0233508 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.DefaultLoadControl;
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 @@ public class LoadController implements LoadControl {
final DefaultLoadControl.Builder builder = new DefaultLoadControl.Builder();
builder.setBufferDurationsMs(minimumPlaybackBufferMs, optimalPlaybackBufferMs,
initialPlaybackBufferMs, initialPlaybackBufferMs);
- internalLoadControl = builder.createDefaultLoadControl();
+ internalLoadControl = builder.build();
}
/*//////////////////////////////////////////////////////////////////////////
@@ -47,9 +47,9 @@ public class LoadController implements LoadControl {
}
@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 class LoadController implements LoadControl {
@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 b0c641433..c7f1f9c8c 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 class MediaSessionManager {
@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 4324fcd0a..0a3ea908a 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.Player.RepeatMode;
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 final class PlayerHelper {
* 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 final class PlayerHelper {
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 final class PlayerHelper {
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 d70707fdb..389be7062 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.RendererCapabilities.Capabilities;
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 class CustomTrackSelector extends DefaultTrackSelector {
@Override
@Nullable
- protected Pair selectTextTrack(
+ protected Pair selectTextTrack(
final TrackGroupArray groups,
@NonNull final int[][] formatSupport,
@NonNull final Parameters params,
@@ -86,7 +86,7 @@ public class CustomTrackSelector extends DefaultTrackSelector {
}
}
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 e06c0ff82..a6dcadd5e 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.NonNull;
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 @@ public interface PlaybackResolver extends Resolver {
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 @@ public interface PlaybackResolver extends Resolver {
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 a2b3a1d3d..245a85e71 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 android.net.Uri;
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 org.schabi.newpipe.util.ListHelper;
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 class VideoPlaybackResolver implements PlaybackResolver {
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 26f67c15f..1e1b03b4f 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java
@@ -7,7 +7,6 @@ import android.os.Bundle;
import android.provider.Settings;
import android.widget.Toast;
-import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.preference.Preference;
@@ -22,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)
@@ -59,11 +58,6 @@ public class AppearanceSettingsFragment extends BasePreferenceFragment {
}
}
- @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) {
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 dbe05bbd2..ad8400401 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java
@@ -10,7 +10,6 @@ import android.util.Log;
import android.widget.Toast;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
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 class ContentSettingsFragment extends BasePreferenceFragment {
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();
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 8742f0937..abd543643 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/DownloadSettingsFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/DownloadSettingsFragment.java
@@ -11,7 +11,6 @@ import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
-import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.preference.Preference;
@@ -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 class DownloadSettingsFragment extends BasePreferenceFragment {
});
}
- @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 89fabbdde..cb6ce263d 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.os.Bundle;
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 class HistorySettingsFragment extends BasePreferenceFragment {
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/SettingsActivity.java b/app/src/main/java/org/schabi/newpipe/settings/SettingsActivity.java
index 4de166a55..68908fc92 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 @@ public class SettingsActivity extends AppCompatActivity
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 class SettingsActivity extends AppCompatActivity
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 f25b25df2..0ca15e245 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 @@ package org.schabi.newpipe.settings;
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 5eca99822..c0d274fe0 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.provider.Settings;
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 @@ public class VideoAudioSettingsFragment extends BasePreferenceFragment {
}
}
- @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 e50c858ca..045e574be 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.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.core.graphics.drawable.DrawableCompat;
@@ -41,9 +42,8 @@ public class NotificationActionsPreference extends Preference {
}
- private NotificationSlot[] notificationSlots;
-
- private List compactSlots;
+ @Nullable private NotificationSlot[] notificationSlots = null;
+ @Nullable private List compactSlots = null;
////////////////////////////////////////////////////////////////////////////
// Lifecycle
@@ -85,19 +85,22 @@ public class NotificationActionsPreference extends Preference {
////////////////////////////////////////////////////////////////////////////
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);
+ }
+
+ editor.apply();
}
-
- for (int i = 0; i < 5; i++) {
- editor.putInt(getContext().getString(NotificationConstants.SLOT_PREF_KEYS[i]),
- notificationSlots[i].selectedAction);
- }
-
- editor.apply();
}
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 52069fd0e..0704dad66 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,13 @@ 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");
+
private DeviceUtils() {
}
@@ -88,4 +95,15 @@ public final class DeviceUtils {
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;
+ }
+
}
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 4f4fd5283..df804136a 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 final class NavigationHelper {
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 81e203b1f..f96bb0d54 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.ArrayList;
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/StreamDialogEntry.java b/app/src/main/java/org/schabi/newpipe/util/StreamDialogEntry.java
index 73fee32f7..2d59febc2 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/res/layout-large-land/fragment_video_detail.xml b/app/src/main/res/layout-large-land/fragment_video_detail.xml
index 02bc169e2..d4f1ccc3d 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
@@ -613,14 +613,12 @@
-
-
-
+ android:layout_weight="3" />
diff --git a/app/src/main/res/layout/activity_downloader.xml b/app/src/main/res/layout/activity_downloader.xml
index d91b943e7..e3b56e282 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 6d25ed097..97ccd199e 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/fragment_about.xml b/app/src/main/res/layout/fragment_about.xml
index 77f940685..3211f3bd9 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">
+
diff --git a/app/src/main/res/layout/related_streams_header.xml b/app/src/main/res/layout/related_items_header.xml
similarity index 100%
rename from app/src/main/res/layout/related_streams_header.xml
rename to app/src/main/res/layout/related_items_header.xml
diff --git a/app/src/main/res/layout/settings_layout.xml b/app/src/main/res/layout/settings_layout.xml
index 32c6c6b91..33237d7b0 100644
--- a/app/src/main/res/layout/settings_layout.xml
+++ b/app/src/main/res/layout/settings_layout.xml
@@ -6,14 +6,14 @@
android:orientation="vertical"
tools:context="org.schabi.newpipe.MainActivity">
-
+ android:id="@+id/settings_toolbar_layout"/>
diff --git a/app/src/main/res/layout/settings_notification_action.xml b/app/src/main/res/layout/settings_notification_action.xml
index 72b7cd984..2aacc9e20 100644
--- a/app/src/main/res/layout/settings_notification_action.xml
+++ b/app/src/main/res/layout/settings_notification_action.xml
@@ -8,13 +8,13 @@
+
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index 826870109..1a90ad686 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -697,7 +697,7 @@
لا يوجد تطبيق على جهازك يمكنه فتح هذافصولوصف
- التيارات ذات الصلة
+ التيارات ذات الصلةتعليقاتقم بإيقاف التشغيل لإخفاء وصف الفيديو والمعلومات الإضافيةإظهار الوصف
diff --git a/app/src/main/res/values-b+zh+HANS+CN/strings.xml b/app/src/main/res/values-b+zh+HANS+CN/strings.xml
index 3baa4e2be..54d747ac3 100644
--- a/app/src/main/res/values-b+zh+HANS+CN/strings.xml
+++ b/app/src/main/res/values-b+zh+HANS+CN/strings.xml
@@ -652,7 +652,7 @@
显示简介章节简介
- 相关视频
+ 相关视频评论显示视频描述和其他信息用…打开
diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml
index 2decfb6cc..00ecdf22b 100644
--- a/app/src/main/res/values-bn/strings.xml
+++ b/app/src/main/res/values-bn/strings.xml
@@ -491,7 +491,7 @@
সাম্প্রতিকইন্সট্যান্স ইতোমধ্যে বিদ্যমানডিফল্ট কন্টেন্টের দেশ
- সম্পর্কিত স্ট্রিম
+ সম্পর্কিত স্ট্রিমবর্ণনা দেখাওহ্যাশ গণনা করা হচ্ছেথাম্বনেইল দেখাও
diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml
index 6f6308f8c..248672b7e 100644
--- a/app/src/main/res/values-ca/strings.xml
+++ b/app/src/main/res/values-ca/strings.xml
@@ -669,7 +669,7 @@
El vostre dispositiu no té cap aplicació capaç d\'obrir aquest tipus de contingutForça l\'aturada de l\'aplicacióResol
- Reproduccions en directe relacionades
+ Reproduccions en directe relacionadesAquest vídeo té restriccions d\'edat.
\nDegut a la nova política d\'edat de YouTube, el NewPipe no pot accedir a aquest contingut i per tant no pot reproduir-lo.Desactiveu per amagar la descripció i la informació addicional del vídeo
diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml
index dbcdf951e..03211ab9c 100644
--- a/app/src/main/res/values-cs/strings.xml
+++ b/app/src/main/res/values-cs/strings.xml
@@ -670,7 +670,7 @@
Zobrazit popisOtevřít sNa Vašem zařízení není aplikace, která to umí otevřít
- Podobné strýmy
+ Podobné strýmyVypnout pro skrytí popisu videa a doplňkové informaceZbořit aplikaci
\ No newline at end of file
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index f7f8cd072..c6dda6f1c 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -656,7 +656,7 @@
Deaktiviere diese Option, um Meta-Infofelder mit zusätzlichen Informationen zum Stream-Ersteller, zum Stream-Inhalt oder zu einer Suchanforderung auszublenden.KapitelBeschreibung
- Verwandte Streams
+ Verwandte StreamsKommentareAusschalten, um Videobeschreibung und Zusatzinformationen auszublendenBeschreibung anzeigen
diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml
index a4f219d21..d96436101 100644
--- a/app/src/main/res/values-el/strings.xml
+++ b/app/src/main/res/values-el/strings.xml
@@ -656,7 +656,7 @@
Εμφάνιση μεταδεδομένωνΚεφάλαιαΠεριγραφή
- Σχετιζόμενες ροές
+ Σχετιζόμενες ροέςΣχόλιαΑπενεργοποιήστε για απόκρυψη περιγραφής και πρόσθετων πληροφοριώνΕμφάνιση περιγραφής
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 729fec623..29f2bf845 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -658,7 +658,7 @@
RecientesCalculando el hashDescripción
- Transmisiones relacionadas
+ Transmisiones relacionadasComentariosNotificaciones sobre el progreso del hashing del vídeoNotificación del hash de vídeo
diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml
index 07cdcadf4..a2cc35f2d 100644
--- a/app/src/main/res/values-eu/strings.xml
+++ b/app/src/main/res/values-eu/strings.xml
@@ -657,7 +657,7 @@
Ez dago zure gailuan hau ireki dezakeen aplikaziorikKapituluakDeskribapena
- Erlazionatutako jarioak
+ Erlazionatutako jarioakIruzkinakDesaktibatu bideoaren deskribapena eta informazio gehigarria ezkutatzekoErakutsi deskribapena
diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml
index b037623b2..57a13288d 100644
--- a/app/src/main/res/values-fi/strings.xml
+++ b/app/src/main/res/values-fi/strings.xml
@@ -658,6 +658,6 @@
Mikään sovellus laitteessasi ei voi avata tätäJaksotKuvaus
- Samankaltaiset striimit
+ Samankaltaiset striimitKommentit
\ No newline at end of file
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 90299ef77..5cef43076 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -661,7 +661,7 @@
Aucune application sur votre appareil ne peut ouvrir ceciChapitresDescription
- Flux associés
+ Flux associésCommentairesDésactiver pour masquer la description de la vidéo et les informations supplémentairesAfficher la description
diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml
index 24a5c4d3a..a515b8cef 100644
--- a/app/src/main/res/values-he/strings.xml
+++ b/app/src/main/res/values-he/strings.xml
@@ -676,7 +676,7 @@
הצגת מידע עלפרקיםתיאור
- תזרימים קשורים
+ תזרימים קשוריםהערותיש לכבות כדי להסתיר תיאורי סרטונים ומידע נוסףהצגת תיאור
diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml
index 530af1ea7..a21a29b00 100644
--- a/app/src/main/res/values-hi/strings.xml
+++ b/app/src/main/res/values-hi/strings.xml
@@ -585,7 +585,7 @@
∞ विडीओ१००+ विडीओविवरण
- संबंधित स्ट्रीमस
+ संबंधित स्ट्रीमसटिप्पणियाँकृपया जांचें लें कि क्या आपके क्रैश पर चर्चा करने वाला मुद्दा पहले से मौजूद है। डुप्लिकेट टिकट बनाते समय, आप हमसे समय लेते हैं जो हम वास्तविक बग को ठीक करने के साथ खर्च कर सकते हैं।गिटहब पर रिपोर्ट करें
diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml
index 5d6fafd82..1f34ba934 100644
--- a/app/src/main/res/values-hr/strings.xml
+++ b/app/src/main/res/values-hr/strings.xml
@@ -664,7 +664,7 @@
NedavniIsključi za skrivanje polja metapodataka s dodatnim podacima o autoru streama, sadržaju streama ili zahtjevu za pretraživanje.Prikaži metapodatke
- Slični videozapisi
+ Slični videozapisiNijedna aplikacija na vašem uređaju ne može to otvoritiPoglavlja videozapisaOpis
diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml
index ec57ea849..9a6570d5e 100644
--- a/app/src/main/res/values-in/strings.xml
+++ b/app/src/main/res/values-in/strings.xml
@@ -647,7 +647,7 @@
Tidak ada apl di perangkat Anda yang bisa membuka iniChapterDeskripsi
- Stream terkait
+ Stream terkaitKomentarNonaktifkan untuk menyembunyikan deskripsi dan informasi tambahanTampilkan deskripsi
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index a62c2bbb2..9ca1ade5a 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -654,7 +654,7 @@
RecenteDisattiva per nascondere i riquadri con informazioni aggiuntive sul contenuto, sul suo creatore o su una richiesta di ricerca.Mostra meta-informazioni
- Contenuti correlati
+ Contenuti correlatiCapitoliDescrizioneCommenti
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index 8f83e28f9..7efaabb90 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -648,7 +648,7 @@
最近開く説明
- 関連動画
+ 関連動画動画作成者、動画コンテンツ、検索リクエストに関する追加情報を含むメタ情報ボックスを非表示にするにはオフにします。お使いのデバイス上のアプリでは、これを開くことはできませんチャプター
diff --git a/app/src/main/res/values-kmr/strings.xml b/app/src/main/res/values-kmr/strings.xml
index 75ca42bc8..8f03299b1 100644
--- a/app/src/main/res/values-kmr/strings.xml
+++ b/app/src/main/res/values-kmr/strings.xml
@@ -73,7 +73,7 @@
(Ceribandî) Ji bo nepeniya zêde trafîka dakêşanê bi rêya Tor bikişîne (vîdyoyên weşanê hîn piştgirî nabin).Tor bikar bîninTerîf
- Çemên pêwendîdar
+ Çemên pêwendîdarÎroveHejmara nefretanEvîn
diff --git a/app/src/main/res/values-ku/strings.xml b/app/src/main/res/values-ku/strings.xml
index 8025242e4..944f9b8c8 100644
--- a/app/src/main/res/values-ku/strings.xml
+++ b/app/src/main/res/values-ku/strings.xml
@@ -630,7 +630,7 @@
دوایینپیشاندانی وێنۆچکەوەسف
- پەخشی لێکچوو
+ پەخشی لێکچوولێدوانەکانشەکرۆکەکانی reCAPTCHA سڕانەوەسڕینەوەی شەکرۆکەکانی RECAPTCHA
diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml
index f06a85ff5..455a972a8 100644
--- a/app/src/main/res/values-lv/strings.xml
+++ b/app/src/main/res/values-lv/strings.xml
@@ -181,7 +181,7 @@
(Eksperimentāls) Piespiediet lejupielādēt saturu caur Tor, lai palielinātu privātumu (tiešraides vēl nav atbalstītas).Izmantojiet TorApraksts
- Līdzīgi video
+ Līdzīgi videoKomentāriNepatīkPatīk
diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml
index 824be52d5..25391c1ed 100644
--- a/app/src/main/res/values-nb-rNO/strings.xml
+++ b/app/src/main/res/values-nb-rNO/strings.xml
@@ -657,7 +657,7 @@
Ingen programmer på enheten din kan åpne detteKapitlerBeskrivelse
- Relaterte strømmer
+ Relaterte strømmerKommentarerSkru av for å skjule videobeskrivelse og ytterligere infoVis beskrivelse
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index 7d0171904..d3b6ea937 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -658,7 +658,7 @@
Toon beschrijvingGeen app op je apparaat kan dit openenHoofdstukken
- Gerelateerde streams
+ Gerelateerde streamsCommentaarSchakel dit uit om video beschrijvingen en additionele informatie te verbergenOpenen met
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index 707bbc620..a39553880 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -671,7 +671,7 @@
Pokaż opisOtwórz za pomocąŻadna aplikacja na Twoim urządzeniu nie może tego otworzyć
- Powiązane strumienie
+ Powiązane strumienieAwaria aplikacjiTa zawartość jest płatna, więc jest dostępna tylko dla użytkowników, którzy za nią zapłacili, dlatego nie może być przesyłana strumieniowo lub pobierana przez NewPipe.Ten film jest dostępny tylko dla subskrybentów YouTube Music Premium, więc nie może być przesyłany strumieniowo ani pobierany przez NewPipe.
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index 2d5210f8e..ffe008a48 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -656,7 +656,7 @@
RecentesCapítulosDescrição
- Transmissões relacionadas
+ Transmissões relacionadasComentáriosDesative para ocultar a descrição do vídeo e informações adicionaisMostrar descrição
diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml
index baac54c18..4d9e692d1 100644
--- a/app/src/main/res/values-pt-rPT/strings.xml
+++ b/app/src/main/res/values-pt-rPT/strings.xml
@@ -657,7 +657,7 @@
Não possui qualquer aplicação para abrir este ficheiroCapítulosDescrição
- Emissões relacionadas
+ Emissões relacionadasComentáriosDesative para ocultar a descrição do vídeo e informações adicionaisMostrar descrição
diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml
index 3a08e14e3..0e492831c 100644
--- a/app/src/main/res/values-pt/strings.xml
+++ b/app/src/main/res/values-pt/strings.xml
@@ -657,7 +657,7 @@
Não possui qualquer aplicação para abrir este ficheiroCapítulosDescrição
- Emissões relacionadas
+ Emissões relacionadasComentáriosDesative para ocultar a descrição do vídeo e informações adicionaisMostrar descrição
diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml
index 7696ffb7c..71fda40c8 100644
--- a/app/src/main/res/values-ro/strings.xml
+++ b/app/src/main/res/values-ro/strings.xml
@@ -664,7 +664,7 @@
Nimeni nu se uităComutare serviciu, selectat în prezent:Descriere
- Fluxuri corelate
+ Fluxuri corelateComentariiVă rugăm să verificați dacă există deja o problemă legată de crash-ul dvs. Când creați bilete duplicat, ne luați timp pe care l-am putea petrece cu remedierea erorii.Copiați raportul formatat
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index db26e27ed..8058d527c 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -665,7 +665,7 @@
НедавнееОтключите, чтобы скрыть поля метаданных (автор потока, содержимое потока или поисковый запрос).Показать метаданные
- Похожие потоки
+ Похожие потокиГлавыОписаниеКомментарии
diff --git a/app/src/main/res/values-sc/strings.xml b/app/src/main/res/values-sc/strings.xml
index 2d0b39153..334e68581 100644
--- a/app/src/main/res/values-sc/strings.xml
+++ b/app/src/main/res/values-sc/strings.xml
@@ -657,7 +657,7 @@
Peruna aplicatzione in su dispositivu tuo podet abèrrere custuCapìtulosDescritzione
- Flussos ligados
+ Flussos ligadosCummentosIstuda pro cuare sa descritzione de su vìdeu e sas informatziones additzionalesAmmustra sa descritzione
diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml
index 80a564a1e..99bc917bd 100644
--- a/app/src/main/res/values-sk/strings.xml
+++ b/app/src/main/res/values-sk/strings.xml
@@ -666,7 +666,7 @@
Zobrazovať meta informácieKapitolyPopis
- Súvisiace streamy
+ Súvisiace streamyKomentáreVypnutím skryjete popis videa a ďalšie informácieZobraziť popis
diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml
index 6f71d69bf..12500a528 100644
--- a/app/src/main/res/values-sl/strings.xml
+++ b/app/src/main/res/values-sl/strings.xml
@@ -451,7 +451,7 @@ odpiranje v pojavnem načinuVklop/izklop storitve, trenutno izbrana:Povlecite za preureditevOpis
- Podobni pretoki
+ Podobni pretokiKomentarjiProsimo preverite, če težava, ki opisuje vašo zrušitev aplikacije že obstaja. Ko ustvarite dvojne pripombe, vzamete naš čas, ki bi ga lahko porabili z odpravljanjem dejanske napake.Prijavite na GitHub-u
diff --git a/app/src/main/res/values-so/strings.xml b/app/src/main/res/values-so/strings.xml
index dea8f2be5..4041bb3ce 100644
--- a/app/src/main/res/values-so/strings.xml
+++ b/app/src/main/res/values-so/strings.xml
@@ -656,7 +656,7 @@
Faahfaahinta dheeraadka ahCutubyadaFaahfaahin
- La xidhiidha
+ La xidhiidhaFaallooyinXidh si aad u qariso faahfaahinta muuqaalka iyo xogaha dheeraadka ahTus faahfaahinta
diff --git a/app/src/main/res/values-sq/strings.xml b/app/src/main/res/values-sq/strings.xml
index 9f1e69221..98c1ec742 100644
--- a/app/src/main/res/values-sq/strings.xml
+++ b/app/src/main/res/values-sq/strings.xml
@@ -643,7 +643,7 @@
Shfaq pamjen miniaturëDuke llogaritur hashPërshkrimi
- Streams të ngjashme
+ Streams të ngjashmeKomentetNjoftimet mbi progresin e hash-imit të videoveNjoftimi për Hash e Videos
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index 7e0e3726d..5302d8695 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -656,7 +656,7 @@
Üst bilgiyi gösterBölümlerAçıklama
- İlgili akışlar
+ İlgili akışlarYorumlarVideo açıklamasını ve ek bilgileri gizlemek için kapatınAçıklamayı göster
diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml
index 9d2e40dbe..3c9851452 100644
--- a/app/src/main/res/values-ur/strings.xml
+++ b/app/src/main/res/values-ur/strings.xml
@@ -524,7 +524,7 @@
∞ ویڈیوز100 سے زائد ویڈیوتفصیل
- متعلقہ سلسلے
+ متعلقہ سلسلےتبصرےبراہ کرم چیک کریں کہ آیا آپ کے کریش پر بحث کرنے والا مسئلہ پہلے سے موجود ہے۔ جعلی ٹکٹ تیار کرتے وقت، آپ ہم سے وقت نکالتے ہیں جو ہم اصل مسئلے کو ٹھیک کرنے میں گزار سکتے ہیں۔گِٹ ہب میں اطلاع دیں
diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml
index 769994acc..1cffd2bc0 100644
--- a/app/src/main/res/values-vi/strings.xml
+++ b/app/src/main/res/values-vi/strings.xml
@@ -643,7 +643,7 @@
Gần đâyĐang tính toán hashMô tả
- Stream liên quan
+ Stream liên quanBình luậnThông báo cho quá trình hash videoThông báo hash video
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index 8b2875ad0..d3c7c888c 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -646,7 +646,7 @@
顯示詮釋資訊章節描述
- 相關的串流
+ 相關的串流留言關閉以隱藏影片描述與其他資訊顯示描述
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index b372bee7f..6759110b3 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -283,7 +283,7 @@
LikesDislikesComments
- Related streams
+ Related itemsDescriptionUse Tor(Experimental) Force download traffic through Tor for increased privacy (streaming videos not yet supported).
@@ -466,6 +466,7 @@
DetailsAudio SettingsHold to enqueue
+ Show channel detailsEnqueueEnqueuedStart playing here
diff --git a/build.gradle b/build.gradle
index b2593ab42..315625a0f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -7,7 +7,7 @@ buildscript {
google()
}
dependencies {
- classpath 'com.android.tools.build:gradle:4.1.2'
+ classpath 'com.android.tools.build:gradle:4.1.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index ed88a042a..e708b1c02 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index c02f7cf09..8cf6eb5ad 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,5 @@
-#Thu Oct 15 11:41:05 CEST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
diff --git a/gradlew b/gradlew
index cccdd3d51..4f906e0c8 100755
--- a/gradlew
+++ b/gradlew
@@ -1,5 +1,21 @@
#!/usr/bin/env sh
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
##############################################################################
##
## Gradle start up script for UN*X
@@ -28,7 +44,7 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
@@ -66,6 +82,7 @@ esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
@@ -109,10 +126,11 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin ; then
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
@@ -138,19 +156,19 @@ if $cygwin ; then
else
eval `echo args$i`="\"$arg\""
fi
- i=$((i+1))
+ i=`expr $i + 1`
done
case $i in
- (0) set -- ;;
- (1) set -- "$args0" ;;
- (2) set -- "$args0" "$args1" ;;
- (3) set -- "$args0" "$args1" "$args2" ;;
- (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
- (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
- (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
- (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
- (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
- (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
@@ -159,14 +177,9 @@ save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
-APP_ARGS=$(save "$@")
+APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
-# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
-if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
- cd "$(dirname "$0")"
-fi
-
exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
index e95643d6a..ac1b06f93 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -1,3 +1,19 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
+if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -35,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-if exist "%JAVA_EXE%" goto init
+if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -45,28 +64,14 @@ echo location of your Java installation.
goto fail
-:init
-@rem Get command-line arguments, handling Windows variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell