diff --git a/app/build.gradle b/app/build.gradle index 500909c9a..a40c5b328 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -89,20 +89,20 @@ android { ext { icepickVersion = '3.2.0' - checkstyleVersion = '8.36.2' + checkstyleVersion = '8.37' stethoVersion = '1.5.1' - leakCanaryVersion = '2.2' + leakCanaryVersion = '2.5' exoPlayerVersion = '2.11.8' androidxLifecycleVersion = '2.2.0' - androidxRoomVersion = '2.2.5' - groupieVersion = '2.8.0' - markwonVersion = '4.3.1' + androidxRoomVersion = '2.3.0-alpha03' + groupieVersion = '2.8.1' + markwonVersion = '4.6.0' googleAutoServiceVersion = '1.0-rc7' } configurations { checkstyle -// ktlint + ktlint } checkstyle { @@ -130,79 +130,81 @@ task runCheckstyle(type: Checkstyle) { } } -//task runKtlint(type: JavaExec) { -// main = "com.pinterest.ktlint.Main" -// classpath = configurations.ktlint -// args "src/**/*.kt" -//} -// -//task formatKtlint(type: JavaExec) { -// main = "com.pinterest.ktlint.Main" -// classpath = configurations.ktlint -// args "-F", "src/**/*.kt" -//} +def outputDir = "${project.buildDir}/reports/ktlint/" +def inputFiles = project.fileTree(dir: "src", include: "**/*.kt") + +task runKtlint(type: JavaExec) { + inputs.files(inputFiles) + outputs.dir(outputDir) + main = "com.pinterest.ktlint.Main" + classpath = configurations.ktlint + args "src/**/*.kt" +} + +task formatKtlint(type: JavaExec) { + inputs.files(inputFiles) + outputs.dir(outputDir) + main = "com.pinterest.ktlint.Main" + classpath = configurations.ktlint + args "-F", "src/**/*.kt" +} afterEvaluate { - preDebugBuild.dependsOn runCheckstyle //, runKtlint + preDebugBuild.dependsOn formatKtlint, runCheckstyle, runKtlint } dependencies { - coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10' + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.1' - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" + 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.35.0" + ktlint "com.pinterest:ktlint:0.39.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" - testImplementation 'junit:junit:4.13.1' - testImplementation 'org.mockito:mockito-core:3.3.3' - - androidTestImplementation "androidx.test.ext:junit:1.1.1" - androidTestImplementation "androidx.room:room-testing:${androidxRoomVersion}" - androidTestImplementation "androidx.test.espresso:espresso-core:3.2.0", { - exclude module: 'support-annotations' - } - // NewPipe dependencies // You can use a local version by uncommenting a few lines in settings.gradle - implementation 'com.github.TeamNewPipe:NewPipeExtractor:6701b0fe718f6bdc385221341fa473e8aaab560e' + implementation 'com.github.TeamNewPipe:NewPipeExtractor:650f0920fea535e08728d895d7b21f19c740817c' 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.12" implementation "com.google.android.exoplayer:exoplayer:${exoPlayerVersion}" implementation "com.google.android.exoplayer:extension-mediasession:${exoPlayerVersion}" - implementation "com.google.android.material:material:1.1.0" + 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.1.0" + 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:1.1.3" - implementation 'androidx.core:core-ktx:1.3.1' + 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.lifecycle:lifecycle-livedata:${androidxLifecycleVersion}" implementation "androidx.lifecycle:lifecycle-viewmodel:${androidxLifecycleVersion}" implementation "androidx.room:room-runtime:${androidxRoomVersion}" - implementation "androidx.room:room-rxjava2:${androidxRoomVersion}" + implementation "androidx.room:room-rxjava3:${androidxRoomVersion}" kapt "androidx.room:room-compiler:${androidxRoomVersion}" implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" @@ -218,13 +220,22 @@ dependencies { implementation "com.nononsenseapps:filepicker:4.2.1" - implementation "ch.acra:acra-core:5.5.0" + implementation "ch.acra:acra-core:5.7.0" - implementation "io.reactivex.rxjava2:rxjava:2.2.19" - implementation "io.reactivex.rxjava2:rxandroid:2.1.1" - implementation "com.jakewharton.rxbinding2:rxbinding:2.2.0" + implementation "io.reactivex.rxjava3:rxjava:3.0.7" + implementation "io.reactivex.rxjava3:rxandroid:3.0.0" + implementation "com.jakewharton.rxbinding4:rxbinding:4.0.0" implementation "org.ocpsoft.prettytime:prettytime:4.0.6.Final" + + testImplementation 'junit:junit:4.13.1' + testImplementation 'org.mockito:mockito-core:3.6.0' + + androidTestImplementation "androidx.test.ext:junit:1.1.2" + androidTestImplementation "androidx.room:room-testing:${androidxRoomVersion}" + androidTestImplementation "androidx.test.espresso:espresso-core:3.3.0", { + exclude module: 'support-annotations' + } } static String getGitWorkingBranch() { diff --git a/app/src/androidTest/java/org/schabi/newpipe/database/AppDatabaseTest.kt b/app/src/androidTest/java/org/schabi/newpipe/database/AppDatabaseTest.kt index e37eb5db9..239c46f7a 100644 --- a/app/src/androidTest/java/org/schabi/newpipe/database/AppDatabaseTest.kt +++ b/app/src/androidTest/java/org/schabi/newpipe/database/AppDatabaseTest.kt @@ -31,49 +31,62 @@ class AppDatabaseTest { } @get:Rule - val testHelper = MigrationTestHelper(InstrumentationRegistry.getInstrumentation(), - AppDatabase::class.java.canonicalName, FrameworkSQLiteOpenHelperFactory()) + val testHelper = MigrationTestHelper( + InstrumentationRegistry.getInstrumentation(), + AppDatabase::class.java.canonicalName, FrameworkSQLiteOpenHelperFactory() + ) @Test fun migrateDatabaseFrom2to3() { val databaseInV2 = testHelper.createDatabase(AppDatabase.DATABASE_NAME, Migrations.DB_VER_2) databaseInV2.run { - insert("streams", SQLiteDatabase.CONFLICT_FAIL, ContentValues().apply { - // put("uid", null) - put("service_id", DEFAULT_SERVICE_ID) - put("url", DEFAULT_URL) - put("title", DEFAULT_TITLE) - put("stream_type", DEFAULT_TYPE.name) - put("duration", DEFAULT_DURATION) - put("uploader", DEFAULT_UPLOADER_NAME) - put("thumbnail_url", DEFAULT_THUMBNAIL) - }) - insert("streams", SQLiteDatabase.CONFLICT_FAIL, ContentValues().apply { - // put("uid", null) - put("service_id", DEFAULT_SECOND_SERVICE_ID) - put("url", DEFAULT_SECOND_URL) - // put("title", null) - // put("stream_type", null) - // put("duration", null) - // put("uploader", null) - // put("thumbnail_url", null) - }) - insert("streams", SQLiteDatabase.CONFLICT_FAIL, ContentValues().apply { - // put("uid", null) - put("service_id", DEFAULT_SERVICE_ID) - // put("url", null) - // put("title", null) - // put("stream_type", null) - // put("duration", null) - // put("uploader", null) - // put("thumbnail_url", null) - }) + insert( + "streams", SQLiteDatabase.CONFLICT_FAIL, + ContentValues().apply { + // put("uid", null) + put("service_id", DEFAULT_SERVICE_ID) + put("url", DEFAULT_URL) + put("title", DEFAULT_TITLE) + put("stream_type", DEFAULT_TYPE.name) + put("duration", DEFAULT_DURATION) + put("uploader", DEFAULT_UPLOADER_NAME) + put("thumbnail_url", DEFAULT_THUMBNAIL) + } + ) + insert( + "streams", SQLiteDatabase.CONFLICT_FAIL, + ContentValues().apply { + // put("uid", null) + put("service_id", DEFAULT_SECOND_SERVICE_ID) + put("url", DEFAULT_SECOND_URL) + // put("title", null) + // put("stream_type", null) + // put("duration", null) + // put("uploader", null) + // put("thumbnail_url", null) + } + ) + insert( + "streams", SQLiteDatabase.CONFLICT_FAIL, + ContentValues().apply { + // put("uid", null) + put("service_id", DEFAULT_SERVICE_ID) + // put("url", null) + // put("title", null) + // put("stream_type", null) + // put("duration", null) + // put("uploader", null) + // put("thumbnail_url", null) + } + ) close() } - testHelper.runMigrationsAndValidate(AppDatabase.DATABASE_NAME, Migrations.DB_VER_3, - true, Migrations.MIGRATION_2_3) + testHelper.runMigrationsAndValidate( + AppDatabase.DATABASE_NAME, Migrations.DB_VER_3, + true, Migrations.MIGRATION_2_3 + ) val migratedDatabaseV3 = getMigratedDatabase() val listFromDB = migratedDatabaseV3.streamDAO().all.blockingFirst() @@ -110,9 +123,11 @@ class AppDatabaseTest { } private fun getMigratedDatabase(): AppDatabase { - val database: AppDatabase = Room.databaseBuilder(ApplicationProvider.getApplicationContext(), - AppDatabase::class.java, AppDatabase.DATABASE_NAME) - .build() + val database: AppDatabase = Room.databaseBuilder( + ApplicationProvider.getApplicationContext(), + AppDatabase::class.java, AppDatabase.DATABASE_NAME + ) + .build() testHelper.closeWhenFinished(database) return database } diff --git a/app/src/debug/java/org/schabi/newpipe/DebugApp.kt b/app/src/debug/java/org/schabi/newpipe/DebugApp.kt index 3ace75f0b..600851c81 100644 --- a/app/src/debug/java/org/schabi/newpipe/DebugApp.kt +++ b/app/src/debug/java/org/schabi/newpipe/DebugApp.kt @@ -15,14 +15,22 @@ class DebugApp : App() { // Give each object 10 seconds to be GC'ed, before LeakCanary gets nosy on it AppWatcher.config = AppWatcher.config.copy(watchDurationMillis = 10000) - LeakCanary.config = LeakCanary.config.copy(dumpHeap = PreferenceManager - .getDefaultSharedPreferences(this).getBoolean(getString( - R.string.allow_heap_dumping_key), false)) + LeakCanary.config = LeakCanary.config.copy( + dumpHeap = PreferenceManager + .getDefaultSharedPreferences(this).getBoolean( + getString( + R.string.allow_heap_dumping_key + ), + false + ) + ) } override fun getDownloader(): Downloader { - val downloader = DownloaderImpl.init(OkHttpClient.Builder() - .addNetworkInterceptor(StethoInterceptor())) + val downloader = DownloaderImpl.init( + OkHttpClient.Builder() + .addNetworkInterceptor(StethoInterceptor()) + ) setCookiesToDownloader(downloader) return downloader } @@ -36,7 +44,8 @@ class DebugApp : App() { // Enable command line interface initializerBuilder.enableDumpapp( - Stetho.defaultDumperPluginsProvider(applicationContext)) + Stetho.defaultDumperPluginsProvider(applicationContext) + ) // Use the InitializerBuilder to generate an Initializer val initializer = initializerBuilder.build() @@ -47,6 +56,6 @@ class DebugApp : App() { override fun isDisposedRxExceptionsReported(): Boolean { return PreferenceManager.getDefaultSharedPreferences(this) - .getBoolean(getString(R.string.allow_disposed_exceptions_key), false) + .getBoolean(getString(R.string.allow_disposed_exceptions_key), false) } } diff --git a/app/src/main/java/org/schabi/newpipe/App.java b/app/src/main/java/org/schabi/newpipe/App.java index 5348db115..de401d4f5 100644 --- a/app/src/main/java/org/schabi/newpipe/App.java +++ b/app/src/main/java/org/schabi/newpipe/App.java @@ -38,13 +38,13 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; -import io.reactivex.disposables.Disposable; -import io.reactivex.exceptions.CompositeException; -import io.reactivex.exceptions.MissingBackpressureException; -import io.reactivex.exceptions.OnErrorNotImplementedException; -import io.reactivex.exceptions.UndeliverableException; -import io.reactivex.functions.Consumer; -import io.reactivex.plugins.RxJavaPlugins; +import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.exceptions.CompositeException; +import io.reactivex.rxjava3.exceptions.MissingBackpressureException; +import io.reactivex.rxjava3.exceptions.OnErrorNotImplementedException; +import io.reactivex.rxjava3.exceptions.UndeliverableException; +import io.reactivex.rxjava3.functions.Consumer; +import io.reactivex.rxjava3.plugins.RxJavaPlugins; /* * Copyright (C) Hans-Christoph Steiner 2016 diff --git a/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java b/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java index 661337b28..4dfd1bdce 100644 --- a/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java +++ b/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java @@ -35,10 +35,10 @@ import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; -import io.reactivex.Maybe; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.Disposable; -import io.reactivex.schedulers.Schedulers; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.core.Maybe; +import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.schedulers.Schedulers; public final class CheckForNewAppVersion { private CheckForNewAppVersion() { } diff --git a/app/src/main/java/org/schabi/newpipe/RouterActivity.java b/app/src/main/java/org/schabi/newpipe/RouterActivity.java index e14eeeba6..9ad993de1 100644 --- a/app/src/main/java/org/schabi/newpipe/RouterActivity.java +++ b/app/src/main/java/org/schabi/newpipe/RouterActivity.java @@ -66,13 +66,13 @@ import java.util.List; import icepick.Icepick; import icepick.State; -import io.reactivex.Observable; -import io.reactivex.Single; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.CompositeDisposable; -import io.reactivex.disposables.Disposable; -import io.reactivex.functions.Consumer; -import io.reactivex.schedulers.Schedulers; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.core.Single; +import io.reactivex.rxjava3.disposables.CompositeDisposable; +import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.functions.Consumer; +import io.reactivex.rxjava3.schedulers.Schedulers; import static org.schabi.newpipe.extractor.StreamingService.ServiceInfo.MediaCapability.AUDIO; import static org.schabi.newpipe.extractor.StreamingService.ServiceInfo.MediaCapability.VIDEO; diff --git a/app/src/main/java/org/schabi/newpipe/about/License.kt b/app/src/main/java/org/schabi/newpipe/about/License.kt index 00a66c84a..ed0c9927f 100644 --- a/app/src/main/java/org/schabi/newpipe/about/License.kt +++ b/app/src/main/java/org/schabi/newpipe/about/License.kt @@ -2,8 +2,8 @@ package org.schabi.newpipe.about import android.net.Uri import android.os.Parcelable -import java.io.Serializable import kotlinx.android.parcel.Parcelize +import java.io.Serializable /** * Class for storing information about a software license. @@ -12,8 +12,8 @@ import kotlinx.android.parcel.Parcelize class License(val name: String, val abbreviation: String, val filename: String) : Parcelable, Serializable { val contentUri: Uri get() = Uri.Builder() - .scheme("file") - .path("/android_asset") - .appendPath(filename) - .build() + .scheme("file") + .path("/android_asset") + .appendPath(filename) + .build() } diff --git a/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.java b/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.java index bac789dbd..8367a75dc 100644 --- a/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.java +++ b/app/src/main/java/org/schabi/newpipe/about/LicenseFragment.java @@ -20,7 +20,7 @@ import java.io.Serializable; import java.util.Arrays; import java.util.Comparator; -import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.rxjava3.disposables.CompositeDisposable; /** * Fragment containing the software licenses. diff --git a/app/src/main/java/org/schabi/newpipe/about/LicenseFragmentHelper.java b/app/src/main/java/org/schabi/newpipe/about/LicenseFragmentHelper.java index a58f27898..b0241049d 100644 --- a/app/src/main/java/org/schabi/newpipe/about/LicenseFragmentHelper.java +++ b/app/src/main/java/org/schabi/newpipe/about/LicenseFragmentHelper.java @@ -16,11 +16,10 @@ import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; -import io.reactivex.Observable; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.Disposable; -import io.reactivex.disposables.Disposables; -import io.reactivex.schedulers.Schedulers; +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; @@ -55,7 +54,7 @@ public final class LicenseFragmentHelper { } /** - * @param context + * @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) { @@ -86,7 +85,7 @@ public final class LicenseFragmentHelper { static Disposable showLicense(@Nullable final Context context, @NonNull final License license) { if (context == null) { - return Disposables.empty(); + return Disposable.empty(); } return Observable.fromCallable(() -> getFormattedLicense(context, license)) diff --git a/app/src/main/java/org/schabi/newpipe/database/BasicDAO.java b/app/src/main/java/org/schabi/newpipe/database/BasicDAO.java index dd526ecc8..1b8540808 100644 --- a/app/src/main/java/org/schabi/newpipe/database/BasicDAO.java +++ b/app/src/main/java/org/schabi/newpipe/database/BasicDAO.java @@ -9,7 +9,7 @@ import androidx.room.Update; import java.util.Collection; import java.util.List; -import io.reactivex.Flowable; +import io.reactivex.rxjava3.core.Flowable; @Dao public interface BasicDAO { diff --git a/app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedDAO.kt b/app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedDAO.kt index d8b4f72cc..f216ba1d8 100644 --- a/app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedDAO.kt +++ b/app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedDAO.kt @@ -6,19 +6,20 @@ import androidx.room.OnConflictStrategy import androidx.room.Query import androidx.room.Transaction import androidx.room.Update -import io.reactivex.Flowable -import java.time.OffsetDateTime +import io.reactivex.rxjava3.core.Flowable import org.schabi.newpipe.database.feed.model.FeedEntity import org.schabi.newpipe.database.feed.model.FeedLastUpdatedEntity import org.schabi.newpipe.database.stream.model.StreamEntity import org.schabi.newpipe.database.subscription.SubscriptionEntity +import java.time.OffsetDateTime @Dao abstract class FeedDAO { @Query("DELETE FROM feed") abstract fun deleteAll(): Int - @Query(""" + @Query( + """ SELECT s.* FROM streams s INNER JOIN feed f @@ -27,10 +28,12 @@ abstract class FeedDAO { ORDER BY s.upload_date IS NULL DESC, s.upload_date DESC, s.uploader ASC LIMIT 500 - """) + """ + ) abstract fun getAllStreams(): Flowable> - @Query(""" + @Query( + """ SELECT s.* FROM streams s INNER JOIN feed f @@ -46,10 +49,12 @@ abstract class FeedDAO { ORDER BY s.upload_date IS NULL DESC, s.upload_date DESC, s.uploader ASC LIMIT 500 - """) + """ + ) abstract fun getAllStreamsFromGroup(groupId: Long): Flowable> - @Query(""" + @Query( + """ DELETE FROM feed WHERE feed.stream_id IN ( @@ -60,10 +65,12 @@ abstract class FeedDAO { WHERE s.upload_date < :offsetDateTime ) - """) + """ + ) abstract fun unlinkStreamsOlderThan(offsetDateTime: OffsetDateTime) - @Query(""" + @Query( + """ DELETE FROM feed WHERE feed.subscription_id = :subscriptionId @@ -76,7 +83,8 @@ abstract class FeedDAO { WHERE s.stream_type = "LIVE_STREAM" OR s.stream_type = "AUDIO_LIVE_STREAM" ) - """) + """ + ) abstract fun unlinkOldLivestreams(subscriptionId: Long) @Insert(onConflict = OnConflictStrategy.IGNORE) @@ -100,12 +108,14 @@ abstract class FeedDAO { } } - @Query(""" + @Query( + """ SELECT MIN(lu.last_updated) FROM feed_last_updated lu INNER JOIN feed_group_subscription_join fgs ON fgs.subscription_id = lu.subscription_id AND fgs.group_id = :groupId - """) + """ + ) abstract fun oldestSubscriptionUpdate(groupId: Long): Flowable> @Query("SELECT MIN(last_updated) FROM feed_last_updated") @@ -114,7 +124,8 @@ abstract class FeedDAO { @Query("SELECT COUNT(*) FROM feed_last_updated WHERE last_updated IS NULL") abstract fun notLoadedCount(): Flowable - @Query(""" + @Query( + """ SELECT COUNT(*) FROM subscriptions s INNER JOIN feed_group_subscription_join fgs @@ -124,20 +135,24 @@ abstract class FeedDAO { ON s.uid = lu.subscription_id WHERE lu.last_updated IS NULL - """) + """ + ) abstract fun notLoadedCountForGroup(groupId: Long): Flowable - @Query(""" + @Query( + """ SELECT s.* FROM subscriptions s LEFT JOIN feed_last_updated lu ON s.uid = lu.subscription_id WHERE lu.last_updated IS NULL OR lu.last_updated < :outdatedThreshold - """) + """ + ) abstract fun getAllOutdated(outdatedThreshold: OffsetDateTime): Flowable> - @Query(""" + @Query( + """ SELECT s.* FROM subscriptions s INNER JOIN feed_group_subscription_join fgs @@ -147,6 +162,7 @@ abstract class FeedDAO { ON s.uid = lu.subscription_id WHERE lu.last_updated IS NULL OR lu.last_updated < :outdatedThreshold - """) + """ + ) abstract fun getAllOutdatedForGroup(groupId: Long, outdatedThreshold: OffsetDateTime): Flowable> } diff --git a/app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedGroupDAO.kt b/app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedGroupDAO.kt index c8700dea2..217eef03f 100644 --- a/app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedGroupDAO.kt +++ b/app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedGroupDAO.kt @@ -6,8 +6,8 @@ import androidx.room.OnConflictStrategy import androidx.room.Query import androidx.room.Transaction import androidx.room.Update -import io.reactivex.Flowable -import io.reactivex.Maybe +import io.reactivex.rxjava3.core.Flowable +import io.reactivex.rxjava3.core.Maybe import org.schabi.newpipe.database.feed.model.FeedGroupEntity import org.schabi.newpipe.database.feed.model.FeedGroupSubscriptionEntity diff --git a/app/src/main/java/org/schabi/newpipe/database/feed/model/FeedEntity.kt b/app/src/main/java/org/schabi/newpipe/database/feed/model/FeedEntity.kt index 8a1eb65d4..beeedc62b 100644 --- a/app/src/main/java/org/schabi/newpipe/database/feed/model/FeedEntity.kt +++ b/app/src/main/java/org/schabi/newpipe/database/feed/model/FeedEntity.kt @@ -10,21 +10,24 @@ import org.schabi.newpipe.database.feed.model.FeedEntity.Companion.SUBSCRIPTION_ import org.schabi.newpipe.database.stream.model.StreamEntity import org.schabi.newpipe.database.subscription.SubscriptionEntity -@Entity(tableName = FEED_TABLE, - primaryKeys = [STREAM_ID, SUBSCRIPTION_ID], - indices = [Index(SUBSCRIPTION_ID)], - foreignKeys = [ - ForeignKey( - entity = StreamEntity::class, - parentColumns = [StreamEntity.STREAM_ID], - childColumns = [STREAM_ID], - onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE, deferred = true), - ForeignKey( - entity = SubscriptionEntity::class, - parentColumns = [SubscriptionEntity.SUBSCRIPTION_UID], - childColumns = [SUBSCRIPTION_ID], - onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE, deferred = true) - ] +@Entity( + tableName = FEED_TABLE, + primaryKeys = [STREAM_ID, SUBSCRIPTION_ID], + indices = [Index(SUBSCRIPTION_ID)], + foreignKeys = [ + ForeignKey( + entity = StreamEntity::class, + parentColumns = [StreamEntity.STREAM_ID], + childColumns = [STREAM_ID], + onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE, deferred = true + ), + ForeignKey( + entity = SubscriptionEntity::class, + parentColumns = [SubscriptionEntity.SUBSCRIPTION_UID], + childColumns = [SUBSCRIPTION_ID], + onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE, deferred = true + ) + ] ) data class FeedEntity( @ColumnInfo(name = STREAM_ID) diff --git a/app/src/main/java/org/schabi/newpipe/database/feed/model/FeedGroupEntity.kt b/app/src/main/java/org/schabi/newpipe/database/feed/model/FeedGroupEntity.kt index e772168fd..1dd26946a 100644 --- a/app/src/main/java/org/schabi/newpipe/database/feed/model/FeedGroupEntity.kt +++ b/app/src/main/java/org/schabi/newpipe/database/feed/model/FeedGroupEntity.kt @@ -9,8 +9,8 @@ import org.schabi.newpipe.database.feed.model.FeedGroupEntity.Companion.SORT_ORD import org.schabi.newpipe.local.subscription.FeedGroupIcon @Entity( - tableName = FEED_GROUP_TABLE, - indices = [Index(SORT_ORDER)] + tableName = FEED_GROUP_TABLE, + indices = [Index(SORT_ORDER)] ) data class FeedGroupEntity( @PrimaryKey(autoGenerate = true) diff --git a/app/src/main/java/org/schabi/newpipe/database/feed/model/FeedGroupSubscriptionEntity.kt b/app/src/main/java/org/schabi/newpipe/database/feed/model/FeedGroupSubscriptionEntity.kt index eac6bddee..40f7d203b 100644 --- a/app/src/main/java/org/schabi/newpipe/database/feed/model/FeedGroupSubscriptionEntity.kt +++ b/app/src/main/java/org/schabi/newpipe/database/feed/model/FeedGroupSubscriptionEntity.kt @@ -11,22 +11,24 @@ import org.schabi.newpipe.database.feed.model.FeedGroupSubscriptionEntity.Compan import org.schabi.newpipe.database.subscription.SubscriptionEntity @Entity( - tableName = FEED_GROUP_SUBSCRIPTION_TABLE, - primaryKeys = [GROUP_ID, SUBSCRIPTION_ID], - indices = [Index(SUBSCRIPTION_ID)], - foreignKeys = [ - ForeignKey( - entity = FeedGroupEntity::class, - parentColumns = [FeedGroupEntity.ID], - childColumns = [GROUP_ID], - onDelete = CASCADE, onUpdate = CASCADE, deferred = true), + tableName = FEED_GROUP_SUBSCRIPTION_TABLE, + primaryKeys = [GROUP_ID, SUBSCRIPTION_ID], + indices = [Index(SUBSCRIPTION_ID)], + foreignKeys = [ + ForeignKey( + entity = FeedGroupEntity::class, + parentColumns = [FeedGroupEntity.ID], + childColumns = [GROUP_ID], + onDelete = CASCADE, onUpdate = CASCADE, deferred = true + ), - ForeignKey( - entity = SubscriptionEntity::class, - parentColumns = [SubscriptionEntity.SUBSCRIPTION_UID], - childColumns = [SUBSCRIPTION_ID], - onDelete = CASCADE, onUpdate = CASCADE, deferred = true) - ] + ForeignKey( + entity = SubscriptionEntity::class, + parentColumns = [SubscriptionEntity.SUBSCRIPTION_UID], + childColumns = [SUBSCRIPTION_ID], + onDelete = CASCADE, onUpdate = CASCADE, deferred = true + ) + ] ) data class FeedGroupSubscriptionEntity( @ColumnInfo(name = GROUP_ID) diff --git a/app/src/main/java/org/schabi/newpipe/database/feed/model/FeedLastUpdatedEntity.kt b/app/src/main/java/org/schabi/newpipe/database/feed/model/FeedLastUpdatedEntity.kt index 069d1138f..a19af9c45 100644 --- a/app/src/main/java/org/schabi/newpipe/database/feed/model/FeedLastUpdatedEntity.kt +++ b/app/src/main/java/org/schabi/newpipe/database/feed/model/FeedLastUpdatedEntity.kt @@ -4,20 +4,21 @@ import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.ForeignKey import androidx.room.PrimaryKey -import java.time.OffsetDateTime import org.schabi.newpipe.database.feed.model.FeedLastUpdatedEntity.Companion.FEED_LAST_UPDATED_TABLE import org.schabi.newpipe.database.feed.model.FeedLastUpdatedEntity.Companion.SUBSCRIPTION_ID import org.schabi.newpipe.database.subscription.SubscriptionEntity +import java.time.OffsetDateTime @Entity( - tableName = FEED_LAST_UPDATED_TABLE, - foreignKeys = [ - ForeignKey( - entity = SubscriptionEntity::class, - parentColumns = [SubscriptionEntity.SUBSCRIPTION_UID], - childColumns = [SUBSCRIPTION_ID], - onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE, deferred = true) - ] + tableName = FEED_LAST_UPDATED_TABLE, + foreignKeys = [ + ForeignKey( + entity = SubscriptionEntity::class, + parentColumns = [SubscriptionEntity.SUBSCRIPTION_UID], + childColumns = [SUBSCRIPTION_ID], + onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE, deferred = true + ) + ] ) data class FeedLastUpdatedEntity( @PrimaryKey diff --git a/app/src/main/java/org/schabi/newpipe/database/history/dao/SearchHistoryDAO.java b/app/src/main/java/org/schabi/newpipe/database/history/dao/SearchHistoryDAO.java index 972435859..a0010a419 100644 --- a/app/src/main/java/org/schabi/newpipe/database/history/dao/SearchHistoryDAO.java +++ b/app/src/main/java/org/schabi/newpipe/database/history/dao/SearchHistoryDAO.java @@ -8,7 +8,7 @@ import org.schabi.newpipe.database.history.model.SearchHistoryEntry; import java.util.List; -import io.reactivex.Flowable; +import io.reactivex.rxjava3.core.Flowable; import static org.schabi.newpipe.database.history.model.SearchHistoryEntry.CREATION_DATE; import static org.schabi.newpipe.database.history.model.SearchHistoryEntry.ID; diff --git a/app/src/main/java/org/schabi/newpipe/database/history/dao/StreamHistoryDAO.java b/app/src/main/java/org/schabi/newpipe/database/history/dao/StreamHistoryDAO.java index 8a9cab182..535f2d2d0 100644 --- a/app/src/main/java/org/schabi/newpipe/database/history/dao/StreamHistoryDAO.java +++ b/app/src/main/java/org/schabi/newpipe/database/history/dao/StreamHistoryDAO.java @@ -10,7 +10,7 @@ import org.schabi.newpipe.database.stream.StreamStatisticsEntry; import java.util.List; -import io.reactivex.Flowable; +import io.reactivex.rxjava3.core.Flowable; import static org.schabi.newpipe.database.history.model.StreamHistoryEntity.JOIN_STREAM_ID; import static org.schabi.newpipe.database.history.model.StreamHistoryEntity.STREAM_ACCESS_DATE; diff --git a/app/src/main/java/org/schabi/newpipe/database/history/model/StreamHistoryEntry.kt b/app/src/main/java/org/schabi/newpipe/database/history/model/StreamHistoryEntry.kt index b928b00bf..a93ba1652 100644 --- a/app/src/main/java/org/schabi/newpipe/database/history/model/StreamHistoryEntry.kt +++ b/app/src/main/java/org/schabi/newpipe/database/history/model/StreamHistoryEntry.kt @@ -2,8 +2,8 @@ package org.schabi.newpipe.database.history.model import androidx.room.ColumnInfo import androidx.room.Embedded -import java.time.OffsetDateTime import org.schabi.newpipe.database.stream.model.StreamEntity +import java.time.OffsetDateTime data class StreamHistoryEntry( @Embedded @@ -25,6 +25,6 @@ data class StreamHistoryEntry( fun hasEqualValues(other: StreamHistoryEntry): Boolean { return this.streamEntity.uid == other.streamEntity.uid && streamId == other.streamId && - accessDate.isEqual(other.accessDate) + accessDate.isEqual(other.accessDate) } } diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistDAO.java b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistDAO.java index ad9c148ca..078385e56 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistDAO.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistDAO.java @@ -8,7 +8,7 @@ import org.schabi.newpipe.database.playlist.model.PlaylistEntity; import java.util.List; -import io.reactivex.Flowable; +import io.reactivex.rxjava3.core.Flowable; import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.PLAYLIST_ID; import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.PLAYLIST_TABLE; diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistRemoteDAO.java b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistRemoteDAO.java index 23442ceff..a488f00fc 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistRemoteDAO.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistRemoteDAO.java @@ -9,7 +9,7 @@ import org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity; import java.util.List; -import io.reactivex.Flowable; +import io.reactivex.rxjava3.core.Flowable; import static org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity.REMOTE_PLAYLIST_ID; import static org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity.REMOTE_PLAYLIST_SERVICE_ID; diff --git a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java index a41f36d72..09da6aca0 100644 --- a/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java +++ b/app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.java @@ -11,7 +11,7 @@ import org.schabi.newpipe.database.playlist.model.PlaylistStreamEntity; import java.util.List; -import io.reactivex.Flowable; +import io.reactivex.rxjava3.core.Flowable; import static org.schabi.newpipe.database.playlist.PlaylistMetadataEntry.PLAYLIST_STREAM_COUNT; import static org.schabi.newpipe.database.playlist.model.PlaylistEntity.PLAYLIST_ID; diff --git a/app/src/main/java/org/schabi/newpipe/database/stream/dao/StreamDAO.kt b/app/src/main/java/org/schabi/newpipe/database/stream/dao/StreamDAO.kt index 89757c17d..be8590382 100644 --- a/app/src/main/java/org/schabi/newpipe/database/stream/dao/StreamDAO.kt +++ b/app/src/main/java/org/schabi/newpipe/database/stream/dao/StreamDAO.kt @@ -6,14 +6,14 @@ import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query import androidx.room.Transaction -import io.reactivex.Flowable -import java.time.OffsetDateTime +import io.reactivex.rxjava3.core.Flowable import org.schabi.newpipe.database.BasicDAO import org.schabi.newpipe.database.stream.model.StreamEntity import org.schabi.newpipe.database.stream.model.StreamEntity.Companion.STREAM_ID import org.schabi.newpipe.extractor.stream.StreamType import org.schabi.newpipe.extractor.stream.StreamType.AUDIO_LIVE_STREAM import org.schabi.newpipe.extractor.stream.StreamType.LIVE_STREAM +import java.time.OffsetDateTime @Dao abstract class StreamDAO : BasicDAO { @@ -35,10 +35,12 @@ abstract class StreamDAO : BasicDAO { @Insert(onConflict = OnConflictStrategy.IGNORE) internal abstract fun silentInsertAllInternal(streams: List): List - @Query(""" + @Query( + """ SELECT uid, stream_type, textual_upload_date, upload_date, is_upload_date_approximation, duration FROM streams WHERE url = :url AND service_id = :serviceId - """) + """ + ) internal abstract fun getMinimalStreamForCompare(serviceId: Int, url: String): StreamCompareFeed? @Transaction @@ -79,7 +81,7 @@ abstract class StreamDAO : BasicDAO { private fun compareAndUpdateStream(newerStream: StreamEntity) { val existentMinimalStream = getMinimalStreamForCompare(newerStream.serviceId, newerStream.url) - ?: throw IllegalStateException("Stream cannot be null just after insertion.") + ?: throw IllegalStateException("Stream cannot be null just after insertion.") newerStream.uid = existentMinimalStream.uid val isNewerStreamLive = newerStream.streamType == AUDIO_LIVE_STREAM || newerStream.streamType == LIVE_STREAM @@ -88,7 +90,7 @@ abstract class StreamDAO : BasicDAO { // Use the existent upload date if the newer stream does not have a better precision // (i.e. is an approximation). This is done to prevent unnecessary changes. val hasBetterPrecision = - newerStream.uploadDate != null && newerStream.isUploadDateApproximation != true + newerStream.uploadDate != null && newerStream.isUploadDateApproximation != true if (existentMinimalStream.uploadDate != null && !hasBetterPrecision) { newerStream.uploadDate = existentMinimalStream.uploadDate newerStream.textualUploadDate = existentMinimalStream.textualUploadDate @@ -101,7 +103,8 @@ abstract class StreamDAO : BasicDAO { } } - @Query(""" + @Query( + """ DELETE FROM streams WHERE NOT EXISTS (SELECT 1 FROM stream_history sh @@ -112,7 +115,8 @@ abstract class StreamDAO : BasicDAO { AND NOT EXISTS (SELECT 1 FROM feed f WHERE f.stream_id = streams.uid) - """) + """ + ) abstract fun deleteOrphans(): Int /** diff --git a/app/src/main/java/org/schabi/newpipe/database/stream/dao/StreamStateDAO.java b/app/src/main/java/org/schabi/newpipe/database/stream/dao/StreamStateDAO.java index eb0f77f66..a6b36e3ff 100644 --- a/app/src/main/java/org/schabi/newpipe/database/stream/dao/StreamStateDAO.java +++ b/app/src/main/java/org/schabi/newpipe/database/stream/dao/StreamStateDAO.java @@ -11,7 +11,7 @@ import org.schabi.newpipe.database.stream.model.StreamStateEntity; import java.util.List; -import io.reactivex.Flowable; +import io.reactivex.rxjava3.core.Flowable; import static org.schabi.newpipe.database.stream.model.StreamStateEntity.JOIN_STREAM_ID; import static org.schabi.newpipe.database.stream.model.StreamStateEntity.STREAM_STATE_TABLE; diff --git a/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt b/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt index defcb7acf..0f3e18e7b 100644 --- a/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt +++ b/app/src/main/java/org/schabi/newpipe/database/stream/model/StreamEntity.kt @@ -5,8 +5,6 @@ import androidx.room.Entity import androidx.room.Ignore import androidx.room.Index import androidx.room.PrimaryKey -import java.io.Serializable -import java.time.OffsetDateTime import org.schabi.newpipe.database.stream.model.StreamEntity.Companion.STREAM_SERVICE_ID import org.schabi.newpipe.database.stream.model.StreamEntity.Companion.STREAM_TABLE import org.schabi.newpipe.database.stream.model.StreamEntity.Companion.STREAM_URL @@ -15,11 +13,14 @@ import org.schabi.newpipe.extractor.stream.StreamInfo import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.extractor.stream.StreamType import org.schabi.newpipe.player.playqueue.PlayQueueItem +import java.io.Serializable +import java.time.OffsetDateTime -@Entity(tableName = STREAM_TABLE, - indices = [ - Index(value = [STREAM_SERVICE_ID, STREAM_URL], unique = true) - ] +@Entity( + tableName = STREAM_TABLE, + indices = [ + Index(value = [STREAM_SERVICE_ID, STREAM_URL], unique = true) + ] ) data class StreamEntity( @PrimaryKey(autoGenerate = true) @@ -61,27 +62,27 @@ data class StreamEntity( ) : Serializable { @Ignore constructor(item: StreamInfoItem) : this( - serviceId = item.serviceId, url = item.url, title = item.name, - streamType = item.streamType, duration = item.duration, uploader = item.uploaderName, - thumbnailUrl = item.thumbnailUrl, viewCount = item.viewCount, - textualUploadDate = item.textualUploadDate, uploadDate = item.uploadDate?.offsetDateTime(), - isUploadDateApproximation = item.uploadDate?.isApproximation + serviceId = item.serviceId, url = item.url, title = item.name, + streamType = item.streamType, duration = item.duration, uploader = item.uploaderName, + thumbnailUrl = item.thumbnailUrl, viewCount = item.viewCount, + textualUploadDate = item.textualUploadDate, uploadDate = item.uploadDate?.offsetDateTime(), + isUploadDateApproximation = item.uploadDate?.isApproximation ) @Ignore constructor(info: StreamInfo) : this( - serviceId = info.serviceId, url = info.url, title = info.name, - streamType = info.streamType, duration = info.duration, uploader = info.uploaderName, - thumbnailUrl = info.thumbnailUrl, viewCount = info.viewCount, - textualUploadDate = info.textualUploadDate, uploadDate = info.uploadDate?.offsetDateTime(), - isUploadDateApproximation = info.uploadDate?.isApproximation + serviceId = info.serviceId, url = info.url, title = info.name, + streamType = info.streamType, duration = info.duration, uploader = info.uploaderName, + thumbnailUrl = info.thumbnailUrl, viewCount = info.viewCount, + textualUploadDate = info.textualUploadDate, uploadDate = info.uploadDate?.offsetDateTime(), + isUploadDateApproximation = info.uploadDate?.isApproximation ) @Ignore constructor(item: PlayQueueItem) : this( - serviceId = item.serviceId, url = item.url, title = item.title, - streamType = item.streamType, duration = item.duration, uploader = item.uploader, - thumbnailUrl = item.thumbnailUrl + serviceId = item.serviceId, url = item.url, title = item.title, + streamType = item.streamType, duration = item.duration, uploader = item.uploader, + thumbnailUrl = item.thumbnailUrl ) fun toStreamInfoItem(): StreamInfoItem { diff --git a/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionDAO.kt b/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionDAO.kt index 60dd343b9..9798ec72d 100644 --- a/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionDAO.kt +++ b/app/src/main/java/org/schabi/newpipe/database/subscription/SubscriptionDAO.kt @@ -5,8 +5,8 @@ import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query import androidx.room.Transaction -import io.reactivex.Flowable -import io.reactivex.Maybe +import io.reactivex.rxjava3.core.Flowable +import io.reactivex.rxjava3.core.Maybe import org.schabi.newpipe.database.BasicDAO @Dao @@ -20,16 +20,19 @@ abstract class SubscriptionDAO : BasicDAO { @Query("SELECT * FROM subscriptions ORDER BY name COLLATE NOCASE ASC") abstract override fun getAll(): Flowable> - @Query(""" + @Query( + """ SELECT * FROM subscriptions WHERE name LIKE '%' || :filter || '%' ORDER BY name COLLATE NOCASE ASC - """) + """ + ) abstract fun getSubscriptionsFiltered(filter: String): Flowable> - @Query(""" + @Query( + """ SELECT * FROM subscriptions s LEFT JOIN feed_group_subscription_join fgs @@ -38,12 +41,14 @@ abstract class SubscriptionDAO : BasicDAO { WHERE (fgs.subscription_id IS NULL OR fgs.group_id = :currentGroupId) ORDER BY name COLLATE NOCASE ASC - """) + """ + ) abstract fun getSubscriptionsOnlyUngrouped( currentGroupId: Long ): Flowable> - @Query(""" + @Query( + """ SELECT * FROM subscriptions s LEFT JOIN feed_group_subscription_join fgs @@ -53,7 +58,8 @@ abstract class SubscriptionDAO : BasicDAO { AND s.name LIKE '%' || :filter || '%' ORDER BY name COLLATE NOCASE ASC - """) + """ + ) abstract fun getSubscriptionsOnlyUngroupedFiltered( currentGroupId: Long, filter: String diff --git a/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java b/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java index 827da87e1..e80a0ab21 100644 --- a/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java +++ b/app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java @@ -10,7 +10,6 @@ import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.os.IBinder; -import androidx.preference.PreferenceManager; import android.util.Log; import android.util.SparseArray; import android.view.LayoutInflater; @@ -34,6 +33,7 @@ import androidx.appcompat.view.menu.ActionMenuItemView; import androidx.appcompat.widget.Toolbar; import androidx.documentfile.provider.DocumentFile; import androidx.fragment.app.DialogFragment; +import androidx.preference.PreferenceManager; import com.nononsenseapps.filepicker.Utils; @@ -70,7 +70,7 @@ import java.util.Locale; import icepick.Icepick; import icepick.State; -import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.rxjava3.disposables.CompositeDisposable; import us.shandian.giga.get.MissionRecoveryInfo; import us.shandian.giga.io.StoredDirectoryHelper; import us.shandian.giga.io.StoredFileHelper; diff --git a/app/src/main/java/org/schabi/newpipe/fragments/BaseStateFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/BaseStateFragment.java index a9007052f..0d25765a4 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/BaseStateFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/BaseStateFragment.java @@ -13,7 +13,7 @@ import android.widget.Toast; import androidx.annotation.Nullable; import androidx.annotation.StringRes; -import com.jakewharton.rxbinding2.view.RxView; +import com.jakewharton.rxbinding4.view.RxView; import org.schabi.newpipe.BaseFragment; import org.schabi.newpipe.MainActivity; @@ -34,8 +34,8 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import icepick.State; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.Disposable; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.disposables.Disposable; import static org.schabi.newpipe.util.AnimationUtils.animateView; 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 e7c98fe8b..427cff06e 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 @@ -15,9 +15,6 @@ import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Looper; -import android.view.ViewTreeObserver; -import androidx.core.text.HtmlCompat; -import androidx.preference.PreferenceManager; import android.provider.Settings; import android.text.TextUtils; import android.text.util.Linkify; @@ -27,6 +24,7 @@ import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; +import android.view.ViewTreeObserver; import android.view.WindowManager; import android.view.animation.DecelerateInterpolator; import android.widget.FrameLayout; @@ -45,7 +43,9 @@ import androidx.appcompat.content.res.AppCompatResources; import androidx.appcompat.widget.Toolbar; import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.core.content.ContextCompat; +import androidx.core.text.HtmlCompat; import androidx.fragment.app.Fragment; +import androidx.preference.PreferenceManager; import androidx.viewpager.widget.ViewPager; import com.google.android.exoplayer2.ExoPlaybackException; @@ -116,11 +116,11 @@ import java.util.concurrent.TimeUnit; import icepick.State; import io.noties.markwon.Markwon; import io.noties.markwon.linkify.LinkifyPlugin; -import io.reactivex.Single; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.CompositeDisposable; -import io.reactivex.disposables.Disposable; -import io.reactivex.schedulers.Schedulers; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.core.Single; +import io.reactivex.rxjava3.disposables.CompositeDisposable; +import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.schedulers.Schedulers; import static org.schabi.newpipe.extractor.StreamingService.ServiceInfo.MediaCapability.COMMENTS; import static org.schabi.newpipe.extractor.stream.StreamExtractor.NO_AGE_LIMIT; diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java index 43fc74922..006072e93 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListInfoFragment.java @@ -16,10 +16,10 @@ import org.schabi.newpipe.views.NewPipeRecyclerView; import java.util.Queue; import icepick.State; -import io.reactivex.Single; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.Disposable; -import io.reactivex.schedulers.Schedulers; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.core.Single; +import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.schedulers.Schedulers; public abstract class BaseListInfoFragment extends BaseListFragment { diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index 6ec818909..0342bb99c 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -24,7 +24,7 @@ import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AppCompatActivity; import androidx.core.content.ContextCompat; -import com.jakewharton.rxbinding2.view.RxView; +import com.jakewharton.rxbinding4.view.RxView; import org.schabi.newpipe.R; import org.schabi.newpipe.database.subscription.SubscriptionEntity; @@ -53,15 +53,15 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; -import io.reactivex.Observable; -import io.reactivex.Single; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.CompositeDisposable; -import io.reactivex.disposables.Disposable; -import io.reactivex.functions.Action; -import io.reactivex.functions.Consumer; -import io.reactivex.functions.Function; -import io.reactivex.schedulers.Schedulers; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.core.Single; +import io.reactivex.rxjava3.disposables.CompositeDisposable; +import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.functions.Action; +import io.reactivex.rxjava3.functions.Consumer; +import io.reactivex.rxjava3.functions.Function; +import io.reactivex.rxjava3.schedulers.Schedulers; import static org.schabi.newpipe.util.AnimationUtils.animateBackgroundColor; import static org.schabi.newpipe.util.AnimationUtils.animateTextColor; diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentsFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentsFragment.java index cb9f83895..68b0d823a 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentsFragment.java @@ -20,8 +20,8 @@ import org.schabi.newpipe.report.UserAction; import org.schabi.newpipe.util.AnimationUtils; import org.schabi.newpipe.util.ExtractorHelper; -import io.reactivex.Single; -import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.rxjava3.core.Single; +import io.reactivex.rxjava3.disposables.CompositeDisposable; public class CommentsFragment extends BaseListInfoFragment { private final CompositeDisposable disposables = new CompositeDisposable(); diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/kiosk/KioskFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/kiosk/KioskFragment.java index 68097e21e..8770e6936 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/kiosk/KioskFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/kiosk/KioskFragment.java @@ -26,7 +26,7 @@ import org.schabi.newpipe.util.KioskTranslator; import org.schabi.newpipe.util.Localization; import icepick.State; -import io.reactivex.Single; +import io.reactivex.rxjava3.core.Single; import static org.schabi.newpipe.util.AnimationUtils.animateView; 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 71b51f9a1..d1a964fb2 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 @@ -51,12 +51,11 @@ import java.util.Arrays; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; -import io.reactivex.Flowable; -import io.reactivex.Single; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.CompositeDisposable; -import io.reactivex.disposables.Disposable; -import io.reactivex.disposables.Disposables; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.core.Flowable; +import io.reactivex.rxjava3.core.Single; +import io.reactivex.rxjava3.disposables.CompositeDisposable; +import io.reactivex.rxjava3.disposables.Disposable; import static org.schabi.newpipe.util.AnimationUtils.animateView; @@ -460,7 +459,7 @@ public class PlaylistFragment extends BaseListInfoFragment { .doFinally(() -> playlistEntity = null) .subscribe(ignored -> { /* Do nothing */ }, this::onError); } else { - action = Disposables.empty(); + action = Disposable.empty(); } disposables.add(action); 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 66e16ff3c..02dbf176b 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 @@ -68,13 +68,13 @@ import java.util.Queue; import java.util.concurrent.TimeUnit; import icepick.State; -import io.reactivex.Flowable; -import io.reactivex.Observable; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.CompositeDisposable; -import io.reactivex.disposables.Disposable; -import io.reactivex.schedulers.Schedulers; -import io.reactivex.subjects.PublishSubject; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.core.Flowable; +import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.disposables.CompositeDisposable; +import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.schedulers.Schedulers; +import io.reactivex.rxjava3.subjects.PublishSubject; import static androidx.recyclerview.widget.ItemTouchHelper.Callback.makeMovementFlags; import static java.util.Arrays.asList; @@ -709,7 +709,7 @@ public class SearchFragment extends BaseListFragment observable = suggestionPublisher .debounce(SUGGESTIONS_DEBOUNCE, TimeUnit.MILLISECONDS) - .startWith(searchString != null + .startWithItem(searchString != null ? searchString : "") .filter(ss -> isSuggestionsEnabled); 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/RelatedVideosFragment.java index 90cb60d33..907615b45 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/RelatedVideosFragment.java @@ -3,7 +3,6 @@ package org.schabi.newpipe.fragments.list.videos; import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; -import androidx.preference.PreferenceManager; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -13,6 +12,7 @@ import android.widget.Switch; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.preference.PreferenceManager; import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.ListExtractor; @@ -25,8 +25,8 @@ import org.schabi.newpipe.util.RelatedStreamInfo; import java.io.Serializable; -import io.reactivex.Single; -import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.rxjava3.core.Single; +import io.reactivex.rxjava3.disposables.CompositeDisposable; public class RelatedVideosFragment extends BaseListInfoFragment implements SharedPreferences.OnSharedPreferenceChangeListener { diff --git a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java index d7555a79d..d5241ae02 100644 --- a/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/bookmark/BookmarkFragment.java @@ -33,11 +33,11 @@ import org.schabi.newpipe.util.OnClickGesture; import java.util.List; import icepick.State; -import io.reactivex.Flowable; -import io.reactivex.Single; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.CompositeDisposable; -import io.reactivex.disposables.Disposable; +import io.reactivex.rxjava3.core.Flowable; +import io.reactivex.rxjava3.core.Single; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.disposables.CompositeDisposable; +import io.reactivex.rxjava3.disposables.Disposable; public final class BookmarkFragment extends BaseLocalListFragment, Void> { @State diff --git a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java index 4a09da77f..93e1141c7 100644 --- a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java +++ b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistAppendDialog.java @@ -28,9 +28,9 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.CompositeDisposable; -import io.reactivex.disposables.Disposable; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.disposables.CompositeDisposable; +import io.reactivex.rxjava3.disposables.Disposable; public final class PlaylistAppendDialog extends PlaylistDialog { private static final String TAG = PlaylistAppendDialog.class.getCanonicalName(); @@ -98,7 +98,7 @@ public final class PlaylistAppendDialog extends PlaylistDialog { super.onViewCreated(view, savedInstanceState); final LocalPlaylistManager playlistManager = - new LocalPlaylistManager(NewPipeDatabase.getInstance(getContext())); + new LocalPlaylistManager(NewPipeDatabase.getInstance(requireContext())); playlistAdapter = new LocalItemListAdapter(getActivity()); playlistAdapter.setSelectedListener(new OnClickGesture() { @@ -113,7 +113,7 @@ public final class PlaylistAppendDialog extends PlaylistDialog { }); playlistRecyclerView = view.findViewById(R.id.playlist_list); - playlistRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + playlistRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); playlistRecyclerView.setAdapter(playlistAdapter); final View newPlaylistButton = view.findViewById(R.id.newPlaylist); @@ -146,12 +146,12 @@ public final class PlaylistAppendDialog extends PlaylistDialog { //////////////////////////////////////////////////////////////////////////*/ public void openCreatePlaylistDialog() { - if (getStreams() == null || getFragmentManager() == null) { + if (getStreams() == null || !isAdded()) { return; } - PlaylistCreationDialog.newInstance(getStreams()).show(getFragmentManager(), TAG); - getDialog().dismiss(); + PlaylistCreationDialog.newInstance(getStreams()).show(getParentFragmentManager(), TAG); + requireDialog().dismiss(); } private void onPlaylistsReceived(@NonNull final List playlists) { @@ -183,6 +183,6 @@ public final class PlaylistAppendDialog extends PlaylistDialog { .observeOn(AndroidSchedulers.mainThread()) .subscribe(ignored -> successToast.show())); - getDialog().dismiss(); + requireDialog().dismiss(); } } diff --git a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistCreationDialog.java b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistCreationDialog.java index 55782b452..4d19f0dd9 100644 --- a/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistCreationDialog.java +++ b/app/src/main/java/org/schabi/newpipe/local/dialog/PlaylistCreationDialog.java @@ -17,7 +17,7 @@ import org.schabi.newpipe.local.playlist.LocalPlaylistManager; import java.util.List; -import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; public final class PlaylistCreationDialog extends PlaylistDialog { public static PlaylistCreationDialog newInstance(final List streams) { diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/FeedDatabaseManager.kt b/app/src/main/java/org/schabi/newpipe/local/feed/FeedDatabaseManager.kt index 8bd8c1986..9a4832c81 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/FeedDatabaseManager.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/FeedDatabaseManager.kt @@ -2,14 +2,11 @@ package org.schabi.newpipe.local.feed import android.content.Context import android.util.Log -import io.reactivex.Completable -import io.reactivex.Flowable -import io.reactivex.Maybe -import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.schedulers.Schedulers -import java.time.LocalDate -import java.time.OffsetDateTime -import java.time.ZoneOffset +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers +import io.reactivex.rxjava3.core.Completable +import io.reactivex.rxjava3.core.Flowable +import io.reactivex.rxjava3.core.Maybe +import io.reactivex.rxjava3.schedulers.Schedulers import org.schabi.newpipe.MainActivity.DEBUG import org.schabi.newpipe.NewPipeDatabase import org.schabi.newpipe.database.feed.model.FeedEntity @@ -19,6 +16,9 @@ import org.schabi.newpipe.database.stream.model.StreamEntity import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.extractor.stream.StreamType import org.schabi.newpipe.local.subscription.FeedGroupIcon +import java.time.LocalDate +import java.time.OffsetDateTime +import java.time.ZoneOffset class FeedDatabaseManager(context: Context) { private val database = NewPipeDatabase.getInstance(context) @@ -31,7 +31,7 @@ class FeedDatabaseManager(context: Context) { * Only items that are newer than this will be saved. */ val FEED_OLDEST_ALLOWED_DATE: OffsetDateTime = LocalDate.now().minusWeeks(13) - .atStartOfDay().atOffset(ZoneOffset.UTC) + .atStartOfDay().atOffset(ZoneOffset.UTC) } fun groups() = feedGroupTable.getAll() @@ -44,9 +44,9 @@ class FeedDatabaseManager(context: Context) { else -> feedTable.getAllStreamsFromGroup(groupId) } - return streams.map> { + return streams.map { val items = ArrayList(it.size) - it.mapTo(items) { it.toStreamInfoItem() } + it.mapTo(items) { stream -> stream.toStreamInfoItem() } return@map items } } @@ -61,10 +61,10 @@ class FeedDatabaseManager(context: Context) { } fun outdatedSubscriptionsForGroup(groupId: Long = FeedGroupEntity.GROUP_ALL_ID, outdatedThreshold: OffsetDateTime) = - feedTable.getAllOutdatedForGroup(groupId, outdatedThreshold) + feedTable.getAllOutdatedForGroup(groupId, outdatedThreshold) fun markAsOutdated(subscriptionId: Long) = feedTable - .setLastUpdatedForSubscription(FeedLastUpdatedEntity(subscriptionId, null)) + .setLastUpdatedForSubscription(FeedLastUpdatedEntity(subscriptionId, null)) fun upsertAll( subscriptionId: Long, @@ -92,8 +92,12 @@ class FeedDatabaseManager(context: Context) { feedTable.insertAll(feedEntities) } - feedTable.setLastUpdatedForSubscription(FeedLastUpdatedEntity(subscriptionId, - OffsetDateTime.now(ZoneOffset.UTC))) + feedTable.setLastUpdatedForSubscription( + FeedLastUpdatedEntity( + subscriptionId, + OffsetDateTime.now(ZoneOffset.UTC) + ) + ) } fun removeOrphansOrOlderStreams(oldestAllowedDate: OffsetDateTime = FEED_OLDEST_ALLOWED_DATE) { @@ -113,38 +117,38 @@ class FeedDatabaseManager(context: Context) { fun subscriptionIdsForGroup(groupId: Long): Flowable> { return feedGroupTable.getSubscriptionIdsFor(groupId) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) } fun updateSubscriptionsForGroup(groupId: Long, subscriptionIds: List): Completable { return Completable.fromCallable { feedGroupTable.updateSubscriptionsForGroup(groupId, subscriptionIds) } - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) } fun createGroup(name: String, icon: FeedGroupIcon): Maybe { return Maybe.fromCallable { feedGroupTable.insert(FeedGroupEntity(0, name, icon)) } - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) } fun getGroup(groupId: Long): Maybe { return feedGroupTable.getGroup(groupId) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) } fun updateGroup(feedGroupEntity: FeedGroupEntity): Completable { return Completable.fromCallable { feedGroupTable.update(feedGroupEntity) } - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) } fun deleteGroup(groupId: Long): Completable { return Completable.fromCallable { feedGroupTable.delete(groupId) } - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) } fun updateGroupsOrder(groupIdList: List): Completable { @@ -152,8 +156,8 @@ class FeedDatabaseManager(context: Context) { val orderMap = groupIdList.associateBy({ it }, { index++ }) return Completable.fromCallable { feedGroupTable.updateOrder(orderMap) } - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) } fun oldestSubscriptionUpdate(groupId: Long): Flowable> { diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt b/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt index b6b198b58..dbe91ec55 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt @@ -37,7 +37,6 @@ import androidx.lifecycle.ViewModelProvider import androidx.preference.PreferenceManager import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import icepick.State -import java.util.Calendar import kotlinx.android.synthetic.main.error_retry.error_button_retry import kotlinx.android.synthetic.main.error_retry.error_message_view import kotlinx.android.synthetic.main.fragment_feed.empty_state_view @@ -55,6 +54,7 @@ import org.schabi.newpipe.local.feed.service.FeedLoadService import org.schabi.newpipe.report.UserAction import org.schabi.newpipe.util.AnimationUtils.animateView import org.schabi.newpipe.util.Localization +import java.util.Calendar class FeedFragment : BaseListFragment() { private lateinit var viewModel: FeedViewModel @@ -76,7 +76,7 @@ class FeedFragment : BaseListFragment() { super.onCreate(savedInstanceState) groupId = arguments?.getLong(KEY_GROUP_ID, FeedGroupEntity.GROUP_ALL_ID) - ?: FeedGroupEntity.GROUP_ALL_ID + ?: FeedGroupEntity.GROUP_ALL_ID groupName = arguments?.getString(KEY_GROUP_NAME) ?: "" } @@ -144,15 +144,15 @@ class FeedFragment : BaseListFragment() { } AlertDialog.Builder(requireContext()) - .setMessage(R.string.feed_use_dedicated_fetch_method_help_text) - .setNeutralButton(enableDisableButtonText) { _, _ -> - sharedPreferences.edit { - putBoolean(getString(R.string.feed_use_dedicated_fetch_method_key), !usingDedicatedMethod) - } + .setMessage(R.string.feed_use_dedicated_fetch_method_help_text) + .setNeutralButton(enableDisableButtonText) { _, _ -> + sharedPreferences.edit { + putBoolean(getString(R.string.feed_use_dedicated_fetch_method_key), !usingDedicatedMethod) } - .setPositiveButton(resources.getString(R.string.finish), null) - .create() - .show() + } + .setPositiveButton(resources.getString(R.string.finish), null) + .create() + .show() return true } @@ -234,7 +234,7 @@ class FeedFragment : BaseListFragment() { showLoading() val isIndeterminate = progressState.currentProgress == -1 && - progressState.maxProgress == -1 + progressState.maxProgress == -1 if (!isIndeterminate) { loading_progress_text.text = "${progressState.currentProgress}/${progressState.maxProgress}" @@ -245,7 +245,7 @@ class FeedFragment : BaseListFragment() { } loading_progress_bar.isIndeterminate = isIndeterminate || - (progressState.maxProgress > 0 && progressState.currentProgress == 0) + (progressState.maxProgress > 0 && progressState.currentProgress == 0) loading_progress_bar.progress = progressState.currentProgress loading_progress_bar.max = progressState.maxProgress @@ -267,8 +267,10 @@ class FeedFragment : BaseListFragment() { } if (loadedState.itemsErrors.isNotEmpty()) { - showSnackBarError(loadedState.itemsErrors, UserAction.REQUESTED_FEED, - "none", "Loading feed", R.string.general_error) + showSnackBarError( + loadedState.itemsErrors, UserAction.REQUESTED_FEED, + "none", "Loading feed", R.string.general_error + ) } if (loadedState.items.isEmpty()) { @@ -311,9 +313,11 @@ class FeedFragment : BaseListFragment() { override fun hasMoreItems() = false private fun triggerUpdate() { - getActivity()?.startService(Intent(requireContext(), FeedLoadService::class.java).apply { - putExtra(FeedLoadService.EXTRA_GROUP_ID, groupId) - }) + getActivity()?.startService( + Intent(requireContext(), FeedLoadService::class.java).apply { + putExtra(FeedLoadService.EXTRA_GROUP_ID, groupId) + } + ) listState = null } diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/FeedState.kt b/app/src/main/java/org/schabi/newpipe/local/feed/FeedState.kt index de3dd3113..00ca76b8e 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/FeedState.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/FeedState.kt @@ -1,8 +1,8 @@ package org.schabi.newpipe.local.feed import androidx.annotation.StringRes -import java.util.Calendar import org.schabi.newpipe.extractor.stream.StreamInfoItem +import java.util.Calendar sealed class FeedState { data class ProgressState( diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/FeedViewModel.kt b/app/src/main/java/org/schabi/newpipe/local/feed/FeedViewModel.kt index 0976de248..84f913409 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/FeedViewModel.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/FeedViewModel.kt @@ -5,12 +5,10 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider -import io.reactivex.Flowable -import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.functions.Function4 -import io.reactivex.schedulers.Schedulers -import java.time.OffsetDateTime -import java.util.concurrent.TimeUnit +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers +import io.reactivex.rxjava3.core.Flowable +import io.reactivex.rxjava3.functions.Function4 +import io.reactivex.rxjava3.schedulers.Schedulers import org.schabi.newpipe.database.feed.model.FeedGroupEntity import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.ktx.toCalendar @@ -20,6 +18,8 @@ import org.schabi.newpipe.local.feed.service.FeedEventManager.Event.IdleEvent import org.schabi.newpipe.local.feed.service.FeedEventManager.Event.ProgressEvent import org.schabi.newpipe.local.feed.service.FeedEventManager.Event.SuccessResultEvent import org.schabi.newpipe.util.DEFAULT_THROTTLE_TIMEOUT +import java.time.OffsetDateTime +import java.util.concurrent.TimeUnit class FeedViewModel(applicationContext: Context, val groupId: Long = FeedGroupEntity.GROUP_ALL_ID) : ViewModel() { class Factory(val context: Context, val groupId: Long = FeedGroupEntity.GROUP_ALL_ID) : ViewModelProvider.Factory { @@ -35,34 +35,34 @@ class FeedViewModel(applicationContext: Context, val groupId: Long = FeedGroupEn val stateLiveData: LiveData = mutableStateLiveData private var combineDisposable = Flowable - .combineLatest( - FeedEventManager.events(), - feedDatabaseManager.asStreamItems(groupId), - feedDatabaseManager.notLoadedCount(groupId), - feedDatabaseManager.oldestSubscriptionUpdate(groupId), + .combineLatest( + FeedEventManager.events(), + feedDatabaseManager.asStreamItems(groupId), + feedDatabaseManager.notLoadedCount(groupId), + feedDatabaseManager.oldestSubscriptionUpdate(groupId), + Function4 { t1: FeedEventManager.Event, t2: List, t3: Long, t4: List -> + return@Function4 CombineResultHolder(t1, t2, t3, t4.firstOrNull()) + } + ) + .throttleLatest(DEFAULT_THROTTLE_TIMEOUT, TimeUnit.MILLISECONDS) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { (event, listFromDB, notLoadedCount, oldestUpdate) -> + val oldestUpdateCalendar = oldestUpdate?.toCalendar() - Function4 { t1: FeedEventManager.Event, t2: List, t3: Long, t4: List -> - return@Function4 CombineResultHolder(t1, t2, t3, t4.firstOrNull()) - } - ) - .throttleLatest(DEFAULT_THROTTLE_TIMEOUT, TimeUnit.MILLISECONDS) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe { (event, listFromDB, notLoadedCount, oldestUpdate) -> - - val oldestUpdateCalendar = oldestUpdate?.toCalendar() - - mutableStateLiveData.postValue(when (event) { + mutableStateLiveData.postValue( + when (event) { is IdleEvent -> FeedState.LoadedState(listFromDB, oldestUpdateCalendar, notLoadedCount) is ProgressEvent -> FeedState.ProgressState(event.currentProgress, event.maxProgress, event.progressMessage) is SuccessResultEvent -> FeedState.LoadedState(listFromDB, oldestUpdateCalendar, notLoadedCount, event.itemsErrors) is ErrorResultEvent -> FeedState.ErrorState(event.error) - }) - - if (event is ErrorResultEvent || event is SuccessResultEvent) { - FeedEventManager.reset() } + ) + + if (event is ErrorResultEvent || event is SuccessResultEvent) { + FeedEventManager.reset() } + } override fun onCleared() { super.onCleared() diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedEventManager.kt b/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedEventManager.kt index b72098345..3d19de9c6 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedEventManager.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedEventManager.kt @@ -1,15 +1,15 @@ package org.schabi.newpipe.local.feed.service import androidx.annotation.StringRes -import io.reactivex.Flowable -import io.reactivex.processors.BehaviorProcessor -import java.util.concurrent.atomic.AtomicBoolean +import io.reactivex.rxjava3.core.Flowable +import io.reactivex.rxjava3.processors.BehaviorProcessor import org.schabi.newpipe.local.feed.service.FeedEventManager.Event.IdleEvent +import java.util.concurrent.atomic.AtomicBoolean object FeedEventManager { private var processor: BehaviorProcessor = BehaviorProcessor.create() private var ignoreUpstream = AtomicBoolean() - private var eventsFlowable = processor.startWith(IdleEvent) + private var eventsFlowable = processor.startWithItem(IdleEvent) fun postEvent(event: Event) { processor.onNext(event) diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadService.kt b/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadService.kt index 8d3afbc7e..ddbbea23d 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadService.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadService.kt @@ -31,21 +31,15 @@ import android.util.Log import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import androidx.preference.PreferenceManager -import io.reactivex.Flowable -import io.reactivex.Notification -import io.reactivex.Single -import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.disposables.CompositeDisposable -import io.reactivex.functions.Consumer -import io.reactivex.functions.Function -import io.reactivex.processors.PublishProcessor -import io.reactivex.schedulers.Schedulers -import java.io.IOException -import java.time.OffsetDateTime -import java.time.ZoneOffset -import java.util.concurrent.TimeUnit -import java.util.concurrent.atomic.AtomicBoolean -import java.util.concurrent.atomic.AtomicInteger +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers +import io.reactivex.rxjava3.core.Flowable +import io.reactivex.rxjava3.core.Notification +import io.reactivex.rxjava3.core.Single +import io.reactivex.rxjava3.disposables.CompositeDisposable +import io.reactivex.rxjava3.functions.Consumer +import io.reactivex.rxjava3.functions.Function +import io.reactivex.rxjava3.processors.PublishProcessor +import io.reactivex.rxjava3.schedulers.Schedulers import org.reactivestreams.Subscriber import org.reactivestreams.Subscription import org.schabi.newpipe.MainActivity.DEBUG @@ -56,13 +50,18 @@ import org.schabi.newpipe.extractor.exceptions.ReCaptchaException import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.local.feed.FeedDatabaseManager import org.schabi.newpipe.local.feed.service.FeedEventManager.Event.ErrorResultEvent -import org.schabi.newpipe.local.feed.service.FeedEventManager.Event.IdleEvent import org.schabi.newpipe.local.feed.service.FeedEventManager.Event.ProgressEvent import org.schabi.newpipe.local.feed.service.FeedEventManager.Event.SuccessResultEvent import org.schabi.newpipe.local.feed.service.FeedEventManager.postEvent import org.schabi.newpipe.local.subscription.SubscriptionManager import org.schabi.newpipe.util.ExceptionUtils import org.schabi.newpipe.util.ExtractorHelper +import java.io.IOException +import java.time.OffsetDateTime +import java.time.ZoneOffset +import java.util.concurrent.TimeUnit +import java.util.concurrent.atomic.AtomicBoolean +import java.util.concurrent.atomic.AtomicInteger class FeedLoadService : Service() { companion object { @@ -109,8 +108,11 @@ class FeedLoadService : Service() { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { if (DEBUG) { - Log.d(TAG, "onStartCommand() called with: intent = [" + intent + "]," + - " flags = [" + flags + "], startId = [" + startId + "]") + Log.d( + TAG, + "onStartCommand() called with: intent = [" + intent + "]," + + " flags = [" + flags + "], startId = [" + startId + "]" + ) } if (intent == null || loadingSubscription != null) { @@ -123,10 +125,10 @@ class FeedLoadService : Service() { val groupId = intent.getLongExtra(EXTRA_GROUP_ID, FeedGroupEntity.GROUP_ALL_ID) val useFeedExtractor = defaultSharedPreferences - .getBoolean(getString(R.string.feed_use_dedicated_fetch_method_key), false) + .getBoolean(getString(R.string.feed_use_dedicated_fetch_method_key), false) val thresholdOutdatedSecondsString = defaultSharedPreferences - .getString(getString(R.string.feed_update_threshold_key), getString(R.string.feed_update_threshold_default_value)) + .getString(getString(R.string.feed_update_threshold_key), getString(R.string.feed_update_threshold_default_value)) val thresholdOutdatedSeconds = thresholdOutdatedSecondsString!!.toInt() startLoading(groupId, useFeedExtractor, thresholdOutdatedSeconds) @@ -181,63 +183,63 @@ class FeedLoadService : Service() { } subscriptions - .limit(1) + .take(1) - .doOnNext { - currentProgress.set(0) - maxProgress.set(it.size) + .doOnNext { + currentProgress.set(0) + maxProgress.set(it.size) + } + .filter { it.isNotEmpty() } + + .observeOn(AndroidSchedulers.mainThread()) + .doOnNext { + startForeground(NOTIFICATION_ID, notificationBuilder.build()) + updateNotificationProgress(null) + broadcastProgress() + } + + .observeOn(Schedulers.io()) + .flatMap { Flowable.fromIterable(it) } + .takeWhile { !cancelSignal.get() } + + .parallel(PARALLEL_EXTRACTIONS, PARALLEL_EXTRACTIONS * 2) + .runOn(Schedulers.io(), PARALLEL_EXTRACTIONS * 2) + .filter { !cancelSignal.get() } + + .map { subscriptionEntity -> + try { + val listInfo = if (useFeedExtractor) { + ExtractorHelper + .getFeedInfoFallbackToChannelInfo(subscriptionEntity.serviceId, subscriptionEntity.url) + .blockingGet() + } else { + ExtractorHelper + .getChannelInfo(subscriptionEntity.serviceId, subscriptionEntity.url, true) + .blockingGet() + } as ListInfo + + return@map Notification.createOnNext(Pair(subscriptionEntity.uid, listInfo)) + } catch (e: Throwable) { + val request = "${subscriptionEntity.serviceId}:${subscriptionEntity.url}" + val wrapper = RequestException(subscriptionEntity.uid, request, e) + return@map Notification.createOnError>>(wrapper) } - .filter { it.isNotEmpty() } + } + .sequential() - .observeOn(AndroidSchedulers.mainThread()) - .doOnNext { - startForeground(NOTIFICATION_ID, notificationBuilder.build()) - updateNotificationProgress(null) - broadcastProgress() - } + .observeOn(AndroidSchedulers.mainThread()) + .doOnNext(errorHandlingConsumer) - .observeOn(Schedulers.io()) - .flatMap { Flowable.fromIterable(it) } - .takeWhile { !cancelSignal.get() } + .observeOn(AndroidSchedulers.mainThread()) + .doOnNext(notificationsConsumer) - .parallel(PARALLEL_EXTRACTIONS, PARALLEL_EXTRACTIONS * 2) - .runOn(Schedulers.io(), PARALLEL_EXTRACTIONS * 2) - .filter { !cancelSignal.get() } + .observeOn(Schedulers.io()) + .buffer(BUFFER_COUNT_BEFORE_INSERT) + .doOnNext(databaseConsumer) - .map { subscriptionEntity -> - try { - val listInfo = if (useFeedExtractor) { - ExtractorHelper - .getFeedInfoFallbackToChannelInfo(subscriptionEntity.serviceId, subscriptionEntity.url) - .blockingGet() - } else { - ExtractorHelper - .getChannelInfo(subscriptionEntity.serviceId, subscriptionEntity.url, true) - .blockingGet() - } as ListInfo - - return@map Notification.createOnNext(Pair(subscriptionEntity.uid, listInfo)) - } catch (e: Throwable) { - val request = "${subscriptionEntity.serviceId}:${subscriptionEntity.url}" - val wrapper = RequestException(subscriptionEntity.uid, request, e) - return@map Notification.createOnError>>(wrapper) - } - } - .sequential() - - .observeOn(AndroidSchedulers.mainThread()) - .doOnNext(errorHandlingConsumer) - - .observeOn(AndroidSchedulers.mainThread()) - .doOnNext(notificationsConsumer) - - .observeOn(Schedulers.io()) - .buffer(BUFFER_COUNT_BEFORE_INSERT) - .doOnNext(databaseConsumer) - - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(resultSubscriber) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(resultSubscriber) } private fun broadcastProgress() { @@ -262,7 +264,7 @@ class FeedLoadService : Service() { override fun onComplete() { if (maxProgress.get() == 0) { - postEvent(IdleEvent) + postEvent(FeedEventManager.Event.IdleEvent) stopService() return @@ -274,7 +276,8 @@ class FeedLoadService : Service() { notificationUpdater.onNext(getString(R.string.feed_processing_message)) postEvent(ProgressEvent(R.string.feed_processing_message)) - disposables.add(Single + disposables.add( + Single .fromCallable { feedResultsHolder.ready() @@ -293,7 +296,8 @@ class FeedLoadService : Service() { return@subscribe } stopService() - }) + } + ) } } @@ -364,16 +368,18 @@ class FeedLoadService : Service() { private var maxProgress = AtomicInteger(-1) private fun createNotification(): NotificationCompat.Builder { - val cancelActionIntent = PendingIntent.getBroadcast(this, - NOTIFICATION_ID, Intent(ACTION_CANCEL), 0) + val cancelActionIntent = PendingIntent.getBroadcast( + this, + NOTIFICATION_ID, Intent(ACTION_CANCEL), 0 + ) return NotificationCompat.Builder(this, getString(R.string.notification_channel_id)) - .setOngoing(true) - .setProgress(-1, -1, true) - .setSmallIcon(R.drawable.ic_newpipe_triangle_white) - .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) - .addAction(0, getString(R.string.cancel), cancelActionIntent) - .setContentTitle(getString(R.string.feed_notification_loading)) + .setOngoing(true) + .setProgress(-1, -1, true) + .setSmallIcon(R.drawable.ic_newpipe_triangle_white) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + .addAction(0, getString(R.string.cancel), cancelActionIntent) + .setContentTitle(getString(R.string.feed_notification_loading)) } private fun setupNotification() { @@ -381,13 +387,15 @@ class FeedLoadService : Service() { notificationBuilder = createNotification() val throttleAfterFirstEmission = Function { flow: Flowable -> - flow.limit(1).concatWith(flow.skip(1).throttleLatest(NOTIFICATION_SAMPLING_PERIOD.toLong(), TimeUnit.MILLISECONDS)) + flow.take(1).concatWith(flow.skip(1).throttleLatest(NOTIFICATION_SAMPLING_PERIOD.toLong(), TimeUnit.MILLISECONDS)) } - disposables.add(notificationUpdater + disposables.add( + notificationUpdater .publish(throttleAfterFirstEmission) .observeOn(AndroidSchedulers.mainThread()) - .subscribe(this::updateNotificationProgress)) + .subscribe(this::updateNotificationProgress) + ) } private fun updateNotificationProgress(updateDescription: String?) { diff --git a/app/src/main/java/org/schabi/newpipe/local/history/HistoryRecordManager.java b/app/src/main/java/org/schabi/newpipe/local/history/HistoryRecordManager.java index 7f5c4f7a7..66f1bda0e 100644 --- a/app/src/main/java/org/schabi/newpipe/local/history/HistoryRecordManager.java +++ b/app/src/main/java/org/schabi/newpipe/local/history/HistoryRecordManager.java @@ -50,11 +50,11 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; -import io.reactivex.Completable; -import io.reactivex.Flowable; -import io.reactivex.Maybe; -import io.reactivex.Single; -import io.reactivex.schedulers.Schedulers; +import io.reactivex.rxjava3.core.Completable; +import io.reactivex.rxjava3.core.Flowable; +import io.reactivex.rxjava3.core.Maybe; +import io.reactivex.rxjava3.core.Single; +import io.reactivex.rxjava3.schedulers.Schedulers; public class HistoryRecordManager { private final AppDatabase database; diff --git a/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java index 511e3c7a3..9750d9820 100644 --- a/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/history/StatisticsPlaylistFragment.java @@ -49,9 +49,9 @@ import java.util.Comparator; import java.util.List; import icepick.State; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.CompositeDisposable; -import io.reactivex.disposables.Disposable; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.disposables.CompositeDisposable; +import io.reactivex.rxjava3.disposables.Disposable; public class StatisticsPlaylistFragment extends BaseLocalListFragment, Void> { diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java index 71df07a4b..a8974e018 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistFragment.java @@ -55,13 +55,12 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import icepick.State; -import io.reactivex.Flowable; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.CompositeDisposable; -import io.reactivex.disposables.Disposable; -import io.reactivex.disposables.Disposables; -import io.reactivex.schedulers.Schedulers; -import io.reactivex.subjects.PublishSubject; +import io.reactivex.rxjava3.core.Flowable; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.disposables.CompositeDisposable; +import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.schedulers.Schedulers; +import io.reactivex.rxjava3.subjects.PublishSubject; import static org.schabi.newpipe.util.AnimationUtils.animateView; @@ -641,7 +640,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment() { private lateinit var viewModel: SubscriptionViewModel @@ -208,14 +208,19 @@ class SubscriptionFragment : BaseStateFragment() { if (!exportFile.parentFile.canWrite() || !exportFile.parentFile.canRead()) { Toast.makeText(activity, R.string.invalid_directory, Toast.LENGTH_SHORT).show() } else { - activity.startService(Intent(activity, SubscriptionsExportService::class.java) - .putExtra(KEY_FILE_PATH, exportFile.absolutePath)) + activity.startService( + Intent(activity, SubscriptionsExportService::class.java) + .putExtra(KEY_FILE_PATH, exportFile.absolutePath) + ) } } else if (requestCode == REQUEST_IMPORT_CODE) { val path = Utils.getFileForUri(data.data!!).absolutePath - ImportConfirmationDialog.show(this, Intent(activity, SubscriptionsImportService::class.java) + ImportConfirmationDialog.show( + this, + Intent(activity, SubscriptionsImportService::class.java) .putExtra(KEY_MODE, PREVIOUS_EXPORT_MODE) - .putExtra(KEY_VALUE, path)) + .putExtra(KEY_VALUE, path) + ) } } } @@ -247,9 +252,9 @@ class SubscriptionFragment : BaseStateFragment() { feedGroupsCarousel = FeedGroupCarouselItem(requireContext(), carouselAdapter) feedGroupsSortMenuItem = HeaderWithMenuItem( - getString(R.string.feed_groups_header_title), - ThemeHelper.resolveResourceIdFromAttr(requireContext(), R.attr.ic_sort), - menuItemOnClickListener = ::openReorderDialog + getString(R.string.feed_groups_header_title), + ThemeHelper.resolveResourceIdFromAttr(requireContext(), R.attr.ic_sort), + menuItemOnClickListener = ::openReorderDialog ) add(Section(feedGroupsSortMenuItem, listOf(feedGroupsCarousel))) @@ -260,10 +265,11 @@ class SubscriptionFragment : BaseStateFragment() { subscriptionsSection.setHideWhenEmpty(true) importExportItem = FeedImportExportItem( - { onImportPreviousSelected() }, - { onImportFromServiceSelected(it) }, - { onExportSelected() }, - importExportItemExpandedState ?: false) + { onImportPreviousSelected() }, + { onImportFromServiceSelected(it) }, + { onExportSelected() }, + importExportItemExpandedState ?: false + ) groupAdapter.add(Section(importExportItem, listOf(subscriptionsSection))) } @@ -284,8 +290,8 @@ class SubscriptionFragment : BaseStateFragment() { private fun showLongTapDialog(selectedItem: ChannelInfoItem) { val commands = arrayOf( - getString(R.string.share), - getString(R.string.unsubscribe) + getString(R.string.share), + getString(R.string.unsubscribe) ) val actions = DialogInterface.OnClickListener { _, i -> @@ -301,16 +307,18 @@ class SubscriptionFragment : BaseStateFragment() { bannerView.itemAdditionalDetails.visibility = View.GONE AlertDialog.Builder(requireContext()) - .setCustomTitle(bannerView) - .setItems(commands, actions) - .create() - .show() + .setCustomTitle(bannerView) + .setItems(commands, actions) + .create() + .show() } private fun deleteChannel(selectedItem: ChannelInfoItem) { - disposables.add(subscriptionManager.deleteSubscription(selectedItem.serviceId, selectedItem.url).subscribe { - Toast.makeText(requireContext(), getString(R.string.channel_unsubscribed), Toast.LENGTH_SHORT).show() - }) + disposables.add( + subscriptionManager.deleteSubscription(selectedItem.serviceId, selectedItem.url).subscribe { + Toast.makeText(requireContext(), getString(R.string.channel_unsubscribed), Toast.LENGTH_SHORT).show() + } + ) } override fun doInitialLoadLogic() = Unit @@ -332,8 +340,10 @@ class SubscriptionFragment : BaseStateFragment() { } private val listenerChannelItem = object : OnClickGesture() { - override fun selected(selectedItem: ChannelInfoItem) = NavigationHelper.openChannelFragment(fm, - selectedItem.serviceId, selectedItem.url, selectedItem.name) + override fun selected(selectedItem: ChannelInfoItem) = NavigationHelper.openChannelFragment( + fm, + selectedItem.serviceId, selectedItem.url, selectedItem.name + ) override fun held(selectedItem: ChannelInfoItem) = showLongTapDialog(selectedItem) } @@ -420,14 +430,16 @@ class SubscriptionFragment : BaseStateFragment() { private fun shouldUseGridLayout(): Boolean { val listMode = PreferenceManager.getDefaultSharedPreferences(requireContext()) - .getString(getString(R.string.list_view_mode_key), getString(R.string.list_view_mode_value)) + .getString(getString(R.string.list_view_mode_key), getString(R.string.list_view_mode_value)) return when (listMode) { getString(R.string.list_view_mode_auto_key) -> { val configuration = resources.configuration - (configuration.orientation == Configuration.ORIENTATION_LANDSCAPE && - configuration.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE)) + ( + configuration.orientation == Configuration.ORIENTATION_LANDSCAPE && + configuration.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE) + ) } getString(R.string.list_view_mode_grid_key) -> true else -> false diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt index 2740591e6..fb9cffa98 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionManager.kt @@ -1,10 +1,10 @@ package org.schabi.newpipe.local.subscription import android.content.Context -import io.reactivex.Completable -import io.reactivex.Flowable -import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.schedulers.Schedulers +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers +import io.reactivex.rxjava3.core.Completable +import io.reactivex.rxjava3.core.Flowable +import io.reactivex.rxjava3.schedulers.Schedulers import org.schabi.newpipe.NewPipeDatabase import org.schabi.newpipe.database.feed.model.FeedGroupEntity import org.schabi.newpipe.database.subscription.SubscriptionDAO @@ -32,7 +32,8 @@ class SubscriptionManager(context: Context) { filterQuery.isNotEmpty() -> { return if (showOnlyUngrouped) { subscriptionTable.getSubscriptionsOnlyUngroupedFiltered( - currentGroupId, filterQuery) + currentGroupId, filterQuery + ) } else { subscriptionTable.getSubscriptionsFiltered(filterQuery) } @@ -44,7 +45,8 @@ class SubscriptionManager(context: Context) { fun upsertAll(infoList: List): List { val listEntities = subscriptionTable.upsertAll( - infoList.map { SubscriptionEntity.from(it) }) + infoList.map { SubscriptionEntity.from(it) } + ) database.runInTransaction { infoList.forEachIndexed { index, info -> diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionViewModel.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionViewModel.kt index b7f16c319..da009e1a0 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionViewModel.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionViewModel.kt @@ -5,12 +5,12 @@ import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import com.xwray.groupie.Group -import io.reactivex.schedulers.Schedulers -import java.util.concurrent.TimeUnit +import io.reactivex.rxjava3.schedulers.Schedulers import org.schabi.newpipe.local.feed.FeedDatabaseManager import org.schabi.newpipe.local.subscription.item.ChannelItem import org.schabi.newpipe.local.subscription.item.FeedGroupCardItem import org.schabi.newpipe.util.DEFAULT_THROTTLE_TIMEOUT +import java.util.concurrent.TimeUnit class SubscriptionViewModel(application: Application) : AndroidViewModel(application) { private var feedDatabaseManager: FeedDatabaseManager = FeedDatabaseManager(application) @@ -22,22 +22,22 @@ class SubscriptionViewModel(application: Application) : AndroidViewModel(applica val feedGroupsLiveData: LiveData> = mutableFeedGroupsLiveData private var feedGroupItemsDisposable = feedDatabaseManager.groups() - .throttleLatest(DEFAULT_THROTTLE_TIMEOUT, TimeUnit.MILLISECONDS) - .map { it.map(::FeedGroupCardItem) } - .subscribeOn(Schedulers.io()) - .subscribe( - { mutableFeedGroupsLiveData.postValue(it) }, - { mutableStateLiveData.postValue(SubscriptionState.ErrorState(it)) } - ) + .throttleLatest(DEFAULT_THROTTLE_TIMEOUT, TimeUnit.MILLISECONDS) + .map { it.map(::FeedGroupCardItem) } + .subscribeOn(Schedulers.io()) + .subscribe( + { mutableFeedGroupsLiveData.postValue(it) }, + { mutableStateLiveData.postValue(SubscriptionState.ErrorState(it)) } + ) private var stateItemsDisposable = subscriptionManager.subscriptions() - .throttleLatest(DEFAULT_THROTTLE_TIMEOUT, TimeUnit.MILLISECONDS) - .map { it.map { entity -> ChannelItem(entity.toChannelInfoItem(), entity.uid, ChannelItem.ItemVersion.MINI) } } - .subscribeOn(Schedulers.io()) - .subscribe( - { mutableStateLiveData.postValue(SubscriptionState.LoadedState(it)) }, - { mutableStateLiveData.postValue(SubscriptionState.ErrorState(it)) } - ) + .throttleLatest(DEFAULT_THROTTLE_TIMEOUT, TimeUnit.MILLISECONDS) + .map { it.map { entity -> ChannelItem(entity.toChannelInfoItem(), entity.uid, ChannelItem.ItemVersion.MINI) } } + .subscribeOn(Schedulers.io()) + .subscribe( + { mutableStateLiveData.postValue(SubscriptionState.LoadedState(it)) }, + { mutableStateLiveData.postValue(SubscriptionState.ErrorState(it)) } + ) override fun onCleared() { super.onCleared() diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupDialog.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupDialog.kt index 9f82aefb7..1d5650a99 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupDialog.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupDialog.kt @@ -24,8 +24,6 @@ import com.xwray.groupie.Section import com.xwray.groupie.kotlinandroidextensions.GroupieViewHolder import icepick.Icepick import icepick.State -import java.io.Serializable -import kotlin.collections.contains import kotlinx.android.synthetic.main.dialog_feed_group_create.* import kotlinx.android.synthetic.main.toolbar_search_layout.* import org.schabi.newpipe.R @@ -43,6 +41,8 @@ import org.schabi.newpipe.local.subscription.item.PickerIconItem import org.schabi.newpipe.local.subscription.item.PickerSubscriptionItem import org.schabi.newpipe.util.DeviceUtils import org.schabi.newpipe.util.ThemeHelper +import java.io.Serializable +import kotlin.collections.contains class FeedGroupDialog : DialogFragment(), BackPressable { private lateinit var viewModel: FeedGroupDialogViewModel @@ -116,21 +116,30 @@ class FeedGroupDialog : DialogFragment(), BackPressable { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - viewModel = ViewModelProvider(this, - FeedGroupDialogViewModel.Factory(requireContext(), - groupId, subscriptionsCurrentSearchQuery, subscriptionsShowOnlyUngrouped) + viewModel = ViewModelProvider( + this, + FeedGroupDialogViewModel.Factory( + requireContext(), + groupId, subscriptionsCurrentSearchQuery, subscriptionsShowOnlyUngrouped + ) ).get(FeedGroupDialogViewModel::class.java) viewModel.groupLiveData.observe(viewLifecycleOwner, Observer(::handleGroup)) - viewModel.subscriptionsLiveData.observe(viewLifecycleOwner, Observer { - setupSubscriptionPicker(it.first, it.second) - }) - viewModel.dialogEventLiveData.observe(viewLifecycleOwner, Observer { - when (it) { - ProcessingEvent -> disableInput() - SuccessEvent -> dismiss() + viewModel.subscriptionsLiveData.observe( + viewLifecycleOwner, + Observer { + setupSubscriptionPicker(it.first, it.second) } - }) + ) + viewModel.dialogEventLiveData.observe( + viewLifecycleOwner, + Observer { + when (it) { + ProcessingEvent -> disableInput() + SuccessEvent -> dismiss() + } + } + ) subscriptionGroupAdapter = GroupAdapter().apply { add(subscriptionMainSection) @@ -141,8 +150,10 @@ class FeedGroupDialog : DialogFragment(), BackPressable { // Disable animations, too distracting. itemAnimator = null adapter = subscriptionGroupAdapter - layoutManager = GridLayoutManager(requireContext(), subscriptionGroupAdapter.spanCount, - RecyclerView.VERTICAL, false).apply { + layoutManager = GridLayoutManager( + requireContext(), subscriptionGroupAdapter.spanCount, + RecyclerView.VERTICAL, false + ).apply { spanSizeLookup = subscriptionGroupAdapter.spanSizeLookup } } @@ -346,7 +357,8 @@ class FeedGroupDialog : DialogFragment(), BackPressable { val selectedCount = this.selectedSubscriptions.size val selectedCountText = resources.getQuantityString( R.plurals.feed_group_dialog_selection_count, - selectedCount, selectedCount) + selectedCount, selectedCount + ) selected_subscription_count_view.text = selectedCountText subscriptions_header_info.text = selectedCountText } @@ -401,10 +413,12 @@ class FeedGroupDialog : DialogFragment(), BackPressable { separator.onlyVisibleIn(SubscriptionsPickerScreen, IconPickerScreen) cancel_button.onlyVisibleIn(InitialScreen, DeleteScreen) - confirm_button.setText(when { - currentScreen == InitialScreen && groupId == NO_GROUP_SELECTED -> R.string.create - else -> android.R.string.ok - }) + confirm_button.setText( + when { + currentScreen == InitialScreen && groupId == NO_GROUP_SELECTED -> R.string.create + else -> android.R.string.ok + } + ) delete_button.isGone = currentScreen != InitialScreen || groupId == NO_GROUP_SELECTED @@ -454,8 +468,10 @@ class FeedGroupDialog : DialogFragment(), BackPressable { } private fun hideKeyboardSearch() { - inputMethodManager.hideSoftInputFromWindow(toolbar_search_edit_text.windowToken, - InputMethodManager.RESULT_UNCHANGED_SHOWN) + inputMethodManager.hideSoftInputFromWindow( + toolbar_search_edit_text.windowToken, + InputMethodManager.RESULT_UNCHANGED_SHOWN + ) toolbar_search_edit_text.clearFocus() } @@ -466,8 +482,10 @@ class FeedGroupDialog : DialogFragment(), BackPressable { } private fun hideKeyboard() { - inputMethodManager.hideSoftInputFromWindow(group_name_input.windowToken, - InputMethodManager.RESULT_UNCHANGED_SHOWN) + inputMethodManager.hideSoftInputFromWindow( + group_name_input.windowToken, + InputMethodManager.RESULT_UNCHANGED_SHOWN + ) group_name_input.clearFocus() } diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupDialogViewModel.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupDialogViewModel.kt index 4b1a4df5e..d49df6303 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupDialogViewModel.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupDialogViewModel.kt @@ -5,12 +5,12 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider -import io.reactivex.Completable -import io.reactivex.Flowable -import io.reactivex.disposables.Disposable -import io.reactivex.functions.BiFunction -import io.reactivex.processors.BehaviorProcessor -import io.reactivex.schedulers.Schedulers +import io.reactivex.rxjava3.core.Completable +import io.reactivex.rxjava3.core.Flowable +import io.reactivex.rxjava3.disposables.Disposable +import io.reactivex.rxjava3.functions.BiFunction +import io.reactivex.rxjava3.processors.BehaviorProcessor +import io.reactivex.rxjava3.schedulers.Schedulers import org.schabi.newpipe.database.feed.model.FeedGroupEntity import org.schabi.newpipe.local.feed.FeedDatabaseManager import org.schabi.newpipe.local.subscription.FeedGroupIcon @@ -32,9 +32,9 @@ class FeedGroupDialogViewModel( private var subscriptionsFlowable = Flowable .combineLatest( - filterSubscriptions.startWith(initialQuery), - toggleShowOnlyUngrouped.startWith(initialShowOnlyUngrouped), - BiFunction { t1: String, t2: Boolean -> Filter(t1, t2) } + filterSubscriptions.startWithItem(initialQuery), + toggleShowOnlyUngrouped.startWithItem(initialShowOnlyUngrouped), + BiFunction { t1: String, t2: Boolean -> Filter(t1, t2) } ) .distinctUntilChanged() .switchMap { (query, showOnlyUngrouped) -> @@ -55,8 +55,10 @@ class FeedGroupDialogViewModel( .subscribe(mutableGroupLiveData::postValue) private var subscriptionsDisposable = Flowable - .combineLatest(subscriptionsFlowable, feedDatabaseManager.subscriptionIdsForGroup(groupId), - BiFunction { t1: List, t2: List -> t1 to t2.toSet() }) + .combineLatest( + subscriptionsFlowable, feedDatabaseManager.subscriptionIdsForGroup(groupId), + BiFunction { t1: List, t2: List -> t1 to t2.toSet() } + ) .subscribeOn(Schedulers.io()) .subscribe(mutableSubscriptionsLiveData::postValue) @@ -68,15 +70,19 @@ class FeedGroupDialogViewModel( } fun createGroup(name: String, selectedIcon: FeedGroupIcon, selectedSubscriptions: Set) { - doAction(feedDatabaseManager.createGroup(name, selectedIcon) - .flatMapCompletable { - feedDatabaseManager.updateSubscriptionsForGroup(it, selectedSubscriptions.toList()) - }) + doAction( + feedDatabaseManager.createGroup(name, selectedIcon) + .flatMapCompletable { + feedDatabaseManager.updateSubscriptionsForGroup(it, selectedSubscriptions.toList()) + } + ) } fun updateGroup(name: String, selectedIcon: FeedGroupIcon, selectedSubscriptions: Set, sortOrder: Long) { - doAction(feedDatabaseManager.updateSubscriptionsForGroup(groupId, selectedSubscriptions.toList()) - .andThen(feedDatabaseManager.updateGroup(FeedGroupEntity(groupId, name, selectedIcon, sortOrder)))) + doAction( + feedDatabaseManager.updateSubscriptionsForGroup(groupId, selectedSubscriptions.toList()) + .andThen(feedDatabaseManager.updateGroup(FeedGroupEntity(groupId, name, selectedIcon, sortOrder))) + ) } fun deleteGroup() { @@ -120,8 +126,10 @@ class FeedGroupDialogViewModel( ) : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") override fun create(modelClass: Class): T { - return FeedGroupDialogViewModel(context.applicationContext, - groupId, initialQuery, initialShowOnlyUngrouped) as T + return FeedGroupDialogViewModel( + context.applicationContext, + groupId, initialQuery, initialShowOnlyUngrouped + ) as T } } } diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupReorderDialog.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupReorderDialog.kt index 48f40e219..380bf13f5 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupReorderDialog.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupReorderDialog.kt @@ -16,7 +16,6 @@ import com.xwray.groupie.TouchCallback import com.xwray.groupie.kotlinandroidextensions.GroupieViewHolder import icepick.Icepick import icepick.State -import java.util.Collections import kotlinx.android.synthetic.main.dialog_feed_group_reorder.confirm_button import kotlinx.android.synthetic.main.dialog_feed_group_reorder.feed_groups_list import org.schabi.newpipe.R @@ -25,6 +24,7 @@ import org.schabi.newpipe.local.subscription.dialog.FeedGroupReorderDialogViewMo import org.schabi.newpipe.local.subscription.dialog.FeedGroupReorderDialogViewModel.DialogEvent.SuccessEvent import org.schabi.newpipe.local.subscription.item.FeedGroupReorderItem import org.schabi.newpipe.util.ThemeHelper +import java.util.Collections class FeedGroupReorderDialog : DialogFragment() { private lateinit var viewModel: FeedGroupReorderDialogViewModel @@ -51,12 +51,15 @@ class FeedGroupReorderDialog : DialogFragment() { viewModel = ViewModelProvider(this).get(FeedGroupReorderDialogViewModel::class.java) viewModel.groupsLiveData.observe(viewLifecycleOwner, Observer(::handleGroups)) - viewModel.dialogEventLiveData.observe(viewLifecycleOwner, Observer { - when (it) { - ProcessingEvent -> disableInput() - SuccessEvent -> dismiss() + viewModel.dialogEventLiveData.observe( + viewLifecycleOwner, + Observer { + when (it) { + ProcessingEvent -> disableInput() + SuccessEvent -> dismiss() + } } - }) + ) feed_groups_list.layoutManager = LinearLayoutManager(requireContext()) feed_groups_list.adapter = groupAdapter diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupReorderDialogViewModel.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupReorderDialogViewModel.kt index ea2cbe98f..e1b3429b9 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupReorderDialogViewModel.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/dialog/FeedGroupReorderDialogViewModel.kt @@ -4,9 +4,9 @@ import android.app.Application import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData -import io.reactivex.Completable -import io.reactivex.disposables.Disposable -import io.reactivex.schedulers.Schedulers +import io.reactivex.rxjava3.core.Completable +import io.reactivex.rxjava3.disposables.Disposable +import io.reactivex.rxjava3.schedulers.Schedulers import org.schabi.newpipe.database.feed.model.FeedGroupEntity import org.schabi.newpipe.local.feed.FeedDatabaseManager @@ -21,9 +21,9 @@ class FeedGroupReorderDialogViewModel(application: Application) : AndroidViewMod private var actionProcessingDisposable: Disposable? = null private var groupsDisposable = feedDatabaseManager.groups() - .limit(1) - .subscribeOn(Schedulers.io()) - .subscribe(mutableGroupsLiveData::postValue) + .take(1) + .subscribeOn(Schedulers.io()) + .subscribe(mutableGroupsLiveData::postValue) override fun onCleared() { super.onCleared() @@ -40,8 +40,8 @@ class FeedGroupReorderDialogViewModel(application: Application) : AndroidViewMod mutableDialogEventLiveData.value = DialogEvent.ProcessingEvent actionProcessingDisposable = completable - .subscribeOn(Schedulers.io()) - .subscribe { mutableDialogEventLiveData.postValue(DialogEvent.SuccessEvent) } + .subscribeOn(Schedulers.io()) + .subscribe { mutableDialogEventLiveData.postValue(DialogEvent.SuccessEvent) } } } diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/item/ChannelItem.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/item/ChannelItem.kt index f33c58f43..8089f6480 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/item/ChannelItem.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/item/ChannelItem.kt @@ -36,8 +36,10 @@ class ChannelItem( viewHolder.itemAdditionalDetails.text = getDetailLine(viewHolder.root.context) if (itemVersion == ItemVersion.NORMAL) viewHolder.itemChannelDescriptionView.text = infoItem.description - ImageLoader.getInstance().displayImage(infoItem.thumbnailUrl, viewHolder.itemThumbnailView, - ImageDisplayConstants.DISPLAY_THUMBNAIL_OPTIONS) + ImageLoader.getInstance().displayImage( + infoItem.thumbnailUrl, viewHolder.itemThumbnailView, + ImageDisplayConstants.DISPLAY_THUMBNAIL_OPTIONS + ) gesturesListener?.run { viewHolder.containerView.setOnClickListener { selected(infoItem) } diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/item/FeedGroupReorderItem.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/item/FeedGroupReorderItem.kt index 717e2410a..e56bb408c 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/item/FeedGroupReorderItem.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/item/FeedGroupReorderItem.kt @@ -20,7 +20,7 @@ data class FeedGroupReorderItem( val dragCallback: ItemTouchHelper ) : Item() { constructor (feedGroupEntity: FeedGroupEntity, dragCallback: ItemTouchHelper) : - this(feedGroupEntity.uid, feedGroupEntity.name, feedGroupEntity.icon, dragCallback) + this(feedGroupEntity.uid, feedGroupEntity.name, feedGroupEntity.icon, dragCallback) override fun getId(): Long { return when (groupId) { diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/item/FeedImportExportItem.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/item/FeedImportExportItem.kt index 5478dcac4..5fd70a684 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/item/FeedImportExportItem.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/item/FeedImportExportItem.kt @@ -49,8 +49,10 @@ class FeedImportExportItem( expandIconListener?.let { viewHolder.import_export_options.removeListener(it) } expandIconListener = CollapsibleView.StateListener { newState -> - AnimationUtils.animateRotation(viewHolder.import_export_expand_icon, - 250, if (newState == CollapsibleView.COLLAPSED) 0 else 180) + AnimationUtils.animateRotation( + viewHolder.import_export_expand_icon, + 250, if (newState == CollapsibleView.COLLAPSED) 0 else 180 + ) } viewHolder.import_export_options.currentState = if (isExpanded) CollapsibleView.EXPANDED else CollapsibleView.COLLAPSED @@ -85,8 +87,10 @@ class FeedImportExportItem( } private fun setupImportFromItems(listHolder: ViewGroup) { - val previousBackupItem = addItemView(listHolder.context.getString(R.string.previous_export), - ThemeHelper.resolveResourceIdFromAttr(listHolder.context, R.attr.ic_backup), listHolder) + val previousBackupItem = addItemView( + listHolder.context.getString(R.string.previous_export), + ThemeHelper.resolveResourceIdFromAttr(listHolder.context, R.attr.ic_backup), listHolder + ) previousBackupItem.setOnClickListener { onImportPreviousSelected() } val iconColor = if (ThemeHelper.isLightThemeSelected(listHolder.context)) Color.BLACK else Color.WHITE @@ -112,8 +116,10 @@ class FeedImportExportItem( } private fun setupExportToItems(listHolder: ViewGroup) { - val previousBackupItem = addItemView(listHolder.context.getString(R.string.file), - ThemeHelper.resolveResourceIdFromAttr(listHolder.context, R.attr.ic_save), listHolder) + val previousBackupItem = addItemView( + listHolder.context.getString(R.string.file), + ThemeHelper.resolveResourceIdFromAttr(listHolder.context, R.attr.ic_save), listHolder + ) previousBackupItem.setOnClickListener { onExportSelected() } } } diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/item/HeaderWithMenuItem.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/item/HeaderWithMenuItem.kt index 142bba433..b5aa6b1d0 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/item/HeaderWithMenuItem.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/item/HeaderWithMenuItem.kt @@ -36,11 +36,11 @@ class HeaderWithMenuItem( viewHolder.header_menu_item.setImageResource(itemIcon) val listener: OnClickListener? = - onClickListener?.let { OnClickListener { onClickListener.invoke() } } + onClickListener?.let { OnClickListener { onClickListener.invoke() } } viewHolder.root.setOnClickListener(listener) val menuItemListener: OnClickListener? = - menuItemOnClickListener?.let { OnClickListener { menuItemOnClickListener.invoke() } } + menuItemOnClickListener?.let { OnClickListener { menuItemOnClickListener.invoke() } } viewHolder.header_menu_item.setOnClickListener(menuItemListener) updateMenuItemVisibility(viewHolder) } diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/item/PickerSubscriptionItem.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/item/PickerSubscriptionItem.kt index df84c115a..fd98d0447 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/item/PickerSubscriptionItem.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/item/PickerSubscriptionItem.kt @@ -22,8 +22,10 @@ data class PickerSubscriptionItem( override fun getSpanSize(spanCount: Int, position: Int): Int = 1 override fun bind(viewHolder: GroupieViewHolder, position: Int) { - ImageLoader.getInstance().displayImage(subscriptionEntity.avatarUrl, - viewHolder.thumbnail_view, ImageDisplayConstants.DISPLAY_AVATAR_OPTIONS) + ImageLoader.getInstance().displayImage( + subscriptionEntity.avatarUrl, + viewHolder.thumbnail_view, ImageDisplayConstants.DISPLAY_AVATAR_OPTIONS + ) viewHolder.title_view.text = subscriptionEntity.name viewHolder.selected_highlight.isVisible = isSelected @@ -39,7 +41,9 @@ data class PickerSubscriptionItem( fun updateSelected(containerView: View, isSelected: Boolean) { this.isSelected = isSelected - animateView(containerView.selected_highlight, - AnimationUtils.Type.LIGHT_SCALE_AND_ALPHA, isSelected, 150) + animateView( + containerView.selected_highlight, + AnimationUtils.Type.LIGHT_SCALE_AND_ALPHA, isSelected, 150 + ) } } diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/services/BaseImportExportService.java b/app/src/main/java/org/schabi/newpipe/local/subscription/services/BaseImportExportService.java index 9b9a55afb..73c0d23a0 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/services/BaseImportExportService.java +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/services/BaseImportExportService.java @@ -46,11 +46,11 @@ import java.util.Collections; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import io.reactivex.Flowable; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.CompositeDisposable; -import io.reactivex.functions.Function; -import io.reactivex.processors.PublishProcessor; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.core.Flowable; +import io.reactivex.rxjava3.disposables.CompositeDisposable; +import io.reactivex.rxjava3.functions.Function; +import io.reactivex.rxjava3.processors.PublishProcessor; public abstract class BaseImportExportService extends Service { protected final String TAG = this.getClass().getSimpleName(); @@ -120,7 +120,7 @@ public abstract class BaseImportExportService extends Service { startForeground(getNotificationId(), notificationBuilder.build()); final Function, Publisher> throttleAfterFirstEmission = flow -> - flow.limit(1).concatWith(flow.skip(1) + flow.take(1).concatWith(flow.skip(1) .throttleLast(NOTIFICATION_SAMPLING_PERIOD, TimeUnit.MILLISECONDS)); disposables.add(notificationUpdater diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsExportService.java b/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsExportService.java index f7d099712..982701d1f 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsExportService.java +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsExportService.java @@ -37,9 +37,9 @@ import java.io.FileOutputStream; import java.util.ArrayList; import java.util.List; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.functions.Function; -import io.reactivex.schedulers.Schedulers; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.functions.Function; +import io.reactivex.rxjava3.schedulers.Schedulers; import static org.schabi.newpipe.MainActivity.DEBUG; diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java b/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java index 51afc9fda..b1c67719c 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java @@ -46,12 +46,12 @@ import java.io.InputStream; import java.util.ArrayList; import java.util.List; -import io.reactivex.Flowable; -import io.reactivex.Notification; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.functions.Consumer; -import io.reactivex.functions.Function; -import io.reactivex.schedulers.Schedulers; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.core.Flowable; +import io.reactivex.rxjava3.core.Notification; +import io.reactivex.rxjava3.functions.Consumer; +import io.reactivex.rxjava3.functions.Function; +import io.reactivex.rxjava3.schedulers.Schedulers; import static org.schabi.newpipe.MainActivity.DEBUG; diff --git a/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java b/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java index 4790dc029..ac205d2d4 100644 --- a/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java @@ -27,13 +27,13 @@ import android.content.SharedPreferences; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.media.AudioManager; -import androidx.preference.PreferenceManager; import android.util.Log; import android.view.View; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.preference.PreferenceManager; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.DefaultRenderersFactory; @@ -77,17 +77,16 @@ import org.schabi.newpipe.util.SerializedCache; import java.io.IOException; -import io.reactivex.Observable; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.CompositeDisposable; -import io.reactivex.disposables.Disposable; -import io.reactivex.disposables.SerialDisposable; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.disposables.CompositeDisposable; +import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.disposables.SerialDisposable; import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_INTERNAL; import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_PERIOD_TRANSITION; import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_SEEK; import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_SEEK_ADJUSTMENT; -import static io.reactivex.android.schedulers.AndroidSchedulers.mainThread; import static java.util.concurrent.TimeUnit.MILLISECONDS; /** @@ -720,8 +719,9 @@ public abstract class BasePlayer implements } private Disposable getProgressReactor() { - return Observable.interval(PROGRESS_LOOP_INTERVAL_MILLIS, MILLISECONDS, mainThread()) - .observeOn(mainThread()) + return Observable.interval(PROGRESS_LOOP_INTERVAL_MILLIS, MILLISECONDS, + AndroidSchedulers.mainThread()) + .observeOn(AndroidSchedulers.mainThread()) .subscribe(ignored -> triggerProgressUpdate(), error -> Log.e(TAG, "Progress update failure: ", error)); } @@ -1319,7 +1319,7 @@ public abstract class BasePlayer implements final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); if (prefs.getBoolean(context.getString(R.string.enable_watch_history_key), true)) { final Disposable stateSaver = recordManager.saveStreamState(info, progress) - .observeOn(mainThread()) + .observeOn(AndroidSchedulers.mainThread()) .doOnError((e) -> { if (DEBUG) { e.printStackTrace(); @@ -1339,7 +1339,7 @@ public abstract class BasePlayer implements if (prefs.getBoolean(context.getString(R.string.enable_watch_history_key), true)) { final Disposable stateSaver = queueItem.getStream() .flatMapCompletable(info -> recordManager.saveStreamState(info, 0)) - .observeOn(mainThread()) + .observeOn(AndroidSchedulers.mainThread()) .doOnError((e) -> { if (DEBUG) { e.printStackTrace(); 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 5bd13a569..043e7f31d 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 @@ -118,22 +118,30 @@ abstract class BasePlayerGestureListener( initSecPointerX = event.getX(1) initSecPointerY = event.getY(1) // record distance between fingers - initPointerDistance = hypot(initFirstPointerX - initSecPointerX.toDouble(), - initFirstPointerY - initSecPointerY.toDouble()) + initPointerDistance = hypot( + initFirstPointerX - initSecPointerX.toDouble(), + initFirstPointerY - initSecPointerY.toDouble() + ) isResizing = true } if (event.action == MotionEvent.ACTION_MOVE && !isMovingInPopup && isResizing) { if (DEBUG) { - Log.d(TAG, "onTouch() ACTION_MOVE > v = [$v], e1.getRaw = [${event.rawX}" + - ", ${event.rawY}]") + Log.d( + TAG, + "onTouch() ACTION_MOVE > v = [$v], e1.getRaw =" + + "[${event.rawX}, ${event.rawY}]" + ) } return handleMultiDrag(event) } if (event.action == MotionEvent.ACTION_UP) { if (DEBUG) { - Log.d(TAG, "onTouch() ACTION_UP > v = [$v], e1.getRaw = [${event.rawX}" + - ", ${event.rawY}]") + Log.d( + TAG, + "onTouch() ACTION_UP > v = [$v], e1.getRaw =" + + " [${event.rawX}, ${event.rawY}]" + ) } if (isMovingInPopup) { isMovingInPopup = false @@ -163,18 +171,24 @@ abstract class BasePlayerGestureListener( private fun handleMultiDrag(event: MotionEvent): Boolean { if (initPointerDistance != -1.0 && event.pointerCount == 2) { // get the movements of the fingers - val firstPointerMove = hypot(event.getX(0) - initFirstPointerX.toDouble(), - event.getY(0) - initFirstPointerY.toDouble()) - val secPointerMove = hypot(event.getX(1) - initSecPointerX.toDouble(), - event.getY(1) - initSecPointerY.toDouble()) + val firstPointerMove = hypot( + event.getX(0) - initFirstPointerX.toDouble(), + event.getY(0) - initFirstPointerY.toDouble() + ) + val secPointerMove = hypot( + event.getX(1) - initSecPointerX.toDouble(), + event.getY(1) - initSecPointerY.toDouble() + ) // minimum threshold beyond which pinch gesture will work val minimumMove = ViewConfiguration.get(service).scaledTouchSlop if (max(firstPointerMove, secPointerMove) > minimumMove) { // calculate current distance between the pointers - val currentPointerDistance = hypot(event.getX(0) - event.getX(1).toDouble(), - event.getY(0) - event.getY(1).toDouble()) + val currentPointerDistance = hypot( + event.getX(0) - event.getX(1).toDouble(), + event.getY(0) - event.getY(1).toDouble() + ) val popupWidth = playerImpl.popupWidth.toDouble() // change co-ordinates of popup so the center stays at the same position @@ -187,7 +201,8 @@ abstract class BasePlayerGestureListener( playerImpl.updatePopupSize( min(playerImpl.screenWidth.toDouble(), newWidth).toInt(), - -1) + -1 + ) return true } } @@ -316,22 +331,30 @@ abstract class BasePlayerGestureListener( } val isTouchingStatusBar: Boolean = initialEvent.y < getStatusBarHeight(service) - val isTouchingNavigationBar: Boolean = (initialEvent.y - > playerImpl.rootView.height - getNavigationBarHeight(service)) + val isTouchingNavigationBar: Boolean = + initialEvent.y > (playerImpl.rootView.height - getNavigationBarHeight(service)) if (isTouchingStatusBar || isTouchingNavigationBar) { return false } val insideThreshold = abs(movingEvent.y - initialEvent.y) <= MOVEMENT_THRESHOLD - if (!isMovingInMain && (insideThreshold || abs(distanceX) > abs(distanceY)) || - playerImpl.currentState == BasePlayer.STATE_COMPLETED) { + if ( + !isMovingInMain && (insideThreshold || abs(distanceX) > abs(distanceY)) || + playerImpl.currentState == BasePlayer.STATE_COMPLETED + ) { return false } isMovingInMain = true - onScroll(MainPlayer.PlayerType.VIDEO, getDisplayHalfPortion(initialEvent), - initialEvent, movingEvent, distanceX, distanceY) + onScroll( + MainPlayer.PlayerType.VIDEO, + getDisplayHalfPortion(initialEvent), + initialEvent, + movingEvent, + distanceX, + distanceY + ) return true } @@ -373,8 +396,14 @@ abstract class BasePlayerGestureListener( playerImpl.popupLayoutParams.x = posX.toInt() playerImpl.popupLayoutParams.y = posY.toInt() - onScroll(MainPlayer.PlayerType.POPUP, getDisplayHalfPortion(initialEvent), - initialEvent, movingEvent, distanceX, distanceY) + onScroll( + MainPlayer.PlayerType.POPUP, + getDisplayHalfPortion(initialEvent), + initialEvent, + movingEvent, + distanceX, + distanceY + ) playerImpl.windowManager .updateViewLayout(playerImpl.rootView, playerImpl.popupLayoutParams) diff --git a/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java b/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java index 056002b14..f3049d11d 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java +++ b/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java @@ -30,14 +30,14 @@ import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; -import io.reactivex.Observable; -import io.reactivex.Single; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.CompositeDisposable; -import io.reactivex.disposables.Disposable; -import io.reactivex.internal.subscriptions.EmptySubscription; -import io.reactivex.schedulers.Schedulers; -import io.reactivex.subjects.PublishSubject; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.core.Single; +import io.reactivex.rxjava3.disposables.CompositeDisposable; +import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.internal.subscriptions.EmptySubscription; +import io.reactivex.rxjava3.schedulers.Schedulers; +import io.reactivex.rxjava3.subjects.PublishSubject; import static org.schabi.newpipe.player.mediasource.FailedMediaSource.MediaSourceResolutionException; import static org.schabi.newpipe.player.mediasource.FailedMediaSource.StreamInfoLoadException; diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/AbstractInfoPlayQueue.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/AbstractInfoPlayQueue.java index ec364c4df..17bb6f4c4 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playqueue/AbstractInfoPlayQueue.java +++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/AbstractInfoPlayQueue.java @@ -14,8 +14,8 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import io.reactivex.SingleObserver; -import io.reactivex.disposables.Disposable; +import io.reactivex.rxjava3.core.SingleObserver; +import io.reactivex.rxjava3.disposables.Disposable; abstract class AbstractInfoPlayQueue extends PlayQueue { boolean isInitial; diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/ChannelPlayQueue.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/ChannelPlayQueue.java index 9e0d2b694..f85349797 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playqueue/ChannelPlayQueue.java +++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/ChannelPlayQueue.java @@ -9,8 +9,8 @@ import org.schabi.newpipe.util.ExtractorHelper; import java.util.List; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.schedulers.Schedulers; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.schedulers.Schedulers; public final class ChannelPlayQueue extends AbstractInfoPlayQueue { public ChannelPlayQueue(final ChannelInfoItem item) { diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueue.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueue.java index b8bb677e0..90a979872 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueue.java +++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueue.java @@ -21,10 +21,10 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; -import io.reactivex.BackpressureStrategy; -import io.reactivex.Flowable; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.subjects.BehaviorSubject; +import io.reactivex.rxjava3.core.BackpressureStrategy; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.core.Flowable; +import io.reactivex.rxjava3.subjects.BehaviorSubject; /** * PlayQueue is responsible for keeping track of a list of streams and the index of @@ -80,7 +80,7 @@ public abstract class PlayQueue implements Serializable { broadcastReceiver = eventBroadcast.toFlowable(BackpressureStrategy.BUFFER) .observeOn(AndroidSchedulers.mainThread()) - .startWith(new InitEvent()); + .startWithItem(new InitEvent()); } /** diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueAdapter.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueAdapter.java index d063766c2..462b9eb53 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueAdapter.java @@ -20,8 +20,8 @@ import org.schabi.newpipe.util.FallbackViewHolder; import java.util.List; -import io.reactivex.Observer; -import io.reactivex.disposables.Disposable; +import io.reactivex.rxjava3.core.Observer; +import io.reactivex.rxjava3.disposables.Disposable; /** * Created by Christian Schabesberger on 01.08.16. diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItem.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItem.java index 79efc03ae..1c38ebbca 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItem.java +++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlayQueueItem.java @@ -10,8 +10,8 @@ import org.schabi.newpipe.util.ExtractorHelper; import java.io.Serializable; -import io.reactivex.Single; -import io.reactivex.schedulers.Schedulers; +import io.reactivex.rxjava3.core.Single; +import io.reactivex.rxjava3.schedulers.Schedulers; public class PlayQueueItem implements Serializable { public static final long RECOVERY_UNSET = Long.MIN_VALUE; diff --git a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlaylistPlayQueue.java b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlaylistPlayQueue.java index 077702747..ac5dce9ba 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playqueue/PlaylistPlayQueue.java +++ b/app/src/main/java/org/schabi/newpipe/player/playqueue/PlaylistPlayQueue.java @@ -8,8 +8,8 @@ import org.schabi.newpipe.util.ExtractorHelper; import java.util.List; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.schedulers.Schedulers; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.schedulers.Schedulers; public final class PlaylistPlayQueue extends AbstractInfoPlayQueue { public PlaylistPlayQueue(final PlaylistInfoItem item) { 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 e0cf2e4ad..98c1ffc30 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/HistorySettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/HistorySettingsFragment.java @@ -14,9 +14,9 @@ import org.schabi.newpipe.report.ErrorInfo; import org.schabi.newpipe.report.UserAction; import org.schabi.newpipe.util.InfoCache; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.CompositeDisposable; -import io.reactivex.disposables.Disposable; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.disposables.CompositeDisposable; +import io.reactivex.rxjava3.disposables.Disposable; public class HistorySettingsFragment extends BasePreferenceFragment { private String cacheWipeKey; diff --git a/app/src/main/java/org/schabi/newpipe/settings/NotificationSettingsFragment.kt b/app/src/main/java/org/schabi/newpipe/settings/NotificationSettingsFragment.kt index c68b699d3..e03aa4074 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/NotificationSettingsFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/settings/NotificationSettingsFragment.kt @@ -16,4 +16,4 @@ class NotificationSettingsFragment : BasePreferenceFragment() { } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/org/schabi/newpipe/settings/PeertubeInstanceListFragment.java b/app/src/main/java/org/schabi/newpipe/settings/PeertubeInstanceListFragment.java index 1e23c513b..bd3cbf79d 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/PeertubeInstanceListFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/PeertubeInstanceListFragment.java @@ -4,7 +4,6 @@ import android.annotation.SuppressLint; import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; -import androidx.preference.PreferenceManager; import android.text.InputType; import android.view.LayoutInflater; import android.view.Menu; @@ -26,6 +25,7 @@ import androidx.appcompat.app.AlertDialog; import androidx.appcompat.content.res.AppCompatResources; import androidx.appcompat.widget.AppCompatImageView; import androidx.fragment.app.Fragment; +import androidx.preference.PreferenceManager; import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; @@ -44,11 +44,11 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import io.reactivex.Single; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.CompositeDisposable; -import io.reactivex.disposables.Disposable; -import io.reactivex.schedulers.Schedulers; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.core.Single; +import io.reactivex.rxjava3.disposables.CompositeDisposable; +import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.schedulers.Schedulers; public class PeertubeInstanceListFragment extends Fragment { private static final int MENU_ITEM_RESTORE_ID = 123456; diff --git a/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java b/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java index f87b5cd2a..90537564a 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java @@ -30,10 +30,10 @@ import java.util.List; import java.util.Vector; import de.hdodenhof.circleimageview.CircleImageView; -import io.reactivex.Observer; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.Disposable; -import io.reactivex.schedulers.Schedulers; +import io.reactivex.rxjava3.core.Observer; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.schedulers.Schedulers; /** * Created by Christian Schabesberger on 26.09.17. diff --git a/app/src/main/java/org/schabi/newpipe/settings/SelectPlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/settings/SelectPlaylistFragment.java index f2876f1ee..16ccd0953 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SelectPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/SelectPlaylistFragment.java @@ -33,9 +33,9 @@ import org.schabi.newpipe.report.UserAction; import java.util.List; import java.util.Vector; -import io.reactivex.Flowable; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.Disposable; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.core.Flowable; +import io.reactivex.rxjava3.disposables.Disposable; public class SelectPlaylistFragment extends DialogFragment { /** diff --git a/app/src/main/java/org/schabi/newpipe/util/CommentTextOnTouchListener.java b/app/src/main/java/org/schabi/newpipe/util/CommentTextOnTouchListener.java index cf347e7c4..36f39a6e5 100644 --- a/app/src/main/java/org/schabi/newpipe/util/CommentTextOnTouchListener.java +++ b/app/src/main/java/org/schabi/newpipe/util/CommentTextOnTouchListener.java @@ -23,9 +23,9 @@ import org.schabi.newpipe.player.playqueue.SinglePlayQueue; import java.util.regex.Matcher; import java.util.regex.Pattern; -import io.reactivex.Single; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.schedulers.Schedulers; +import io.reactivex.rxjava3.core.Single; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.schedulers.Schedulers; public class CommentTextOnTouchListener implements View.OnTouchListener { public static final CommentTextOnTouchListener INSTANCE = new CommentTextOnTouchListener(); diff --git a/app/src/main/java/org/schabi/newpipe/util/ExceptionUtils.kt b/app/src/main/java/org/schabi/newpipe/util/ExceptionUtils.kt index 528912ceb..0addb26fb 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ExceptionUtils.kt +++ b/app/src/main/java/org/schabi/newpipe/util/ExceptionUtils.kt @@ -10,9 +10,11 @@ class ExceptionUtils { */ @JvmStatic fun isInterruptedCaused(throwable: Throwable): Boolean { - return hasExactCause(throwable, - InterruptedIOException::class.java, - InterruptedException::class.java) + return hasExactCause( + throwable, + InterruptedIOException::class.java, + InterruptedException::class.java + ) } /** @@ -20,8 +22,10 @@ class ExceptionUtils { */ @JvmStatic fun isNetworkRelated(throwable: Throwable): Boolean { - return hasAssignableCause(throwable, - IOException::class.java) + return hasAssignableCause( + throwable, + IOException::class.java + ) } /** diff --git a/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java b/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java index 91a38d8d8..650c5ae11 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java @@ -57,8 +57,8 @@ import org.schabi.newpipe.report.UserAction; import java.util.Collections; import java.util.List; -import io.reactivex.Maybe; -import io.reactivex.Single; +import io.reactivex.rxjava3.core.Maybe; +import io.reactivex.rxjava3.core.Single; public final class ExtractorHelper { private static final String TAG = ExtractorHelper.class.getSimpleName(); diff --git a/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java b/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java index 2bfd27c47..9150b5c1a 100644 --- a/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java @@ -23,9 +23,9 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.Callable; -import io.reactivex.Single; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.schedulers.Schedulers; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.core.Single; +import io.reactivex.rxjava3.schedulers.Schedulers; import us.shandian.giga.util.Utility; /** diff --git a/app/src/main/java/us/shandian/giga/get/MissionRecoveryInfo.kt b/app/src/main/java/us/shandian/giga/get/MissionRecoveryInfo.kt index 568ae8d13..b2364f058 100644 --- a/app/src/main/java/us/shandian/giga/get/MissionRecoveryInfo.kt +++ b/app/src/main/java/us/shandian/giga/get/MissionRecoveryInfo.kt @@ -1,13 +1,13 @@ package us.shandian.giga.get import android.os.Parcelable -import java.io.Serializable import kotlinx.android.parcel.Parcelize import org.schabi.newpipe.extractor.MediaFormat import org.schabi.newpipe.extractor.stream.AudioStream import org.schabi.newpipe.extractor.stream.Stream import org.schabi.newpipe.extractor.stream.SubtitlesStream import org.schabi.newpipe.extractor.stream.VideoStream +import java.io.Serializable @Parcelize class MissionRecoveryInfo( @@ -62,10 +62,10 @@ class MissionRecoveryInfo( } } str.append(" format=") - .append(format.getName()) - .append(' ') - .append(info) - .append('}') + .append(format.getName()) + .append(' ') + .append(info) + .append('}') return str.toString() } } diff --git a/app/src/main/java/us/shandian/giga/ui/adapter/MissionAdapter.java b/app/src/main/java/us/shandian/giga/ui/adapter/MissionAdapter.java index 07fe2fcc4..be7d78299 100644 --- a/app/src/main/java/us/shandian/giga/ui/adapter/MissionAdapter.java +++ b/app/src/main/java/us/shandian/giga/ui/adapter/MissionAdapter.java @@ -49,10 +49,10 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; -import io.reactivex.Observable; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.CompositeDisposable; -import io.reactivex.schedulers.Schedulers; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.disposables.CompositeDisposable; +import io.reactivex.rxjava3.schedulers.Schedulers; import us.shandian.giga.get.DownloadMission; import us.shandian.giga.get.FinishedMission; import us.shandian.giga.get.Mission; diff --git a/app/src/test/java/org/schabi/newpipe/local/subscription/FeedGroupIconTest.kt b/app/src/test/java/org/schabi/newpipe/local/subscription/FeedGroupIconTest.kt index a0db83ba9..e6d4247ca 100644 --- a/app/src/test/java/org/schabi/newpipe/local/subscription/FeedGroupIconTest.kt +++ b/app/src/test/java/org/schabi/newpipe/local/subscription/FeedGroupIconTest.kt @@ -13,8 +13,10 @@ class FeedGroupIconTest { val added = usedIds.add(currentIcon.id) assertTrue("Repeated ids (current item: ${currentIcon.name} - ${currentIcon.id})", added) - assertEquals("Gap between ids detected (current item: ${currentIcon.name} - ${currentIcon.id} → should be: $shouldBeId)", - shouldBeId, currentIcon.id) + assertEquals( + "Gap between ids detected (current item: ${currentIcon.name} - ${currentIcon.id} → should be: $shouldBeId)", + shouldBeId, currentIcon.id + ) } } diff --git a/app/src/test/java/org/schabi/newpipe/util/ExceptionUtilsTest.kt b/app/src/test/java/org/schabi/newpipe/util/ExceptionUtilsTest.kt index 55dc9f469..2d897e379 100644 --- a/app/src/test/java/org/schabi/newpipe/util/ExceptionUtilsTest.kt +++ b/app/src/test/java/org/schabi/newpipe/util/ExceptionUtilsTest.kt @@ -1,14 +1,14 @@ package org.schabi.newpipe.util -import java.io.IOException -import java.io.InterruptedIOException -import java.net.SocketException -import javax.net.ssl.SSLException import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Test import org.schabi.newpipe.util.ExceptionUtils.Companion.hasAssignableCause import org.schabi.newpipe.util.ExceptionUtils.Companion.hasExactCause +import java.io.IOException +import java.io.InterruptedIOException +import java.net.SocketException +import javax.net.ssl.SSLException class ExceptionUtilsTest { @Test fun `assignable causes`() { diff --git a/app/src/test/java/org/schabi/newpipe/util/urlfinder/UrlFinderTest.kt b/app/src/test/java/org/schabi/newpipe/util/urlfinder/UrlFinderTest.kt index 99f26e472..ac8e4c8da 100644 --- a/app/src/test/java/org/schabi/newpipe/util/urlfinder/UrlFinderTest.kt +++ b/app/src/test/java/org/schabi/newpipe/util/urlfinder/UrlFinderTest.kt @@ -9,7 +9,8 @@ import org.junit.Test class UrlFinderTest { @Test fun `first url from long text`() { val expected = "https://www.youtube.com/playlist?list=PLabcdefghij-ABCDEFGHIJ1234567890_" - val result = UrlFinder.firstUrlFromInput(""" + val result = UrlFinder.firstUrlFromInput( + """ |Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. |Eu tincidunt tortor aliquam nulla. URL: https://www.youtube.com/playlist?list=PLabcdefghij-ABCDEFGHIJ1234567890_ Sed dictum consequat dui. |Pharetra diam sit amet nisl suscipit adipiscing bibendum est. @@ -18,13 +19,15 @@ class UrlFinderTest { |Dapibus ultrices in iaculis nunc sed augue lacus viverra. Nisl purus in mollis nunc. |Viverra nibh cras pulvinar mattis. ####!@!@!@!#### Not this one: https://www.youtube.com/playlist?list=SHOULD_NOT Nunc sed blandit libero volutpat. |Nisl tincidunt eget nullam non nisi est sit amet. Purus in massa tempor nec feugiat nisl pretium fusce id. - |Vulputate eu scelerisque felis imperdiet proin fermentum leo vel.""".trimMargin()) + |Vulputate eu scelerisque felis imperdiet proin fermentum leo vel.""".trimMargin() + ) assertEquals(expected, result) } @Test fun `no url from long text`() { - val result = UrlFinder.firstUrlFromInput(""" + val result = UrlFinder.firstUrlFromInput( + """ |Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. |Eu tincidunt tortor aliquam nulla. Sed dictum consequat dui. Pharetra diam sit amet nisl suscipit adipiscing bibendum est. |Volutpat sed cras ornare arcu dui vivamus. Nulla posuere sollicitudin aliquam ultrices sagittis. @@ -32,7 +35,8 @@ class UrlFinderTest { |Dapibus ultrices in iaculis nunc sed augue lacus viverra. Nisl purus in mollis nunc. |Viverra nibh cras pulvinar mattis. Not this one: sed blandit libero volutpat. |Nisl tincidunt eget nullam non nisi est sit amet. Purus in massa tempor nec feugiat nisl pretium fusce id. - |Vulputate eu scelerisque felis imperdiet proin fermentum leo vel.""".trimMargin()) + |Vulputate eu scelerisque felis imperdiet proin fermentum leo vel.""".trimMargin() + ) assertEquals(null, result) } @@ -44,14 +48,20 @@ class UrlFinderTest { } @Test fun `normal urls`() { - assertEquals("https://www.youtube.com/playlist?list=PLabcdefghij-ABCDEFGHIJ1234567890_", - UrlFinder.firstUrlFromInput("https://www.youtube.com/playlist?list=PLabcdefghij-ABCDEFGHIJ1234567890_")) + assertEquals( + "https://www.youtube.com/playlist?list=PLabcdefghij-ABCDEFGHIJ1234567890_", + UrlFinder.firstUrlFromInput("https://www.youtube.com/playlist?list=PLabcdefghij-ABCDEFGHIJ1234567890_") + ) - assertEquals("https://www.youtube.com/watch?v=dQw4w9WgXcQ", - UrlFinder.firstUrlFromInput("https://www.youtube.com/watch?v=dQw4w9WgXcQ")) + assertEquals( + "https://www.youtube.com/watch?v=dQw4w9WgXcQ", + UrlFinder.firstUrlFromInput("https://www.youtube.com/watch?v=dQw4w9WgXcQ") + ) - assertEquals("http://www.youtube.com/watch?v=dQw4w9WgXcQ", - UrlFinder.firstUrlFromInput("http://www.youtube.com/watch?v=dQw4w9WgXcQ")) + assertEquals( + "http://www.youtube.com/watch?v=dQw4w9WgXcQ", + UrlFinder.firstUrlFromInput("http://www.youtube.com/watch?v=dQw4w9WgXcQ") + ) assertEquals("https://www.google.com", UrlFinder.firstUrlFromInput("https://www.google.com")) assertEquals("http://www.google.com/test/", UrlFinder.firstUrlFromInput("http://www.google.com/test/")) @@ -79,21 +89,33 @@ class UrlFinderTest { } @Test fun `random prefixes and suffixes`() { - assertEquals("https://www.youtube.com/playlist?list=PLabcdefghij-ABCDEFGHIJ1234567890_", - UrlFinder.firstUrlFromInput("$#!@#@!#https://www.youtube.com/playlist?list=PLabcdefghij-ABCDEFGHIJ1234567890_ @@@@@@@@@@@")) + assertEquals( + "https://www.youtube.com/playlist?list=PLabcdefghij-ABCDEFGHIJ1234567890_", + UrlFinder.firstUrlFromInput("$#!@#@!#https://www.youtube.com/playlist?list=PLabcdefghij-ABCDEFGHIJ1234567890_ @@@@@@@@@@@") + ) - assertEquals("https://www.youtube.com/playlist?list=PLabcdefghij-ABCDEFGHIJ1234567890_", - UrlFinder.firstUrlFromInput("(___\"https://www.youtube.com/playlist?list=PLabcdefghij-ABCDEFGHIJ1234567890_\")))_")) + assertEquals( + "https://www.youtube.com/playlist?list=PLabcdefghij-ABCDEFGHIJ1234567890_", + UrlFinder.firstUrlFromInput("(___\"https://www.youtube.com/playlist?list=PLabcdefghij-ABCDEFGHIJ1234567890_\")))_") + ) - assertEquals("https://www.youtube.com/watch?v=dQw4w9WgXcQ", - UrlFinder.firstUrlFromInput(" https://www.youtube.com/watch?v=dQw4w9WgXcQ ")) + assertEquals( + "https://www.youtube.com/watch?v=dQw4w9WgXcQ", + UrlFinder.firstUrlFromInput(" https://www.youtube.com/watch?v=dQw4w9WgXcQ ") + ) - assertEquals("https://www.youtube.com/watch?v=dQw4w9WgXcQ", - UrlFinder.firstUrlFromInput(" ------_---__-https://www.youtube.com/watch?v=dQw4w9WgXcQ !!!!!!")) + assertEquals( + "https://www.youtube.com/watch?v=dQw4w9WgXcQ", + UrlFinder.firstUrlFromInput(" ------_---__-https://www.youtube.com/watch?v=dQw4w9WgXcQ !!!!!!") + ) - assertEquals("https://www.youtube.com/watch?v=dQw4w9WgXcQ", - UrlFinder.firstUrlFromInput("****https://www.youtube.com/watch?v=dQw4w9WgXcQ _")) - assertEquals("https://www.youtube.com/watch?v=dQw4w9WgXcQ", - UrlFinder.firstUrlFromInput("https://www.youtube.com/watch?v=dQw4w9WgXcQ\"Not PartOfTheUrl")) + assertEquals( + "https://www.youtube.com/watch?v=dQw4w9WgXcQ", + UrlFinder.firstUrlFromInput("****https://www.youtube.com/watch?v=dQw4w9WgXcQ _") + ) + assertEquals( + "https://www.youtube.com/watch?v=dQw4w9WgXcQ", + UrlFinder.firstUrlFromInput("https://www.youtube.com/watch?v=dQw4w9WgXcQ\"Not PartOfTheUrl") + ) } } diff --git a/build.gradle b/build.gradle index 6e9b57cac..acb201794 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.3.72' + ext.kotlin_version = '1.4.10' repositories { jcenter() google() diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ca28934d5..c02f7cf09 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,4 +1,4 @@ -#Sat Oct 17 06:10:46 IST 2020 +#Thu Oct 15 11:41:05 CEST 2020 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME