Use sqldelight in migration (#7331)
* Use sqldelight in migration * Some more changes Co-Authored-By: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com> * Review Changes * Review changes 2 * Review Changes 3 * Review Changes 4 Co-authored-by: Ivan Iskandar <12537387+ivaniskandar@users.noreply.github.com> (cherry picked from commit e3b1053c03da17c8c1b66f1914251707134e84a9) # Conflicts: # app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SearchPresenter.kt # app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt
This commit is contained in:
parent
9e63d7fb0b
commit
14a57b7d4d
@ -55,6 +55,12 @@ class CategoryRepositoryImpl(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getCategoriesForManga(mangaId: Long): List<Category> {
|
||||
return handler.awaitList {
|
||||
categoriesQueries.getCategoriesByMangaId(mangaId, categoryMapper)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun checkDuplicateName(name: String): Boolean {
|
||||
return handler
|
||||
.awaitList { categoriesQueries.getCategories() }
|
||||
|
@ -41,8 +41,27 @@ class ChapterRepositoryImpl(
|
||||
}
|
||||
|
||||
override suspend fun update(chapterUpdate: ChapterUpdate) {
|
||||
try {
|
||||
handler.await {
|
||||
handler.await {
|
||||
chaptersQueries.update(
|
||||
chapterUpdate.mangaId,
|
||||
chapterUpdate.url,
|
||||
chapterUpdate.name,
|
||||
chapterUpdate.scanlator,
|
||||
chapterUpdate.read?.toLong(),
|
||||
chapterUpdate.bookmark?.toLong(),
|
||||
chapterUpdate.lastPageRead,
|
||||
chapterUpdate.chapterNumber?.toDouble(),
|
||||
chapterUpdate.sourceOrder,
|
||||
chapterUpdate.dateFetch,
|
||||
chapterUpdate.dateUpload,
|
||||
chapterId = chapterUpdate.id,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun updateAll(chapterUpdates: List<ChapterUpdate>) {
|
||||
handler.await(inTransaction = true) {
|
||||
chapterUpdates.forEach { chapterUpdate ->
|
||||
chaptersQueries.update(
|
||||
chapterUpdate.mangaId,
|
||||
chapterUpdate.url,
|
||||
@ -58,33 +77,6 @@ class ChapterRepositoryImpl(
|
||||
chapterId = chapterUpdate.id,
|
||||
)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
logcat(LogPriority.ERROR, e)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun updateAll(chapterUpdates: List<ChapterUpdate>) {
|
||||
try {
|
||||
handler.await(inTransaction = true) {
|
||||
chapterUpdates.forEach { chapterUpdate ->
|
||||
chaptersQueries.update(
|
||||
chapterUpdate.mangaId,
|
||||
chapterUpdate.url,
|
||||
chapterUpdate.name,
|
||||
chapterUpdate.scanlator,
|
||||
chapterUpdate.read?.toLong(),
|
||||
chapterUpdate.bookmark?.toLong(),
|
||||
chapterUpdate.lastPageRead,
|
||||
chapterUpdate.chapterNumber?.toDouble(),
|
||||
chapterUpdate.sourceOrder,
|
||||
chapterUpdate.dateFetch,
|
||||
chapterUpdate.dateUpload,
|
||||
chapterId = chapterUpdate.id,
|
||||
)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
logcat(LogPriority.ERROR, e)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,15 @@ class MangaRepositoryImpl(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun moveMangaToCategories(mangaId: Long, categoryIds: List<Long>) {
|
||||
handler.await(inTransaction = true) {
|
||||
mangas_categoriesQueries.deleteMangaCategoryByMangaId(mangaId)
|
||||
categoryIds.map { categoryId ->
|
||||
mangas_categoriesQueries.insert(mangaId, categoryId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun update(update: MangaUpdate): Boolean {
|
||||
return try {
|
||||
handler.await {
|
||||
|
22
app/src/main/java/eu/kanade/data/track/TrackMapper.kt
Normal file
22
app/src/main/java/eu/kanade/data/track/TrackMapper.kt
Normal file
@ -0,0 +1,22 @@
|
||||
package eu.kanade.data.track
|
||||
|
||||
import eu.kanade.domain.track.model.Track
|
||||
|
||||
val trackMapper: (Long, Long, Long, Long, Long?, String, Double, Long, Long, Float, String, Long, Long) -> Track =
|
||||
{ id, mangaId, syncId, remoteId, libraryId, title, lastChapterRead, totalChapters, status, score, remoteUrl, startDate, finishDate ->
|
||||
Track(
|
||||
id = id,
|
||||
mangaId = mangaId,
|
||||
syncId = syncId,
|
||||
remoteId = remoteId,
|
||||
libraryId = libraryId,
|
||||
title = title,
|
||||
lastChapterRead = lastChapterRead,
|
||||
totalChapters = totalChapters,
|
||||
status = status,
|
||||
score = score,
|
||||
remoteUrl = remoteUrl,
|
||||
startDate = startDate,
|
||||
finishDate = finishDate,
|
||||
)
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package eu.kanade.data.track
|
||||
|
||||
import eu.kanade.data.DatabaseHandler
|
||||
import eu.kanade.domain.track.model.Track
|
||||
import eu.kanade.domain.track.repository.TrackRepository
|
||||
|
||||
class TrackRepositoryImpl(
|
||||
private val handler: DatabaseHandler,
|
||||
) : TrackRepository {
|
||||
|
||||
override suspend fun getTracksByMangaId(mangaId: Long): List<Track> {
|
||||
return handler.awaitList {
|
||||
manga_syncQueries.getTracksByMangaId(mangaId, trackMapper)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun insertAll(tracks: List<Track>) {
|
||||
handler.await(inTransaction = true) {
|
||||
tracks.forEach { mangaTrack ->
|
||||
manga_syncQueries.insert(
|
||||
mangaId = mangaTrack.id,
|
||||
syncId = mangaTrack.syncId,
|
||||
remoteId = mangaTrack.remoteId,
|
||||
libraryId = mangaTrack.libraryId,
|
||||
title = mangaTrack.title,
|
||||
lastChapterRead = mangaTrack.lastChapterRead,
|
||||
totalChapters = mangaTrack.totalChapters,
|
||||
status = mangaTrack.status,
|
||||
score = mangaTrack.score,
|
||||
remoteUrl = mangaTrack.remoteUrl,
|
||||
startDate = mangaTrack.startDate,
|
||||
finishDate = mangaTrack.finishDate,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -5,9 +5,11 @@ import eu.kanade.data.chapter.ChapterRepositoryImpl
|
||||
import eu.kanade.data.history.HistoryRepositoryImpl
|
||||
import eu.kanade.data.manga.MangaRepositoryImpl
|
||||
import eu.kanade.data.source.SourceRepositoryImpl
|
||||
import eu.kanade.data.track.TrackRepositoryImpl
|
||||
import eu.kanade.domain.category.interactor.DeleteCategory
|
||||
import eu.kanade.domain.category.interactor.GetCategories
|
||||
import eu.kanade.domain.category.interactor.InsertCategory
|
||||
import eu.kanade.domain.category.interactor.MoveMangaToCategories
|
||||
import eu.kanade.domain.category.interactor.UpdateCategory
|
||||
import eu.kanade.domain.category.repository.CategoryRepository
|
||||
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
|
||||
@ -29,6 +31,7 @@ import eu.kanade.domain.history.repository.HistoryRepository
|
||||
import eu.kanade.domain.manga.interactor.GetDuplicateLibraryManga
|
||||
import eu.kanade.domain.manga.interactor.GetFavoritesBySourceId
|
||||
import eu.kanade.domain.manga.interactor.GetMangaById
|
||||
import eu.kanade.domain.manga.interactor.GetMangaWithChapters
|
||||
import eu.kanade.domain.manga.interactor.ResetViewerFlags
|
||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||
import eu.kanade.domain.manga.repository.MangaRepository
|
||||
@ -43,6 +46,9 @@ import eu.kanade.domain.source.interactor.ToggleSource
|
||||
import eu.kanade.domain.source.interactor.ToggleSourcePin
|
||||
import eu.kanade.domain.source.interactor.UpsertSourceData
|
||||
import eu.kanade.domain.source.repository.SourceRepository
|
||||
import eu.kanade.domain.track.interactor.GetTracks
|
||||
import eu.kanade.domain.track.interactor.InsertTrack
|
||||
import eu.kanade.domain.track.repository.TrackRepository
|
||||
import uy.kohesive.injekt.api.InjektModule
|
||||
import uy.kohesive.injekt.api.InjektRegistrar
|
||||
import uy.kohesive.injekt.api.addFactory
|
||||
@ -61,10 +67,16 @@ class DomainModule : InjektModule {
|
||||
addSingletonFactory<MangaRepository> { MangaRepositoryImpl(get()) }
|
||||
addFactory { GetDuplicateLibraryManga(get()) }
|
||||
addFactory { GetFavoritesBySourceId(get()) }
|
||||
addFactory { GetMangaWithChapters(get(), get()) }
|
||||
addFactory { GetMangaById(get()) }
|
||||
addFactory { GetNextChapter(get()) }
|
||||
addFactory { ResetViewerFlags(get()) }
|
||||
addFactory { UpdateManga(get()) }
|
||||
addFactory { MoveMangaToCategories(get()) }
|
||||
|
||||
addSingletonFactory<TrackRepository> { TrackRepositoryImpl(get()) }
|
||||
addFactory { GetTracks(get()) }
|
||||
addFactory { InsertTrack(get()) }
|
||||
|
||||
addSingletonFactory<ChapterRepository> { ChapterRepositoryImpl(get()) }
|
||||
addFactory { GetChapterByMangaId(get()) }
|
||||
|
@ -11,4 +11,8 @@ class GetCategories(
|
||||
fun subscribe(): Flow<List<Category>> {
|
||||
return categoryRepository.getAll()
|
||||
}
|
||||
|
||||
suspend fun await(mangaId: Long): List<Category> {
|
||||
return categoryRepository.getCategoriesForManga(mangaId)
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,18 @@
|
||||
package eu.kanade.domain.category.interactor
|
||||
|
||||
import eu.kanade.domain.manga.repository.MangaRepository
|
||||
import eu.kanade.tachiyomi.util.system.logcat
|
||||
import logcat.LogPriority
|
||||
|
||||
class MoveMangaToCategories(
|
||||
private val mangaRepository: MangaRepository,
|
||||
) {
|
||||
|
||||
suspend fun await(mangaId: Long, categoryIds: List<Long>) {
|
||||
try {
|
||||
mangaRepository.moveMangaToCategories(mangaId, categoryIds)
|
||||
} catch (e: Exception) {
|
||||
logcat(LogPriority.ERROR, e)
|
||||
}
|
||||
}
|
||||
}
|
@ -16,6 +16,8 @@ interface CategoryRepository {
|
||||
|
||||
suspend fun delete(categoryId: Long)
|
||||
|
||||
suspend fun getCategoriesForManga(mangaId: Long): List<Category>
|
||||
|
||||
suspend fun checkDuplicateName(name: String): Boolean
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,6 @@ package eu.kanade.domain.chapter.interactor
|
||||
import eu.kanade.domain.chapter.model.Chapter
|
||||
import eu.kanade.domain.chapter.repository.ChapterRepository
|
||||
import eu.kanade.tachiyomi.util.system.logcat
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import logcat.LogPriority
|
||||
|
||||
class GetChapterByMangaId(
|
||||
@ -19,13 +17,4 @@ class GetChapterByMangaId(
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun subscribe(mangaId: Long): Flow<List<Chapter>> {
|
||||
return try {
|
||||
chapterRepository.getChapterByMangaIdAsFlow(mangaId)
|
||||
} catch (e: Exception) {
|
||||
logcat(LogPriority.ERROR, e)
|
||||
flowOf(emptyList())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ class SyncChaptersWithSource(
|
||||
private val chapterRepository: ChapterRepository = Injekt.get(),
|
||||
private val shouldUpdateDbChapter: ShouldUpdateDbChapter = Injekt.get(),
|
||||
private val updateManga: UpdateManga = Injekt.get(),
|
||||
private val updateChapter: UpdateChapter = Injekt.get(),
|
||||
private val getChapterByMangaId: GetChapterByMangaId = Injekt.get(),
|
||||
) {
|
||||
|
||||
@ -184,7 +185,7 @@ class SyncChaptersWithSource(
|
||||
|
||||
if (toChange.isNotEmpty()) {
|
||||
val chapterUpdates = toChange.map { it.toChapterUpdate() }
|
||||
chapterRepository.updateAll(chapterUpdates)
|
||||
updateChapter.awaitAll(chapterUpdates)
|
||||
}
|
||||
|
||||
// Set this manga as updated since chapters were changed
|
||||
|
@ -2,12 +2,26 @@ package eu.kanade.domain.chapter.interactor
|
||||
|
||||
import eu.kanade.domain.chapter.model.ChapterUpdate
|
||||
import eu.kanade.domain.chapter.repository.ChapterRepository
|
||||
import eu.kanade.tachiyomi.util.system.logcat
|
||||
import logcat.LogPriority
|
||||
|
||||
class UpdateChapter(
|
||||
private val chapterRepository: ChapterRepository,
|
||||
) {
|
||||
|
||||
suspend fun await(chapterUpdate: ChapterUpdate) {
|
||||
chapterRepository.update(chapterUpdate)
|
||||
try {
|
||||
chapterRepository.update(chapterUpdate)
|
||||
} catch (e: Exception) {
|
||||
logcat(LogPriority.ERROR, e)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun awaitAll(chapterUpdates: List<ChapterUpdate>) {
|
||||
try {
|
||||
chapterRepository.updateAll(chapterUpdates)
|
||||
} catch (e: Exception) {
|
||||
logcat(LogPriority.ERROR, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,23 @@
|
||||
package eu.kanade.domain.manga.interactor
|
||||
|
||||
import eu.kanade.domain.chapter.model.Chapter
|
||||
import eu.kanade.domain.chapter.repository.ChapterRepository
|
||||
import eu.kanade.domain.manga.model.Manga
|
||||
import eu.kanade.domain.manga.repository.MangaRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
|
||||
class GetMangaWithChapters(
|
||||
private val mangaRepository: MangaRepository,
|
||||
private val chapterRepository: ChapterRepository,
|
||||
) {
|
||||
|
||||
suspend fun subscribe(id: Long): Flow<Pair<Manga, List<Chapter>>> {
|
||||
return combine(
|
||||
mangaRepository.subscribeMangaById(id),
|
||||
chapterRepository.getChapterByMangaIdAsFlow(id),
|
||||
) { manga, chapters ->
|
||||
Pair(manga, chapters)
|
||||
}
|
||||
}
|
||||
}
|
@ -14,6 +14,10 @@ class UpdateManga(
|
||||
private val mangaRepository: MangaRepository,
|
||||
) {
|
||||
|
||||
suspend fun await(mangaUpdate: MangaUpdate): Boolean {
|
||||
return mangaRepository.update(mangaUpdate)
|
||||
}
|
||||
|
||||
suspend fun awaitUpdateFromSource(
|
||||
localManga: Manga,
|
||||
remoteManga: MangaInfo,
|
||||
|
@ -16,5 +16,7 @@ interface MangaRepository {
|
||||
|
||||
suspend fun resetViewerFlags(): Boolean
|
||||
|
||||
suspend fun moveMangaToCategories(mangaId: Long, categoryIds: List<Long>)
|
||||
|
||||
suspend fun update(update: MangaUpdate): Boolean
|
||||
}
|
||||
|
@ -0,0 +1,20 @@
|
||||
package eu.kanade.domain.track.interactor
|
||||
|
||||
import eu.kanade.domain.track.model.Track
|
||||
import eu.kanade.domain.track.repository.TrackRepository
|
||||
import eu.kanade.tachiyomi.util.system.logcat
|
||||
import logcat.LogPriority
|
||||
|
||||
class GetTracks(
|
||||
private val trackRepository: TrackRepository,
|
||||
) {
|
||||
|
||||
suspend fun await(mangaId: Long): List<Track> {
|
||||
return try {
|
||||
trackRepository.getTracksByMangaId(mangaId)
|
||||
} catch (e: Exception) {
|
||||
logcat(LogPriority.ERROR, e)
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package eu.kanade.domain.track.interactor
|
||||
|
||||
import eu.kanade.domain.track.model.Track
|
||||
import eu.kanade.domain.track.repository.TrackRepository
|
||||
import eu.kanade.tachiyomi.util.system.logcat
|
||||
import logcat.LogPriority
|
||||
|
||||
class InsertTrack(
|
||||
private val trackRepository: TrackRepository,
|
||||
) {
|
||||
|
||||
suspend fun awaitAll(tracks: List<Track>) {
|
||||
try {
|
||||
trackRepository.insertAll(tracks)
|
||||
} catch (e: Exception) {
|
||||
logcat(LogPriority.ERROR, e)
|
||||
}
|
||||
}
|
||||
}
|
27
app/src/main/java/eu/kanade/domain/track/model/Track.kt
Normal file
27
app/src/main/java/eu/kanade/domain/track/model/Track.kt
Normal file
@ -0,0 +1,27 @@
|
||||
package eu.kanade.domain.track.model
|
||||
|
||||
data class Track(
|
||||
val id: Long,
|
||||
val mangaId: Long,
|
||||
val syncId: Long,
|
||||
val remoteId: Long,
|
||||
val libraryId: Long?,
|
||||
val title: String,
|
||||
val lastChapterRead: Double,
|
||||
val totalChapters: Long,
|
||||
val status: Long,
|
||||
val score: Float,
|
||||
val remoteUrl: String,
|
||||
val startDate: Long,
|
||||
val finishDate: Long,
|
||||
) {
|
||||
fun copyPersonalFrom(other: Track): Track {
|
||||
return this.copy(
|
||||
lastChapterRead = other.lastChapterRead,
|
||||
score = other.score,
|
||||
status = other.status,
|
||||
startDate = other.startDate,
|
||||
finishDate = other.finishDate,
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package eu.kanade.domain.track.repository
|
||||
|
||||
import eu.kanade.domain.track.model.Track
|
||||
|
||||
interface TrackRepository {
|
||||
|
||||
suspend fun getTracksByMangaId(mangaId: Long): List<Track>
|
||||
|
||||
suspend fun insertAll(tracks: List<Track>)
|
||||
}
|
@ -1,9 +1,10 @@
|
||||
package eu.kanade.tachiyomi.data.track
|
||||
|
||||
import eu.kanade.domain.track.model.Track
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.database.models.Track
|
||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.domain.manga.model.Manga as DomainManga
|
||||
|
||||
/**
|
||||
* An Enhanced Track Service will never prompt the user to match a manga with the remote.
|
||||
@ -30,10 +31,10 @@ interface EnhancedTrackService {
|
||||
/**
|
||||
* Checks whether the provided source/track/manga triplet is from this TrackService
|
||||
*/
|
||||
fun isTrackFrom(track: Track, manga: Manga, source: Source?): Boolean
|
||||
fun isTrackFrom(track: Track, manga: DomainManga, source: Source?): Boolean
|
||||
|
||||
/**
|
||||
* Migrates the given track for the manga to the newSource, if possible
|
||||
*/
|
||||
fun migrateTrack(track: Track, manga: Manga, newSource: Source): Track?
|
||||
fun migrateTrack(track: Track, manga: DomainManga, newSource: Source): Track?
|
||||
}
|
||||
|
@ -13,6 +13,8 @@ import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import okhttp3.Dns
|
||||
import okhttp3.OkHttpClient
|
||||
import eu.kanade.domain.manga.model.Manga as DomainManga
|
||||
import eu.kanade.domain.track.model.Track as DomainTrack
|
||||
|
||||
class Komga(private val context: Context, id: Int) : TrackService(id), EnhancedTrackService, NoLoginTrackService {
|
||||
|
||||
@ -105,12 +107,12 @@ class Komga(private val context: Context, id: Int) : TrackService(id), EnhancedT
|
||||
null
|
||||
}
|
||||
|
||||
override fun isTrackFrom(track: Track, manga: Manga, source: Source?): Boolean =
|
||||
track.tracking_url == manga.url && source?.let { accept(it) } == true
|
||||
override fun isTrackFrom(track: DomainTrack, manga: DomainManga, source: Source?): Boolean =
|
||||
track.remoteUrl == manga.url && source?.let { accept(it) } == true
|
||||
|
||||
override fun migrateTrack(track: Track, manga: Manga, newSource: Source): Track? =
|
||||
override fun migrateTrack(track: DomainTrack, manga: DomainManga, newSource: Source): DomainTrack? =
|
||||
if (accept(newSource)) {
|
||||
track.also { track.tracking_url = manga.url }
|
||||
track.copy(remoteUrl = manga.url)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
@ -5,11 +5,13 @@ import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import com.jakewharton.rxrelay.PublishRelay
|
||||
import eu.kanade.domain.category.interactor.GetCategories
|
||||
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
|
||||
import eu.kanade.domain.chapter.interactor.GetMergedChapterByMangaId
|
||||
import eu.kanade.domain.chapter.model.toDbChapter
|
||||
import eu.kanade.domain.manga.interactor.GetDuplicateLibraryManga
|
||||
import eu.kanade.domain.manga.interactor.GetMangaWithChapters
|
||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||
import eu.kanade.domain.manga.model.toDbManga
|
||||
import eu.kanade.domain.manga.model.toMangaInfo
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
@ -31,7 +33,6 @@ import eu.kanade.tachiyomi.source.LocalSource
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.source.model.toSChapter
|
||||
import eu.kanade.tachiyomi.source.model.toSManga
|
||||
import eu.kanade.tachiyomi.source.online.MetadataSource
|
||||
import eu.kanade.tachiyomi.source.online.all.MergedSource
|
||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||
@ -45,7 +46,6 @@ import eu.kanade.tachiyomi.util.isLocal
|
||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||
import eu.kanade.tachiyomi.util.lang.launchUI
|
||||
import eu.kanade.tachiyomi.util.lang.withUIContext
|
||||
import eu.kanade.tachiyomi.util.prepUpdateCover
|
||||
import eu.kanade.tachiyomi.util.removeCovers
|
||||
import eu.kanade.tachiyomi.util.shouldDownloadNewChapters
|
||||
import eu.kanade.tachiyomi.util.system.logcat
|
||||
@ -98,12 +98,17 @@ class MangaPresenter(
|
||||
private val db: DatabaseHelper = Injekt.get(),
|
||||
private val trackManager: TrackManager = Injekt.get(),
|
||||
private val downloadManager: DownloadManager = Injekt.get(),
|
||||
private val coverCache: CoverCache = Injekt.get(),
|
||||
// SY -->
|
||||
private val sourceManager: SourceManager = Injekt.get(),
|
||||
private val getChapterByMangaId: GetChapterByMangaId = Injekt.get(),
|
||||
// SY <--
|
||||
private val coverCache: CoverCache = Injekt.get(),
|
||||
private val getMangaWithChapters: GetMangaWithChapters = Injekt.get(),
|
||||
// SY -->
|
||||
private val getMergedChapterByMangaId: GetMergedChapterByMangaId = Injekt.get(),
|
||||
// SY <--
|
||||
private val getDuplicateLibraryManga: GetDuplicateLibraryManga = Injekt.get(),
|
||||
private val getCategories: GetCategories = Injekt.get(),
|
||||
private val getMergedChapterByMangaId: GetMergedChapterByMangaId = Injekt.get(),
|
||||
private val updateManga: UpdateManga = Injekt.get(),
|
||||
) : BasePresenter<MangaController>() {
|
||||
|
||||
/**
|
||||
@ -183,7 +188,6 @@ class MangaPresenter(
|
||||
}
|
||||
|
||||
// Manga info - start
|
||||
|
||||
getMangaObservable()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
// SY -->
|
||||
@ -232,27 +236,27 @@ class MangaPresenter(
|
||||
manga.id?.let { mangaId ->
|
||||
if (source is MergedSource) {
|
||||
getMergedChapterByMangaId.subscribe(mangaId)
|
||||
.map { source.transformMergedChapters(mangaId, it, true, dedupe) }
|
||||
.map { manga to source.transformMergedChapters(mangaId, it, true, dedupe) }
|
||||
} else {
|
||||
getChapterByMangaId.subscribe(mangaId)
|
||||
getMangaWithChapters.subscribe(mangaId)
|
||||
}
|
||||
.collectLatest { domainChapters ->
|
||||
val chapterItems = domainChapters.map { it.toDbChapter().toModel() }
|
||||
.collectLatest { (_, chapters) ->
|
||||
val chapterItems = chapters.map { it.toDbChapter().toModel() }
|
||||
setDownloadedChapters(chapterItems)
|
||||
this@MangaPresenter.allChapters = chapterItems
|
||||
observeDownloads()
|
||||
|
||||
// SY -->
|
||||
if (domainChapters.isNotEmpty() && (source.isEhBasedSource()) && DebugToggles.ENABLE_EXH_ROOT_REDIRECT.enabled) {
|
||||
if (chapters.isNotEmpty() && (source.isEhBasedSource()) && DebugToggles.ENABLE_EXH_ROOT_REDIRECT.enabled) {
|
||||
// Check for gallery in library and accept manga with lowest id
|
||||
// Find chapters sharing same root
|
||||
updateHelper.findAcceptedRootAndDiscardOthers(manga.source, domainChapters.map { it.toDbChapter() })
|
||||
updateHelper.findAcceptedRootAndDiscardOthers(manga.source, chapters.map { it.toDbChapter() })
|
||||
.onEach { (acceptedChain, _) ->
|
||||
// Redirect if we are not the accepted root
|
||||
if (manga.id != acceptedChain.manga.id && acceptedChain.manga.favorite) {
|
||||
// Update if any of our chapters are not in accepted manga's chapters
|
||||
xLogD("Found accepted manga %s", manga.url)
|
||||
val ourChapterUrls = domainChapters.map { it.url }.toSet()
|
||||
val ourChapterUrls = chapters.map { it.url }.toSet()
|
||||
val acceptedChapterUrls = acceptedChain.chapters.map { it.url }.toSet()
|
||||
val update = (ourChapterUrls - acceptedChapterUrls).isNotEmpty()
|
||||
redirectFlow.emit(
|
||||
@ -280,7 +284,6 @@ class MangaPresenter(
|
||||
}
|
||||
|
||||
// Manga info - start
|
||||
|
||||
private fun getMangaObservable(): Observable<Manga> {
|
||||
return db.getManga(manga.url, manga.source).asRxObservable()
|
||||
}
|
||||
@ -318,16 +321,11 @@ class MangaPresenter(
|
||||
if (fetchMangaJob?.isActive == true) return
|
||||
fetchMangaJob = presenterScope.launchIO {
|
||||
try {
|
||||
val networkManga = source.getMangaDetails(manga.toMangaInfo())
|
||||
val sManga = networkManga.toSManga()
|
||||
manga.prepUpdateCover(coverCache, sManga, manualFetch)
|
||||
manga.copyFrom(sManga)
|
||||
if (!manga.favorite) {
|
||||
// if the manga isn't a favorite, set its title from source and update in db
|
||||
manga.title = sManga.title
|
||||
manga.toDomainManga()?.let { domainManga ->
|
||||
val networkManga = source.getMangaDetails(domainManga.toMangaInfo())
|
||||
|
||||
updateManga.awaitUpdateFromSource(domainManga, networkManga, manualFetch, coverCache)
|
||||
}
|
||||
manga.initialized = true
|
||||
db.insertManga(manga).executeAsBlocking()
|
||||
|
||||
withUIContext { view?.onFetchMangaInfoDone() }
|
||||
} catch (e: Throwable) {
|
||||
|
@ -245,7 +245,6 @@ class MangaFullCoverDialog : FullComposeController<MangaFullCoverDialog.MangaFul
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
@ -257,4 +256,3 @@ class MangaFullCoverDialog : FullComposeController<MangaFullCoverDialog.MangaFul
|
||||
private const val REQUEST_IMAGE_OPEN = 101
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,8 +56,10 @@ class MaterialSpinnerView @JvmOverloads constructor(context: Context, attrs: Att
|
||||
val title = getString(R.styleable.MaterialSpinnerView_title).orEmpty()
|
||||
binding.title.text = title
|
||||
|
||||
val viewEntries = (getTextArray(R.styleable.MaterialSpinnerView_android_entries)
|
||||
?: emptyArray()).map { it.toString() }
|
||||
val viewEntries = (
|
||||
getTextArray(R.styleable.MaterialSpinnerView_android_entries)
|
||||
?: emptyArray()
|
||||
).map { it.toString() }
|
||||
entries = viewEntries
|
||||
binding.details.text = viewEntries.firstOrNull().orEmpty()
|
||||
}
|
||||
|
@ -23,7 +23,8 @@ SELECT
|
||||
C._id AS id,
|
||||
C.name,
|
||||
C.sort AS `order`,
|
||||
C.flags
|
||||
C.flags,
|
||||
C.manga_order AS `mangaOrder`
|
||||
FROM categories C
|
||||
JOIN mangas_categories MC
|
||||
ON C._id = MC.category_id
|
||||
|
Loading…
x
Reference in New Issue
Block a user