Browse Source

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
Ivan Iskandar 2 năm trước cách đây
mục cha
commit
b3426f37e7

+ 14 - 18
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<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()
@@ -156,18 +154,16 @@ 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()
-            }
-
-            availableExtensions = extensions
+    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()
         }
+
+        availableExtensions = extensions
     }
 
     /**

+ 19 - 17
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<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) {