From d3350eb404f3237f4ad9568d56efa9fdd0e58e3c Mon Sep 17 00:00:00 2001 From: Land Date: Tue, 30 Jun 2026 17:45:59 +0530 Subject: [PATCH] fix(explore): prevent permanently pinned mihon sources fixed the bug where Mihon sources could not be unpinned or disabled and stayed permanently pinned. Now they work the same as any other source Fixes #72 --- .../explore/data/MangaSourcesRepository.kt | 38 ++++++++++++++----- .../futon/suggestions/ui/SuggestionsWorker.kt | 1 + 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/explore/data/MangaSourcesRepository.kt b/app/src/main/kotlin/io/github/landwarderer/futon/explore/data/MangaSourcesRepository.kt index 516905a990..7ea2ec1180 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/explore/data/MangaSourcesRepository.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/explore/data/MangaSourcesRepository.kt @@ -24,6 +24,9 @@ import io.github.landwarderer.futon.core.ui.util.ReversibleHandle import io.github.landwarderer.futon.core.util.ext.flattenLatest import io.github.landwarderer.futon.mihon.MihonExtensionManager import io.github.landwarderer.futon.mihon.model.MihonMangaSource +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.channels.trySendBlocking import kotlinx.coroutines.flow.Flow @@ -32,7 +35,9 @@ import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onStart import org.koitharu.kotatsu.parsers.model.ContentType import org.koitharu.kotatsu.parsers.model.MangaParserSource @@ -54,10 +59,20 @@ class MangaSourcesRepository @Inject constructor( private val mihonExtensionManager: MihonExtensionManager, ) { + private val repositoryScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) private val isNewSourcesAssimilated = AtomicBoolean(false) private val dao: MangaSourcesDao get() = db.getSourcesDao() + init { + mihonExtensionManager.installedExtensions + .onEach { + isNewSourcesAssimilated.set(false) + assimilateNewSources() + } + .launchIn(repositoryScope) + } + val allMangaSources: Set = Collections.unmodifiableSet( EnumSet.noneOf(MangaParserSource::class.java).also { MangaParserSource.entries.filterNotTo(it, MangaParserSource::isBroken) @@ -69,7 +84,8 @@ class MangaSourcesRepository @Inject constructor( val order = settings.sourcesSortOrder return dao.findAll(!settings.isAllSourcesEnabled, order).toSources(settings.isNsfwContentDisabled, order) .let { enabled -> - val external = getExternalSources() + val enabledNames = enabled.mapToSet { it.name } + val external = getExternalSources().filterNot { it.name in enabledNames } val list = ArrayList(enabled.size + external.size) external.mapTo(list) { MangaSourceInfo(it, isEnabled = true, isPinned = true) } list.addAll(enabled) @@ -225,8 +241,10 @@ class MangaSourcesRepository @Inject constructor( }.flattenLatest() .onStart { assimilateNewSources() } .combine(observeExternalSources()) { enabled, external -> - val list = ArrayList(enabled.size + external.size) - external.mapTo(list) { MangaSourceInfo(it, isEnabled = true, isPinned = true) } + val enabledNames = enabled.mapToSet { it.name } + val newExternal = external.filterNot { it.name in enabledNames } + val list = ArrayList(enabled.size + newExternal.size) + newExternal.mapTo(list) { MangaSourceInfo(it, isEnabled = true, isPinned = true) } list.addAll(enabled) list } @@ -313,11 +331,11 @@ class MangaSourcesRepository @Inject constructor( val entities = new.map { x -> MangaSourceEntity( source = x.name, - isEnabled = isAllEnabled, + isEnabled = if (x is MihonMangaSource) true else isAllEnabled, sortKey = ++maxSortKey, addedIn = BuildConfig.VERSION_CODE, lastUsedAt = 0, - isPinned = false, + isPinned = x is MihonMangaSource, cfState = CloudFlareHelper.PROTECTION_NOT_DETECTED, title = x.getTitle(context), ) @@ -422,7 +440,7 @@ class MangaSourcesRepository @Inject constructor( } fun getExternalSources(): List { - val external = context.packageManager.queryIntentContentProviders( + return context.packageManager.queryIntentContentProviders( Intent("app.futon.parser.PROVIDE_MANGA"), 0, ).map { resolveInfo -> ExternalMangaSource( @@ -430,8 +448,10 @@ class MangaSourcesRepository @Inject constructor( authority = resolveInfo.providerInfo.authority, ) } - val mihon = mihonExtensionManager.getMihonMangaSources() - return external + mihon + } + + fun getMihonSources(): List { + return mihonExtensionManager.getMihonMangaSources() } private fun List.toSources( @@ -448,7 +468,7 @@ class MangaSourcesRepository @Inject constructor( if (source.isBroken) { continue } - if (source is MangaParserSource || source.name.startsWith("mihon:") || source.name.startsWith("MIHON_")) { + if (source is MangaParserSource || source is MihonMangaSource) { result.add( MangaSourceInfo( mangaSource = source, diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/suggestions/ui/SuggestionsWorker.kt b/app/src/main/kotlin/io/github/landwarderer/futon/suggestions/ui/SuggestionsWorker.kt index 31185289bd..50bfdd8096 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/suggestions/ui/SuggestionsWorker.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/suggestions/ui/SuggestionsWorker.kt @@ -250,6 +250,7 @@ class SuggestionsWorker @AssistedInject constructor( if (appSettings.isSuggestionsIncludeDisabledSources) { val result = sourcesRepository.allMangaSources.toMutableList() result.addAll(sourcesRepository.getExternalSources()) + result.addAll(sourcesRepository.getMihonSources()) result.shuffle() result.sortWith(compareBy(nullsLast(LocaleComparator())) { it.getLocale() }) return result