mirror of
https://github.com/mihonapp/mihon.git
synced 2026-10-16 13:48:09 -07:00
Improve performance across screens (#4071)
* Keep screens loaded while they're hidden and rebuild the library faster * Count chapters in SQL for the migration list * Show the extension list sooner and check trust against loaded stores * Cancel the previous tracker search when searching again * Write reader progress less often and keep its work off the main thread * Stop rebuilding the settings search index on every key * Watch updates for widgets only while one is placed The query re-ran on every chapter or manga write even with no widget on the home screen. * Observe download pages and limit how often their progress updates * Throttle the library update notification and write fetch data together
This commit is contained in:
+11
@@ -1,9 +1,20 @@
|
||||
package tachiyomi.presentation.widget
|
||||
|
||||
import android.content.Context
|
||||
import androidx.glance.appwidget.GlanceAppWidget
|
||||
import androidx.glance.appwidget.GlanceAppWidgetReceiver
|
||||
|
||||
class UpdatesGridCoverScreenGlanceReceiver : GlanceAppWidgetReceiver() {
|
||||
override val glanceAppWidget: GlanceAppWidget
|
||||
get() = UpdatesGridCoverScreenGlanceWidget()
|
||||
|
||||
override fun onEnabled(context: Context) {
|
||||
super.onEnabled(context)
|
||||
WidgetManager.onWidgetEnabled(glanceAppWidget)
|
||||
}
|
||||
|
||||
override fun onDisabled(context: Context) {
|
||||
super.onDisabled(context)
|
||||
WidgetManager.onWidgetDisabled(glanceAppWidget)
|
||||
}
|
||||
}
|
||||
|
||||
+11
@@ -1,5 +1,6 @@
|
||||
package tachiyomi.presentation.widget
|
||||
|
||||
import android.content.Context
|
||||
import androidx.glance.appwidget.GlanceAppWidget
|
||||
import androidx.glance.appwidget.GlanceAppWidgetReceiver
|
||||
|
||||
@@ -7,4 +8,14 @@ class UpdatesGridGlanceReceiver : GlanceAppWidgetReceiver() {
|
||||
|
||||
override val glanceAppWidget: GlanceAppWidget
|
||||
get() = UpdatesGridGlanceWidget()
|
||||
|
||||
override fun onEnabled(context: Context) {
|
||||
super.onEnabled(context)
|
||||
WidgetManager.onWidgetEnabled(glanceAppWidget)
|
||||
}
|
||||
|
||||
override fun onDisabled(context: Context) {
|
||||
super.onDisabled(context)
|
||||
WidgetManager.onWidgetDisabled(glanceAppWidget)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,25 @@
|
||||
package tachiyomi.presentation.widget
|
||||
|
||||
import android.content.Context
|
||||
import androidx.glance.appwidget.GlanceAppWidget
|
||||
import androidx.glance.appwidget.GlanceAppWidgetManager
|
||||
import androidx.glance.appwidget.updateAll
|
||||
import dev.zacsweers.metro.Inject
|
||||
import eu.kanade.tachiyomi.core.security.SecurityPreferences
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.emptyFlow
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import logcat.LogPriority
|
||||
import tachiyomi.core.common.util.system.logcat
|
||||
import tachiyomi.domain.updates.interactor.GetUpdates
|
||||
@@ -21,21 +30,40 @@ class WidgetManager(
|
||||
private val securityPreferences: SecurityPreferences,
|
||||
) {
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
context(context: Context)
|
||||
fun init(scope: CoroutineScope) {
|
||||
combine(
|
||||
getUpdates.subscribe(read = false, after = BaseUpdatesGridGlanceWidget.DateLimit),
|
||||
securityPreferences.useAuthenticator.changes(),
|
||||
transform = { a, b -> a to b },
|
||||
)
|
||||
scope.launch(Dispatchers.Default) {
|
||||
val manager = GlanceAppWidgetManager(context)
|
||||
val placed = widgets.filter { manager.getGlanceIds(it.javaClass).isNotEmpty() }
|
||||
placedWidgets.update { it + placed.map { widget -> widget.javaClass } }
|
||||
}
|
||||
|
||||
// Only watch updates while a widget is on the home screen
|
||||
placedWidgets
|
||||
.map { it.isNotEmpty() }
|
||||
.distinctUntilChanged()
|
||||
.flatMapLatest { hasWidgets ->
|
||||
if (hasWidgets) {
|
||||
combine(
|
||||
getUpdates.subscribe(
|
||||
read = false,
|
||||
after = BaseUpdatesGridGlanceWidget.DateLimit,
|
||||
),
|
||||
securityPreferences.useAuthenticator.changes(),
|
||||
transform = { a, b -> a to b },
|
||||
)
|
||||
} else {
|
||||
emptyFlow()
|
||||
}
|
||||
}
|
||||
.distinctUntilChanged { old, new ->
|
||||
old.second == new.second &&
|
||||
old.first.map { it.chapterId }.toSet() == new.first.map { it.chapterId }.toSet()
|
||||
}
|
||||
.onEach {
|
||||
try {
|
||||
UpdatesGridGlanceWidget().updateAll(context)
|
||||
UpdatesGridCoverScreenGlanceWidget().updateAll(context)
|
||||
widgets.forEach { it.updateAll(context) }
|
||||
} catch (e: Exception) {
|
||||
this.logcat(LogPriority.ERROR, e) { "Failed to update widget" }
|
||||
}
|
||||
@@ -43,4 +71,19 @@ class WidgetManager(
|
||||
.flowOn(Dispatchers.Default)
|
||||
.launchIn(scope)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val widgets: List<GlanceAppWidget>
|
||||
get() = listOf(UpdatesGridGlanceWidget(), UpdatesGridCoverScreenGlanceWidget())
|
||||
|
||||
private val placedWidgets = MutableStateFlow(emptySet<Class<out GlanceAppWidget>>())
|
||||
|
||||
internal fun onWidgetEnabled(widget: GlanceAppWidget) {
|
||||
placedWidgets.update { it + widget.javaClass }
|
||||
}
|
||||
|
||||
internal fun onWidgetDisabled(widget: GlanceAppWidget) {
|
||||
placedWidgets.update { it - widget.javaClass }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user