Fix chapter list live update (#7296)
This commit is contained in:
parent
e7695aef78
commit
b96686e6ad
@ -6,6 +6,7 @@ import eu.kanade.domain.chapter.model.Chapter
|
|||||||
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 eu.kanade.tachiyomi.util.system.logcat
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
|
|
||||||
class ChapterRepositoryImpl(
|
class ChapterRepositoryImpl(
|
||||||
@ -96,11 +97,10 @@ class ChapterRepositoryImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getChapterByMangaId(mangaId: Long): List<Chapter> {
|
override suspend fun getChapterByMangaId(mangaId: Long): List<Chapter> {
|
||||||
return try {
|
return handler.awaitList { chaptersQueries.getChaptersByMangaId(mangaId, chapterMapper) }
|
||||||
handler.awaitList { chaptersQueries.getChapterByMangaId(mangaId, chapterMapper) }
|
}
|
||||||
} catch (e: Exception) {
|
|
||||||
logcat(LogPriority.ERROR, e)
|
override suspend fun getChapterByMangaIdFlow(mangaId: Long): Flow<List<Chapter>> {
|
||||||
emptyList()
|
return handler.subscribeToList { chaptersQueries.getChaptersByMangaId(mangaId, chapterMapper) }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ class HistoryRepositoryImpl(
|
|||||||
else -> throw NotImplementedError("Unknown sorting method")
|
else -> throw NotImplementedError("Unknown sorting method")
|
||||||
}
|
}
|
||||||
|
|
||||||
val chapters = handler.awaitList { chaptersQueries.getChapterByMangaId(mangaId, chapterMapper) }
|
val chapters = handler.awaitList { chaptersQueries.getChaptersByMangaId(mangaId, chapterMapper) }
|
||||||
.sortedWith(sortFunction)
|
.sortedWith(sortFunction)
|
||||||
|
|
||||||
val currChapterIndex = chapters.indexOfFirst { chapter.id == it.id }
|
val currChapterIndex = chapters.indexOfFirst { chapter.id == it.id }
|
||||||
|
@ -4,6 +4,7 @@ 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.domain.chapter.interactor.GetChapterByMangaId
|
||||||
import eu.kanade.domain.chapter.interactor.ShouldUpdateDbChapter
|
import eu.kanade.domain.chapter.interactor.ShouldUpdateDbChapter
|
||||||
import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
|
import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
|
||||||
import eu.kanade.domain.chapter.interactor.UpdateChapter
|
import eu.kanade.domain.chapter.interactor.UpdateChapter
|
||||||
@ -50,6 +51,7 @@ class DomainModule : InjektModule {
|
|||||||
addFactory { UpdateManga(get()) }
|
addFactory { UpdateManga(get()) }
|
||||||
|
|
||||||
addSingletonFactory<ChapterRepository> { ChapterRepositoryImpl(get()) }
|
addSingletonFactory<ChapterRepository> { ChapterRepositoryImpl(get()) }
|
||||||
|
addFactory { GetChapterByMangaId(get()) }
|
||||||
addFactory { UpdateChapter(get()) }
|
addFactory { UpdateChapter(get()) }
|
||||||
addFactory { ShouldUpdateDbChapter() }
|
addFactory { ShouldUpdateDbChapter() }
|
||||||
addFactory { SyncChaptersWithSource(get(), get(), get(), get()) }
|
addFactory { SyncChaptersWithSource(get(), get(), get(), get()) }
|
||||||
|
@ -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())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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 getChapterByMangaId: GetChapterByMangaId = Injekt.get(),
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend fun await(
|
suspend fun await(
|
||||||
@ -45,7 +46,7 @@ class SyncChaptersWithSource(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Chapters from db.
|
// Chapters from db.
|
||||||
val dbChapters = chapterRepository.getChapterByMangaId(manga.id)
|
val dbChapters = getChapterByMangaId.await(manga.id)
|
||||||
|
|
||||||
// Chapters from the source not in db.
|
// Chapters from the source not in db.
|
||||||
val toAdd = mutableListOf<Chapter>()
|
val toAdd = mutableListOf<Chapter>()
|
||||||
|
@ -2,6 +2,7 @@ package eu.kanade.domain.chapter.repository
|
|||||||
|
|
||||||
import eu.kanade.domain.chapter.model.Chapter
|
import eu.kanade.domain.chapter.model.Chapter
|
||||||
import eu.kanade.domain.chapter.model.ChapterUpdate
|
import eu.kanade.domain.chapter.model.ChapterUpdate
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
interface ChapterRepository {
|
interface ChapterRepository {
|
||||||
|
|
||||||
@ -14,4 +15,6 @@ interface ChapterRepository {
|
|||||||
suspend fun removeChaptersWithIds(chapterIds: List<Long>)
|
suspend fun removeChaptersWithIds(chapterIds: List<Long>)
|
||||||
|
|
||||||
suspend fun getChapterByMangaId(mangaId: Long): List<Chapter>
|
suspend fun getChapterByMangaId(mangaId: Long): List<Chapter>
|
||||||
|
|
||||||
|
suspend fun getChapterByMangaIdFlow(mangaId: Long): Flow<List<Chapter>>
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,8 @@ import android.content.Context
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import com.jakewharton.rxrelay.PublishRelay
|
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.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
|
||||||
@ -44,6 +46,7 @@ import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.Stat
|
|||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.awaitAll
|
import kotlinx.coroutines.awaitAll
|
||||||
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
import kotlinx.coroutines.supervisorScope
|
import kotlinx.coroutines.supervisorScope
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
@ -63,6 +66,7 @@ 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(),
|
||||||
) : BasePresenter<MangaController>() {
|
) : BasePresenter<MangaController>() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,9 +82,7 @@ class MangaPresenter(
|
|||||||
/**
|
/**
|
||||||
* Subject of list of chapters to allow updating the view without going to DB.
|
* Subject of list of chapters to allow updating the view without going to DB.
|
||||||
*/
|
*/
|
||||||
private val chaptersRelay: PublishRelay<List<ChapterItem>> by lazy {
|
private val chaptersRelay by lazy { PublishRelay.create<List<ChapterItem>>() }
|
||||||
PublishRelay.create<List<ChapterItem>>()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the chapter list has been requested to the source.
|
* Whether the chapter list has been requested to the source.
|
||||||
@ -144,26 +146,19 @@ class MangaPresenter(
|
|||||||
|
|
||||||
// Chapters list - start
|
// Chapters list - start
|
||||||
|
|
||||||
// Add the subscription that retrieves the chapters from the database, keeps subscribed to
|
// Keeps subscribed to changes and sends the list of chapters to the relay.
|
||||||
// changes, and sends the list of chapters to the relay.
|
presenterScope.launchIO {
|
||||||
add(
|
manga.id?.let { mangaId ->
|
||||||
db.getChapters(manga).asRxObservable()
|
getChapterByMangaId.subscribe(mangaId)
|
||||||
.map { chapters ->
|
.collectLatest { domainChapters ->
|
||||||
// Convert every chapter to a model.
|
val chapterItems = domainChapters.map { it.toDbChapter().toModel() }
|
||||||
chapters.map { it.toModel() }
|
setDownloadedChapters(chapterItems)
|
||||||
}
|
this@MangaPresenter.allChapters = chapterItems
|
||||||
.doOnNext { chapters ->
|
|
||||||
// Find downloaded chapters
|
|
||||||
setDownloadedChapters(chapters)
|
|
||||||
|
|
||||||
// Store the last emission
|
|
||||||
this.allChapters = chapters
|
|
||||||
|
|
||||||
// Listen for download status changes
|
|
||||||
observeDownloads()
|
observeDownloads()
|
||||||
|
chaptersRelay.call(chapterItems)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.subscribe { chaptersRelay.call(it) },
|
|
||||||
)
|
|
||||||
|
|
||||||
// Chapters list - end
|
// Chapters list - end
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ SELECT *
|
|||||||
FROM chapters
|
FROM chapters
|
||||||
WHERE _id = :id;
|
WHERE _id = :id;
|
||||||
|
|
||||||
getChapterByMangaId:
|
getChaptersByMangaId:
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM chapters
|
FROM chapters
|
||||||
WHERE manga_id = :mangaId;
|
WHERE manga_id = :mangaId;
|
||||||
|
Loading…
Reference in New Issue
Block a user