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
This commit is contained in:
arkon 2022-10-30 18:43:16 -04:00
parent cac80daa71
commit 5d1f79012e
4 changed files with 11 additions and 7 deletions

View File

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

View File

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

View File

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

View File

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