diff --git a/app/src/main/java/eu/kanade/domain/extension/interactor/GetExtensionLanguages.kt b/app/src/main/java/eu/kanade/domain/extension/interactor/GetExtensionLanguages.kt index 16d2ae8f8..a4917f43f 100644 --- a/app/src/main/java/eu/kanade/domain/extension/interactor/GetExtensionLanguages.kt +++ b/app/src/main/java/eu/kanade/domain/extension/interactor/GetExtensionLanguages.kt @@ -13,7 +13,7 @@ class GetExtensionLanguages( fun subscribe(): Flow> { return combine( preferences.enabledLanguages().changes(), - extensionManager.getAvailableExtensionsFlow(), + extensionManager.availableExtensionsFlow, ) { enabledLanguage, availableExtensions -> availableExtensions .flatMap { ext -> diff --git a/app/src/main/java/eu/kanade/domain/extension/interactor/GetExtensionsByType.kt b/app/src/main/java/eu/kanade/domain/extension/interactor/GetExtensionsByType.kt index c73829d12..b6023c7ae 100644 --- a/app/src/main/java/eu/kanade/domain/extension/interactor/GetExtensionsByType.kt +++ b/app/src/main/java/eu/kanade/domain/extension/interactor/GetExtensionsByType.kt @@ -17,9 +17,9 @@ class GetExtensionsByType( return combine( preferences.enabledLanguages().changes(), - extensionManager.getInstalledExtensionsFlow(), - extensionManager.getUntrustedExtensionsFlow(), - extensionManager.getAvailableExtensionsFlow(), + extensionManager.installedExtensionsFlow, + extensionManager.untrustedExtensionsFlow, + extensionManager.availableExtensionsFlow, ) { _activeLanguages, _installed, _untrusted, _available -> val (updates, installed) = _installed .filter { (showNsfwSources || it.isNsfw.not()) } 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 c3fc16de7..7feebfe0e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionManager.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionManager.kt @@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.extension import android.content.Context import android.graphics.drawable.Drawable import androidx.core.content.ContextCompat -import com.jakewharton.rxrelay.BehaviorRelay import eu.kanade.domain.source.model.SourceData import eu.kanade.domain.source.service.SourcePreferences import eu.kanade.tachiyomi.R @@ -15,7 +14,6 @@ import eu.kanade.tachiyomi.extension.model.LoadResult import eu.kanade.tachiyomi.extension.util.ExtensionInstallReceiver 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 @@ -26,10 +24,14 @@ import exh.source.BlacklistedSources import exh.source.EH_SOURCE_ID import exh.source.EXH_SOURCE_ID import exh.source.MERGED_SOURCE_ID +import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.async import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.stateIn import logcat.LogPriority import rx.Observable import uy.kohesive.injekt.Injekt @@ -61,37 +63,15 @@ class ExtensionManager( */ private val installer by lazy { ExtensionInstaller(context) } - /** - * Relay used to notify the installed extensions. - */ - private val installedExtensionsRelay = BehaviorRelay.create>() - private val iconMap = mutableMapOf() - /** - * List of the currently installed extensions. - */ - var installedExtensions = emptyList() - private set(value) { - field = value - installedExtensionsFlow.value = field - installedExtensionsRelay.call(value) - } - - private val installedExtensionsFlow = MutableStateFlow(installedExtensions) + private val _installedExtensionsFlow = MutableStateFlow(emptyList()) + val installedExtensionsFlow = _installedExtensionsFlow.asStateFlow() private var subLanguagesEnabledOnFirstRun = preferences.enabledLanguages().isSet() - fun getInstalledExtensionsFlow(): StateFlow> { - return installedExtensionsFlow.asStateFlow() - } - - fun getAppIconForSource(source: Source): Drawable? { - return getAppIconForSource(source.id) - } - fun getAppIconForSource(sourceId: Long): Drawable? { - val pkgName = installedExtensions.find { ext -> ext.sources.any { it.id == sourceId } }?.pkgName + val pkgName = _installedExtensionsFlow.value.find { ext -> ext.sources.any { it.id == sourceId } }?.pkgName if (pkgName != null) { return iconMap[pkgName] ?: iconMap.getOrPut(pkgName) { context.packageManager.getApplicationIcon(pkgName) } } @@ -106,22 +86,14 @@ class ExtensionManager( // SY <-- } - /** - * List of the currently available extensions. - */ - var availableExtensions = emptyList() - private set(value) { - field = value - availableExtensionsFlow.value = field - updatedInstalledExtensionsStatuses(value) - setupAvailableExtensionsSourcesDataMap(value) - } + private val _availableExtensionsFlow = MutableStateFlow(emptyList()) - private val availableExtensionsFlow = MutableStateFlow(availableExtensions) - - fun getAvailableExtensionsFlow(): StateFlow> { - return availableExtensionsFlow.asStateFlow() - } + // SY --> + @OptIn(DelicateCoroutinesApi::class) + val availableExtensionsFlow = _availableExtensionsFlow + .map { it.filterNotBlacklisted() } + .stateIn(GlobalScope, SharingStarted.Eagerly, emptyList()) + // SY <-- private var availableExtensionsSourcesData: Map = mapOf() @@ -134,24 +106,8 @@ class ExtensionManager( fun getSourceData(id: Long) = availableExtensionsSourcesData[id] - // SY --> - var unalteredAvailableExtensions = emptyList() - // SY <-- - - /** - * List of the currently untrusted extensions. - */ - var untrustedExtensions = emptyList() - private set(value) { - field = value - untrustedExtensionsFlow.value = field - } - - private val untrustedExtensionsFlow = MutableStateFlow(untrustedExtensions) - - fun getUntrustedExtensionsFlow(): StateFlow> { - return untrustedExtensionsFlow.asStateFlow() - } + private val _untrustedExtensionsFlow = MutableStateFlow(emptyList()) + val untrustedExtensionsFlow = _untrustedExtensionsFlow.asStateFlow() init { initExtensions() @@ -164,11 +120,11 @@ class ExtensionManager( private fun initExtensions() { val extensions = ExtensionLoader.loadExtensions(context) - installedExtensions = extensions + _installedExtensionsFlow.value = extensions .filterIsInstance() .map { it.extension } - untrustedExtensions = extensions + _untrustedExtensionsFlow.value = extensions .filterIsInstance() .map { it.extension } // SY --> @@ -206,10 +162,9 @@ class ExtensionManager( enableAdditionalSubLanguages(extensions) - // SY --> - unalteredAvailableExtensions = extensions - availableExtensions = extensions.filterNotBlacklisted() - // SY <-- + _availableExtensionsFlow.value = extensions + updatedInstalledExtensionsStatuses(extensions) + setupAvailableExtensionsSourcesDataMap(extensions) } /** @@ -253,13 +208,13 @@ class ExtensionManager( return } - val mutInstalledExtensions = installedExtensions.toMutableList() + val mutInstalledExtensions = _installedExtensionsFlow.value.toMutableList() var changed = false for ((index, installedExt) in mutInstalledExtensions.withIndex()) { val pkgName = installedExt.pkgName // SY --> - val availableExt = unalteredAvailableExtensions.find { it.pkgName == pkgName } + val availableExt = _availableExtensionsFlow.value.find { it.pkgName == pkgName } // SY <-- if (!installedExt.isUnofficial && availableExt == null && !installedExt.isObsolete) { @@ -286,7 +241,7 @@ class ExtensionManager( } } if (changed) { - installedExtensions = mutInstalledExtensions + _installedExtensionsFlow.value = mutInstalledExtensions } updatePendingUpdatesCount() } @@ -310,7 +265,7 @@ class ExtensionManager( * @param extension The extension to be updated. */ fun updateExtension(extension: Extension.Installed): Observable { - val availableExt = availableExtensions.find { it.pkgName == extension.pkgName } + val availableExt = _availableExtensionsFlow.value.find { it.pkgName == extension.pkgName } ?: return Observable.empty() return installExtension(availableExt) } @@ -348,14 +303,14 @@ class ExtensionManager( * @param signature The signature to whitelist. */ fun trustSignature(signature: String) { - val untrustedSignatures = untrustedExtensions.map { it.signatureHash }.toSet() + val untrustedSignatures = _untrustedExtensionsFlow.value.map { it.signatureHash }.toSet() if (signature !in untrustedSignatures) return ExtensionLoader.trustedSignatures += signature preferences.trustedSignatures() += signature - val nowTrustedExtensions = untrustedExtensions.filter { it.signatureHash == signature } - untrustedExtensions -= nowTrustedExtensions + val nowTrustedExtensions = _untrustedExtensionsFlow.value.filter { it.signatureHash == signature } + _untrustedExtensionsFlow.value -= nowTrustedExtensions val ctx = context launchNow { @@ -385,7 +340,7 @@ class ExtensionManager( } // SY <-- - installedExtensions += extension + _installedExtensionsFlow.value += extension } /** @@ -402,13 +357,13 @@ class ExtensionManager( } // SY <-- - val mutInstalledExtensions = installedExtensions.toMutableList() + val mutInstalledExtensions = _installedExtensionsFlow.value.toMutableList() val oldExtension = mutInstalledExtensions.find { it.pkgName == extension.pkgName } if (oldExtension != null) { mutInstalledExtensions -= oldExtension } mutInstalledExtensions += extension - installedExtensions = mutInstalledExtensions + _installedExtensionsFlow.value = mutInstalledExtensions } /** @@ -418,13 +373,13 @@ class ExtensionManager( * @param pkgName The package name of the uninstalled application. */ private fun unregisterExtension(pkgName: String) { - val installedExtension = installedExtensions.find { it.pkgName == pkgName } + val installedExtension = _installedExtensionsFlow.value.find { it.pkgName == pkgName } if (installedExtension != null) { - installedExtensions -= installedExtension + _installedExtensionsFlow.value -= installedExtension } - val untrustedExtension = untrustedExtensions.find { it.pkgName == pkgName } + val untrustedExtension = _untrustedExtensionsFlow.value.find { it.pkgName == pkgName } if (untrustedExtension != null) { - untrustedExtensions -= untrustedExtension + _untrustedExtensionsFlow.value -= untrustedExtension } } @@ -444,7 +399,7 @@ class ExtensionManager( } override fun onExtensionUntrusted(extension: Extension.Untrusted) { - untrustedExtensions += extension + _untrustedExtensionsFlow.value += extension } override fun onPackageUninstalled(pkgName: String) { @@ -457,14 +412,14 @@ class ExtensionManager( * Extension method to set the update field of an installed extension. */ private fun Extension.Installed.withUpdateCheck(): Extension.Installed { - val availableExt = availableExtensions.find { it.pkgName == pkgName } - if ((isUnofficial.not() || availableExt?.isRepoSource == true) && availableExt != null && availableExt.versionCode > versionCode) { + val availableExt = _availableExtensionsFlow.value.find { it.pkgName == pkgName } + if ((!isUnofficial || availableExt?.isRepoSource == true) && availableExt != null && availableExt.versionCode > versionCode) { return copy(hasUpdate = true) } return this } private fun updatePendingUpdatesCount() { - preferences.extensionUpdatesCount().set(installedExtensions.count { it.hasUpdate }) + preferences.extensionUpdatesCount().set(_installedExtensionsFlow.value.count { it.hasUpdate }) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt index 6ef051e25..5f49473c4 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt @@ -96,7 +96,7 @@ internal class ExtensionGithubApi { } val extensions = if (fromAvailableExtensionList) { - extensionManager.availableExtensions + extensionManager.availableExtensionsFlow.value } else { findExtensions().also { lastExtCheck.set(Date().time) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/SourceExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/source/SourceExtensions.kt index 93c78166f..34ce39267 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/SourceExtensions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/SourceExtensions.kt @@ -7,7 +7,7 @@ import eu.kanade.tachiyomi.extension.ExtensionManager import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get -fun Source.icon(): Drawable? = Injekt.get().getAppIconForSource(this) +fun Source.icon(): Drawable? = Injekt.get().getAppIconForSource(this.id) fun Source.getPreferenceKey(): String = "source_$id" diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/SourceManager.kt b/app/src/main/java/eu/kanade/tachiyomi/source/SourceManager.kt index ae4f965ec..b8cb8ffba 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/source/SourceManager.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/SourceManager.kt @@ -73,7 +73,7 @@ class SourceManager( init { scope.launch { - extensionManager.getInstalledExtensionsFlow() + extensionManager.installedExtensionsFlow // SY --> .combine(preferences.enableExhentai().changes()) { extensions, enableExhentai -> extensions to enableExhentai diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/details/ExtensionDetailsPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/details/ExtensionDetailsPresenter.kt index b5a6fb063..3e972394e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/details/ExtensionDetailsPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/details/ExtensionDetailsPresenter.kt @@ -36,7 +36,7 @@ class ExtensionDetailsPresenter( super.onCreate(savedState) presenterScope.launchIO { - extensionManager.getInstalledExtensionsFlow() + extensionManager.installedExtensionsFlow .map { it.firstOrNull { pkg -> pkg.pkgName == pkgName } } .collectLatest { extension -> // If extension is null it's most likely uninstalled diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/GlobalSearchPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/GlobalSearchPresenter.kt index 6f298ca3b..81407fcee 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/GlobalSearchPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/GlobalSearchPresenter.kt @@ -117,7 +117,7 @@ open class GlobalSearchPresenter( if (!filter.isNullOrEmpty()) { // SY --> - val filteredSourceIds = extensionManager.installedExtensions + val filteredSourceIds = extensionManager.installedExtensionsFlow.value .filter { it.pkgName == filter } .flatMap { it.sources } .map { it.id }