Wait for extensions to load before the list is propagated (#3841)
This commit is contained in:
@@ -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() }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user