Fix chapter list live update (#7296)

This commit is contained in:
AntsyLich 2022-06-12 21:23:41 +06:00 committed by GitHub
parent e7695aef78
commit b96686e6ad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 64 additions and 32 deletions

View file

@ -6,6 +6,7 @@ import eu.kanade.domain.chapter.model.Chapter
import eu.kanade.domain.chapter.model.ChapterUpdate
import eu.kanade.domain.chapter.repository.ChapterRepository
import eu.kanade.tachiyomi.util.system.logcat
import kotlinx.coroutines.flow.Flow
import logcat.LogPriority
class ChapterRepositoryImpl(
@ -96,11 +97,10 @@ class ChapterRepositoryImpl(
}
override suspend fun getChapterByMangaId(mangaId: Long): List<Chapter> {
return try {
handler.awaitList { chaptersQueries.getChapterByMangaId(mangaId, chapterMapper) }
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
emptyList()
}
return handler.awaitList { chaptersQueries.getChaptersByMangaId(mangaId, chapterMapper) }
}
override suspend fun getChapterByMangaIdFlow(mangaId: Long): Flow<List<Chapter>> {
return handler.subscribeToList { chaptersQueries.getChaptersByMangaId(mangaId, chapterMapper) }
}
}

View file

@ -47,7 +47,7 @@ class HistoryRepositoryImpl(
else -> throw NotImplementedError("Unknown sorting method")
}
val chapters = handler.awaitList { chaptersQueries.getChapterByMangaId(mangaId, chapterMapper) }
val chapters = handler.awaitList { chaptersQueries.getChaptersByMangaId(mangaId, chapterMapper) }
.sortedWith(sortFunction)
val currChapterIndex = chapters.indexOfFirst { chapter.id == it.id }

View file

@ -4,6 +4,7 @@ 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.domain.chapter.interactor.GetChapterByMangaId
import eu.kanade.domain.chapter.interactor.ShouldUpdateDbChapter
import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
import eu.kanade.domain.chapter.interactor.UpdateChapter
@ -50,6 +51,7 @@ class DomainModule : InjektModule {
addFactory { UpdateManga(get()) }
addSingletonFactory<ChapterRepository> { ChapterRepositoryImpl(get()) }
addFactory { GetChapterByMangaId(get()) }
addFactory { UpdateChapter(get()) }
addFactory { ShouldUpdateDbChapter() }
addFactory { SyncChaptersWithSource(get(), get(), get(), get()) }

View file

@ -0,0 +1,31 @@
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(
private val chapterRepository: ChapterRepository,
) {
suspend fun await(mangaId: Long): List<Chapter> {
return try {
chapterRepository.getChapterByMangaId(mangaId)
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
emptyList()
}
}
suspend fun subscribe(mangaId: Long): Flow<List<Chapter>> {
return try {
chapterRepository.getChapterByMangaIdFlow(mangaId)
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
flowOf(emptyList())
}
}
}

View file

@ -25,6 +25,7 @@ class SyncChaptersWithSource(
private val chapterRepository: ChapterRepository = Injekt.get(),
private val shouldUpdateDbChapter: ShouldUpdateDbChapter = Injekt.get(),
private val updateManga: UpdateManga = Injekt.get(),
private val getChapterByMangaId: GetChapterByMangaId = Injekt.get(),
) {
suspend fun await(
@ -45,7 +46,7 @@ class SyncChaptersWithSource(
}
// Chapters from db.
val dbChapters = chapterRepository.getChapterByMangaId(manga.id)
val dbChapters = getChapterByMangaId.await(manga.id)
// Chapters from the source not in db.
val toAdd = mutableListOf<Chapter>()

View file

@ -2,6 +2,7 @@ package eu.kanade.domain.chapter.repository
import eu.kanade.domain.chapter.model.Chapter
import eu.kanade.domain.chapter.model.ChapterUpdate
import kotlinx.coroutines.flow.Flow
interface ChapterRepository {
@ -14,4 +15,6 @@ interface ChapterRepository {
suspend fun removeChaptersWithIds(chapterIds: List<Long>)
suspend fun getChapterByMangaId(mangaId: Long): List<Chapter>
suspend fun getChapterByMangaIdFlow(mangaId: Long): Flow<List<Chapter>>
}

View file

@ -4,6 +4,8 @@ import android.content.Context
import android.net.Uri
import android.os.Bundle
import com.jakewharton.rxrelay.PublishRelay
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
import eu.kanade.domain.chapter.model.toDbChapter
import eu.kanade.tachiyomi.data.cache.CoverCache
import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Category
@ -44,6 +46,7 @@ import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.Stat
import kotlinx.coroutines.Job
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.supervisorScope
import logcat.LogPriority
import rx.Observable
@ -63,6 +66,7 @@ class MangaPresenter(
private val trackManager: TrackManager = Injekt.get(),
private val downloadManager: DownloadManager = Injekt.get(),
private val coverCache: CoverCache = Injekt.get(),
private val getChapterByMangaId: GetChapterByMangaId = Injekt.get(),
) : BasePresenter<MangaController>() {
/**
@ -78,9 +82,7 @@ class MangaPresenter(
/**
* Subject of list of chapters to allow updating the view without going to DB.
*/
private val chaptersRelay: PublishRelay<List<ChapterItem>> by lazy {
PublishRelay.create<List<ChapterItem>>()
}
private val chaptersRelay by lazy { PublishRelay.create<List<ChapterItem>>() }
/**
* Whether the chapter list has been requested to the source.
@ -144,26 +146,19 @@ class MangaPresenter(
// Chapters list - start
// Add the subscription that retrieves the chapters from the database, keeps subscribed to
// changes, and sends the list of chapters to the relay.
add(
db.getChapters(manga).asRxObservable()
.map { chapters ->
// Convert every chapter to a model.
chapters.map { it.toModel() }
}
.doOnNext { chapters ->
// Find downloaded chapters
setDownloadedChapters(chapters)
// Store the last emission
this.allChapters = chapters
// Listen for download status changes
observeDownloads()
}
.subscribe { chaptersRelay.call(it) },
)
// Keeps subscribed to changes and sends the list of chapters to the relay.
presenterScope.launchIO {
manga.id?.let { mangaId ->
getChapterByMangaId.subscribe(mangaId)
.collectLatest { domainChapters ->
val chapterItems = domainChapters.map { it.toDbChapter().toModel() }
setDownloadedChapters(chapterItems)
this@MangaPresenter.allChapters = chapterItems
observeDownloads()
chaptersRelay.call(chapterItems)
}
}
}
// Chapters list - end

View file

@ -23,7 +23,7 @@ SELECT *
FROM chapters
WHERE _id = :id;
getChapterByMangaId:
getChaptersByMangaId:
SELECT *
FROM chapters
WHERE manga_id = :mangaId;