From 78a261f5d3911cd0546445c8f6e6e7baff35ae35 Mon Sep 17 00:00:00 2001 From: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com> Date: Sun, 9 Jan 2022 00:55:22 +0700 Subject: [PATCH] Reduce stutter when entering Browse screen (#6435) * More coil * ExtensionController: Drop first text change event * Browse-Source: Remove unnecessary load * ExtensionPresenter: Increase debounce timeout To avoid heavy list reload during first enter animation --- .../kanade/tachiyomi/extension/model/Extension.kt | 2 ++ .../tachiyomi/extension/util/ExtensionLoader.kt | 4 +++- .../ui/browse/extension/ExtensionController.kt | 2 ++ .../ui/browse/extension/ExtensionHolder.kt | 4 ++-- .../ui/browse/extension/ExtensionPresenter.kt | 2 +- .../ui/browse/migration/sources/SourceHolder.kt | 3 ++- .../tachiyomi/ui/browse/source/SourceController.kt | 1 + .../tachiyomi/ui/browse/source/SourceHolder.kt | 13 ++++++------- .../tachiyomi/ui/browse/source/SourcePresenter.kt | 9 --------- .../tachiyomi/util/system/ContextExtensions.kt | 9 +++++++++ 10 files changed, 28 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/model/Extension.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/model/Extension.kt index 0b38cb7286..8619c0cf7d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/model/Extension.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/model/Extension.kt @@ -1,5 +1,6 @@ package eu.kanade.tachiyomi.extension.model +import android.graphics.drawable.Drawable import eu.kanade.tachiyomi.source.Source sealed class Extension { @@ -20,6 +21,7 @@ sealed class Extension { override val isNsfw: Boolean, val pkgFactory: String?, val sources: List, + val icon: Drawable?, val hasUpdate: Boolean = false, val isObsolete: Boolean = false, val isUnofficial: Boolean = false diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionLoader.kt index 47b52569a0..f1fd0b3246 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionLoader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionLoader.kt @@ -13,6 +13,7 @@ import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.SourceFactory import eu.kanade.tachiyomi.util.lang.Hash +import eu.kanade.tachiyomi.util.system.getApplicationIcon import eu.kanade.tachiyomi.util.system.logcat import kotlinx.coroutines.async import kotlinx.coroutines.runBlocking @@ -181,7 +182,8 @@ internal object ExtensionLoader { isNsfw, sources = sources, pkgFactory = appInfo.metaData.getString(METADATA_SOURCE_FACTORY), - isUnofficial = signatureHash != officialSignature + isUnofficial = signatureHash != officialSignature, + icon = context.getApplicationIcon(pkgName) ) return LoadResult.Success(extension) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionController.kt index 496f3d1930..e7f5adc961 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionController.kt @@ -20,6 +20,7 @@ import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.browse.BrowseController import eu.kanade.tachiyomi.ui.browse.extension.details.ExtensionDetailsController +import kotlinx.coroutines.flow.drop import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach @@ -143,6 +144,7 @@ open class ExtensionController : } searchView.queryTextChanges() + .drop(1) // Drop first event after subscribed .filter { router.backstack.lastOrNull()?.controller == this } .onEach { query = it.toString() diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionHolder.kt index dde63907b0..718e146d33 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionHolder.kt @@ -42,8 +42,8 @@ class ExtensionHolder(view: View, val adapter: ExtensionAdapter) : binding.icon.clear() if (extension is Extension.Available) { binding.icon.load(extension.iconUrl) - } else { - extension.getApplicationIcon(itemView.context)?.let { binding.icon.setImageDrawable(it) } + } else if (extension is Extension.Installed) { + binding.icon.load(extension.icon) } bindButtons(item) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionPresenter.kt index a76b12ada3..f9cef42085 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionPresenter.kt @@ -47,7 +47,7 @@ open class ExtensionPresenter( .startWith(emptyList()) return Observable.combineLatest(installedObservable, untrustedObservable, availableObservable) { installed, untrusted, available -> Triple(installed, untrusted, available) } - .debounce(100, TimeUnit.MILLISECONDS) + .debounce(500, TimeUnit.MILLISECONDS) .map(::toItems) .observeOn(AndroidSchedulers.mainThread()) .subscribeLatestCache({ view, _ -> view.setExtensions(extensions) }) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/sources/SourceHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/sources/SourceHolder.kt index bf956f1f02..ed5730bb15 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/sources/SourceHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/sources/SourceHolder.kt @@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.browse.migration.sources import android.view.View import androidx.core.view.isVisible +import coil.load import eu.davidea.viewholders.FlexibleViewHolder import eu.kanade.tachiyomi.databinding.SourceMainControllerItemBinding import eu.kanade.tachiyomi.source.icon @@ -20,7 +21,7 @@ class SourceHolder(view: View, val adapter: SourceAdapter) : binding.subtitle.text = LocaleHelper.getDisplayName(source.lang) itemView.post { - binding.image.setImageDrawable(source.icon()) + binding.image.load(source.icon()) } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceController.kt index 894a3e0ac3..f5d16adc67 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceController.kt @@ -92,6 +92,7 @@ class SourceController : // Update list on extension changes (e.g. new installation) (parentController as BrowseController).extensionListUpdateRelay + .skip(1) // Skip first update when ExtensionController created .subscribeUntilDestroy { presenter.updateSources() } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceHolder.kt index 2a5a02f437..db0678a582 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourceHolder.kt @@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.browse.source import android.view.View import androidx.core.view.isVisible +import coil.load import eu.davidea.viewholders.FlexibleViewHolder import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.databinding.SourceMainControllerItemBinding @@ -10,7 +11,7 @@ import eu.kanade.tachiyomi.source.icon import eu.kanade.tachiyomi.util.system.LocaleHelper import eu.kanade.tachiyomi.util.view.setVectorCompat -class SourceHolder(private val view: View, val adapter: SourceAdapter) : +class SourceHolder(view: View, val adapter: SourceAdapter) : FlexibleViewHolder(view, adapter) { private val binding = SourceMainControllerItemBinding.bind(view) @@ -33,12 +34,10 @@ class SourceHolder(private val view: View, val adapter: SourceAdapter) : binding.subtitle.text = LocaleHelper.getDisplayName(source.lang) // Set source icon - itemView.post { - val icon = source.icon() - when { - icon != null -> binding.image.setImageDrawable(icon) - item.source.id == LocalSource.ID -> binding.image.setImageResource(R.mipmap.ic_local_source) - } + val icon = source.icon() + when { + icon != null -> binding.image.load(icon) + item.source.id == LocalSource.ID -> binding.image.load(R.mipmap.ic_local_source) } binding.sourceLatest.isVisible = source.supportsLatest diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourcePresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourcePresenter.kt index 626fa8b55b..31ee700320 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourcePresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourcePresenter.kt @@ -1,6 +1,5 @@ package eu.kanade.tachiyomi.ui.browse.source -import android.os.Bundle import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.LocalSource @@ -37,14 +36,6 @@ class SourcePresenter( */ private var sourceSubscription: Subscription? = null - override fun onCreate(savedState: Bundle?) { - super.onCreate(savedState) - - // Load enabled and last used sources - loadSources() - loadLastUsedSource() - } - /** * Unsubscribe and create a new subscription to fetch enabled sources. */ diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/system/ContextExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/system/ContextExtensions.kt index 870c699c67..85478c3c57 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/system/ContextExtensions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/system/ContextExtensions.kt @@ -14,6 +14,7 @@ import android.content.pm.PackageManager import android.content.res.Configuration import android.content.res.Resources import android.graphics.Color +import android.graphics.drawable.Drawable import android.net.ConnectivityManager import android.net.NetworkCapabilities import android.net.Uri @@ -418,3 +419,11 @@ fun Context.isPackageInstalled(packageName: String): Boolean { false } } + +fun Context.getApplicationIcon(pkgName: String): Drawable? { + return try { + packageManager.getApplicationIcon(pkgName) + } catch (e: PackageManager.NameNotFoundException) { + null + } +}