diff --git a/app/build.gradle b/app/build.gradle index 1f98c503007..5337b3484c8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -85,14 +85,14 @@ android { ext { icepickVersion = '3.2.0' - checkstyleVersion = '8.32' + checkstyleVersion = '8.36.2' 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' } @@ -126,13 +126,20 @@ task runCheckstyle(type: Checkstyle) { } } +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" @@ -149,26 +156,27 @@ dependencies { 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}" debugImplementation "androidx.multidex:multidex:2.0.1" - testImplementation 'junit:junit:4.13' - testImplementation 'org.mockito:mockito-core:3.3.3' + testImplementation 'junit:junit:4.13.1' + testImplementation 'org.mockito:mockito-core:3.5.13' - androidTestImplementation "androidx.test.ext:junit:1.1.1" + androidTestImplementation "androidx.test.ext:junit:1.1.2" androidTestImplementation "androidx.room:room-testing:${androidxRoomVersion}" - androidTestImplementation "androidx.test.espresso:espresso-core:3.2.0", { + androidTestImplementation "androidx.test.espresso:espresso-core:3.3.0", { exclude module: 'support-annotations' } - implementation 'com.github.TeamNewPipe:NewPipeExtractor:2463884aa8b696df5812f7feff553008bbd2f888' + implementation 'com.github.TeamNewPipe:NewPipeExtractor:acb04eb351374229a023518605edf6360bc92e80' implementation "com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751" implementation "org.jsoup:jsoup:1.13.1" @@ -178,23 +186,25 @@ dependencies { 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.2" + 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 "com.xwray:groupie:${groupieVersion}" @@ -208,11 +218,11 @@ 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" } 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 e37eb5db999..239c46f7a0a 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 9ea3bdabec8..24f9fdf3f66 100644 --- a/app/src/debug/java/org/schabi/newpipe/DebugApp.kt +++ b/app/src/debug/java/org/schabi/newpipe/DebugApp.kt @@ -16,14 +16,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 } @@ -43,7 +51,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() @@ -54,6 +63,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 4b2a858c741..117811a02e1 100644 --- a/app/src/main/java/org/schabi/newpipe/App.java +++ b/app/src/main/java/org/schabi/newpipe/App.java @@ -36,12 +36,12 @@ import java.util.Collections; import java.util.List; -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.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/RouterActivity.java b/app/src/main/java/org/schabi/newpipe/RouterActivity.java index 251affaed22..902449d6ec9 100644 --- a/app/src/main/java/org/schabi/newpipe/RouterActivity.java +++ b/app/src/main/java/org/schabi/newpipe/RouterActivity.java @@ -8,7 +8,6 @@ import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.os.Bundle; -import androidx.preference.PreferenceManager; import android.text.TextUtils; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; @@ -28,6 +27,7 @@ import androidx.appcompat.content.res.AppCompatResources; import androidx.core.app.NotificationCompat; import androidx.fragment.app.FragmentManager; +import androidx.preference.PreferenceManager; import org.schabi.newpipe.download.DownloadDialog; import org.schabi.newpipe.extractor.Info; @@ -45,8 +45,8 @@ import org.schabi.newpipe.player.playqueue.PlaylistPlayQueue; import org.schabi.newpipe.player.playqueue.SinglePlayQueue; import org.schabi.newpipe.report.UserAction; -import org.schabi.newpipe.util.DeviceUtils; import org.schabi.newpipe.util.Constants; +import org.schabi.newpipe.util.DeviceUtils; import org.schabi.newpipe.util.ExtractorHelper; import org.schabi.newpipe.util.ListHelper; import org.schabi.newpipe.util.NavigationHelper; @@ -65,13 +65,13 @@ 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/database/BasicDAO.java b/app/src/main/java/org/schabi/newpipe/database/BasicDAO.java index dd526ecc8b8..1b8540808c0 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 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 74f5b369e04..c609882696e 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.util.Date +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.util.Date @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 < :date ) - """) + """ + ) abstract fun unlinkStreamsOlderThan(date: Date) - @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: Date): 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: Date): 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 c8700dea2fe..217eef03f1d 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 8a1eb65d4a1..beeedc62bc8 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 e772168fde4..1dd26946a96 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 eac6bddeecf..40f7d203bd4 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 78b2550a55b..78adf5f964b 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.util.Date 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.util.Date @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 97243585952..a0010a41934 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 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 c716a2d9112..af713713809 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 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 c653e6c6ffc..e5204655249 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.util.Date import org.schabi.newpipe.database.stream.model.StreamEntity +import java.util.Date 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.compareTo(other.accessDate) == 0 + accessDate.compareTo(other.accessDate) == 0 } } 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 2cfe5440c97..eee2e1a85bd 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 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 23442ceff55..a488f00fcbf 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 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 2c0f7e5069a..1d3f4bb1be6 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 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/StreamStatisticsEntry.kt b/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt index dde1f0392bc..102432e5baa 100644 --- a/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt +++ b/app/src/main/java/org/schabi/newpipe/database/stream/StreamStatisticsEntry.kt @@ -2,11 +2,11 @@ package org.schabi.newpipe.database.stream import androidx.room.ColumnInfo import androidx.room.Embedded -import java.util.Date import org.schabi.newpipe.database.LocalItem import org.schabi.newpipe.database.history.model.StreamHistoryEntity import org.schabi.newpipe.database.stream.model.StreamEntity import org.schabi.newpipe.extractor.stream.StreamInfoItem +import java.util.Date class StreamStatisticsEntry( @Embedded 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 921c08b4623..b306cb55320 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.util.Date +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.util.Date @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 eb0f77f66fa..a6b36e3ff90 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 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 d13f5cc2d13..7d9b76e0263 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,9 +5,6 @@ import androidx.room.Entity import androidx.room.Ignore import androidx.room.Index import androidx.room.PrimaryKey -import java.io.Serializable -import java.util.Calendar -import java.util.Date 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 @@ -16,11 +13,15 @@ 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.util.Calendar +import java.util.Date -@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) @@ -63,27 +64,27 @@ data class StreamEntity( @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?.date()?.time, - 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?.date()?.time, + 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?.date()?.time, - 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?.date()?.time, + 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 { @@ -95,8 +96,11 @@ data class StreamEntity( if (viewCount != null) item.viewCount = viewCount as Long item.textualUploadDate = textualUploadDate item.uploadDate = uploadDate?.let { - DateWrapper(Calendar.getInstance().apply { time = it }, isUploadDateApproximation - ?: false) + DateWrapper( + Calendar.getInstance().apply { time = it }, + isUploadDateApproximation + ?: false + ) } return item 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 60dd343b9f8..9798ec72dda 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 17d079d50ea..03e864b3582 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.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.widget.Toolbar; import androidx.documentfile.provider.DocumentFile; import androidx.fragment.app.DialogFragment; +import androidx.preference.PreferenceManager; import com.nononsenseapps.filepicker.Utils; @@ -69,7 +69,7 @@ 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 c687c4a6a04..29df6ed9f2b 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 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; @@ -33,7 +33,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import icepick.State; -import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; 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 536c3b35cbc..fa90fdef59e 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.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.Spanned; import android.text.TextUtils; @@ -28,6 +25,7 @@ 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; @@ -46,7 +44,9 @@ 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; @@ -114,11 +114,11 @@ 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 f21eb529184..0d3c728d9d5 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 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 8902834e4e3..648bd808ceb 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.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; @@ -54,15 +54,15 @@ 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 fc61a4518bd..ce8393eecf8 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.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 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 68097e21eea..8770e6936ea 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.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 67f1a007aa6..92f05c7ca18 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.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 @@ private void onBookmarkClicked() { .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 c402565fd00..766e1554288 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.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 @@ private void initSuggestionObserver() { final Observable 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 da7e8df8b13..d62f4eb179e 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 @@ 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 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 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 d7555a79d7a..d5241ae02ff 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 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 5bb03f531dd..bbd91cf169d 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 @@ -27,8 +27,8 @@ import java.util.Collections; import java.util.List; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.disposables.CompositeDisposable; public final class PlaylistAppendDialog extends PlaylistDialog { private static final String TAG = PlaylistAppendDialog.class.getCanonicalName(); 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 ff696664401..98ef4a54418 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 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 d319c9fa345..80f12e7dac7 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,13 +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.util.Calendar -import java.util.Date +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 @@ -18,6 +16,8 @@ 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.util.Calendar +import java.util.Date class FeedDatabaseManager(context: Context) { private val database = NewPipeDatabase.getInstance(context) @@ -65,10 +65,10 @@ class FeedDatabaseManager(context: Context) { } fun outdatedSubscriptionsForGroup(groupId: Long = FeedGroupEntity.GROUP_ALL_ID, outdatedThreshold: Date) = - 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, @@ -116,38 +116,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 { @@ -155,8 +155,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 915bc3ec063..72afa097783 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 @@ -33,7 +33,6 @@ import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import androidx.preference.PreferenceManager 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 @@ -51,6 +50,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 @@ -71,7 +71,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) ?: "" } @@ -138,15 +138,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) - .apply() - } - .setPositiveButton(resources.getString(R.string.finish), null) - .create() - .show() + .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) + .apply() + } + .setPositiveButton(resources.getString(R.string.finish), null) + .create() + .show() return true } @@ -227,7 +227,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}" @@ -238,7 +238,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 @@ -261,8 +261,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()) { @@ -305,9 +307,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 de3dd31135c..00ca76b8ea8 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 da2b5ffa4d2..441cdf36dc5 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,13 +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.util.Calendar -import java.util.Date -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.local.feed.service.FeedEventManager @@ -20,6 +17,9 @@ 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.util.Calendar +import java.util.Date +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,36 +35,38 @@ 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 { - val (event, listFromDB, notLoadedCount, oldestUpdate) = it + 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 { + val (event, listFromDB, notLoadedCount, oldestUpdate) = it - val oldestUpdateCalendar = - oldestUpdate?.let { Calendar.getInstance().apply { time = it } } + val oldestUpdateCalendar = + oldestUpdate?.let { Calendar.getInstance().apply { time = it } } - 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 b72098345fc..3d19de9c693 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 0181f2711ad..b47e2b95653 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,20 +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.util.Calendar -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 @@ -62,6 +57,11 @@ 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.util.Calendar +import java.util.concurrent.TimeUnit +import java.util.concurrent.atomic.AtomicBoolean +import java.util.concurrent.atomic.AtomicInteger class FeedLoadService : Service() { companion object { @@ -108,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) { @@ -122,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) @@ -182,63 +185,63 @@ class FeedLoadService : Service() { } subscriptions - .limit(1) + .take(1) - .doOnNext { - currentProgress.set(0) - maxProgress.set(it.size) - } - .filter { it.isNotEmpty() } + .doOnNext { + currentProgress.set(0) + maxProgress.set(it.size) + } + .filter { it.isNotEmpty() } - .observeOn(AndroidSchedulers.mainThread()) - .doOnNext { - startForeground(NOTIFICATION_ID, notificationBuilder.build()) - updateNotificationProgress(null) - broadcastProgress() - } + .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) - } + .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) } - .sequential() + } + .sequential() - .observeOn(AndroidSchedulers.mainThread()) - .doOnNext(errorHandlingConsumer) + .observeOn(AndroidSchedulers.mainThread()) + .doOnNext(errorHandlingConsumer) - .observeOn(AndroidSchedulers.mainThread()) - .doOnNext(notificationsConsumer) + .observeOn(AndroidSchedulers.mainThread()) + .doOnNext(notificationsConsumer) - .observeOn(Schedulers.io()) - .buffer(BUFFER_COUNT_BEFORE_INSERT) - .doOnNext(databaseConsumer) + .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() { @@ -275,7 +278,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() @@ -294,7 +298,8 @@ class FeedLoadService : Service() { return@subscribe } stopService() - }) + } + ) } } @@ -365,16 +370,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() { @@ -382,13 +389,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 6af57bc9439..1c36efd0204 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 @@ -49,11 +49,11 @@ import java.util.Date; 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 48a0e343032..cf6658cc81a 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 @@ -46,9 +46,9 @@ 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 32fac9de072..da06093e719 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 @@ -54,13 +54,12 @@ 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; @@ -640,7 +639,7 @@ private void saveChanges() { private Disposable getDebouncedSaver() { if (debouncedSaveSignal == null) { - return Disposables.empty(); + return Disposable.empty(); } return debouncedSaveSignal diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java index 2dec53fae44..64122af6270 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/LocalPlaylistManager.java @@ -15,11 +15,11 @@ import java.util.ArrayList; 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 LocalPlaylistManager { private final AppDatabase database; diff --git a/app/src/main/java/org/schabi/newpipe/local/playlist/RemotePlaylistManager.java b/app/src/main/java/org/schabi/newpipe/local/playlist/RemotePlaylistManager.java index 331eb5b08df..5221139e34f 100644 --- a/app/src/main/java/org/schabi/newpipe/local/playlist/RemotePlaylistManager.java +++ b/app/src/main/java/org/schabi/newpipe/local/playlist/RemotePlaylistManager.java @@ -7,9 +7,9 @@ import java.util.List; -import io.reactivex.Flowable; -import io.reactivex.Single; -import io.reactivex.schedulers.Schedulers; +import io.reactivex.rxjava3.core.Flowable; +import io.reactivex.rxjava3.core.Single; +import io.reactivex.rxjava3.schedulers.Schedulers; public class RemotePlaylistManager { diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt index b0d0fe801b9..64286dab347 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/SubscriptionFragment.kt @@ -28,13 +28,7 @@ import com.xwray.groupie.Item import com.xwray.groupie.Section import com.xwray.groupie.kotlinandroidextensions.GroupieViewHolder import icepick.State -import io.reactivex.disposables.CompositeDisposable -import java.io.File -import java.text.SimpleDateFormat -import java.util.Date -import java.util.Locale -import kotlin.math.floor -import kotlin.math.max +import io.reactivex.rxjava3.disposables.CompositeDisposable import kotlinx.android.synthetic.main.dialog_title.view.itemAdditionalDetails import kotlinx.android.synthetic.main.dialog_title.view.itemTitleView import kotlinx.android.synthetic.main.fragment_subscription.items_list @@ -68,6 +62,12 @@ import org.schabi.newpipe.util.NavigationHelper import org.schabi.newpipe.util.OnClickGesture import org.schabi.newpipe.util.ShareUtils import org.schabi.newpipe.util.ThemeHelper +import java.io.File +import java.text.SimpleDateFormat +import java.util.Date +import java.util.Locale +import kotlin.math.floor +import kotlin.math.max class SubscriptionFragment : BaseStateFragment() { 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 2740591e662..fb9cffa9855 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 b7f16c31955..da009e1a043 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 486f774837f..c2e119607ac 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 @@ -23,8 +23,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 @@ -42,6 +40,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 @@ -115,21 +115,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) @@ -140,8 +149,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 } } @@ -354,7 +365,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 } @@ -409,10 +421,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.visibility = when { currentScreen != InitialScreen -> View.GONE @@ -469,8 +483,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() } @@ -481,8 +497,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 e9a7e4eb70a..01369627bc9 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 { filter -> @@ -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 48f40e21934..380bf13f5bc 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 ea2cbe98f57..e1b3429b91b 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 f33c58f432e..8089f6480c2 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 717e2410ac3..e56bb408cd8 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 5478dcac42c..5fd70a684f2 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 32493225610..0f5bdeb94f6 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 @@ -37,11 +37,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 7d33da71f3a..9fa8c652bf9 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 @@ -21,8 +21,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.visibility = if (isSelected) View.VISIBLE else View.GONE @@ -38,7 +40,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 f485844ea15..f04605ceb42 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 @@ -45,11 +45,11 @@ 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(); @@ -119,7 +119,7 @@ protected void setupNotification() { 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 f7d09971210..982701d1f56 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.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 51afc9fdad7..b1c67719c5c 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.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 70f2e158b9f..bf32b0a0cdf 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.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 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; /** @@ -717,8 +716,9 @@ public void triggerProgressUpdate() { } 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)); } @@ -1316,7 +1316,7 @@ private void savePlaybackState(final StreamInfo info, final long progress) { 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(); @@ -1336,7 +1336,7 @@ private void resetPlaybackState(final PlayQueueItem queueItem) { 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/playback/MediaSourceManager.java b/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java index 1b8c62e6411..4d38b4138b0 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.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 ec364c4df7f..17bb6f4c4cf 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.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 9e0d2b6942b..f8534979770 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 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 8bef0b2e023..1ef278a76d8 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 @@ -25,10 +25,10 @@ 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 @@ -86,7 +86,7 @@ public void init() { broadcastReceiver = eventBroadcast.toFlowable(BackpressureStrategy.BUFFER) .observeOn(AndroidSchedulers.mainThread()) - .startWith(new InitEvent()); + .startWithItem(new InitEvent()); if (DEBUG) { broadcastReceiver.subscribe(getSelfReporter()); 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 3b42f274555..abbdddb76fd 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 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 74aef07fadb..182a91e5939 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 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 0777027470d..ac5dce9ba4e 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 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 893e7c740e0..f59d53a60e0 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/HistorySettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/HistorySettingsFragment.java @@ -13,9 +13,9 @@ 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/PeertubeInstanceListFragment.java b/app/src/main/java/org/schabi/newpipe/settings/PeertubeInstanceListFragment.java index 7559f6ed5a6..9abc5ae0c2c 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.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.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.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 96e2781f5b1..b1ec778b1e9 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/SelectChannelFragment.java @@ -29,10 +29,10 @@ 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 c858c7f7719..7e89cb26089 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SelectPlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/SelectPlaylistFragment.java @@ -33,8 +33,8 @@ import java.util.List; import java.util.Vector; -import io.reactivex.Flowable; -import io.reactivex.disposables.Disposable; +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 cf347e7c48d..36f39a6e554 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 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 528912cebd3..0addb26fb91 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 a1a73d7acbf..b845e64b4dc 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java @@ -56,8 +56,8 @@ 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 2bfd27c4736..9150b5c1a69 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.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/test/java/org/schabi/newpipe/local/subscription/FeedGroupIconTest.kt b/app/src/test/java/org/schabi/newpipe/local/subscription/FeedGroupIconTest.kt index a0db83ba917..e6d4247ca4b 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 55dc9f46902..2d897e37931 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 99f26e47242..ac8e4c8da92 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/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/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\"Not PartOfTheUrl") + ) } } diff --git a/build.gradle b/build.gradle index f15900bc6ba..fbf1896c2d7 100644 --- a/build.gradle +++ b/build.gradle @@ -1,13 +1,13 @@ // 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() } dependencies { - classpath 'com.android.tools.build:gradle:3.6.3' + classpath 'com.android.tools.build:gradle:4.1.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 5f9210e2756..c02f7cf097b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Fri May 01 19:39:41 CEST 2020 +#Thu Oct 15 11:41:05 CEST 2020 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip