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