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>
This commit is contained in:
parent
c2520bff12
commit
e3b1053c03
@ -48,6 +48,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 {
|
override suspend fun checkDuplicateName(name: String): Boolean {
|
||||||
return handler
|
return handler
|
||||||
.awaitList { categoriesQueries.getCategories() }
|
.awaitList { categoriesQueries.getCategories() }
|
||||||
|
@ -41,8 +41,27 @@ class ChapterRepositoryImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun update(chapterUpdate: ChapterUpdate) {
|
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(
|
chaptersQueries.update(
|
||||||
chapterUpdate.mangaId,
|
chapterUpdate.mangaId,
|
||||||
chapterUpdate.url,
|
chapterUpdate.url,
|
||||||
@ -58,33 +77,6 @@ class ChapterRepositoryImpl(
|
|||||||
chapterId = chapterUpdate.id,
|
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 {
|
override suspend fun update(update: MangaUpdate): Boolean {
|
||||||
return try {
|
return try {
|
||||||
handler.await {
|
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.history.HistoryRepositoryImpl
|
||||||
import eu.kanade.data.manga.MangaRepositoryImpl
|
import eu.kanade.data.manga.MangaRepositoryImpl
|
||||||
import eu.kanade.data.source.SourceRepositoryImpl
|
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.DeleteCategory
|
||||||
import eu.kanade.domain.category.interactor.GetCategories
|
import eu.kanade.domain.category.interactor.GetCategories
|
||||||
import eu.kanade.domain.category.interactor.InsertCategory
|
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.interactor.UpdateCategory
|
||||||
import eu.kanade.domain.category.repository.CategoryRepository
|
import eu.kanade.domain.category.repository.CategoryRepository
|
||||||
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
|
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.GetDuplicateLibraryManga
|
||||||
import eu.kanade.domain.manga.interactor.GetFavoritesBySourceId
|
import eu.kanade.domain.manga.interactor.GetFavoritesBySourceId
|
||||||
import eu.kanade.domain.manga.interactor.GetMangaById
|
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.ResetViewerFlags
|
||||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||||
import eu.kanade.domain.manga.repository.MangaRepository
|
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.ToggleSourcePin
|
||||||
import eu.kanade.domain.source.interactor.UpsertSourceData
|
import eu.kanade.domain.source.interactor.UpsertSourceData
|
||||||
import eu.kanade.domain.source.repository.SourceRepository
|
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.InjektModule
|
||||||
import uy.kohesive.injekt.api.InjektRegistrar
|
import uy.kohesive.injekt.api.InjektRegistrar
|
||||||
import uy.kohesive.injekt.api.addFactory
|
import uy.kohesive.injekt.api.addFactory
|
||||||
@ -61,10 +67,16 @@ class DomainModule : InjektModule {
|
|||||||
addSingletonFactory<MangaRepository> { MangaRepositoryImpl(get()) }
|
addSingletonFactory<MangaRepository> { MangaRepositoryImpl(get()) }
|
||||||
addFactory { GetDuplicateLibraryManga(get()) }
|
addFactory { GetDuplicateLibraryManga(get()) }
|
||||||
addFactory { GetFavoritesBySourceId(get()) }
|
addFactory { GetFavoritesBySourceId(get()) }
|
||||||
|
addFactory { GetMangaWithChapters(get(), get()) }
|
||||||
addFactory { GetMangaById(get()) }
|
addFactory { GetMangaById(get()) }
|
||||||
addFactory { GetNextChapter(get()) }
|
addFactory { GetNextChapter(get()) }
|
||||||
addFactory { ResetViewerFlags(get()) }
|
addFactory { ResetViewerFlags(get()) }
|
||||||
addFactory { UpdateManga(get()) }
|
addFactory { UpdateManga(get()) }
|
||||||
|
addFactory { MoveMangaToCategories(get()) }
|
||||||
|
|
||||||
|
addSingletonFactory<TrackRepository> { TrackRepositoryImpl(get()) }
|
||||||
|
addFactory { GetTracks(get()) }
|
||||||
|
addFactory { InsertTrack(get()) }
|
||||||
|
|
||||||
addSingletonFactory<ChapterRepository> { ChapterRepositoryImpl(get()) }
|
addSingletonFactory<ChapterRepository> { ChapterRepositoryImpl(get()) }
|
||||||
addFactory { GetChapterByMangaId(get()) }
|
addFactory { GetChapterByMangaId(get()) }
|
||||||
|
@ -11,4 +11,8 @@ class GetCategories(
|
|||||||
fun subscribe(): Flow<List<Category>> {
|
fun subscribe(): Flow<List<Category>> {
|
||||||
return categoryRepository.getAll()
|
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 delete(categoryId: Long)
|
||||||
|
|
||||||
|
suspend fun getCategoriesForManga(mangaId: Long): List<Category>
|
||||||
|
|
||||||
suspend fun checkDuplicateName(name: String): Boolean
|
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.model.Chapter
|
||||||
import eu.kanade.domain.chapter.repository.ChapterRepository
|
import eu.kanade.domain.chapter.repository.ChapterRepository
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
import eu.kanade.tachiyomi.util.system.logcat
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
import kotlinx.coroutines.flow.flowOf
|
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
|
|
||||||
class GetChapterByMangaId(
|
class GetChapterByMangaId(
|
||||||
@ -19,13 +17,4 @@ class GetChapterByMangaId(
|
|||||||
emptyList()
|
emptyList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun subscribe(mangaId: Long): Flow<List<Chapter>> {
|
|
||||||
return try {
|
|
||||||
chapterRepository.getChapterByMangaIdAsFlow(mangaId)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
logcat(LogPriority.ERROR, e)
|
|
||||||
flowOf(emptyList())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ class SyncChaptersWithSource(
|
|||||||
private val chapterRepository: ChapterRepository = Injekt.get(),
|
private val chapterRepository: ChapterRepository = Injekt.get(),
|
||||||
private val shouldUpdateDbChapter: ShouldUpdateDbChapter = Injekt.get(),
|
private val shouldUpdateDbChapter: ShouldUpdateDbChapter = Injekt.get(),
|
||||||
private val updateManga: UpdateManga = Injekt.get(),
|
private val updateManga: UpdateManga = Injekt.get(),
|
||||||
|
private val updateChapter: UpdateChapter = Injekt.get(),
|
||||||
private val getChapterByMangaId: GetChapterByMangaId = Injekt.get(),
|
private val getChapterByMangaId: GetChapterByMangaId = Injekt.get(),
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@ -167,7 +168,7 @@ class SyncChaptersWithSource(
|
|||||||
|
|
||||||
if (toChange.isNotEmpty()) {
|
if (toChange.isNotEmpty()) {
|
||||||
val chapterUpdates = toChange.map { it.toChapterUpdate() }
|
val chapterUpdates = toChange.map { it.toChapterUpdate() }
|
||||||
chapterRepository.updateAll(chapterUpdates)
|
updateChapter.awaitAll(chapterUpdates)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set this manga as updated since chapters were changed
|
// 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.model.ChapterUpdate
|
||||||
import eu.kanade.domain.chapter.repository.ChapterRepository
|
import eu.kanade.domain.chapter.repository.ChapterRepository
|
||||||
|
import eu.kanade.tachiyomi.util.system.logcat
|
||||||
|
import logcat.LogPriority
|
||||||
|
|
||||||
class UpdateChapter(
|
class UpdateChapter(
|
||||||
private val chapterRepository: ChapterRepository,
|
private val chapterRepository: ChapterRepository,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend fun await(chapterUpdate: ChapterUpdate) {
|
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,
|
private val mangaRepository: MangaRepository,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
suspend fun await(mangaUpdate: MangaUpdate): Boolean {
|
||||||
|
return mangaRepository.update(mangaUpdate)
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun awaitUpdateFromSource(
|
suspend fun awaitUpdateFromSource(
|
||||||
localManga: Manga,
|
localManga: Manga,
|
||||||
remoteManga: MangaInfo,
|
remoteManga: MangaInfo,
|
||||||
|
@ -16,5 +16,7 @@ interface MangaRepository {
|
|||||||
|
|
||||||
suspend fun resetViewerFlags(): Boolean
|
suspend fun resetViewerFlags(): Boolean
|
||||||
|
|
||||||
|
suspend fun moveMangaToCategories(mangaId: Long, categoryIds: List<Long>)
|
||||||
|
|
||||||
suspend fun update(update: MangaUpdate): Boolean
|
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
|
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.Manga
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import eu.kanade.tachiyomi.source.Source
|
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.
|
* 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
|
* 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
|
* 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 eu.kanade.tachiyomi.source.Source
|
||||||
import okhttp3.Dns
|
import okhttp3.Dns
|
||||||
import okhttp3.OkHttpClient
|
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 {
|
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
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isTrackFrom(track: Track, manga: Manga, source: Source?): Boolean =
|
override fun isTrackFrom(track: DomainTrack, manga: DomainManga, source: Source?): Boolean =
|
||||||
track.tracking_url == manga.url && source?.let { accept(it) } == true
|
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)) {
|
if (accept(newSource)) {
|
||||||
track.also { track.tracking_url = manga.url }
|
track.copy(remoteUrl = manga.url)
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,21 @@ package eu.kanade.tachiyomi.ui.browse.migration.search
|
|||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import com.jakewharton.rxrelay.BehaviorRelay
|
import com.jakewharton.rxrelay.BehaviorRelay
|
||||||
|
import eu.kanade.domain.category.interactor.GetCategories
|
||||||
|
import eu.kanade.domain.category.interactor.MoveMangaToCategories
|
||||||
|
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
|
||||||
|
import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
|
||||||
|
import eu.kanade.domain.chapter.interactor.UpdateChapter
|
||||||
|
import eu.kanade.domain.chapter.model.toChapterUpdate
|
||||||
|
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||||
|
import eu.kanade.domain.manga.model.MangaUpdate
|
||||||
|
import eu.kanade.domain.manga.model.hasCustomCover
|
||||||
|
import eu.kanade.domain.manga.model.toDbManga
|
||||||
|
import eu.kanade.domain.track.interactor.GetTracks
|
||||||
|
import eu.kanade.domain.track.interactor.InsertTrack
|
||||||
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.Manga
|
||||||
import eu.kanade.tachiyomi.data.database.models.MangaCategory
|
import eu.kanade.tachiyomi.data.database.models.toDomainManga
|
||||||
import eu.kanade.tachiyomi.data.database.models.toMangaInfo
|
import eu.kanade.tachiyomi.data.database.models.toMangaInfo
|
||||||
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
|
||||||
@ -17,8 +29,6 @@ import eu.kanade.tachiyomi.ui.browse.migration.MigrationFlags
|
|||||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchCardItem
|
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchCardItem
|
||||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchItem
|
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchItem
|
||||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchPresenter
|
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchPresenter
|
||||||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
|
||||||
import eu.kanade.tachiyomi.util.hasCustomCover
|
|
||||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||||
import eu.kanade.tachiyomi.util.lang.launchUI
|
import eu.kanade.tachiyomi.util.lang.launchUI
|
||||||
import eu.kanade.tachiyomi.util.lang.withUIContext
|
import eu.kanade.tachiyomi.util.lang.withUIContext
|
||||||
@ -31,6 +41,14 @@ import java.util.Date
|
|||||||
class SearchPresenter(
|
class SearchPresenter(
|
||||||
initialQuery: String? = "",
|
initialQuery: String? = "",
|
||||||
private val manga: Manga,
|
private val manga: Manga,
|
||||||
|
private val syncChaptersWithSource: SyncChaptersWithSource = Injekt.get(),
|
||||||
|
private val getChapterByMangaId: GetChapterByMangaId = Injekt.get(),
|
||||||
|
private val updateChapter: UpdateChapter = Injekt.get(),
|
||||||
|
private val updateManga: UpdateManga = Injekt.get(),
|
||||||
|
private val getCategories: GetCategories = Injekt.get(),
|
||||||
|
private val getTracks: GetTracks = Injekt.get(),
|
||||||
|
private val insertTrack: InsertTrack = Injekt.get(),
|
||||||
|
private val moveMangaToCategories: MoveMangaToCategories = Injekt.get(),
|
||||||
) : GlobalSearchPresenter(initialQuery) {
|
) : GlobalSearchPresenter(initialQuery) {
|
||||||
|
|
||||||
private val replacingMangaRelay = BehaviorRelay.create<Pair<Boolean, Manga?>>()
|
private val replacingMangaRelay = BehaviorRelay.create<Pair<Boolean, Manga?>>()
|
||||||
@ -94,101 +112,93 @@ class SearchPresenter(
|
|||||||
replace: Boolean,
|
replace: Boolean,
|
||||||
) {
|
) {
|
||||||
val flags = preferences.migrateFlags().get()
|
val flags = preferences.migrateFlags().get()
|
||||||
val migrateChapters =
|
|
||||||
MigrationFlags.hasChapters(
|
val migrateChapters = MigrationFlags.hasChapters(flags)
|
||||||
flags,
|
val migrateCategories = MigrationFlags.hasCategories(flags)
|
||||||
)
|
val migrateTracks = MigrationFlags.hasTracks(flags)
|
||||||
val migrateCategories =
|
val migrateCustomCover = MigrationFlags.hasCustomCover(flags)
|
||||||
MigrationFlags.hasCategories(
|
|
||||||
flags,
|
val prevDomainManga = prevManga.toDomainManga() ?: return
|
||||||
)
|
val domainManga = manga.toDomainManga() ?: return
|
||||||
val migrateTracks =
|
|
||||||
MigrationFlags.hasTracks(
|
|
||||||
flags,
|
|
||||||
)
|
|
||||||
val migrateCustomCover =
|
|
||||||
MigrationFlags.hasCustomCover(
|
|
||||||
flags,
|
|
||||||
)
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
syncChaptersWithSource(sourceChapters, manga, source)
|
syncChaptersWithSource.await(sourceChapters, domainManga, source)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
// Worst case, chapters won't be synced
|
// Worst case, chapters won't be synced
|
||||||
}
|
}
|
||||||
|
|
||||||
db.inTransaction {
|
// Update chapters read, bookmark and dateFetch
|
||||||
// Update chapters read
|
if (migrateChapters) {
|
||||||
if (migrateChapters) {
|
val prevMangaChapters = getChapterByMangaId.await(prevDomainManga.id)
|
||||||
val prevMangaChapters = db.getChapters(prevManga).executeAsBlocking()
|
val mangaChapters = getChapterByMangaId.await(domainManga.id)
|
||||||
val maxChapterRead = prevMangaChapters
|
|
||||||
.filter { it.read }
|
val maxChapterRead = prevMangaChapters
|
||||||
.maxOfOrNull { it.chapter_number } ?: 0f
|
.filter { it.read }
|
||||||
val dbChapters = db.getChapters(manga).executeAsBlocking()
|
.maxOfOrNull { it.chapterNumber }
|
||||||
for (chapter in dbChapters) {
|
|
||||||
if (chapter.isRecognizedNumber) {
|
val updatedMangaChapters = mangaChapters.map { mangaChapter ->
|
||||||
val prevChapter = prevMangaChapters
|
var updatedChapter = mangaChapter
|
||||||
.find { it.isRecognizedNumber && it.chapter_number == chapter.chapter_number }
|
if (updatedChapter.isRecognizedNumber) {
|
||||||
if (prevChapter != null) {
|
val prevChapter = prevMangaChapters
|
||||||
chapter.date_fetch = prevChapter.date_fetch
|
.find { it.isRecognizedNumber && it.chapterNumber == updatedChapter.chapterNumber }
|
||||||
chapter.bookmark = prevChapter.bookmark
|
|
||||||
}
|
if (prevChapter != null) {
|
||||||
if (chapter.chapter_number <= maxChapterRead) {
|
updatedChapter = updatedChapter.copy(
|
||||||
chapter.read = true
|
dateFetch = prevChapter.dateFetch,
|
||||||
}
|
bookmark = prevChapter.bookmark,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxChapterRead != null && updatedChapter.chapterNumber <= maxChapterRead) {
|
||||||
|
updatedChapter = updatedChapter.copy(read = true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
db.insertChapters(dbChapters).executeAsBlocking()
|
|
||||||
|
updatedChapter
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update categories
|
val chapterUpdates = updatedMangaChapters.map { it.toChapterUpdate() }
|
||||||
if (migrateCategories) {
|
updateChapter.awaitAll(chapterUpdates)
|
||||||
val categories = db.getCategoriesForManga(prevManga).executeAsBlocking()
|
|
||||||
val mangaCategories = categories.map { MangaCategory.create(manga, it) }
|
|
||||||
db.setMangaCategories(mangaCategories, listOf(manga))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update track
|
|
||||||
if (migrateTracks) {
|
|
||||||
val tracksToUpdate = db.getTracks(prevManga.id).executeAsBlocking().mapNotNull { track ->
|
|
||||||
track.id = null
|
|
||||||
track.manga_id = manga.id!!
|
|
||||||
|
|
||||||
val service = enhancedServices
|
|
||||||
.firstOrNull { it.isTrackFrom(track, prevManga, prevSource) }
|
|
||||||
if (service != null) service.migrateTrack(track, manga, source)
|
|
||||||
else track
|
|
||||||
}
|
|
||||||
db.insertTracks(tracksToUpdate).executeAsBlocking()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update favorite status
|
|
||||||
if (replace) {
|
|
||||||
prevManga.favorite = false
|
|
||||||
db.updateMangaFavorite(prevManga).executeAsBlocking()
|
|
||||||
}
|
|
||||||
manga.favorite = true
|
|
||||||
|
|
||||||
// Update reading preferences
|
|
||||||
manga.chapter_flags = prevManga.chapter_flags
|
|
||||||
manga.viewer_flags = prevManga.viewer_flags
|
|
||||||
|
|
||||||
// Update date added
|
|
||||||
if (replace) {
|
|
||||||
manga.date_added = prevManga.date_added
|
|
||||||
prevManga.date_added = 0
|
|
||||||
} else {
|
|
||||||
manga.date_added = Date().time
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update custom cover
|
|
||||||
if (migrateCustomCover) {
|
|
||||||
coverCache.setCustomCoverToCache(manga, coverCache.getCustomCoverFile(prevManga.id).inputStream())
|
|
||||||
}
|
|
||||||
|
|
||||||
// SearchPresenter#networkToLocalManga may have updated the manga title,
|
|
||||||
// so ensure db gets updated title too
|
|
||||||
db.insertManga(manga).executeAsBlocking()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update categories
|
||||||
|
if (migrateCategories) {
|
||||||
|
val categoryIds = getCategories.await(prevDomainManga.id).map { it.id }
|
||||||
|
moveMangaToCategories.await(domainManga.id, categoryIds)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update track
|
||||||
|
if (migrateTracks) {
|
||||||
|
val tracks = getTracks.await(prevDomainManga.id).mapNotNull { track ->
|
||||||
|
val updatedTrack = track.copy(mangaId = domainManga.id)
|
||||||
|
|
||||||
|
val service = enhancedServices
|
||||||
|
.firstOrNull { it.isTrackFrom(updatedTrack, prevDomainManga, prevSource) }
|
||||||
|
|
||||||
|
if (service != null) service.migrateTrack(updatedTrack, domainManga, source)
|
||||||
|
else track
|
||||||
|
}
|
||||||
|
insertTrack.awaitAll(tracks)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (replace) {
|
||||||
|
updateManga.await(MangaUpdate(prevDomainManga.id, favorite = false, dateAdded = 0))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update custom cover (recheck if custom cover exists)
|
||||||
|
if (migrateCustomCover && prevDomainManga.hasCustomCover()) {
|
||||||
|
@Suppress("BlockingMethodInNonBlockingContext")
|
||||||
|
coverCache.setCustomCoverToCache(domainManga.toDbManga(), coverCache.getCustomCoverFile(prevDomainManga.id).inputStream())
|
||||||
|
}
|
||||||
|
|
||||||
|
updateManga.await(
|
||||||
|
MangaUpdate(
|
||||||
|
id = domainManga.id,
|
||||||
|
favorite = true,
|
||||||
|
chapterFlags = prevDomainManga.chapterFlags,
|
||||||
|
viewerFlags = prevDomainManga.viewerFlags,
|
||||||
|
dateAdded = if (replace) prevDomainManga.dateAdded else Date().time,
|
||||||
|
),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,12 @@ package eu.kanade.tachiyomi.ui.manga
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import com.jakewharton.rxrelay.PublishRelay
|
import com.jakewharton.rxrelay.PublishRelay
|
||||||
import eu.kanade.domain.category.interactor.GetCategories
|
import eu.kanade.domain.category.interactor.GetCategories
|
||||||
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
|
|
||||||
import eu.kanade.domain.chapter.model.toDbChapter
|
import eu.kanade.domain.chapter.model.toDbChapter
|
||||||
import eu.kanade.domain.manga.interactor.GetDuplicateLibraryManga
|
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.toDbManga
|
||||||
|
import eu.kanade.domain.manga.model.toMangaInfo
|
||||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
import eu.kanade.tachiyomi.data.database.models.Category
|
import eu.kanade.tachiyomi.data.database.models.Category
|
||||||
@ -14,6 +16,7 @@ import eu.kanade.tachiyomi.data.database.models.Chapter
|
|||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.data.database.models.MangaCategory
|
import eu.kanade.tachiyomi.data.database.models.MangaCategory
|
||||||
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.database.models.toMangaInfo
|
import eu.kanade.tachiyomi.data.database.models.toMangaInfo
|
||||||
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
|
||||||
@ -23,7 +26,6 @@ import eu.kanade.tachiyomi.data.track.TrackManager
|
|||||||
import eu.kanade.tachiyomi.data.track.TrackService
|
import eu.kanade.tachiyomi.data.track.TrackService
|
||||||
import eu.kanade.tachiyomi.source.Source
|
import eu.kanade.tachiyomi.source.Source
|
||||||
import eu.kanade.tachiyomi.source.model.toSChapter
|
import eu.kanade.tachiyomi.source.model.toSChapter
|
||||||
import eu.kanade.tachiyomi.source.model.toSManga
|
|
||||||
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
|
||||||
import eu.kanade.tachiyomi.ui.manga.chapter.ChapterItem
|
import eu.kanade.tachiyomi.ui.manga.chapter.ChapterItem
|
||||||
import eu.kanade.tachiyomi.ui.manga.track.TrackItem
|
import eu.kanade.tachiyomi.ui.manga.track.TrackItem
|
||||||
@ -34,7 +36,6 @@ import eu.kanade.tachiyomi.util.chapter.syncChaptersWithTrackServiceTwoWay
|
|||||||
import eu.kanade.tachiyomi.util.isLocal
|
import eu.kanade.tachiyomi.util.isLocal
|
||||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||||
import eu.kanade.tachiyomi.util.lang.withUIContext
|
import eu.kanade.tachiyomi.util.lang.withUIContext
|
||||||
import eu.kanade.tachiyomi.util.prepUpdateCover
|
|
||||||
import eu.kanade.tachiyomi.util.removeCovers
|
import eu.kanade.tachiyomi.util.removeCovers
|
||||||
import eu.kanade.tachiyomi.util.shouldDownloadNewChapters
|
import eu.kanade.tachiyomi.util.shouldDownloadNewChapters
|
||||||
import eu.kanade.tachiyomi.util.system.logcat
|
import eu.kanade.tachiyomi.util.system.logcat
|
||||||
@ -64,9 +65,10 @@ class MangaPresenter(
|
|||||||
private val trackManager: TrackManager = Injekt.get(),
|
private val trackManager: TrackManager = Injekt.get(),
|
||||||
private val downloadManager: DownloadManager = Injekt.get(),
|
private val downloadManager: DownloadManager = Injekt.get(),
|
||||||
private val coverCache: CoverCache = Injekt.get(),
|
private val coverCache: CoverCache = Injekt.get(),
|
||||||
private val getChapterByMangaId: GetChapterByMangaId = Injekt.get(),
|
private val getMangaWithChapters: GetMangaWithChapters = Injekt.get(),
|
||||||
private val getDuplicateLibraryManga: GetDuplicateLibraryManga = Injekt.get(),
|
private val getDuplicateLibraryManga: GetDuplicateLibraryManga = Injekt.get(),
|
||||||
private val getCategories: GetCategories = Injekt.get(),
|
private val getCategories: GetCategories = Injekt.get(),
|
||||||
|
private val updateManga: UpdateManga = Injekt.get(),
|
||||||
) : BasePresenter<MangaController>() {
|
) : BasePresenter<MangaController>() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -118,7 +120,6 @@ class MangaPresenter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Manga info - start
|
// Manga info - start
|
||||||
|
|
||||||
getMangaObservable()
|
getMangaObservable()
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribeLatestCache({ view, manga -> view.onNextMangaInfo(manga, source) })
|
.subscribeLatestCache({ view, manga -> view.onNextMangaInfo(manga, source) })
|
||||||
@ -147,9 +148,9 @@ class MangaPresenter(
|
|||||||
// Keeps subscribed to changes and sends the list of chapters to the relay.
|
// Keeps subscribed to changes and sends the list of chapters to the relay.
|
||||||
presenterScope.launchIO {
|
presenterScope.launchIO {
|
||||||
manga.id?.let { mangaId ->
|
manga.id?.let { mangaId ->
|
||||||
getChapterByMangaId.subscribe(mangaId)
|
getMangaWithChapters.subscribe(mangaId)
|
||||||
.collectLatest { domainChapters ->
|
.collectLatest { (_, chapters) ->
|
||||||
val chapterItems = domainChapters.map { it.toDbChapter().toModel() }
|
val chapterItems = chapters.map { it.toDbChapter().toModel() }
|
||||||
setDownloadedChapters(chapterItems)
|
setDownloadedChapters(chapterItems)
|
||||||
this@MangaPresenter.allChapters = chapterItems
|
this@MangaPresenter.allChapters = chapterItems
|
||||||
observeDownloads()
|
observeDownloads()
|
||||||
@ -168,7 +169,6 @@ class MangaPresenter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Manga info - start
|
// Manga info - start
|
||||||
|
|
||||||
private fun getMangaObservable(): Observable<Manga> {
|
private fun getMangaObservable(): Observable<Manga> {
|
||||||
return db.getManga(manga.url, manga.source).asRxObservable()
|
return db.getManga(manga.url, manga.source).asRxObservable()
|
||||||
}
|
}
|
||||||
@ -193,16 +193,11 @@ class MangaPresenter(
|
|||||||
if (fetchMangaJob?.isActive == true) return
|
if (fetchMangaJob?.isActive == true) return
|
||||||
fetchMangaJob = presenterScope.launchIO {
|
fetchMangaJob = presenterScope.launchIO {
|
||||||
try {
|
try {
|
||||||
val networkManga = source.getMangaDetails(manga.toMangaInfo())
|
manga.toDomainManga()?.let { domainManga ->
|
||||||
val sManga = networkManga.toSManga()
|
val networkManga = source.getMangaDetails(domainManga.toMangaInfo())
|
||||||
manga.prepUpdateCover(coverCache, sManga, manualFetch)
|
|
||||||
manga.copyFrom(sManga)
|
updateManga.awaitUpdateFromSource(domainManga, networkManga, manualFetch, coverCache)
|
||||||
if (!manga.favorite) {
|
|
||||||
// if the manga isn't a favorite, set its title from source and update in db
|
|
||||||
manga.title = sManga.title
|
|
||||||
}
|
}
|
||||||
manga.initialized = true
|
|
||||||
db.insertManga(manga).executeAsBlocking()
|
|
||||||
|
|
||||||
withUIContext { view?.onFetchMangaInfoDone() }
|
withUIContext { view?.onFetchMangaInfoDone() }
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
|
Loading…
Reference in New Issue
Block a user