diff --git a/app/src/main/java/eu/kanade/domain/manga/model/Manga.kt b/app/src/main/java/eu/kanade/domain/manga/model/Manga.kt index 579fc1f72..2898dad0f 100644 --- a/app/src/main/java/eu/kanade/domain/manga/model/Manga.kt +++ b/app/src/main/java/eu/kanade/domain/manga/model/Manga.kt @@ -76,24 +76,6 @@ fun Manga.copyFrom(other: SManga): Manga { ) } -fun SManga.toDomainManga(sourceId: Long): Manga { - return Manga.create().copy( - url = url, - // SY --> - ogTitle = title, - ogArtist = artist, - ogAuthor = author, - ogThumbnailUrl = thumbnail_url, - ogDescription = description, - ogGenre = getGenres(), - ogStatus = status.toLong(), - // SY <-- - updateStrategy = update_strategy, - initialized = initialized, - source = sourceId, - ) -} - fun Manga.hasCustomCover(coverCache: CoverCache = Injekt.get()): Boolean { return coverCache.getCustomCoverFile(id).exists() } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt index cf6666e0f..7e0fe1b9f 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt @@ -510,7 +510,7 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet private suspend fun updateCovers() { val semaphore = Semaphore(5) - val progressCount = AtomicInteger(0) + val progressCount = AtomicInt(0) val currentlyUpdatingManga = CopyOnWriteArrayList() coroutineScope { @@ -585,7 +585,7 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet var dbManga = getManga.await(networkManga.url, mangaDex.id) if (dbManga == null) { - dbManga = networkToLocalManga.await( + dbManga = networkToLocalManga( Manga.create().copy( url = networkManga.url, ogTitle = networkManga.title, diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MergedSource.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MergedSource.kt index beda4188a..e3036e078 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MergedSource.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MergedSource.kt @@ -170,7 +170,7 @@ class MergedSource : HttpSource() { var manga = getManga.await(mangaUrl, mangaSourceId) val source = sourceManager.getOrStub(manga?.source ?: mangaSourceId) if (manga == null) { - val newManga = networkToLocalManga.await( + val newManga = networkToLocalManga( Manga.create().copy( source = mangaSourceId, url = mangaUrl, diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/feed/FeedScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/feed/FeedScreenModel.kt index 091e03e32..6c16f8729 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/feed/FeedScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/feed/FeedScreenModel.kt @@ -7,7 +7,6 @@ import androidx.compose.ui.util.fastAny import cafe.adriel.voyager.core.model.StateScreenModel import cafe.adriel.voyager.core.model.screenModelScope import eu.kanade.domain.manga.interactor.UpdateManga -import eu.kanade.domain.manga.model.toDomainManga import eu.kanade.domain.source.service.SourcePreferences import eu.kanade.presentation.browse.FeedItemUI import eu.kanade.tachiyomi.source.CatalogueSource @@ -31,6 +30,7 @@ import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import kotlinx.serialization.json.Json +import mihon.domain.manga.model.toDomainManga import tachiyomi.core.common.util.lang.launchIO import tachiyomi.core.common.util.lang.launchNonCancellable import tachiyomi.core.common.util.lang.withIOContext @@ -251,9 +251,7 @@ open class FeedScreenModel( val result = withIOContext { itemUI.copy( - results = page.map { - networkToLocalManga.await(it.toDomainManga(itemUI.source!!.id)) - }, + results = networkToLocalManga(page.map { it.toDomainManga(itemUI.source!!.id) }), ) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/advanced/process/MigrationListScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/advanced/process/MigrationListScreenModel.kt index 69df04d0f..2b4d1a2c4 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/advanced/process/MigrationListScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/advanced/process/MigrationListScreenModel.kt @@ -226,7 +226,7 @@ class MigrationListScreenModel( if (searchResult != null && !(searchResult.url == mangaObj.url && source.id == mangaObj.source) ) { - val localManga = networkToLocalManga.await(searchResult) + val localManga = networkToLocalManga(searchResult) val chapters = if (source is EHentai) { source.getChapterList(localManga.toSManga(), throttleManager::throttle) @@ -264,7 +264,7 @@ class MigrationListScreenModel( } if (searchResult != null) { - val localManga = networkToLocalManga.await(searchResult) + val localManga = networkToLocalManga(searchResult) val chapters = try { if (source is EHentai) { source.getChapterList(localManga.toSManga(), throttleManager::throttle) @@ -455,7 +455,7 @@ class MigrationListScreenModel( screenModelScope.launchIO { val result = migratingManga.migrationScope.async { val manga = getManga(newMangaId)!! - val localManga = networkToLocalManga.await(manga) + val localManga = networkToLocalManga(manga) try { val source = sourceManager.get(manga.source)!! val chapters = source.getChapterList(localManga.toSManga()) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreenModel.kt index 624ecfb59..df052612b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreenModel.kt @@ -16,7 +16,6 @@ import cafe.adriel.voyager.core.model.screenModelScope import dev.icerock.moko.resources.StringResource import eu.kanade.core.preference.asState import eu.kanade.domain.manga.interactor.UpdateManga -import eu.kanade.domain.manga.model.toDomainManga import eu.kanade.domain.source.interactor.GetExhSavedSearch import eu.kanade.domain.source.interactor.GetIncognitoState import eu.kanade.domain.source.service.SourcePreferences @@ -39,7 +38,6 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.emptyFlow -import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf @@ -50,7 +48,6 @@ import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking -import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonArray import tachiyomi.core.common.preference.CheckboxState @@ -67,7 +64,6 @@ import tachiyomi.domain.library.service.LibraryPreferences import tachiyomi.domain.manga.interactor.GetDuplicateLibraryManga import tachiyomi.domain.manga.interactor.GetFlatMetadataById import tachiyomi.domain.manga.interactor.GetManga -import tachiyomi.domain.manga.interactor.NetworkToLocalManga import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.manga.model.toMangaUpdate import tachiyomi.domain.source.interactor.DeleteSavedSearchById @@ -75,7 +71,7 @@ import tachiyomi.domain.source.interactor.GetRemoteManga import tachiyomi.domain.source.interactor.InsertSavedSearch import tachiyomi.domain.source.model.EXHSavedSearch import tachiyomi.domain.source.model.SavedSearch -import tachiyomi.domain.source.repository.SourcePagingSourceType +import tachiyomi.domain.source.repository.SourcePagingSource import tachiyomi.domain.source.service.SourceManager import tachiyomi.i18n.sy.SYMR import uy.kohesive.injekt.Injekt @@ -101,7 +97,6 @@ open class BrowseSourceScreenModel( private val setMangaCategories: SetMangaCategories = Injekt.get(), private val setMangaDefaultChapterFlags: SetMangaDefaultChapterFlags = Injekt.get(), private val getManga: GetManga = Injekt.get(), - private val networkToLocalManga: NetworkToLocalManga = Injekt.get(), private val updateManga: UpdateManga = Injekt.get(), private val addTracks: AddTracks = Injekt.get(), private val getIncognitoState: GetIncognitoState = Injekt.get(), @@ -193,10 +188,9 @@ open class BrowseSourceScreenModel( createSourcePagingSource(listing.query ?: "", listing.filters) // SY <-- }.flow.map { pagingData -> - pagingData.map { (it, metadata) -> - networkToLocalManga.await(it.toDomainManga(sourceId)) - .let { localManga -> getManga.subscribe(localManga.url, localManga.source) } - .filterNotNull() + pagingData.map { (manga, metadata) -> + getManga.subscribe(manga.url, manga.source) + .map { it ?: manga } // SY --> .combineMetadata(metadata) // SY <-- @@ -382,8 +376,8 @@ open class BrowseSourceScreenModel( } // SY --> - open fun createSourcePagingSource(query: String, filters: FilterList): SourcePagingSourceType { - return getRemoteManga.subscribe(sourceId, query, filters) + open fun createSourcePagingSource(query: String, filters: FilterList): SourcePagingSource { + return getRemoteManga(sourceId, query, filters) } // SY <-- diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/feed/SourceFeedScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/feed/SourceFeedScreenModel.kt index e23d277f5..5acad9cf9 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/feed/SourceFeedScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/feed/SourceFeedScreenModel.kt @@ -10,7 +10,6 @@ import cafe.adriel.voyager.core.model.screenModelScope import dev.icerock.moko.resources.StringResource import eu.kanade.core.preference.asState import eu.kanade.domain.manga.interactor.UpdateManga -import eu.kanade.domain.manga.model.toDomainManga import eu.kanade.domain.source.interactor.GetExhSavedSearch import eu.kanade.domain.ui.UiPreferences import eu.kanade.presentation.browse.SourceFeedUI @@ -32,8 +31,8 @@ import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json +import mihon.domain.manga.model.toDomainManga import tachiyomi.core.common.util.lang.launchIO import tachiyomi.core.common.util.lang.launchNonCancellable import tachiyomi.core.common.util.lang.withIOContext @@ -173,9 +172,7 @@ open class SourceFeedScreenModel( } val titles = withIOContext { - page.map { - networkToLocalManga.await(it.toDomainManga(source.id)) - } + networkToLocalManga(page.map { it.toDomainManga(source.id) }) } mutableState.update { state -> diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/SearchScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/SearchScreenModel.kt index d8e9106f4..3e9fd6063 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/SearchScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/SearchScreenModel.kt @@ -5,7 +5,6 @@ import androidx.compose.runtime.Immutable import androidx.compose.runtime.produceState import cafe.adriel.voyager.core.model.StateScreenModel import cafe.adriel.voyager.core.model.screenModelScope -import eu.kanade.domain.manga.model.toDomainManga import eu.kanade.domain.source.service.SourcePreferences import eu.kanade.presentation.util.ioCoroutineScope import eu.kanade.tachiyomi.extension.ExtensionManager @@ -25,6 +24,7 @@ import kotlinx.coroutines.flow.update import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import mihon.domain.manga.model.toDomainManga import tachiyomi.core.common.preference.toggle import tachiyomi.domain.manga.interactor.GetManga import tachiyomi.domain.manga.interactor.NetworkToLocalManga @@ -169,9 +169,8 @@ abstract class SearchScreenModel( source.getSearchManga(1, query, source.getFilterList()) } - val titles = page.mangas.map { - networkToLocalManga.await(it.toDomainManga(source.id)) - } + val titles = page.mangas.map { it.toDomainManga(source.id) } + .let { networkToLocalManga(it) } if (isActive) { updateItem(source, SearchItemResult.Success(titles)) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/deeplink/DeepLinkScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/deeplink/DeepLinkScreenModel.kt index 5bef14675..8c71e414c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/deeplink/DeepLinkScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/deeplink/DeepLinkScreenModel.kt @@ -4,18 +4,16 @@ import androidx.compose.runtime.Immutable import cafe.adriel.voyager.core.model.StateScreenModel import cafe.adriel.voyager.core.model.screenModelScope import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource -import eu.kanade.domain.manga.model.toDomainManga import eu.kanade.domain.manga.model.toSManga import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.model.SChapter -import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.online.ResolvableSource import eu.kanade.tachiyomi.source.online.UriType import kotlinx.coroutines.flow.update +import mihon.domain.manga.model.toDomainManga import tachiyomi.core.common.util.lang.launchIO import tachiyomi.domain.chapter.interactor.GetChapterByUrlAndMangaId import tachiyomi.domain.chapter.model.Chapter -import tachiyomi.domain.manga.interactor.GetMangaByUrlAndSourceId import tachiyomi.domain.manga.interactor.NetworkToLocalManga import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.source.service.SourceManager @@ -27,7 +25,6 @@ class DeepLinkScreenModel( private val sourceManager: SourceManager = Injekt.get(), private val networkToLocalManga: NetworkToLocalManga = Injekt.get(), private val getChapterByUrlAndMangaId: GetChapterByUrlAndMangaId = Injekt.get(), - private val getMangaByUrlAndSourceId: GetMangaByUrlAndSourceId = Injekt.get(), private val syncChaptersWithSource: SyncChaptersWithSource = Injekt.get(), ) : StateScreenModel(State.Loading) { @@ -38,7 +35,7 @@ class DeepLinkScreenModel( .firstOrNull { it.getUriType(query) != UriType.Unknown } val manga = source?.getManga(query)?.let { - getMangaFromSManga(it, source.id) + networkToLocalManga(it.toDomainManga(source.id)) } val chapter = if (source?.getUriType(query) == UriType.Chapter && manga != null) { @@ -73,11 +70,6 @@ class DeepLinkScreenModel( } } - private suspend fun getMangaFromSManga(sManga: SManga, sourceId: Long): Manga { - return getMangaByUrlAndSourceId.await(sManga.url, sourceId) - ?: networkToLocalManga.await(sManga.toDomainManga(sourceId)) - } - sealed interface State { @Immutable data object Loading : State diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt index 1c4bb2edb..76570dfc4 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt @@ -658,7 +658,7 @@ class MangaScreenModel( existingManga = getManga.await(mergedManga.url, mergedManga.source) } - mergedManga = networkToLocalManga.await(mergedManga) + mergedManga = networkToLocalManga(mergedManga) getCategories.await(originalMangaId) .let { diff --git a/app/src/main/java/exh/GalleryAdder.kt b/app/src/main/java/exh/GalleryAdder.kt index 1f035ecb5..f9927a43c 100755 --- a/app/src/main/java/exh/GalleryAdder.kt +++ b/app/src/main/java/exh/GalleryAdder.kt @@ -136,7 +136,7 @@ class GalleryAdder( // Use manga in DB if possible, otherwise, make a new manga var manga = getManga.await(cleanedMangaUrl, source.id) - ?: networkToLocalManga.await( + ?: networkToLocalManga( Manga.create().copy( source = source.id, url = cleanedMangaUrl, diff --git a/app/src/main/java/exh/favorites/LocalFavoritesStorage.kt b/app/src/main/java/exh/favorites/LocalFavoritesStorage.kt index 652e39980..d7d655d44 100644 --- a/app/src/main/java/exh/favorites/LocalFavoritesStorage.kt +++ b/app/src/main/java/exh/favorites/LocalFavoritesStorage.kt @@ -1,6 +1,5 @@ package exh.favorites -import eu.kanade.domain.manga.model.toDomainManga import eu.kanade.tachiyomi.source.online.all.EHentai import exh.metadata.metadata.EHentaiSearchMetadata import exh.source.EXH_SOURCE_ID @@ -11,6 +10,7 @@ import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.flow.toList +import mihon.domain.manga.model.toDomainManga import tachiyomi.domain.category.interactor.GetCategories import tachiyomi.domain.category.model.Category import tachiyomi.domain.manga.interactor.DeleteFavoriteEntries diff --git a/app/src/main/java/exh/md/follows/MangaDexFollowsPagingSource.kt b/app/src/main/java/exh/md/follows/MangaDexFollowsPagingSource.kt index dc8e6c501..0c6ca0670 100644 --- a/app/src/main/java/exh/md/follows/MangaDexFollowsPagingSource.kt +++ b/app/src/main/java/exh/md/follows/MangaDexFollowsPagingSource.kt @@ -2,12 +2,12 @@ package exh.md.follows import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.online.all.MangaDex -import tachiyomi.data.source.SourcePagingSource +import tachiyomi.data.source.BaseSourcePagingSource /** * LatestUpdatesPager inherited from the general Pager. */ -class MangaDexFollowsPagingSource(val mangadex: MangaDex) : SourcePagingSource(mangadex) { +class MangaDexFollowsPagingSource(val mangadex: MangaDex) : BaseSourcePagingSource(mangadex) { override suspend fun requestNextPage(currentPage: Int): MangasPage { return mangadex.fetchFollows(currentPage) diff --git a/app/src/main/java/exh/md/follows/MangaDexFollowsScreenModel.kt b/app/src/main/java/exh/md/follows/MangaDexFollowsScreenModel.kt index 65c9594eb..96267b9b8 100644 --- a/app/src/main/java/exh/md/follows/MangaDexFollowsScreenModel.kt +++ b/app/src/main/java/exh/md/follows/MangaDexFollowsScreenModel.kt @@ -8,12 +8,12 @@ import exh.source.getMainSource import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.update +import tachiyomi.data.source.BaseSourcePagingSource import tachiyomi.domain.manga.model.Manga -import tachiyomi.domain.source.repository.SourcePagingSourceType class MangaDexFollowsScreenModel(sourceId: Long) : BrowseSourceScreenModel(sourceId, null) { - override fun createSourcePagingSource(query: String, filters: FilterList): SourcePagingSourceType { + override fun createSourcePagingSource(query: String, filters: FilterList): BaseSourcePagingSource { return MangaDexFollowsPagingSource(source.getMainSource() as MangaDex) } diff --git a/app/src/main/java/exh/recs/RecommendsScreenModel.kt b/app/src/main/java/exh/recs/RecommendsScreenModel.kt index 60095d8a1..6862af6a8 100644 --- a/app/src/main/java/exh/recs/RecommendsScreenModel.kt +++ b/app/src/main/java/exh/recs/RecommendsScreenModel.kt @@ -4,7 +4,6 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.Immutable import androidx.compose.runtime.produceState import cafe.adriel.voyager.core.model.StateScreenModel -import eu.kanade.domain.manga.model.toDomainManga import eu.kanade.presentation.util.ioCoroutineScope import eu.kanade.tachiyomi.source.CatalogueSource import exh.recs.sources.RecommendationPagingSource @@ -23,6 +22,7 @@ import kotlinx.coroutines.flow.update import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import mihon.domain.manga.model.toDomainManga import tachiyomi.domain.manga.interactor.GetManga import tachiyomi.domain.manga.interactor.NetworkToLocalManga import tachiyomi.domain.manga.model.Manga @@ -85,7 +85,7 @@ open class RecommendsScreenModel( val recSourceId = recSource.associatedSourceId if (recSourceId != null) { // If the recommendation is associated with a source, resolve it - networkToLocalManga.await(it.toDomainManga(recSourceId)) + networkToLocalManga(it.toDomainManga(recSourceId)) } else { // Otherwise, skip this step. The user will be prompted to choose a source via SmartSearch it.toDomainManga(-1) diff --git a/app/src/main/java/exh/recs/batch/RecommendationSearchHelper.kt b/app/src/main/java/exh/recs/batch/RecommendationSearchHelper.kt index adb183b90..cfb85ded2 100644 --- a/app/src/main/java/exh/recs/batch/RecommendationSearchHelper.kt +++ b/app/src/main/java/exh/recs/batch/RecommendationSearchHelper.kt @@ -5,7 +5,6 @@ import android.net.wifi.WifiManager import android.os.PowerManager import androidx.annotation.StringRes import androidx.core.net.toUri -import eu.kanade.domain.manga.model.toDomainManga import eu.kanade.domain.manga.model.toSManga import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.model.SManga @@ -26,6 +25,7 @@ import kotlinx.coroutines.awaitAll import kotlinx.coroutines.ensureActive import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.launch +import mihon.domain.manga.model.toDomainManga import tachiyomi.data.source.NoResultsException import tachiyomi.domain.UnsortedPreferences import tachiyomi.domain.library.model.LibraryManga @@ -201,8 +201,7 @@ class RecommendationSearchHelper(val context: Context) { return filterNot { manga -> // Source recommendations can be directly resolved, if the recommendation is from the same source recSource.associatedSourceId?.let { srcId -> - return@filterNot networkToLocalManga - .await(manga.toDomainManga(srcId)) + return@filterNot networkToLocalManga(manga.toDomainManga(srcId)) .let { local -> libraryManga.any { it.id == local.id } } } diff --git a/app/src/main/java/exh/recs/sources/RecommendationPagingSource.kt b/app/src/main/java/exh/recs/sources/RecommendationPagingSource.kt index f0ad18529..732319dc4 100644 --- a/app/src/main/java/exh/recs/sources/RecommendationPagingSource.kt +++ b/app/src/main/java/exh/recs/sources/RecommendationPagingSource.kt @@ -14,8 +14,8 @@ import exh.source.isMdBasedSource import kotlinx.serialization.json.Json import logcat.LogPriority import tachiyomi.core.common.util.system.logcat +import tachiyomi.data.source.BaseSourcePagingSource import tachiyomi.data.source.NoResultsException -import tachiyomi.data.source.SourcePagingSource import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.track.interactor.GetTracks import tachiyomi.i18n.sy.SYMR @@ -29,7 +29,7 @@ import uy.kohesive.injekt.injectLazy abstract class RecommendationPagingSource( protected val manga: Manga, source: CatalogueSource? = null, -) : SourcePagingSource(source) { +) : BaseSourcePagingSource(source) { // Display name abstract val name: String diff --git a/app/src/main/java/exh/smartsearch/SmartSourceSearchEngine.kt b/app/src/main/java/exh/smartsearch/SmartSourceSearchEngine.kt index eaa8b2fb3..766fb146d 100644 --- a/app/src/main/java/exh/smartsearch/SmartSourceSearchEngine.kt +++ b/app/src/main/java/exh/smartsearch/SmartSourceSearchEngine.kt @@ -1,9 +1,9 @@ package exh.smartsearch -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 +import mihon.domain.manga.model.toDomainManga import tachiyomi.domain.manga.model.Manga class SmartSourceSearchEngine( diff --git a/app/src/main/java/exh/ui/smartsearch/SmartSearchScreenModel.kt b/app/src/main/java/exh/ui/smartsearch/SmartSearchScreenModel.kt index bc8018b66..d332f4c8b 100644 --- a/app/src/main/java/exh/ui/smartsearch/SmartSearchScreenModel.kt +++ b/app/src/main/java/exh/ui/smartsearch/SmartSearchScreenModel.kt @@ -28,7 +28,7 @@ class SmartSearchScreenModel( val result = try { val resultManga = smartSearchEngine.smartSearch(source, config.origTitle) if (resultManga != null) { - val localManga = networkToLocalManga.await(resultManga) + val localManga = networkToLocalManga(resultManga) SearchResults.Found(localManga) } else { SearchResults.NotFound diff --git a/data/src/main/java/tachiyomi/data/manga/MangaRepositoryImpl.kt b/data/src/main/java/tachiyomi/data/manga/MangaRepositoryImpl.kt index 0940da181..490bd1631 100644 --- a/data/src/main/java/tachiyomi/data/manga/MangaRepositoryImpl.kt +++ b/data/src/main/java/tachiyomi/data/manga/MangaRepositoryImpl.kt @@ -105,40 +105,6 @@ class MangaRepositoryImpl( } } - override suspend fun insert(manga: Manga): Long? { - return handler.awaitOneOrNullExecutable(inTransaction = true) { - // SY --> - if (mangasQueries.getIdByUrlAndSource(manga.url, manga.source).executeAsOneOrNull() != null) { - return@awaitOneOrNullExecutable mangasQueries.getIdByUrlAndSource(manga.url, manga.source) - } - // SY <-- - mangasQueries.insert( - source = manga.source, - url = manga.url, - artist = manga.artist, - author = manga.author, - description = manga.description, - genre = manga.genre, - title = manga.title, - status = manga.status, - thumbnailUrl = manga.thumbnailUrl, - favorite = manga.favorite, - lastUpdate = manga.lastUpdate, - nextUpdate = manga.nextUpdate, - calculateInterval = manga.fetchInterval.toLong(), - initialized = manga.initialized, - viewerFlags = manga.viewerFlags, - chapterFlags = manga.chapterFlags, - coverLastModified = manga.coverLastModified, - dateAdded = manga.dateAdded, - updateStrategy = manga.updateStrategy, - version = manga.version, - notes = manga.notes, - ) - mangasQueries.selectLastInsertedRowId() - } - } - override suspend fun update(update: MangaUpdate): Boolean { return try { partialUpdate(update) @@ -159,6 +125,39 @@ class MangaRepositoryImpl( } } + override suspend fun insertNetworkManga(manga: List): List { + return handler.await(inTransaction = true) { + manga.map { + mangasQueries.insertNetworkManga( + source = it.source, + url = it.url, + // SY --> + artist = it.ogArtist, + author = it.ogAuthor, + description = it.ogDescription, + genre = it.ogGenre, + title = it.ogTitle, + status = it.ogStatus, + thumbnailUrl = it.ogThumbnailUrl, + // SY <-- + favorite = it.favorite, + lastUpdate = it.lastUpdate, + nextUpdate = it.nextUpdate, + calculateInterval = it.fetchInterval.toLong(), + initialized = it.initialized, + viewerFlags = it.viewerFlags, + chapterFlags = it.chapterFlags, + coverLastModified = it.coverLastModified, + dateAdded = it.dateAdded, + updateStrategy = it.updateStrategy, + version = it.version, + mapper = MangaMapper::mapManga, + ) + .executeAsOne() + } + } + } + private suspend fun partialUpdate(vararg mangaUpdates: MangaUpdate) { handler.await(inTransaction = true) { mangaUpdates.forEach { value -> diff --git a/data/src/main/java/tachiyomi/data/source/EHentaiPagingSource.kt b/data/src/main/java/tachiyomi/data/source/EHentaiPagingSource.kt index 3a781fafc..b580a85ca 100644 --- a/data/src/main/java/tachiyomi/data/source/EHentaiPagingSource.kt +++ b/data/src/main/java/tachiyomi/data/source/EHentaiPagingSource.kt @@ -4,20 +4,26 @@ 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.MetadataMangasPage -import eu.kanade.tachiyomi.source.model.SManga import exh.metadata.metadata.RaisedSearchMetadata +import mihon.domain.manga.model.toDomainManga +import tachiyomi.domain.manga.model.Manga -abstract class EHentaiPagingSource(override val source: CatalogueSource) : SourcePagingSource(source) { +abstract class EHentaiPagingSource( + override val source: CatalogueSource, +) : BaseSourcePagingSource(source) { - override fun getPageLoadResult( + override suspend fun getPageLoadResult( params: LoadParams, mangasPage: MangasPage, - ): LoadResult.Page> { + ): LoadResult.Page> { mangasPage as MetadataMangasPage val metadata = mangasPage.mangasMetadata + val manga = mangasPage.mangas.map { it.toDomainManga(source.id) } + .let { networkToLocalManga(it) } + return LoadResult.Page( - data = mangasPage.mangas + data = manga .mapIndexed { index, sManga -> sManga to metadata.getOrNull(index) }, prevKey = null, nextKey = mangasPage.nextKey, diff --git a/data/src/main/java/tachiyomi/data/source/SourcePagingSource.kt b/data/src/main/java/tachiyomi/data/source/SourcePagingSource.kt index 4a1a1004c..6e6d7c0ab 100644 --- a/data/src/main/java/tachiyomi/data/source/SourcePagingSource.kt +++ b/data/src/main/java/tachiyomi/data/source/SourcePagingSource.kt @@ -5,63 +5,74 @@ 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.MetadataMangasPage -import eu.kanade.tachiyomi.source.model.SManga import exh.metadata.metadata.RaisedSearchMetadata +import mihon.domain.manga.model.toDomainManga import tachiyomi.core.common.util.lang.withIOContext -import tachiyomi.domain.source.repository.SourcePagingSourceType +import tachiyomi.domain.manga.interactor.NetworkToLocalManga +import tachiyomi.domain.manga.model.Manga +import tachiyomi.domain.source.repository.SourcePagingSource +import uy.kohesive.injekt.Injekt +import uy.kohesive.injekt.api.get -class SourceSearchPagingSource(source: CatalogueSource, val query: String, val filters: FilterList) : - SourcePagingSource(source) { +class SourceSearchPagingSource( + source: CatalogueSource, + private val query: String, + private val filters: FilterList, +) : BaseSourcePagingSource(source) { override suspend fun requestNextPage(currentPage: Int): MangasPage { return source!!.getSearchManga(currentPage, query, filters) } } -class SourcePopularPagingSource(source: CatalogueSource) : SourcePagingSource(source) { +class SourcePopularPagingSource(source: CatalogueSource) : BaseSourcePagingSource(source) { override suspend fun requestNextPage(currentPage: Int): MangasPage { return source!!.getPopularManga(currentPage) } } -class SourceLatestPagingSource(source: CatalogueSource) : SourcePagingSource(source) { +class SourceLatestPagingSource(source: CatalogueSource) : BaseSourcePagingSource(source) { override suspend fun requestNextPage(currentPage: Int): MangasPage { return source!!.getLatestUpdates(currentPage) } } -abstract class SourcePagingSource( +abstract class BaseSourcePagingSource( protected open val source: CatalogueSource?, -) : SourcePagingSourceType() { + protected val networkToLocalManga: NetworkToLocalManga = Injekt.get(), +) : SourcePagingSource() { abstract suspend fun requestNextPage(currentPage: Int): MangasPage override suspend fun load( params: LoadParams, - ): LoadResult */ Pair/*SY <-- */> { + ): LoadResult */ Pair/*SY <-- */> { val page = params.key ?: 1 - val mangasPage = try { - withIOContext { + return try { + val mangasPage = withIOContext { requestNextPage(page.toInt()) .takeIf { it.mangas.isNotEmpty() } ?: throw NoResultsException() } - } catch (e: Exception) { - return LoadResult.Error(e) - } - // SY --> - return getPageLoadResult(params, mangasPage) - // SY <-- + // SY --> + getPageLoadResult(params, mangasPage) + // SY <-- + } catch (e: Exception) { + LoadResult.Error(e) + } } // SY --> - open fun getPageLoadResult( + open suspend fun getPageLoadResult( params: LoadParams, mangasPage: MangasPage, - ): LoadResult.Page */ Pair/*SY <-- */> { + ): LoadResult.Page */ Pair/*SY <-- */> { val page = params.key ?: 1 + val manga = mangasPage.mangas.map { it.toDomainManga(source!!.id) } + .let { networkToLocalManga(it) } + // SY --> val metadata = if (mangasPage is MetadataMangasPage) { mangasPage.mangasMetadata @@ -71,10 +82,9 @@ abstract class SourcePagingSource( // SY <-- return LoadResult.Page( - data = mangasPage.mangas - // SY --> + data = manga// SY --> .mapIndexed { index, sManga -> sManga to metadata.getOrNull(index) }, - // SY <-- + // SY <--, prevKey = null, nextKey = if (mangasPage.hasNextPage) page + 1 else null, ) @@ -82,7 +92,7 @@ abstract class SourcePagingSource( // SY <-- override fun getRefreshKey( - state: PagingState */ Pair/*SY <-- */>, + state: PagingState */ Pair/*SY <-- */>, ): Long? { return state.anchorPosition?.let { anchorPosition -> val anchorPage = state.closestPageToPosition(anchorPosition) diff --git a/data/src/main/java/tachiyomi/data/source/SourceRepositoryImpl.kt b/data/src/main/java/tachiyomi/data/source/SourceRepositoryImpl.kt index 0d3a6cb08..1674c7b15 100644 --- a/data/src/main/java/tachiyomi/data/source/SourceRepositoryImpl.kt +++ b/data/src/main/java/tachiyomi/data/source/SourceRepositoryImpl.kt @@ -12,7 +12,7 @@ import kotlinx.coroutines.flow.map import tachiyomi.data.DatabaseHandler import tachiyomi.domain.source.model.SourceWithCount import tachiyomi.domain.source.model.StubSource -import tachiyomi.domain.source.repository.SourcePagingSourceType +import tachiyomi.domain.source.repository.SourcePagingSource import tachiyomi.domain.source.repository.SourceRepository import tachiyomi.domain.source.service.SourceManager import tachiyomi.domain.source.model.Source as DomainSource @@ -77,7 +77,7 @@ class SourceRepositoryImpl( sourceId: Long, query: String, filterList: FilterList, - ): SourcePagingSourceType { + ): SourcePagingSource { val source = sourceManager.get(sourceId) as CatalogueSource // SY --> if (source.isEhBasedSource()) { @@ -87,7 +87,7 @@ class SourceRepositoryImpl( return SourceSearchPagingSource(source, query, filterList) } - override fun getPopular(sourceId: Long): SourcePagingSourceType { + override fun getPopular(sourceId: Long): SourcePagingSource { val source = sourceManager.get(sourceId) as CatalogueSource // SY --> if (source.isEhBasedSource()) { @@ -97,7 +97,7 @@ class SourceRepositoryImpl( return SourcePopularPagingSource(source) } - override fun getLatest(sourceId: Long): SourcePagingSourceType { + override fun getLatest(sourceId: Long): SourcePagingSource { val source = sourceManager.get(sourceId) as CatalogueSource // SY --> if (source.isEhBasedSource()) { diff --git a/data/src/main/sqldelight/tachiyomi/data/mangas.sq b/data/src/main/sqldelight/tachiyomi/data/mangas.sq index 6ee571ef9..dd2a4a3c9 100644 --- a/data/src/main/sqldelight/tachiyomi/data/mangas.sq +++ b/data/src/main/sqldelight/tachiyomi/data/mangas.sq @@ -195,6 +195,34 @@ WHERE _id = :mangaId; selectLastInsertedRowId: SELECT last_insert_rowid(); +insertNetworkManga { + -- Insert the manga if it doesn't exist already + INSERT INTO mangas( + source, url, artist, author, description, genre, title, status, thumbnail_url, favorite, + last_update, next_update, initialized, viewer, chapter_flags, cover_last_modified, date_added, + update_strategy, calculate_interval, last_modified_at, version + ) + SELECT + :source, :url, :artist, :author, :description, :genre, :title, :status, :thumbnailUrl, :favorite, + :lastUpdate, :nextUpdate, :initialized, :viewerFlags, :chapterFlags, :coverLastModified, :dateAdded, + :updateStrategy, :calculateInterval, 0, :version + WHERE NOT EXISTS(SELECT 0 FROM mangas WHERE source = :source AND url = :url); + + -- Update the title if it is not favorite + UPDATE mangas + SET title = :title + WHERE source = :source + AND url = :url + AND favorite = 0; + + -- Finally return the manga + SELECT * + FROM mangas + WHERE source = :source + AND url = :url + LIMIT 1; +} + getEhMangaWithMetadata: SELECT mangas.* FROM mangas INNER JOIN search_metadata diff --git a/domain/src/main/java/mihon/domain/manga/model/SManga.kt b/domain/src/main/java/mihon/domain/manga/model/SManga.kt new file mode 100644 index 000000000..c07ff52c3 --- /dev/null +++ b/domain/src/main/java/mihon/domain/manga/model/SManga.kt @@ -0,0 +1,22 @@ +package mihon.domain.manga.model + +import eu.kanade.tachiyomi.source.model.SManga +import tachiyomi.domain.manga.model.Manga + +fun SManga.toDomainManga(sourceId: Long): Manga { + return Manga.create().copy( + url = url, + // SY --> + ogTitle = title, + ogArtist = artist, + ogAuthor = author, + ogDescription = description, + ogGenre = getGenres(), + ogStatus = status.toLong(), + ogThumbnailUrl = thumbnail_url, + // SY <-- + updateStrategy = update_strategy, + initialized = initialized, + source = sourceId, + ) +} diff --git a/domain/src/main/java/tachiyomi/domain/manga/interactor/NetworkToLocalManga.kt b/domain/src/main/java/tachiyomi/domain/manga/interactor/NetworkToLocalManga.kt index 255951568..a3e35d6e3 100644 --- a/domain/src/main/java/tachiyomi/domain/manga/interactor/NetworkToLocalManga.kt +++ b/domain/src/main/java/tachiyomi/domain/manga/interactor/NetworkToLocalManga.kt @@ -7,29 +7,11 @@ class NetworkToLocalManga( private val mangaRepository: MangaRepository, ) { - suspend fun await(manga: Manga): Manga { - val localManga = getManga(manga.url, manga.source) - 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 - } - } + suspend operator fun invoke(manga: Manga): Manga { + return mangaRepository.insertNetworkManga(listOf(manga)).single() } - 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) + suspend operator fun invoke(manga: List): List { + return mangaRepository.insertNetworkManga(manga) } } diff --git a/domain/src/main/java/tachiyomi/domain/manga/repository/MangaRepository.kt b/domain/src/main/java/tachiyomi/domain/manga/repository/MangaRepository.kt index 0b58a8ece..317c9e156 100644 --- a/domain/src/main/java/tachiyomi/domain/manga/repository/MangaRepository.kt +++ b/domain/src/main/java/tachiyomi/domain/manga/repository/MangaRepository.kt @@ -33,12 +33,12 @@ interface MangaRepository { suspend fun setMangaCategories(mangaId: Long, categoryIds: List) - suspend fun insert(manga: Manga): Long? - suspend fun update(update: MangaUpdate): Boolean suspend fun updateAll(mangaUpdates: List): Boolean + suspend fun insertNetworkManga(manga: List): List + // SY --> suspend fun getMangaBySourceId(sourceId: Long): List diff --git a/domain/src/main/java/tachiyomi/domain/source/interactor/GetRemoteManga.kt b/domain/src/main/java/tachiyomi/domain/source/interactor/GetRemoteManga.kt index 61e5e513e..8ec432bbd 100644 --- a/domain/src/main/java/tachiyomi/domain/source/interactor/GetRemoteManga.kt +++ b/domain/src/main/java/tachiyomi/domain/source/interactor/GetRemoteManga.kt @@ -1,14 +1,14 @@ package tachiyomi.domain.source.interactor import eu.kanade.tachiyomi.source.model.FilterList -import tachiyomi.domain.source.repository.SourcePagingSourceType +import tachiyomi.domain.source.repository.SourcePagingSource import tachiyomi.domain.source.repository.SourceRepository class GetRemoteManga( private val repository: SourceRepository, ) { - fun subscribe(sourceId: Long, query: String, filterList: FilterList): SourcePagingSourceType { + operator fun invoke(sourceId: Long, query: String, filterList: FilterList): SourcePagingSource { return when (query) { QUERY_POPULAR -> repository.getPopular(sourceId) QUERY_LATEST -> repository.getLatest(sourceId) diff --git a/domain/src/main/java/tachiyomi/domain/source/repository/SourceRepository.kt b/domain/src/main/java/tachiyomi/domain/source/repository/SourceRepository.kt index f73e1ea97..869add714 100644 --- a/domain/src/main/java/tachiyomi/domain/source/repository/SourceRepository.kt +++ b/domain/src/main/java/tachiyomi/domain/source/repository/SourceRepository.kt @@ -2,13 +2,13 @@ package tachiyomi.domain.source.repository import androidx.paging.PagingSource import eu.kanade.tachiyomi.source.model.FilterList -import eu.kanade.tachiyomi.source.model.SManga import exh.metadata.metadata.RaisedSearchMetadata import kotlinx.coroutines.flow.Flow +import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.source.model.Source import tachiyomi.domain.source.model.SourceWithCount -typealias SourcePagingSourceType = PagingSource */ Pair/*SY <-- */> +typealias SourcePagingSource = PagingSource */ Pair/*SY <-- */> interface SourceRepository { @@ -20,9 +20,9 @@ interface SourceRepository { fun getSourcesWithNonLibraryManga(): Flow> - fun search(sourceId: Long, query: String, filterList: FilterList): SourcePagingSourceType + fun search(sourceId: Long, query: String, filterList: FilterList): SourcePagingSource - fun getPopular(sourceId: Long): SourcePagingSourceType + fun getPopular(sourceId: Long): SourcePagingSource - fun getLatest(sourceId: Long): SourcePagingSourceType + fun getLatest(sourceId: Long): SourcePagingSource }