From b3426f37e7d36be653363338288f74e2ae252a78 Mon Sep 17 00:00:00 2001 From: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com> Date: Fri, 5 Aug 2022 02:44:37 +0700 Subject: [PATCH] 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 --- .../tachiyomi/extension/ExtensionManager.kt | 32 ++++++++--------- .../browse/extension/ExtensionsPresenter.kt | 36 ++++++++++--------- 2 files changed, 33 insertions(+), 35 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionManager.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionManager.kt index aa95707701..2d441e60d8 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionManager.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionManager.kt @@ -15,15 +15,13 @@ 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 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 @@ -96,15 +94,15 @@ class ExtensionManager( var availableExtensions = emptyList() private set(value) { field = value - availableExtensionsFlow.tryEmit(field) + availableExtensionsFlow.value = field updatedInstalledExtensionsStatuses(value) setupAvailableExtensionsSourcesDataMap(value) } - private val availableExtensionsFlow = MutableSharedFlow>(replay = 1) + private val availableExtensionsFlow = MutableStateFlow(availableExtensions) - fun getAvailableExtensionsFlow(): Flow> { - return availableExtensionsFlow.asSharedFlow() + fun getAvailableExtensionsFlow(): StateFlow> { + return availableExtensionsFlow.asStateFlow() } private var availableExtensionsSourcesData: Map = mapOf() @@ -156,18 +154,16 @@ class ExtensionManager( /** * Finds the available extensions in the [api] and updates [availableExtensions]. */ - fun findAvailableExtensions() { - launchNow { - val extensions: List = try { - api.findExtensions() - } catch (e: Exception) { - logcat(LogPriority.ERROR, e) - context.toast(R.string.extension_api_error) - emptyList() - } - - availableExtensions = extensions + suspend fun findAvailableExtensions() { + val extensions: List = try { + api.findExtensions() + } catch (e: Exception) { + logcat(LogPriority.ERROR, e) + withUIContext { context.toast(R.string.extension_api_error) } + emptyList() } + + availableExtensions = extensions } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionsPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionsPresenter.kt index 099d1a7ae2..42dd5222ba 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionsPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionsPresenter.kt @@ -36,8 +36,6 @@ class ExtensionsPresenter( override fun onCreate(savedState: Bundle?) { super.onCreate(savedState) - extensionManager.findAvailableExtensions() - val context = Injekt.get() val extensionMapper: (Map) -> ((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() - 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) {