feat(tracker): add support for EnhancedTracker to merged sources (#932)
* fix: add support for `EnhancedTracker` to merged sources * ref: readability * fix: use only sources specific to the merged title * fix: don't match using name * formatting * don't block, suspend * Move merged source out of EnhancedTracker * Extract Injekt * Return first accepted merged manga * Move getMergedSources to SourceManager and update usages accordingly * simplify code --------- Co-authored-by: Cuong-Tran <cuongtran.tm@gmail.com> Co-authored-by: Cuong-Tran <16017808+cuong-tran@users.noreply.github.com>
This commit is contained in:
parent
8f57f4a5a0
commit
c7e0585c6f
6 changed files with 76 additions and 14 deletions
|
|
@ -18,6 +18,15 @@ interface EnhancedTracker {
|
|||
return source::class.qualifiedName in getAcceptedSources()
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
/**
|
||||
* This tracker will only work with the sources that are accepted by this filter function.
|
||||
*/
|
||||
fun accept(sources: List<Source>): Boolean {
|
||||
return sources.any { accept(it) }
|
||||
}
|
||||
// KMK <--
|
||||
|
||||
/**
|
||||
* Fully qualified source classes that this tracker is compatible with.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ import kotlinx.coroutines.flow.combine
|
|||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import tachiyomi.domain.manga.interactor.GetMergedReferencesById
|
||||
import tachiyomi.domain.source.model.StubSource
|
||||
import tachiyomi.domain.source.repository.StubSourceRepository
|
||||
import tachiyomi.domain.source.service.SourceManager
|
||||
|
|
@ -76,6 +77,9 @@ class AndroidSourceManager(
|
|||
private val exhPreferences: ExhPreferences by injectLazy()
|
||||
private val sourcePreferences: SourcePreferences by injectLazy()
|
||||
// SY <--
|
||||
// KMK -->
|
||||
private val getMergedReferencesById: GetMergedReferencesById by injectLazy()
|
||||
// KMK <--
|
||||
|
||||
init {
|
||||
scope.launch {
|
||||
|
|
@ -238,6 +242,14 @@ class AndroidSourceManager(
|
|||
}
|
||||
// SY <--
|
||||
|
||||
// KMK -->
|
||||
override suspend fun getMergedSources(mangaId: Long): List<Source> {
|
||||
val sources = getMergedReferencesById.await(mangaId)
|
||||
return sources.distinctBy { it.mangaSourceId }
|
||||
.map { getOrStub(it.mangaSourceId) }
|
||||
}
|
||||
// KMK <--
|
||||
|
||||
private fun registerStubSource(source: StubSource) {
|
||||
scope.launch {
|
||||
val dbSource = sourceRepository.getStubSource(source.id)
|
||||
|
|
|
|||
|
|
@ -1823,7 +1823,16 @@ class MangaScreenModel(
|
|||
trackerManager.loggedInTrackersFlow(),
|
||||
) { mangaTracks, loggedInTrackers ->
|
||||
// Show only if the service supports this manga's source
|
||||
val supportedTrackers = loggedInTrackers.filter { (it as? EnhancedTracker)?.accept(source!!) ?: true }
|
||||
// KMK -->
|
||||
val supportedTrackers = source?.let { source ->
|
||||
val sources = if (source is MergedSource) {
|
||||
state.mergedData?.sources ?: emptyList()
|
||||
} else {
|
||||
listOf(source)
|
||||
}
|
||||
loggedInTrackers.filter { (it as? EnhancedTracker)?.accept(sources) ?: true }
|
||||
} ?: loggedInTrackers.filterNot { it is EnhancedTracker }
|
||||
// KMK <--
|
||||
val supportedTrackerIds = supportedTrackers.map { it.id }.toHashSet()
|
||||
val supportedTrackerTracks = mangaTracks.filter { it.trackerId in supportedTrackerIds }
|
||||
supportedTrackerTracks to supportedTrackers
|
||||
|
|
|
|||
|
|
@ -60,12 +60,14 @@ import eu.kanade.tachiyomi.data.track.Tracker
|
|||
import eu.kanade.tachiyomi.data.track.TrackerManager
|
||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||
import eu.kanade.tachiyomi.source.online.MetadataSource
|
||||
import eu.kanade.tachiyomi.source.online.all.MergedSource
|
||||
import eu.kanade.tachiyomi.util.lang.convertEpochMillisZone
|
||||
import eu.kanade.tachiyomi.util.lang.toLocalDate
|
||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||
import eu.kanade.tachiyomi.util.system.openInBrowser
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import exh.metadata.metadata.base.TrackerIdMetadata
|
||||
import exh.source.MERGED_SOURCE_ID
|
||||
import exh.source.getMainSource
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.coroutines.flow.catch
|
||||
|
|
@ -83,6 +85,8 @@ import tachiyomi.core.common.util.lang.withUIContext
|
|||
import tachiyomi.core.common.util.system.logcat
|
||||
import tachiyomi.domain.manga.interactor.GetFlatMetadataById
|
||||
import tachiyomi.domain.manga.interactor.GetManga
|
||||
import tachiyomi.domain.manga.interactor.GetMergedReferencesById
|
||||
import tachiyomi.domain.manga.model.Manga
|
||||
import tachiyomi.domain.source.service.SourceManager
|
||||
import tachiyomi.domain.track.interactor.DeleteTrack
|
||||
import tachiyomi.domain.track.interactor.GetTracks
|
||||
|
|
@ -94,6 +98,7 @@ import tachiyomi.presentation.core.components.material.padding
|
|||
import tachiyomi.presentation.core.i18n.stringResource
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.time.Instant
|
||||
import java.time.LocalDate
|
||||
import java.time.ZoneOffset
|
||||
|
|
@ -230,10 +235,14 @@ data class TrackInfoDialogHomeScreen(
|
|||
private val trackPreferences: TrackPreferences = Injekt.get(),
|
||||
// SY <--
|
||||
// KMK -->
|
||||
val sourceManager: SourceManager = Injekt.get<SourceManager>(),
|
||||
val getFlatMetadataById: GetFlatMetadataById = Injekt.get<GetFlatMetadataById>(),
|
||||
private val sourceManager: SourceManager = Injekt.get(),
|
||||
// KMK <--
|
||||
) : StateScreenModel<Model.State>(State()) {
|
||||
// KMK -->
|
||||
private val getFlatMetadataById: GetFlatMetadataById by injectLazy()
|
||||
private val getMangaById: GetManga by injectLazy()
|
||||
private val getMergedReferencesById: GetMergedReferencesById by injectLazy()
|
||||
// KMK <--
|
||||
|
||||
init {
|
||||
screenModelScope.launch {
|
||||
|
|
@ -249,10 +258,25 @@ data class TrackInfoDialogHomeScreen(
|
|||
}
|
||||
}
|
||||
|
||||
// KMK -->
|
||||
private suspend fun getMangaForTracking(item: TrackItem): Manga? {
|
||||
if (sourceId != MERGED_SOURCE_ID) {
|
||||
return getMangaById.await(mangaId)
|
||||
}
|
||||
item.tracker as EnhancedTracker
|
||||
val references = getMergedReferencesById.await(mangaId)
|
||||
return references.distinctBy { it.mangaSourceId }.firstNotNullOfOrNull { ref ->
|
||||
sourceManager.get(ref.mangaSourceId)
|
||||
?.takeIf(item.tracker::accept)
|
||||
?.let { ref.mangaId?.let { mangaId -> getMangaById.await(mangaId) } }
|
||||
}
|
||||
}
|
||||
// KMK <--
|
||||
|
||||
fun registerEnhancedTracking(item: TrackItem) {
|
||||
item.tracker as EnhancedTracker
|
||||
screenModelScope.launchNonCancellable {
|
||||
val manga = Injekt.get<GetManga>().await(mangaId) ?: return@launchNonCancellable
|
||||
val manga = getMangaForTracking(item) ?: return@launchNonCancellable
|
||||
try {
|
||||
val matchResult = item.tracker.match(manga) ?: throw Exception()
|
||||
item.tracker.register(matchResult, mangaId)
|
||||
|
|
@ -361,14 +385,23 @@ data class TrackInfoDialogHomeScreen(
|
|||
}
|
||||
}
|
||||
|
||||
private fun List<Track>.mapToTrackItem(): List<TrackItem> {
|
||||
val loggedInTrackers = Injekt.get<TrackerManager>().loggedInTrackers()
|
||||
val source = Injekt.get<SourceManager>().getOrStub(sourceId)
|
||||
private suspend fun List<Track>.mapToTrackItem(): List<TrackItem> {
|
||||
val loggedInTrackers = trackerManager.loggedInTrackers()
|
||||
val source = sourceManager.getOrStub(sourceId)
|
||||
return loggedInTrackers
|
||||
// Map to TrackItem
|
||||
.map { service -> TrackItem(find { it.trackerId == service.id }, service) }
|
||||
// Show only if the service supports this manga's source
|
||||
.filter { (it.tracker as? EnhancedTracker)?.accept(source) ?: true }
|
||||
// KMK -->
|
||||
.let { trackers ->
|
||||
val sources = if (source is MergedSource) {
|
||||
sourceManager.getMergedSources(mangaId)
|
||||
} else {
|
||||
listOf(source)
|
||||
}
|
||||
trackers.filter { (it.tracker as? EnhancedTracker)?.accept(sources) ?: true }
|
||||
}
|
||||
// KMK <--
|
||||
}
|
||||
|
||||
@Immutable
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ import tachiyomi.core.common.util.lang.withUIContext
|
|||
import tachiyomi.core.common.util.system.logcat
|
||||
import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId
|
||||
import tachiyomi.domain.manga.interactor.GetManga
|
||||
import tachiyomi.domain.manga.interactor.GetMergedReferencesById
|
||||
import tachiyomi.domain.manga.interactor.NetworkToLocalManga
|
||||
import tachiyomi.domain.manga.model.Manga
|
||||
import tachiyomi.domain.source.service.SourceManager
|
||||
|
|
@ -57,9 +56,6 @@ class MigrationListScreenModel(
|
|||
private val syncChaptersWithSource: SyncChaptersWithSource = Injekt.get(),
|
||||
private val getChaptersByMangaId: GetChaptersByMangaId = Injekt.get(),
|
||||
private val migrateManga: MigrateMangaUseCase = Injekt.get(),
|
||||
// SY -->
|
||||
private val getMergedReferencesById: GetMergedReferencesById = Injekt.get(),
|
||||
// SY <--
|
||||
) : StateScreenModel<MigrationListScreenModel.State>(State()) {
|
||||
|
||||
private val smartSearchEngine = SmartSourceSearchEngine(extraSearchQuery)
|
||||
|
|
@ -97,8 +93,7 @@ class MigrationListScreenModel(
|
|||
source = sourceManager.getOrStub(manga.source).getNameForMangaInfo(
|
||||
// KMK -->
|
||||
if (manga.source == MERGED_SOURCE_ID) {
|
||||
getMergedReferencesById.await(manga.id)
|
||||
.map { sourceManager.getOrStub(it.mangaSourceId) }
|
||||
sourceManager.getMergedSources(manga.id)
|
||||
} else {
|
||||
null
|
||||
},
|
||||
|
|
|
|||
|
|
@ -27,5 +27,9 @@ interface SourceManager {
|
|||
fun getVisibleCatalogueSources(): List<CatalogueSource>
|
||||
// SY <--
|
||||
|
||||
// KMK -->
|
||||
suspend fun getMergedSources(mangaId: Long): List<Source>
|
||||
// KMK <--
|
||||
|
||||
fun getStubSources(): List<StubSource>
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue