Refactor network to local manga logic
Maybe fixes #8289 (cherry picked from commit d5b4bb49b168adc5b7c3934e530571497c85a916) # Conflicts: # app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SearchPresenter.kt # app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourcePresenter.kt # app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/GlobalSearchPresenter.kt
This commit is contained in:
parent
9b28b65e62
commit
b5ae4c0d43
@ -27,7 +27,7 @@ class MangaRepositoryImpl(
|
||||
}
|
||||
|
||||
override suspend fun getMangaByUrlAndSourceId(url: String, sourceId: Long): Manga? {
|
||||
return handler.awaitOneOrNull { mangasQueries.getMangaByUrlAndSource(url, sourceId, mangaMapper) }
|
||||
return handler.awaitOneOrNull(inTransaction = true) { mangasQueries.getMangaByUrlAndSource(url, sourceId, mangaMapper) }
|
||||
}
|
||||
|
||||
override fun getMangaByUrlAndSourceIdAsFlow(url: String, sourceId: Long): Flow<Manga?> {
|
||||
|
@ -44,7 +44,7 @@ import eu.kanade.domain.manga.interactor.GetFavorites
|
||||
import eu.kanade.domain.manga.interactor.GetLibraryManga
|
||||
import eu.kanade.domain.manga.interactor.GetManga
|
||||
import eu.kanade.domain.manga.interactor.GetMangaWithChapters
|
||||
import eu.kanade.domain.manga.interactor.InsertManga
|
||||
import eu.kanade.domain.manga.interactor.NetworkToLocalManga
|
||||
import eu.kanade.domain.manga.interactor.ResetViewerFlags
|
||||
import eu.kanade.domain.manga.interactor.SetMangaChapterFlags
|
||||
import eu.kanade.domain.manga.interactor.SetMangaViewerFlags
|
||||
@ -98,7 +98,7 @@ class DomainModule : InjektModule {
|
||||
addFactory { SetMangaChapterFlags(get()) }
|
||||
addFactory { SetMangaDefaultChapterFlags(get(), get(), get()) }
|
||||
addFactory { SetMangaViewerFlags(get()) }
|
||||
addFactory { InsertManga(get()) }
|
||||
addFactory { NetworkToLocalManga(get()) }
|
||||
addFactory { UpdateManga(get()) }
|
||||
addFactory { SetMangaCategories(get()) }
|
||||
|
||||
|
@ -24,15 +24,15 @@ class GetManga(
|
||||
return mangaRepository.getMangaByIdAsFlow(id)
|
||||
}
|
||||
|
||||
suspend fun await(url: String, sourceId: Long): Manga? {
|
||||
return mangaRepository.getMangaByUrlAndSourceId(url, sourceId)
|
||||
}
|
||||
|
||||
fun subscribe(url: String, sourceId: Long): Flow<Manga?> {
|
||||
return mangaRepository.getMangaByUrlAndSourceIdAsFlow(url, sourceId)
|
||||
}
|
||||
|
||||
// SY -->
|
||||
suspend fun await(url: String, sourceId: Long): Manga? {
|
||||
return mangaRepository.getMangaByUrlAndSourceId(url, sourceId)
|
||||
}
|
||||
|
||||
override suspend fun awaitId(url: String, sourceId: Long): Long? {
|
||||
return await(url, sourceId)?.id
|
||||
}
|
||||
|
@ -1,13 +0,0 @@
|
||||
package eu.kanade.domain.manga.interactor
|
||||
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
import eu.kanade.domain.manga.repository.MangaRepository
|
||||
|
||||
class InsertManga(
|
||||
private val mangaRepository: MangaRepository,
|
||||
) {
|
||||
|
||||
suspend fun await(manga: Manga): Long? {
|
||||
return mangaRepository.insert(manga)
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package eu.kanade.domain.manga.interactor
|
||||
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
import eu.kanade.domain.manga.repository.MangaRepository
|
||||
|
||||
class NetworkToLocalManga(
|
||||
private val mangaRepository: MangaRepository,
|
||||
) {
|
||||
|
||||
suspend fun await(manga: Manga, sourceId: Long): Manga {
|
||||
val localManga = getManga(manga.url, sourceId)
|
||||
return when {
|
||||
localManga == null -> {
|
||||
val id = insertManga(manga)
|
||||
manga.copy(id = id!!)
|
||||
}
|
||||
!localManga.favorite -> {
|
||||
// if the manga isn't a favorite, set its display title from source
|
||||
// if it later becomes a favorite, updated title will go to db
|
||||
localManga.copy(/* SY --> */ogTitle/* SY <-- */ = manga.title)
|
||||
}
|
||||
else -> {
|
||||
localManga
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun getManga(url: String, sourceId: Long): Manga? {
|
||||
return mangaRepository.getMangaByUrlAndSourceId(url, sourceId)
|
||||
}
|
||||
|
||||
private suspend fun insertManga(manga: Manga): Long? {
|
||||
return mangaRepository.insert(manga)
|
||||
}
|
||||
}
|
@ -295,6 +295,23 @@ fun Manga.toMangaUpdate(): MangaUpdate {
|
||||
)
|
||||
}
|
||||
|
||||
fun SManga.toDomainManga(): Manga {
|
||||
return Manga.create().copy(
|
||||
url = url,
|
||||
// SY -->
|
||||
ogTitle = title,
|
||||
ogArtist = artist,
|
||||
ogAuthor = author,
|
||||
ogDescription = description,
|
||||
ogGenre = getGenres(),
|
||||
ogStatus = status.toLong(),
|
||||
// SY <--
|
||||
thumbnailUrl = thumbnail_url,
|
||||
updateStrategy = update_strategy,
|
||||
initialized = initialized,
|
||||
)
|
||||
}
|
||||
|
||||
fun Manga.isLocal(): Boolean = source == LocalSource.ID
|
||||
|
||||
fun Manga.hasCustomCover(coverCache: CoverCache = Injekt.get()): Boolean {
|
||||
|
@ -25,7 +25,7 @@ import eu.kanade.domain.manga.interactor.GetLibraryManga
|
||||
import eu.kanade.domain.manga.interactor.GetManga
|
||||
import eu.kanade.domain.manga.interactor.GetMergedMangaForDownloading
|
||||
import eu.kanade.domain.manga.interactor.InsertFlatMetadata
|
||||
import eu.kanade.domain.manga.interactor.InsertManga
|
||||
import eu.kanade.domain.manga.interactor.NetworkToLocalManga
|
||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
import eu.kanade.domain.manga.model.toDbManga
|
||||
@ -119,7 +119,7 @@ class LibraryUpdateService(
|
||||
// SY -->
|
||||
private val getFavorites: GetFavorites = Injekt.get(),
|
||||
private val insertFlatMetadata: InsertFlatMetadata = Injekt.get(),
|
||||
private val insertManga: InsertManga = Injekt.get(),
|
||||
private val networkToLocalManga: NetworkToLocalManga = Injekt.get(),
|
||||
private val getMergedMangaForDownloading: GetMergedMangaForDownloading = Injekt.get(),
|
||||
// SY <--
|
||||
) : Service() {
|
||||
@ -728,18 +728,16 @@ class LibraryUpdateService(
|
||||
var dbManga = getManga.await(networkManga.url, mangaDex.id)
|
||||
|
||||
if (dbManga == null) {
|
||||
val newManga = Manga.create().copy(
|
||||
url = networkManga.url,
|
||||
ogTitle = networkManga.title,
|
||||
source = mangaDex.id,
|
||||
favorite = true,
|
||||
dateAdded = System.currentTimeMillis(),
|
||||
dbManga = networkToLocalManga.await(
|
||||
Manga.create().copy(
|
||||
url = networkManga.url,
|
||||
ogTitle = networkManga.title,
|
||||
source = mangaDex.id,
|
||||
favorite = true,
|
||||
dateAdded = System.currentTimeMillis(),
|
||||
),
|
||||
mangaDex.id,
|
||||
)
|
||||
val result = runBlocking {
|
||||
val id = insertManga.await(newManga)
|
||||
getManga.await(id!!)
|
||||
}
|
||||
dbManga = result ?: return
|
||||
} else if (!dbManga.favorite) {
|
||||
updateManga.awaitUpdateFavorite(dbManga.id, true)
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import eu.kanade.domain.chapter.model.toDbChapter
|
||||
import eu.kanade.domain.download.service.DownloadPreferences
|
||||
import eu.kanade.domain.manga.interactor.GetManga
|
||||
import eu.kanade.domain.manga.interactor.GetMergedReferencesById
|
||||
import eu.kanade.domain.manga.interactor.InsertManga
|
||||
import eu.kanade.domain.manga.interactor.NetworkToLocalManga
|
||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||
@ -40,7 +40,7 @@ class MergedSource : HttpSource() {
|
||||
private val getManga: GetManga by injectLazy()
|
||||
private val getMergedReferencesById: GetMergedReferencesById by injectLazy()
|
||||
private val getMergedChaptersByMangaId: GetMergedChapterByMangaId by injectLazy()
|
||||
private val insertManga: InsertManga by injectLazy()
|
||||
private val networkToLocalManga: NetworkToLocalManga by injectLazy()
|
||||
private val updateManga: UpdateManga by injectLazy()
|
||||
private val getCategories: GetCategories by injectLazy()
|
||||
private val sourceManager: SourceManager by injectLazy()
|
||||
@ -187,8 +187,7 @@ class MergedSource : HttpSource() {
|
||||
semaphore.withPermit {
|
||||
values.flatMap {
|
||||
try {
|
||||
val (source, loadedManga, reference) =
|
||||
it.load(sourceManager, getManga, insertManga, updateManga)
|
||||
val (source, loadedManga, reference) = it.load()
|
||||
if (loadedManga != null && reference.getChapterUpdates) {
|
||||
val chapterList = source.getChapterList(loadedManga.toSManga())
|
||||
val results =
|
||||
@ -219,19 +218,19 @@ class MergedSource : HttpSource() {
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun MergedMangaReference.load(sourceManager: SourceManager, getManga: GetManga, insertManga: InsertManga, updateManga: UpdateManga): LoadedMangaSource {
|
||||
suspend fun MergedMangaReference.load(): LoadedMangaSource {
|
||||
var manga = getManga.await(mangaUrl, mangaSourceId)
|
||||
val source = sourceManager.getOrStub(manga?.source ?: mangaSourceId)
|
||||
if (manga == null) {
|
||||
val id = insertManga.await(
|
||||
val newManga = networkToLocalManga.await(
|
||||
Manga.create().copy(
|
||||
source = mangaSourceId,
|
||||
url = mangaUrl,
|
||||
),
|
||||
)!!
|
||||
val newManga = getManga.await(id)!!
|
||||
mangaSourceId,
|
||||
)
|
||||
updateManga.awaitUpdateFromSource(newManga, source.getMangaDetails(newManga.toSManga()), false)
|
||||
manga = getManga.await(id)!!
|
||||
manga = getManga.await(newManga.id)!!
|
||||
}
|
||||
return LoadedMangaSource(source, manga, this)
|
||||
}
|
||||
|
@ -4,9 +4,9 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.produceState
|
||||
import eu.kanade.domain.manga.interactor.GetManga
|
||||
import eu.kanade.domain.manga.interactor.InsertManga
|
||||
import eu.kanade.domain.manga.interactor.NetworkToLocalManga
|
||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||
import eu.kanade.domain.manga.model.toDbManga
|
||||
import eu.kanade.domain.manga.model.toDomainManga
|
||||
import eu.kanade.domain.manga.model.toMangaUpdate
|
||||
import eu.kanade.domain.source.interactor.CountFeedSavedSearchGlobal
|
||||
import eu.kanade.domain.source.interactor.DeleteFeedSavedSearchById
|
||||
@ -18,13 +18,10 @@ import eu.kanade.domain.source.service.SourcePreferences
|
||||
import eu.kanade.presentation.browse.FeedItemUI
|
||||
import eu.kanade.presentation.browse.FeedState
|
||||
import eu.kanade.presentation.browse.FeedStateImpl
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.database.models.toDomainManga
|
||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
import eu.kanade.tachiyomi.source.model.MangasPage
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||
import eu.kanade.tachiyomi.util.lang.launchNonCancellable
|
||||
import eu.kanade.tachiyomi.util.lang.withIOContext
|
||||
@ -60,7 +57,7 @@ open class FeedPresenter(
|
||||
val sourceManager: SourceManager = Injekt.get(),
|
||||
val sourcePreferences: SourcePreferences = Injekt.get(),
|
||||
private val getManga: GetManga = Injekt.get(),
|
||||
private val insertManga: InsertManga = Injekt.get(),
|
||||
private val networkToLocalManga: NetworkToLocalManga = Injekt.get(),
|
||||
private val updateManga: UpdateManga = Injekt.get(),
|
||||
private val getFeedSavedSearchGlobal: GetFeedSavedSearchGlobal = Injekt.get(),
|
||||
private val getSavedSearchGlobalFeed: GetSavedSearchGlobalFeed = Injekt.get(),
|
||||
@ -204,8 +201,8 @@ open class FeedPresenter(
|
||||
.subscribeOn(Schedulers.io())
|
||||
.onErrorReturn { MangasPage(emptyList(), false) } // Ignore timeouts or other exceptions
|
||||
.map { it.mangas } // Get manga from search result.
|
||||
.map { list -> list.map { networkToLocalManga(it, itemUI.source.id) } } // Convert to local manga.
|
||||
.map { list -> itemUI.copy(results = list.mapNotNull { it.toDomainManga() }) }
|
||||
.map { list -> runBlocking { list.map { networkToLocalManga.await(it.toDomainManga(), itemUI.source.id) } } } // Convert to local manga.
|
||||
.map { list -> itemUI.copy(results = list) }
|
||||
} else {
|
||||
Observable.just(itemUI.copy(results = emptyList()))
|
||||
}
|
||||
@ -255,32 +252,6 @@ open class FeedPresenter(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a manga from the database for the given manga from network. It creates a new entry
|
||||
* if the manga is not yet in the database.
|
||||
*
|
||||
* @param sManga the manga from the source.
|
||||
* @return a manga from the database.
|
||||
*/
|
||||
private fun networkToLocalManga(sManga: SManga, sourceId: Long): Manga {
|
||||
var localManga = runBlocking { getManga.await(sManga.url, sourceId) }
|
||||
if (localManga == null) {
|
||||
val newManga = Manga.create(sManga.url, sManga.title, sourceId)
|
||||
newManga.copyFrom(sManga)
|
||||
newManga.id = -1
|
||||
val result = runBlocking {
|
||||
val id = insertManga.await(newManga.toDomainManga()!!)
|
||||
getManga.await(id!!)
|
||||
}
|
||||
localManga = result
|
||||
} else if (!localManga.favorite) {
|
||||
// if the manga isn't a favorite, set its display title from source
|
||||
// if it later becomes a favorite, updated title will go to db
|
||||
localManga = localManga.copy(ogTitle = sManga.title)
|
||||
}
|
||||
return localManga?.toDbManga()!!
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a manga.
|
||||
*
|
||||
|
@ -15,7 +15,7 @@ import eu.kanade.domain.history.interactor.UpsertHistory
|
||||
import eu.kanade.domain.history.model.HistoryUpdate
|
||||
import eu.kanade.domain.manga.interactor.GetManga
|
||||
import eu.kanade.domain.manga.interactor.GetMergedReferencesById
|
||||
import eu.kanade.domain.manga.interactor.InsertManga
|
||||
import eu.kanade.domain.manga.interactor.NetworkToLocalManga
|
||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
import eu.kanade.domain.manga.model.MangaUpdate
|
||||
@ -26,12 +26,10 @@ import eu.kanade.domain.track.interactor.GetTracks
|
||||
import eu.kanade.domain.track.interactor.InsertTrack
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||
import eu.kanade.tachiyomi.data.database.models.toDomainManga
|
||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.source.getNameForMangaInfo
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import eu.kanade.tachiyomi.source.online.all.EHentai
|
||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||
import eu.kanade.tachiyomi.ui.browse.migration.MigrationFlags
|
||||
@ -64,7 +62,7 @@ class MigrationListPresenter(
|
||||
private val sourceManager: SourceManager = Injekt.get(),
|
||||
private val coverCache: CoverCache = Injekt.get(),
|
||||
private val getManga: GetManga = Injekt.get(),
|
||||
private val insertManga: InsertManga = Injekt.get(),
|
||||
private val networkToLocalManga: NetworkToLocalManga = Injekt.get(),
|
||||
private val updateManga: UpdateManga = Injekt.get(),
|
||||
private val syncChaptersWithSource: SyncChaptersWithSource = Injekt.get(),
|
||||
private val updateChapter: UpdateChapter = Injekt.get(),
|
||||
@ -182,7 +180,7 @@ class MigrationListPresenter(
|
||||
}
|
||||
|
||||
if (searchResult != null && !(searchResult.url == mangaObj.url && source.id == mangaObj.source)) {
|
||||
val localManga = networkToLocalManga(
|
||||
val localManga = networkToLocalManga.await(
|
||||
searchResult,
|
||||
source.id,
|
||||
)
|
||||
@ -222,7 +220,7 @@ class MigrationListPresenter(
|
||||
}
|
||||
|
||||
if (searchResult != null) {
|
||||
val localManga = networkToLocalManga(searchResult, source.id)
|
||||
val localManga = networkToLocalManga.await(searchResult, source.id)
|
||||
val chapters = try {
|
||||
if (source is EHentai) {
|
||||
source.getChapterList(localManga.toSManga(), throttleManager::throttle)
|
||||
@ -385,7 +383,7 @@ class MigrationListPresenter(
|
||||
migratingManga.searchResult.value = SearchResult.Searching
|
||||
presenterScope.launchIO {
|
||||
val result = migratingManga.migrationScope.async {
|
||||
val localManga = networkToLocalManga(manga.toDbManga(), source.id)
|
||||
val localManga = networkToLocalManga.await(manga, source.id)
|
||||
try {
|
||||
val chapters = source.getChapterList(localManga.toSManga())
|
||||
syncChaptersWithSource.await(chapters, localManga, source)
|
||||
@ -524,30 +522,4 @@ class MigrationListPresenter(
|
||||
it.migrationScope.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a manga from the database for the given manga from network. It creates a new entry
|
||||
* if the manga is not yet in the database.
|
||||
*
|
||||
* @param sManga the manga from the source.
|
||||
* @return a manga from the database.
|
||||
*/
|
||||
private suspend fun networkToLocalManga(sManga: SManga, sourceId: Long): Manga {
|
||||
var localManga = getManga.await(sManga.url, sourceId)
|
||||
if (localManga == null) {
|
||||
val newManga = eu.kanade.tachiyomi.data.database.models.Manga.create(sManga.url, sManga.title, sourceId)
|
||||
newManga.copyFrom(sManga)
|
||||
newManga.id = -1
|
||||
val result = run {
|
||||
val id = insertManga.await(newManga.toDomainManga()!!)
|
||||
getManga.await(id!!)
|
||||
}
|
||||
localManga = result
|
||||
} else if (!localManga.favorite) {
|
||||
// if the manga isn't a favorite, set its display title from source
|
||||
// if it later becomes a favorite, updated title will go to db
|
||||
localManga = localManga.copy(ogTitle = sManga.title)
|
||||
}
|
||||
return localManga!!
|
||||
}
|
||||
}
|
||||
|
@ -30,9 +30,10 @@ import eu.kanade.domain.library.service.LibraryPreferences
|
||||
import eu.kanade.domain.manga.interactor.GetDuplicateLibraryManga
|
||||
import eu.kanade.domain.manga.interactor.GetFlatMetadataById
|
||||
import eu.kanade.domain.manga.interactor.GetManga
|
||||
import eu.kanade.domain.manga.interactor.InsertManga
|
||||
import eu.kanade.domain.manga.interactor.NetworkToLocalManga
|
||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||
import eu.kanade.domain.manga.model.toDbManga
|
||||
import eu.kanade.domain.manga.model.toDomainManga
|
||||
import eu.kanade.domain.manga.model.toMangaUpdate
|
||||
import eu.kanade.domain.source.interactor.DeleteSavedSearchById
|
||||
import eu.kanade.domain.source.interactor.GetExhSavedSearch
|
||||
@ -45,8 +46,6 @@ import eu.kanade.domain.track.model.toDomainTrack
|
||||
import eu.kanade.presentation.browse.BrowseSourceState
|
||||
import eu.kanade.presentation.browse.BrowseSourceStateImpl
|
||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.database.models.toDomainManga
|
||||
import eu.kanade.tachiyomi.data.track.EnhancedTrackService
|
||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||
import eu.kanade.tachiyomi.data.track.TrackService
|
||||
@ -55,7 +54,6 @@ import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.source.model.Filter
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import eu.kanade.tachiyomi.source.online.MetadataSource
|
||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||
import eu.kanade.tachiyomi.ui.browse.source.filter.AutoComplete
|
||||
@ -124,7 +122,7 @@ open class BrowseSourcePresenter(
|
||||
private val getChapterByMangaId: GetChapterByMangaId = Injekt.get(),
|
||||
private val setMangaCategories: SetMangaCategories = Injekt.get(),
|
||||
private val setMangaDefaultChapterFlags: SetMangaDefaultChapterFlags = Injekt.get(),
|
||||
private val insertManga: InsertManga = Injekt.get(),
|
||||
private val networkToLocalManga: NetworkToLocalManga = Injekt.get(),
|
||||
private val updateManga: UpdateManga = Injekt.get(),
|
||||
private val insertTrack: InsertTrack = Injekt.get(),
|
||||
private val syncChaptersWithTrackServiceTwoWay: SyncChaptersWithTrackServiceTwoWay = Injekt.get(),
|
||||
@ -170,11 +168,11 @@ open class BrowseSourcePresenter(
|
||||
createSourcePagingSource(currentFilter.query, currentFilter.filters)
|
||||
}.flow
|
||||
.map {
|
||||
it.map {
|
||||
it.map { (sManga, metadata) ->
|
||||
// SY -->
|
||||
withIOContext {
|
||||
networkToLocalManga(it.first, sourceId).toDomainManga()!!
|
||||
} to it.second
|
||||
networkToLocalManga.await(sManga.toDomainManga(), sourceId)
|
||||
} to metadata
|
||||
// SY <--
|
||||
}
|
||||
}
|
||||
@ -272,30 +270,6 @@ open class BrowseSourcePresenter(
|
||||
// SY <--
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a manga from the database for the given manga from network. It creates a new entry
|
||||
* if the manga is not yet in the database.
|
||||
*
|
||||
* @param sManga the manga from the source.
|
||||
* @return a manga from the database.
|
||||
*/
|
||||
private suspend fun networkToLocalManga(sManga: SManga, sourceId: Long): Manga {
|
||||
var localManga = getManga.await(sManga.url, sourceId)
|
||||
if (localManga == null) {
|
||||
val newManga = Manga.create(sManga.url, sManga.title, sourceId)
|
||||
newManga.copyFrom(sManga)
|
||||
newManga.id = -1
|
||||
val id = insertManga.await(newManga.toDomainManga()!!)
|
||||
val result = getManga.await(id!!)
|
||||
localManga = result
|
||||
} else if (!localManga.favorite) {
|
||||
// if the manga isn't a favorite, set its display title from source
|
||||
// if it later becomes a favorite, updated title will go to db
|
||||
localManga = localManga.copy(ogTitle = sManga.title)
|
||||
}
|
||||
return localManga?.toDbManga()!!
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a manga.
|
||||
*
|
||||
|
@ -7,9 +7,9 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.produceState
|
||||
import eu.kanade.domain.base.BasePreferences
|
||||
import eu.kanade.domain.manga.interactor.GetManga
|
||||
import eu.kanade.domain.manga.interactor.InsertManga
|
||||
import eu.kanade.domain.manga.interactor.NetworkToLocalManga
|
||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||
import eu.kanade.domain.manga.model.toDbManga
|
||||
import eu.kanade.domain.manga.model.toDomainManga
|
||||
import eu.kanade.domain.manga.model.toMangaUpdate
|
||||
import eu.kanade.domain.source.interactor.CountFeedSavedSearchBySourceId
|
||||
import eu.kanade.domain.source.interactor.DeleteFeedSavedSearchById
|
||||
@ -20,12 +20,9 @@ import eu.kanade.domain.source.interactor.InsertFeedSavedSearch
|
||||
import eu.kanade.presentation.browse.SourceFeedState
|
||||
import eu.kanade.presentation.browse.SourceFeedStateImpl
|
||||
import eu.kanade.presentation.browse.SourceFeedUI
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.database.models.toDomainManga
|
||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
import eu.kanade.tachiyomi.source.model.MangasPage
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||
import eu.kanade.tachiyomi.util.lang.launchNonCancellable
|
||||
import eu.kanade.tachiyomi.util.lang.withIOContext
|
||||
@ -60,7 +57,7 @@ open class SourceFeedPresenter(
|
||||
val source: CatalogueSource,
|
||||
private val preferences: BasePreferences = Injekt.get(),
|
||||
private val getManga: GetManga = Injekt.get(),
|
||||
private val insertManga: InsertManga = Injekt.get(),
|
||||
private val networkToLocalManga: NetworkToLocalManga = Injekt.get(),
|
||||
private val updateManga: UpdateManga = Injekt.get(),
|
||||
private val getFeedSavedSearchBySourceId: GetFeedSavedSearchBySourceId = Injekt.get(),
|
||||
private val getSavedSearchBySourceIdFeed: GetSavedSearchBySourceIdFeed = Injekt.get(),
|
||||
@ -162,8 +159,8 @@ open class SourceFeedPresenter(
|
||||
.subscribeOn(Schedulers.io())
|
||||
.onErrorReturn { MangasPage(emptyList(), false) } // Ignore timeouts or other exceptions
|
||||
.map { it.mangas } // Get manga from search result.
|
||||
.map { list -> list.map { networkToLocalManga(it, source.id) } } // Convert to local manga.
|
||||
.map { list -> sourceFeed.withResults(list.mapNotNull { it.toDomainManga() }) }
|
||||
.map { list -> runBlocking { list.map { networkToLocalManga.await(it.toDomainManga(), source.id) } } } // Convert to local manga.
|
||||
.map { list -> sourceFeed.withResults(list) }
|
||||
},
|
||||
5,
|
||||
)
|
||||
@ -211,32 +208,6 @@ open class SourceFeedPresenter(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a manga from the database for the given manga from network. It creates a new entry
|
||||
* if the manga is not yet in the database.
|
||||
*
|
||||
* @param sManga the manga from the source.
|
||||
* @return a manga from the database.
|
||||
*/
|
||||
private fun networkToLocalManga(sManga: SManga, sourceId: Long): Manga {
|
||||
var localManga = runBlocking { getManga.await(sManga.url, sourceId) }
|
||||
if (localManga == null) {
|
||||
val newManga = Manga.create(sManga.url, sManga.title, sourceId)
|
||||
newManga.copyFrom(sManga)
|
||||
newManga.id = -1
|
||||
val result = runBlocking {
|
||||
val id = insertManga.await(newManga.toDomainManga()!!)
|
||||
getManga.await(id!!)
|
||||
}
|
||||
localManga = result
|
||||
} else if (!localManga.favorite) {
|
||||
// if the manga isn't a favorite, set its display title from source
|
||||
// if it later becomes a favorite, updated title will go to db
|
||||
localManga = localManga.copy(ogTitle = sManga.title)
|
||||
}
|
||||
return localManga?.toDbManga()!!
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a manga.
|
||||
*
|
||||
|
@ -2,10 +2,10 @@ package eu.kanade.tachiyomi.ui.browse.source.globalsearch
|
||||
|
||||
import android.os.Bundle
|
||||
import eu.kanade.domain.base.BasePreferences
|
||||
import eu.kanade.domain.manga.interactor.GetManga
|
||||
import eu.kanade.domain.manga.interactor.InsertManga
|
||||
import eu.kanade.domain.manga.interactor.NetworkToLocalManga
|
||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||
import eu.kanade.domain.manga.model.toDbManga
|
||||
import eu.kanade.domain.manga.model.toDomainManga
|
||||
import eu.kanade.domain.manga.model.toMangaUpdate
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
@ -30,6 +30,7 @@ import rx.subjects.PublishSubject
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import eu.kanade.domain.manga.model.Manga as DomainManga
|
||||
|
||||
open class GlobalSearchPresenter(
|
||||
private val initialQuery: String? = "",
|
||||
@ -38,8 +39,7 @@ open class GlobalSearchPresenter(
|
||||
val sourceManager: SourceManager = Injekt.get(),
|
||||
val preferences: BasePreferences = Injekt.get(),
|
||||
val sourcePreferences: SourcePreferences = Injekt.get(),
|
||||
private val getManga: GetManga = Injekt.get(),
|
||||
private val insertManga: InsertManga = Injekt.get(),
|
||||
private val networkToLocalManga: NetworkToLocalManga = Injekt.get(),
|
||||
private val updateManga: UpdateManga = Injekt.get(),
|
||||
) : BasePresenter<GlobalSearchController>() {
|
||||
|
||||
@ -56,7 +56,7 @@ open class GlobalSearchPresenter(
|
||||
/**
|
||||
* Subject which fetches image of given manga.
|
||||
*/
|
||||
private val fetchImageSubject = PublishSubject.create<Pair<List<Manga>, Source>>()
|
||||
private val fetchImageSubject = PublishSubject.create<Pair<List<DomainManga>, Source>>()
|
||||
|
||||
/**
|
||||
* Subscription for fetching images of manga.
|
||||
@ -172,9 +172,9 @@ open class GlobalSearchPresenter(
|
||||
.subscribeOn(Schedulers.io())
|
||||
.onErrorReturn { MangasPage(emptyList(), false) } // Ignore timeouts or other exceptions
|
||||
.map { it.mangas }
|
||||
.map { list -> list.map { networkToLocalManga(it, source.id) } } // Convert to local manga
|
||||
.map { list -> list.map { runBlocking { networkToLocalManga(it, source.id) } } } // Convert to local manga
|
||||
.doOnNext { fetchImage(it, source) } // Load manga covers
|
||||
.map { list -> createCatalogueSearchItem(source, list.map { GlobalSearchCardItem(it.toDomainManga()!!) }) }
|
||||
.map { list -> createCatalogueSearchItem(source, list.map { GlobalSearchCardItem(it) }) }
|
||||
},
|
||||
5,
|
||||
)
|
||||
@ -212,7 +212,7 @@ open class GlobalSearchPresenter(
|
||||
*
|
||||
* @param manga the list of manga to initialize.
|
||||
*/
|
||||
private fun fetchImage(manga: List<Manga>, source: Source) {
|
||||
private fun fetchImage(manga: List<DomainManga>, source: Source) {
|
||||
fetchImageSubject.onNext(Pair(manga, source))
|
||||
}
|
||||
|
||||
@ -224,9 +224,9 @@ open class GlobalSearchPresenter(
|
||||
fetchImageSubscription = fetchImageSubject.observeOn(Schedulers.io())
|
||||
.flatMap { (first, source) ->
|
||||
Observable.from(first)
|
||||
.filter { it.thumbnail_url == null && !it.initialized }
|
||||
.filter { it.thumbnailUrl == null && !it.initialized }
|
||||
.map { Pair(it, source) }
|
||||
.concatMap { runAsObservable { getMangaDetails(it.first, it.second) } }
|
||||
.concatMap { runAsObservable { getMangaDetails(it.first.toDbManga(), it.second) } }
|
||||
.map { Pair(source as CatalogueSource, it) }
|
||||
}
|
||||
.onBackpressureBuffer()
|
||||
@ -263,22 +263,7 @@ open class GlobalSearchPresenter(
|
||||
* @param sManga the manga from the source.
|
||||
* @return a manga from the database.
|
||||
*/
|
||||
protected open fun networkToLocalManga(sManga: SManga, sourceId: Long): Manga {
|
||||
var localManga = runBlocking { getManga.await(sManga.url, sourceId) }
|
||||
if (localManga == null) {
|
||||
val newManga = Manga.create(sManga.url, sManga.title, sourceId)
|
||||
newManga.copyFrom(sManga)
|
||||
newManga.id = -1
|
||||
val result = runBlocking {
|
||||
val id = insertManga.await(newManga.toDomainManga()!!)
|
||||
getManga.await(id!!)
|
||||
}
|
||||
localManga = result
|
||||
} else if (!localManga.favorite) {
|
||||
// if the manga isn't a favorite, set its display title from source
|
||||
// if it later becomes a favorite, updated title will go to db
|
||||
localManga = localManga.copy(ogTitle = sManga.title)
|
||||
}
|
||||
return localManga!!.toDbManga()
|
||||
protected open suspend fun networkToLocalManga(sManga: SManga, sourceId: Long): DomainManga {
|
||||
return networkToLocalManga.await(sManga.toDomainManga(), sourceId)
|
||||
}
|
||||
}
|
||||
|
@ -29,8 +29,8 @@ import eu.kanade.domain.manga.interactor.GetMangaWithChapters
|
||||
import eu.kanade.domain.manga.interactor.GetMergedMangaById
|
||||
import eu.kanade.domain.manga.interactor.GetMergedReferencesById
|
||||
import eu.kanade.domain.manga.interactor.GetPagePreviews
|
||||
import eu.kanade.domain.manga.interactor.InsertManga
|
||||
import eu.kanade.domain.manga.interactor.InsertMergedReference
|
||||
import eu.kanade.domain.manga.interactor.NetworkToLocalManga
|
||||
import eu.kanade.domain.manga.interactor.SetMangaChapterFlags
|
||||
import eu.kanade.domain.manga.interactor.SetMangaFilteredScanlators
|
||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||
@ -49,7 +49,6 @@ import eu.kanade.domain.track.model.toDomainTrack
|
||||
import eu.kanade.domain.ui.UiPreferences
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.models.Track
|
||||
import eu.kanade.tachiyomi.data.database.models.toDomainManga
|
||||
import eu.kanade.tachiyomi.data.download.DownloadCache
|
||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||
import eu.kanade.tachiyomi.data.download.model.Download
|
||||
@ -125,7 +124,6 @@ import java.text.DecimalFormatSymbols
|
||||
import java.util.Date
|
||||
import eu.kanade.domain.chapter.model.Chapter as DomainChapter
|
||||
import eu.kanade.domain.manga.model.Manga as DomainManga
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga.Companion as DbManga
|
||||
|
||||
class MangaPresenter(
|
||||
val mangaId: Long,
|
||||
@ -149,7 +147,7 @@ class MangaPresenter(
|
||||
private val getMergedReferencesById: GetMergedReferencesById = Injekt.get(),
|
||||
private val insertMergedReference: InsertMergedReference = Injekt.get(),
|
||||
private val updateMergedSettings: UpdateMergedSettings = Injekt.get(),
|
||||
private val insertManga: InsertManga = Injekt.get(),
|
||||
private val networkToLocalManga: NetworkToLocalManga = Injekt.get(),
|
||||
private val deleteMangaById: DeleteMangaById = Injekt.get(),
|
||||
private val deleteByMergeId: DeleteByMergeId = Injekt.get(),
|
||||
private val getFlatMetadata: GetFlatMetadataById = Injekt.get(),
|
||||
@ -577,15 +575,20 @@ class MangaPresenter(
|
||||
|
||||
return originalManga
|
||||
} else {
|
||||
val mergedManga = DbManga.create(originalManga.url, originalManga.title, MERGED_SOURCE_ID).apply {
|
||||
copyFrom(originalManga.toSManga())
|
||||
favorite = true
|
||||
last_update = originalManga.lastUpdate
|
||||
viewer_flags = originalManga.viewerFlags.toInt()
|
||||
chapter_flags = originalManga.chapterFlags.toInt()
|
||||
sorting = DomainManga.CHAPTER_SORTING_NUMBER.toInt()
|
||||
date_added = System.currentTimeMillis()
|
||||
}
|
||||
var mergedManga = DomainManga.create()
|
||||
.copy(
|
||||
url = originalManga.url,
|
||||
ogTitle = originalManga.title,
|
||||
source = MERGED_SOURCE_ID,
|
||||
)
|
||||
.copyFrom(originalManga.toSManga())
|
||||
.copy(
|
||||
favorite = true,
|
||||
lastUpdate = originalManga.lastUpdate,
|
||||
viewerFlags = originalManga.viewerFlags,
|
||||
chapterFlags = originalManga.chapterFlags,
|
||||
dateAdded = System.currentTimeMillis(),
|
||||
)
|
||||
|
||||
var existingManga = getManga.await(mergedManga.url, mergedManga.source)
|
||||
while (existingManga != null) {
|
||||
@ -602,15 +605,11 @@ class MangaPresenter(
|
||||
existingManga = getManga.await(mergedManga.url, mergedManga.source)
|
||||
}
|
||||
|
||||
// Reload chapters immediately
|
||||
mergedManga.initialized = false
|
||||
mergedManga.id = -1
|
||||
val newId = insertManga.await(mergedManga.toDomainManga()!!)
|
||||
mergedManga.id = newId ?: throw NullPointerException("Invalid new manga id")
|
||||
mergedManga = networkToLocalManga.await(mergedManga, mergedManga.source)
|
||||
|
||||
getCategories.await(originalMangaId)
|
||||
.let {
|
||||
setMangaCategories.await(newId, it.map { it.id })
|
||||
setMangaCategories.await(mergedManga.id, it.map { it.id })
|
||||
}
|
||||
|
||||
val originalMangaReference = MergedMangaReference(
|
||||
@ -620,7 +619,7 @@ class MangaPresenter(
|
||||
chapterSortMode = 0,
|
||||
chapterPriority = 0,
|
||||
downloadChapters = true,
|
||||
mergeId = mergedManga.id!!,
|
||||
mergeId = mergedManga.id,
|
||||
mergeUrl = mergedManga.url,
|
||||
mangaId = originalManga.id,
|
||||
mangaUrl = originalManga.url,
|
||||
@ -634,7 +633,7 @@ class MangaPresenter(
|
||||
chapterSortMode = 0,
|
||||
chapterPriority = 0,
|
||||
downloadChapters = true,
|
||||
mergeId = mergedManga.id!!,
|
||||
mergeId = mergedManga.id,
|
||||
mergeUrl = mergedManga.url,
|
||||
mangaId = manga.id,
|
||||
mangaUrl = manga.url,
|
||||
@ -648,16 +647,16 @@ class MangaPresenter(
|
||||
chapterSortMode = 0,
|
||||
chapterPriority = -1,
|
||||
downloadChapters = false,
|
||||
mergeId = mergedManga.id!!,
|
||||
mergeId = mergedManga.id,
|
||||
mergeUrl = mergedManga.url,
|
||||
mangaId = mergedManga.id!!,
|
||||
mangaId = mergedManga.id,
|
||||
mangaUrl = mergedManga.url,
|
||||
mangaSourceId = MERGED_SOURCE_ID,
|
||||
)
|
||||
|
||||
insertMergedReference.awaitAll(listOf(originalMangaReference, newMangaReference, mergedMangaReference))
|
||||
|
||||
return mergedManga.toDomainManga()!!
|
||||
return mergedManga
|
||||
}
|
||||
|
||||
// Note that if the manga are merged in a different order, this won't trigger, but I don't care lol
|
||||
|
@ -6,7 +6,7 @@ import eu.kanade.domain.chapter.interactor.GetChapter
|
||||
import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
|
||||
import eu.kanade.domain.chapter.model.Chapter
|
||||
import eu.kanade.domain.manga.interactor.GetManga
|
||||
import eu.kanade.domain.manga.interactor.InsertManga
|
||||
import eu.kanade.domain.manga.interactor.NetworkToLocalManga
|
||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
@ -22,7 +22,7 @@ import uy.kohesive.injekt.api.get
|
||||
class GalleryAdder(
|
||||
private val getManga: GetManga = Injekt.get(),
|
||||
private val updateManga: UpdateManga = Injekt.get(),
|
||||
private val insertManga: InsertManga = Injekt.get(),
|
||||
private val networkToLocalManga: NetworkToLocalManga = Injekt.get(),
|
||||
private val getChapter: GetChapter = Injekt.get(),
|
||||
private val syncChaptersWithSource: SyncChaptersWithSource = Injekt.get(),
|
||||
private val sourceManager: SourceManager = Injekt.get(),
|
||||
@ -129,15 +129,13 @@ class GalleryAdder(
|
||||
|
||||
// Use manga in DB if possible, otherwise, make a new manga
|
||||
var manga = getManga.await(cleanedMangaUrl, source.id)
|
||||
?: run {
|
||||
insertManga.await(
|
||||
Manga.create().copy(
|
||||
source = source.id,
|
||||
url = cleanedMangaUrl,
|
||||
),
|
||||
)
|
||||
getManga.await(cleanedMangaUrl, source.id)!!
|
||||
}
|
||||
?: networkToLocalManga.await(
|
||||
Manga.create().copy(
|
||||
source = source.id,
|
||||
url = cleanedMangaUrl,
|
||||
),
|
||||
source.id,
|
||||
)
|
||||
|
||||
// Fetch and copy details
|
||||
val newManga = source.getMangaDetails(manga.toSManga())
|
||||
|
@ -1,9 +1,7 @@
|
||||
package exh.smartsearch
|
||||
|
||||
import eu.kanade.domain.manga.interactor.GetManga
|
||||
import eu.kanade.domain.manga.interactor.InsertManga
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
import eu.kanade.tachiyomi.data.database.models.toDomainManga
|
||||
import eu.kanade.domain.manga.model.toDomainManga
|
||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
@ -12,19 +10,14 @@ import info.debatty.java.stringsimilarity.NormalizedLevenshtein
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.supervisorScope
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.util.Locale
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga.Companion as DbManga
|
||||
|
||||
class SmartSearchEngine(
|
||||
private val extraSearchParams: String? = null,
|
||||
) {
|
||||
private val getManga: GetManga by injectLazy()
|
||||
private val insertManga: InsertManga by injectLazy()
|
||||
|
||||
private val normalizedLevenshtein = NormalizedLevenshtein()
|
||||
|
||||
suspend fun smartSearch(source: CatalogueSource, title: String): SManga? {
|
||||
suspend fun smartSearch(source: CatalogueSource, title: String): Manga? {
|
||||
val cleanedTitle = cleanSmartSearchTitle(title)
|
||||
|
||||
val queries = getSmartSearchQueries(cleanedTitle)
|
||||
@ -51,10 +44,10 @@ class SmartSearchEngine(
|
||||
}.flatMap { it.await() }
|
||||
}
|
||||
|
||||
return eligibleManga.maxByOrNull { it.dist }?.manga
|
||||
return eligibleManga.maxByOrNull { it.dist }?.manga?.toDomainManga()
|
||||
}
|
||||
|
||||
suspend fun normalSearch(source: CatalogueSource, title: String): SManga? {
|
||||
suspend fun normalSearch(source: CatalogueSource, title: String): Manga? {
|
||||
val eligibleManga = supervisorScope {
|
||||
val searchQuery = if (extraSearchParams != null) {
|
||||
"$title ${extraSearchParams.trim()}"
|
||||
@ -75,7 +68,7 @@ class SmartSearchEngine(
|
||||
}
|
||||
}
|
||||
|
||||
return eligibleManga.maxByOrNull { it.dist }?.manga
|
||||
return eligibleManga.maxByOrNull { it.dist }?.manga?.toDomainManga()
|
||||
}
|
||||
|
||||
private fun getSmartSearchQueries(cleanedTitle: String): List<String> {
|
||||
@ -169,32 +162,6 @@ class SmartSearchEngine(
|
||||
return result.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a manga from the database for the given manga from network. It creates a new entry
|
||||
* if the manga is not yet in the database.
|
||||
*
|
||||
* @param sManga the manga from the source.
|
||||
* @return a manga from the database.
|
||||
*/
|
||||
suspend fun networkToLocalManga(sManga: SManga, sourceId: Long): Manga {
|
||||
var localManga = getManga.await(sManga.url, sourceId)
|
||||
if (localManga == null) {
|
||||
val newManga = DbManga.create(sManga.url, sManga.title, sourceId)
|
||||
newManga.copyFrom(sManga)
|
||||
newManga.id = -1
|
||||
val result = run {
|
||||
val id = insertManga.await(newManga.toDomainManga()!!)
|
||||
getManga.await(id!!)
|
||||
}
|
||||
localManga = result
|
||||
} else if (!localManga.favorite) {
|
||||
// if the manga isn't a favorite, set its display title from source
|
||||
// if it later becomes a favorite, updated title will go to db
|
||||
localManga = localManga.copy(ogTitle = sManga.title)
|
||||
}
|
||||
return localManga!!
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val MIN_SMART_ELIGIBLE_THRESHOLD = 0.4
|
||||
const val MIN_NORMAL_ELIGIBLE_THRESHOLD = 0.4
|
||||
|
@ -1,6 +1,7 @@
|
||||
package exh.ui.smartsearch
|
||||
|
||||
import android.os.Bundle
|
||||
import eu.kanade.domain.manga.interactor.NetworkToLocalManga
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||
@ -10,8 +11,14 @@ import exh.smartsearch.SmartSearchEngine
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.asSharedFlow
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
class SmartSearchPresenter(private val source: CatalogueSource, private val config: SourcesController.SmartSearchConfig) :
|
||||
class SmartSearchPresenter(
|
||||
private val source: CatalogueSource,
|
||||
private val config: SourcesController.SmartSearchConfig,
|
||||
private val networkToLocalManga: NetworkToLocalManga = Injekt.get(),
|
||||
) :
|
||||
BasePresenter<SmartSearchController>() {
|
||||
|
||||
private val _smartSearchFlow = MutableSharedFlow<SearchResults>()
|
||||
@ -26,7 +33,7 @@ class SmartSearchPresenter(private val source: CatalogueSource, private val conf
|
||||
val result = try {
|
||||
val resultManga = smartSearchEngine.smartSearch(source, config.origTitle)
|
||||
if (resultManga != null) {
|
||||
val localManga = smartSearchEngine.networkToLocalManga(resultManga, source.id)
|
||||
val localManga = networkToLocalManga.await(resultManga, source.id)
|
||||
SearchResults.Found(localManga)
|
||||
} else {
|
||||
SearchResults.NotFound
|
||||
|
Loading…
x
Reference in New Issue
Block a user