mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-03 23:58:55 +01:00 
			
		
		
		
	Fix chapter list live update (#7296)
This commit is contained in:
		@@ -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) }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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 }
 | 
			
		||||
 
 | 
			
		||||
@@ -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()) }
 | 
			
		||||
 
 | 
			
		||||
@@ -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 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>()
 | 
			
		||||
 
 | 
			
		||||
@@ -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>>
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user