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
This commit is contained in:
Ivan Iskandar 2022-01-09 00:55:22 +07:00 committed by GitHub
parent b8f7653fb2
commit 78a261f5d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 28 additions and 21 deletions

View File

@ -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<Source>,
val icon: Drawable?,
val hasUpdate: Boolean = false,
val isObsolete: Boolean = false,
val isUnofficial: Boolean = false

View File

@ -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)
}

View File

@ -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()

View File

@ -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)
}

View File

@ -47,7 +47,7 @@ open class ExtensionPresenter(
.startWith(emptyList<Extension.Available>())
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) })

View File

@ -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())
}
}
}

View File

@ -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()
}

View File

@ -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)
}
icon != null -> binding.image.load(icon)
item.source.id == LocalSource.ID -> binding.image.load(R.mipmap.ic_local_source)
}
binding.sourceLatest.isVisible = source.supportsLatest

View File

@ -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.
*/

View File

@ -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
}
}