ExtensionPresenter: Fix crash on first launch (#7685)

* Revert "Use SharedFlow for available extensions to always emit the value (#7609)"

This reverts commit 73901f50c0aee1cb82695642af72ff6ac7bc232d.

* ExtensionPresenter: Explicitly set refreshing status

* Scope coroutines job to presenter

* cleanup

* fix toast

(cherry picked from commit b3426f37e7d36be653363338288f74e2ae252a78)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionManager.kt
This commit is contained in:
Ivan Iskandar 2022-08-05 02:44:37 +07:00 committed by Jobobby04
parent 353eef34b5
commit 4da028af6a
2 changed files with 36 additions and 38 deletions

View File

@ -16,6 +16,7 @@ import eu.kanade.tachiyomi.extension.util.ExtensionInstaller
import eu.kanade.tachiyomi.extension.util.ExtensionLoader
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.util.lang.launchNow
import eu.kanade.tachiyomi.util.lang.withUIContext
import eu.kanade.tachiyomi.util.preference.plusAssign
import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.util.system.toast
@ -25,11 +26,8 @@ import exh.source.EH_SOURCE_ID
import exh.source.EXH_SOURCE_ID
import exh.source.MERGED_SOURCE_ID
import kotlinx.coroutines.async
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import logcat.LogPriority
import rx.Observable
@ -110,15 +108,15 @@ class ExtensionManager(
var availableExtensions = emptyList<Extension.Available>()
private set(value) {
field = value
availableExtensionsFlow.tryEmit(field)
availableExtensionsFlow.value = field
updatedInstalledExtensionsStatuses(value)
setupAvailableExtensionsSourcesDataMap(value)
}
private val availableExtensionsFlow = MutableSharedFlow<List<Extension.Available>>(replay = 1)
private val availableExtensionsFlow = MutableStateFlow(availableExtensions)
fun getAvailableExtensionsFlow(): Flow<List<Extension.Available>> {
return availableExtensionsFlow.asSharedFlow()
fun getAvailableExtensionsFlow(): StateFlow<List<Extension.Available>> {
return availableExtensionsFlow.asStateFlow()
}
private var availableExtensionsSourcesData: Map<Long, SourceData> = mapOf()
@ -193,21 +191,19 @@ class ExtensionManager(
/**
* Finds the available extensions in the [api] and updates [availableExtensions].
*/
fun findAvailableExtensions() {
launchNow {
val extensions: List<Extension.Available> = try {
api.findExtensions()
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
context.toast(R.string.extension_api_error)
emptyList()
}
// SY -->
unalteredAvailableExtensions = extensions
availableExtensions = extensions.filterNotBlacklisted()
// SY <--
suspend fun findAvailableExtensions() {
val extensions: List<Extension.Available> = try {
api.findExtensions()
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
withUIContext { context.toast(R.string.extension_api_error) }
emptyList()
}
// SY -->
unalteredAvailableExtensions = extensions
availableExtensions = extensions.filterNotBlacklisted()
// SY <--
}
/**

View File

@ -36,8 +36,6 @@ class ExtensionsPresenter(
override fun onCreate(savedState: Bundle?) {
super.onCreate(savedState)
extensionManager.findAvailableExtensions()
val context = Injekt.get<Application>()
val extensionMapper: (Map<String, InstallStep>) -> ((Extension) -> ExtensionUiModel) = { map ->
{
@ -71,13 +69,13 @@ class ExtensionsPresenter(
}
}
launchIO {
presenterScope.launchIO {
combine(
_query,
getExtensions.subscribe(),
_currentDownloads,
) { query, (updates, installed, available, untrusted), downloads ->
val languagesWithExtensions = available
) { query, (_updates, _installed, _available, _untrusted), downloads ->
val languagesWithExtensions = _available
.filter(queryFilter(query))
.groupBy { LocaleHelper.getSourceDisplayName(it.lang, context) }
.toSortedMap()
@ -90,14 +88,14 @@ class ExtensionsPresenter(
val items = mutableListOf<ExtensionUiModel>()
val updates = updates.filter(queryFilter(query)).map(extensionMapper(downloads))
val updates = _updates.filter(queryFilter(query)).map(extensionMapper(downloads))
if (updates.isNotEmpty()) {
items.add(ExtensionUiModel.Header.Resource(R.string.ext_updates_pending))
items.addAll(updates)
}
val installed = installed.filter(queryFilter(query)).map(extensionMapper(downloads))
val untrusted = untrusted.filter(queryFilter(query)).map(extensionMapper(downloads))
val installed = _installed.filter(queryFilter(query)).map(extensionMapper(downloads))
val untrusted = _untrusted.filter(queryFilter(query)).map(extensionMapper(downloads))
if (installed.isNotEmpty() || untrusted.isNotEmpty()) {
items.add(ExtensionUiModel.Header.Resource(R.string.ext_installed))
items.addAll(installed)
@ -110,21 +108,22 @@ class ExtensionsPresenter(
items
}.collectLatest {
state.isRefreshing = false
state.isLoading = false
state.items = it
}
}
presenterScope.launchIO { findAvailableExtensions() }
}
fun search(query: String) {
launchIO {
presenterScope.launchIO {
_query.emit(query)
}
}
fun updateAllExtensions() {
launchIO {
presenterScope.launchIO {
if (state.isEmpty) return@launchIO
val items = state.items
items.mapNotNull {
@ -151,16 +150,16 @@ class ExtensionsPresenter(
}
private fun removeDownloadState(extension: Extension) {
_currentDownloads.update { map ->
val map = map.toMutableMap()
_currentDownloads.update { _map ->
val map = _map.toMutableMap()
map.remove(extension.pkgName)
map
}
}
private fun addDownloadState(extension: Extension, installStep: InstallStep) {
_currentDownloads.update { map ->
val map = map.toMutableMap()
_currentDownloads.update { _map ->
val map = _map.toMutableMap()
map[extension.pkgName] = installStep
map
}
@ -180,8 +179,11 @@ class ExtensionsPresenter(
}
fun findAvailableExtensions() {
state.isRefreshing = true
extensionManager.findAvailableExtensions()
presenterScope.launchIO {
state.isRefreshing = true
extensionManager.findAvailableExtensions()
state.isRefreshing = false
}
}
fun trustSignature(signatureHash: String) {