Remove redundancy in ExtensionManager

This commit is contained in:
arkon 2022-10-21 14:42:21 -04:00
parent b04807e53a
commit 93925a7286
8 changed files with 38 additions and 87 deletions

View File

@ -13,7 +13,7 @@ class GetExtensionLanguages(
fun subscribe(): Flow<List<String>> { fun subscribe(): Flow<List<String>> {
return combine( return combine(
preferences.enabledLanguages().changes(), preferences.enabledLanguages().changes(),
extensionManager.getAvailableExtensionsFlow(), extensionManager.availableExtensionsFlow,
) { enabledLanguage, availableExtensions -> ) { enabledLanguage, availableExtensions ->
availableExtensions availableExtensions
.flatMap { ext -> .flatMap { ext ->

View File

@ -17,9 +17,9 @@ class GetExtensionsByType(
return combine( return combine(
preferences.enabledLanguages().changes(), preferences.enabledLanguages().changes(),
extensionManager.getInstalledExtensionsFlow(), extensionManager.installedExtensionsFlow,
extensionManager.getUntrustedExtensionsFlow(), extensionManager.untrustedExtensionsFlow,
extensionManager.getAvailableExtensionsFlow(), extensionManager.availableExtensionsFlow,
) { _activeLanguages, _installed, _untrusted, _available -> ) { _activeLanguages, _installed, _untrusted, _available ->
val (updates, installed) = _installed val (updates, installed) = _installed
.filter { (showNsfwSources || it.isNsfw.not()) } .filter { (showNsfwSources || it.isNsfw.not()) }

View File

@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.extension
import android.content.Context import android.content.Context
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import com.jakewharton.rxrelay.BehaviorRelay
import eu.kanade.domain.source.model.SourceData import eu.kanade.domain.source.model.SourceData
import eu.kanade.domain.source.service.SourcePreferences import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
@ -14,7 +13,6 @@ import eu.kanade.tachiyomi.extension.model.LoadResult
import eu.kanade.tachiyomi.extension.util.ExtensionInstallReceiver import eu.kanade.tachiyomi.extension.util.ExtensionInstallReceiver
import eu.kanade.tachiyomi.extension.util.ExtensionInstaller import eu.kanade.tachiyomi.extension.util.ExtensionInstaller
import eu.kanade.tachiyomi.extension.util.ExtensionLoader 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.launchNow
import eu.kanade.tachiyomi.util.lang.withUIContext import eu.kanade.tachiyomi.util.lang.withUIContext
import eu.kanade.tachiyomi.util.preference.plusAssign import eu.kanade.tachiyomi.util.preference.plusAssign
@ -22,7 +20,6 @@ import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import kotlinx.coroutines.async import kotlinx.coroutines.async
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
import logcat.LogPriority import logcat.LogPriority
import rx.Observable import rx.Observable
@ -55,59 +52,23 @@ class ExtensionManager(
*/ */
private val installer by lazy { ExtensionInstaller(context) } private val installer by lazy { ExtensionInstaller(context) }
/**
* Relay used to notify the installed extensions.
*/
private val installedExtensionsRelay = BehaviorRelay.create<List<Extension.Installed>>()
private val iconMap = mutableMapOf<String, Drawable>() private val iconMap = mutableMapOf<String, Drawable>()
/** private val _installedExtensionsFlow = MutableStateFlow(emptyList<Extension.Installed>())
* List of the currently installed extensions. val installedExtensionsFlow = _installedExtensionsFlow.asStateFlow()
*/
var installedExtensions = emptyList<Extension.Installed>()
private set(value) {
field = value
installedExtensionsFlow.value = field
installedExtensionsRelay.call(value)
}
private val installedExtensionsFlow = MutableStateFlow(installedExtensions)
private var subLanguagesEnabledOnFirstRun = preferences.enabledLanguages().isSet() private var subLanguagesEnabledOnFirstRun = preferences.enabledLanguages().isSet()
fun getInstalledExtensionsFlow(): StateFlow<List<Extension.Installed>> {
return installedExtensionsFlow.asStateFlow()
}
fun getAppIconForSource(source: Source): Drawable? {
return getAppIconForSource(source.id)
}
fun getAppIconForSource(sourceId: Long): Drawable? { 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) { if (pkgName != null) {
return iconMap[pkgName] ?: iconMap.getOrPut(pkgName) { context.packageManager.getApplicationIcon(pkgName) } return iconMap[pkgName] ?: iconMap.getOrPut(pkgName) { context.packageManager.getApplicationIcon(pkgName) }
} }
return null return null
} }
/** private val _availableExtensionsFlow = MutableStateFlow(emptyList<Extension.Available>())
* List of the currently available extensions. val availableExtensionsFlow = _availableExtensionsFlow.asStateFlow()
*/
var availableExtensions = emptyList<Extension.Available>()
private set(value) {
field = value
availableExtensionsFlow.value = field
updatedInstalledExtensionsStatuses(value)
setupAvailableExtensionsSourcesDataMap(value)
}
private val availableExtensionsFlow = MutableStateFlow(availableExtensions)
fun getAvailableExtensionsFlow(): StateFlow<List<Extension.Available>> {
return availableExtensionsFlow.asStateFlow()
}
private var availableExtensionsSourcesData: Map<Long, SourceData> = mapOf() private var availableExtensionsSourcesData: Map<Long, SourceData> = mapOf()
@ -120,20 +81,8 @@ class ExtensionManager(
fun getSourceData(id: Long) = availableExtensionsSourcesData[id] fun getSourceData(id: Long) = availableExtensionsSourcesData[id]
/** private val _untrustedExtensionsFlow = MutableStateFlow(emptyList<Extension.Untrusted>())
* List of the currently untrusted extensions. val untrustedExtensionsFlow = _untrustedExtensionsFlow.asStateFlow()
*/
var untrustedExtensions = emptyList<Extension.Untrusted>()
private set(value) {
field = value
untrustedExtensionsFlow.value = field
}
private val untrustedExtensionsFlow = MutableStateFlow(untrustedExtensions)
fun getUntrustedExtensionsFlow(): StateFlow<List<Extension.Untrusted>> {
return untrustedExtensionsFlow.asStateFlow()
}
init { init {
initExtensions() initExtensions()
@ -146,11 +95,11 @@ class ExtensionManager(
private fun initExtensions() { private fun initExtensions() {
val extensions = ExtensionLoader.loadExtensions(context) val extensions = ExtensionLoader.loadExtensions(context)
installedExtensions = extensions _installedExtensionsFlow.value = extensions
.filterIsInstance<LoadResult.Success>() .filterIsInstance<LoadResult.Success>()
.map { it.extension } .map { it.extension }
untrustedExtensions = extensions _untrustedExtensionsFlow.value = extensions
.filterIsInstance<LoadResult.Untrusted>() .filterIsInstance<LoadResult.Untrusted>()
.map { it.extension } .map { it.extension }
} }
@ -169,7 +118,9 @@ class ExtensionManager(
enableAdditionalSubLanguages(extensions) enableAdditionalSubLanguages(extensions)
availableExtensions = extensions _availableExtensionsFlow.value = extensions
updatedInstalledExtensionsStatuses(extensions)
setupAvailableExtensionsSourcesDataMap(extensions)
} }
/** /**
@ -213,7 +164,7 @@ class ExtensionManager(
return return
} }
val mutInstalledExtensions = installedExtensions.toMutableList() val mutInstalledExtensions = _installedExtensionsFlow.value.toMutableList()
var changed = false var changed = false
for ((index, installedExt) in mutInstalledExtensions.withIndex()) { for ((index, installedExt) in mutInstalledExtensions.withIndex()) {
@ -234,7 +185,7 @@ class ExtensionManager(
} }
} }
if (changed) { if (changed) {
installedExtensions = mutInstalledExtensions _installedExtensionsFlow.value = mutInstalledExtensions
} }
updatePendingUpdatesCount() updatePendingUpdatesCount()
} }
@ -258,7 +209,7 @@ class ExtensionManager(
* @param extension The extension to be updated. * @param extension The extension to be updated.
*/ */
fun updateExtension(extension: Extension.Installed): Observable<InstallStep> { fun updateExtension(extension: Extension.Installed): Observable<InstallStep> {
val availableExt = availableExtensions.find { it.pkgName == extension.pkgName } val availableExt = _availableExtensionsFlow.value.find { it.pkgName == extension.pkgName }
?: return Observable.empty() ?: return Observable.empty()
return installExtension(availableExt) return installExtension(availableExt)
} }
@ -296,14 +247,14 @@ class ExtensionManager(
* @param signature The signature to whitelist. * @param signature The signature to whitelist.
*/ */
fun trustSignature(signature: String) { fun trustSignature(signature: String) {
val untrustedSignatures = untrustedExtensions.map { it.signatureHash }.toSet() val untrustedSignatures = _untrustedExtensionsFlow.value.map { it.signatureHash }.toSet()
if (signature !in untrustedSignatures) return if (signature !in untrustedSignatures) return
ExtensionLoader.trustedSignatures += signature ExtensionLoader.trustedSignatures += signature
preferences.trustedSignatures() += signature preferences.trustedSignatures() += signature
val nowTrustedExtensions = untrustedExtensions.filter { it.signatureHash == signature } val nowTrustedExtensions = _untrustedExtensionsFlow.value.filter { it.signatureHash == signature }
untrustedExtensions -= nowTrustedExtensions _untrustedExtensionsFlow.value -= nowTrustedExtensions
val ctx = context val ctx = context
launchNow { launchNow {
@ -326,7 +277,7 @@ class ExtensionManager(
* @param extension The extension to be registered. * @param extension The extension to be registered.
*/ */
private fun registerNewExtension(extension: Extension.Installed) { private fun registerNewExtension(extension: Extension.Installed) {
installedExtensions += extension _installedExtensionsFlow.value += extension
} }
/** /**
@ -336,13 +287,13 @@ class ExtensionManager(
* @param extension The extension to be registered. * @param extension The extension to be registered.
*/ */
private fun registerUpdatedExtension(extension: Extension.Installed) { private fun registerUpdatedExtension(extension: Extension.Installed) {
val mutInstalledExtensions = installedExtensions.toMutableList() val mutInstalledExtensions = _installedExtensionsFlow.value.toMutableList()
val oldExtension = mutInstalledExtensions.find { it.pkgName == extension.pkgName } val oldExtension = mutInstalledExtensions.find { it.pkgName == extension.pkgName }
if (oldExtension != null) { if (oldExtension != null) {
mutInstalledExtensions -= oldExtension mutInstalledExtensions -= oldExtension
} }
mutInstalledExtensions += extension mutInstalledExtensions += extension
installedExtensions = mutInstalledExtensions _installedExtensionsFlow.value = mutInstalledExtensions
} }
/** /**
@ -352,13 +303,13 @@ class ExtensionManager(
* @param pkgName The package name of the uninstalled application. * @param pkgName The package name of the uninstalled application.
*/ */
private fun unregisterExtension(pkgName: String) { private fun unregisterExtension(pkgName: String) {
val installedExtension = installedExtensions.find { it.pkgName == pkgName } val installedExtension = _installedExtensionsFlow.value.find { it.pkgName == pkgName }
if (installedExtension != null) { 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) { if (untrustedExtension != null) {
untrustedExtensions -= untrustedExtension _untrustedExtensionsFlow.value -= untrustedExtension
} }
} }
@ -378,7 +329,7 @@ class ExtensionManager(
} }
override fun onExtensionUntrusted(extension: Extension.Untrusted) { override fun onExtensionUntrusted(extension: Extension.Untrusted) {
untrustedExtensions += extension _untrustedExtensionsFlow.value += extension
} }
override fun onPackageUninstalled(pkgName: String) { override fun onPackageUninstalled(pkgName: String) {
@ -391,14 +342,14 @@ class ExtensionManager(
* Extension method to set the update field of an installed extension. * Extension method to set the update field of an installed extension.
*/ */
private fun Extension.Installed.withUpdateCheck(): Extension.Installed { private fun Extension.Installed.withUpdateCheck(): Extension.Installed {
val availableExt = availableExtensions.find { it.pkgName == pkgName } val availableExt = _availableExtensionsFlow.value.find { it.pkgName == pkgName }
if (isUnofficial.not() && availableExt != null && availableExt.versionCode > versionCode) { if (!isUnofficial && availableExt != null && availableExt.versionCode > versionCode) {
return copy(hasUpdate = true) return copy(hasUpdate = true)
} }
return this return this
} }
private fun updatePendingUpdatesCount() { private fun updatePendingUpdatesCount() {
preferences.extensionUpdatesCount().set(installedExtensions.count { it.hasUpdate }) preferences.extensionUpdatesCount().set(_installedExtensionsFlow.value.count { it.hasUpdate })
} }
} }

View File

@ -74,7 +74,7 @@ internal class ExtensionGithubApi {
} }
val extensions = if (fromAvailableExtensionList) { val extensions = if (fromAvailableExtensionList) {
extensionManager.availableExtensions extensionManager.availableExtensionsFlow.value
} else { } else {
findExtensions().also { lastExtCheck.set(Date().time) } findExtensions().also { lastExtCheck.set(Date().time) }
} }

View File

@ -7,7 +7,7 @@ import eu.kanade.tachiyomi.extension.ExtensionManager
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
fun Source.icon(): Drawable? = Injekt.get<ExtensionManager>().getAppIconForSource(this) fun Source.icon(): Drawable? = Injekt.get<ExtensionManager>().getAppIconForSource(this.id)
fun Source.getPreferenceKey(): String = "source_$id" fun Source.getPreferenceKey(): String = "source_$id"

View File

@ -46,7 +46,7 @@ class SourceManager(
init { init {
scope.launch { scope.launch {
extensionManager.getInstalledExtensionsFlow() extensionManager.installedExtensionsFlow
.collectLatest { extensions -> .collectLatest { extensions ->
val mutableMap = mutableMapOf<Long, Source>(LocalSource.ID to LocalSource(context)) val mutableMap = mutableMapOf<Long, Source>(LocalSource.ID to LocalSource(context))
extensions.forEach { extension -> extensions.forEach { extension ->

View File

@ -36,7 +36,7 @@ class ExtensionDetailsPresenter(
super.onCreate(savedState) super.onCreate(savedState)
presenterScope.launchIO { presenterScope.launchIO {
extensionManager.getInstalledExtensionsFlow() extensionManager.installedExtensionsFlow
.map { it.firstOrNull { pkg -> pkg.pkgName == pkgName } } .map { it.firstOrNull { pkg -> pkg.pkgName == pkgName } }
.collectLatest { extension -> .collectLatest { extension ->
// If extension is null it's most likely uninstalled // If extension is null it's most likely uninstalled

View File

@ -114,7 +114,7 @@ open class GlobalSearchPresenter(
var filteredSources: List<CatalogueSource>? = null var filteredSources: List<CatalogueSource>? = null
if (!filter.isNullOrEmpty()) { if (!filter.isNullOrEmpty()) {
filteredSources = extensionManager.installedExtensions filteredSources = extensionManager.installedExtensionsFlow.value
.filter { it.pkgName == filter } .filter { it.pkgName == filter }
.flatMap { it.sources } .flatMap { it.sources }
.filter { it in enabledSources } .filter { it in enabledSources }