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

(cherry picked from commit 5d1f79012e)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourcesPresenter.kt
This commit is contained in:
arkon
2022-10-30 18:43:16 -04:00
committed by Jobobby04
parent b4ede754b9
commit ebfc0f89ed
4 changed files with 11 additions and 6 deletions
@@ -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
@@ -19,14 +19,15 @@ import eu.kanade.tachiyomi.util.system.logcat
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.launchIn
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
@@ -69,6 +70,7 @@ class SourcesPresenter(
logcat(LogPriority.ERROR, exception)
_events.send(Event.FailedFetchingSources)
}
.onStart { delay(500) } // Defer to avoid crashing on initial render
.flowOn(Dispatchers.IO)
.launchIn(presenterScope)
// SY <--
@@ -209,7 +209,8 @@ open class BrowseSourcePresenter(
// SY <--
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)
}
@@ -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