From 5d1f79012e63403ac37309dd958244108e28a1a5 Mon Sep 17 00:00:00 2001 From: arkon Date: Sun, 30 Oct 2022 18:43:16 -0400 Subject: [PATCH] Fix some crashes - Delay the initial emission of updates/sources/extensions lists instead of using a state flow. This hopefully avoids rapid initial recompositions that cause the LazyColumn key duplication crashes. (Closes #8371) - Fix a NPE in BrowseSourcePresenter --- .../tachiyomi/ui/browse/extension/ExtensionsPresenter.kt | 5 +++-- .../eu/kanade/tachiyomi/ui/browse/source/SourcesPresenter.kt | 5 +++-- .../ui/browse/source/browse/BrowseSourcePresenter.kt | 3 ++- .../kanade/tachiyomi/ui/recent/updates/UpdatesPresenter.kt | 5 +++-- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionsPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionsPresenter.kt index a603be96c..da55bc14e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionsPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionsPresenter.kt @@ -15,6 +15,7 @@ import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.util.lang.launchIO import eu.kanade.tachiyomi.util.system.LocaleHelper import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow @@ -22,7 +23,7 @@ import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.update import rx.Observable import uy.kohesive.injekt.Injekt @@ -116,7 +117,7 @@ class ExtensionsPresenter( items } - .stateIn(presenterScope) + .onStart { delay(500) } // Defer to avoid crashing on initial render .collectLatest { state.isLoading = false state.items = it diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourcesPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourcesPresenter.kt index 02f6c0cea..fe2d50e82 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourcesPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourcesPresenter.kt @@ -14,10 +14,11 @@ import eu.kanade.tachiyomi.util.lang.launchIO import eu.kanade.tachiyomi.util.system.logcat import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.receiveAsFlow -import kotlinx.coroutines.flow.stateIn import logcat.LogPriority import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get @@ -43,7 +44,7 @@ class SourcesPresenter( logcat(LogPriority.ERROR, exception) _events.send(Event.FailedFetchingSources) } - .stateIn(presenterScope) + .onStart { delay(500) } // Defer to avoid crashing on initial render .collectLatest(::collectLatestSources) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourcePresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourcePresenter.kt index 9ed2bbf9f..67a9220ec 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourcePresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourcePresenter.kt @@ -154,7 +154,8 @@ open class BrowseSourcePresenter( } fun reset() { - state.filters = source!!.getFilterList() + val source = source ?: return + state.filters = source.getFilterList() if (currentFilter !is Filter.UserInput) return state.currentFilter = (currentFilter as Filter.UserInput).copy(filters = state.filters) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesPresenter.kt index 527cf61a1..7ba2c0897 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesPresenter.kt @@ -29,13 +29,14 @@ import eu.kanade.tachiyomi.util.lang.launchNonCancellable import eu.kanade.tachiyomi.util.lang.withUIContext import eu.kanade.tachiyomi.util.system.logcat import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.receiveAsFlow -import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import logcat.LogPriority import uy.kohesive.injekt.Injekt @@ -87,11 +88,11 @@ class UpdatesPresenter( getUpdates.subscribe(calendar).distinctUntilChanged(), downloadCache.changes, ) { updates, _ -> updates } + .onStart { delay(500) } // Defer to avoid crashing on initial render .catch { logcat(LogPriority.ERROR, it) _events.send(Event.InternalError) } - .stateIn(presenterScope) .collectLatest { updates -> state.items = updates.toUpdateItems() state.isLoading = false