Wait for extensions to load before the list is propagated (#3841)

This commit is contained in:
AntsyLich
2026-08-23 02:37:01 +06:00
committed by GitHub
parent 46c8f07c12
commit 270b78ba95
5 changed files with 37 additions and 33 deletions
@@ -23,9 +23,10 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import logcat.LogPriority
@@ -55,19 +56,18 @@ class ExtensionManager(
val scope = CoroutineScope(SupervisorJob())
private val _isInitialized = MutableStateFlow(false)
val isInitialized: StateFlow<Boolean> = _isInitialized.asStateFlow()
private val isInitialized = MutableStateFlow(false)
private val iconMap = mutableMapOf<String, Drawable>()
private val installedExtensionMapFlow = MutableStateFlow(emptyMap<String, Extension.Installed>())
val installedExtensionsFlow = installedExtensionMapFlow.mapExtensions(scope)
val installedExtensionsFlow = installedExtensionMapFlow.mapExtensionsOnceInitialized()
private val availableExtensionMapFlow = MutableStateFlow(emptyMap<String, Extension.Available>())
val availableExtensionsFlow = availableExtensionMapFlow.mapExtensions(scope)
private val untrustedExtensionMapFlow = MutableStateFlow(emptyMap<String, Extension.Untrusted>())
val untrustedExtensionsFlow = untrustedExtensionMapFlow.mapExtensions(scope)
val untrustedExtensionsFlow = untrustedExtensionMapFlow.mapExtensionsOnceInitialized()
init {
scope.launch(Dispatchers.IO) {
@@ -79,7 +79,7 @@ class ExtensionManager(
private var subLanguagesEnabledOnFirstRun = preferences.enabledLanguages.isSet()
fun getExtensionPackage(sourceId: Long): String? {
return installedExtensionsFlow.value.find { extension ->
return installedExtensionMapFlow.value.values.find { extension ->
extension.sources.any { it.id == sourceId }
}
?.pkgName
@@ -128,7 +128,7 @@ class ExtensionManager(
.filterIsInstance<LoadResult.Untrusted>()
.associate { it.extension.pkgName to it.extension }
_isInitialized.value = true
isInitialized.value = true
}
/**
@@ -378,4 +378,12 @@ class ExtensionManager(
private fun <T : Extension> StateFlow<Map<String, T>>.mapExtensions(scope: CoroutineScope): StateFlow<List<T>> {
return map { it.values.toList() }.stateIn(scope, SharingStarted.Lazily, value.values.toList())
}
/**
* Extensions are loaded in the background, and [stateIn] would replay the empty list it was
* seeded with at construction, so this only starts emitting once that finished.
*/
private fun <T : Extension> StateFlow<Map<String, T>>.mapExtensionsOnceInitialized(): Flow<List<T>> {
return onStart { isInitialized.first { it } }.map { it.values.toList() }
}
}