From ee1c532d53a6ca0e11770156d23ec48a047e0bb7 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Thu, 12 Oct 2023 10:02:46 +0300 Subject: [PATCH] Update progress --- .../details/domain/ProgressUpdateUseCase.kt | 54 +++++++++++++++++++ .../kotatsu/details/ui/DetailsViewModel.kt | 10 ++++ 2 files changed, 64 insertions(+) create mode 100644 app/src/main/kotlin/org/koitharu/kotatsu/details/domain/ProgressUpdateUseCase.kt diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/domain/ProgressUpdateUseCase.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/domain/ProgressUpdateUseCase.kt new file mode 100644 index 000000000..b55f9d132 --- /dev/null +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/domain/ProgressUpdateUseCase.kt @@ -0,0 +1,54 @@ +package org.koitharu.kotatsu.details.domain + +import org.koitharu.kotatsu.core.model.findChapter +import org.koitharu.kotatsu.core.model.isLocal +import org.koitharu.kotatsu.core.parser.MangaRepository +import org.koitharu.kotatsu.history.data.HistoryRepository +import org.koitharu.kotatsu.history.data.PROGRESS_NONE +import org.koitharu.kotatsu.local.data.LocalMangaRepository +import org.koitharu.kotatsu.parsers.model.Manga +import javax.inject.Inject + +class ProgressUpdateUseCase @Inject constructor( + private val mangaRepositoryFactory: MangaRepository.Factory, + private val historyRepository: HistoryRepository, + private val localMangaRepository: LocalMangaRepository, +) { + + suspend operator fun invoke(manga: Manga): Float { + val history = historyRepository.getOne(manga) ?: return PROGRESS_NONE + val seed = if (manga.isLocal) { + localMangaRepository.getRemoteManga(manga) ?: manga + } else { + manga + } + val repo = mangaRepositoryFactory.create(seed.source) + val details = if (manga.source != seed.source || seed.chapters.isNullOrEmpty()) { + repo.getDetails(seed) + } else { + seed + } + val chapter = details.findChapter(history.chapterId) ?: return PROGRESS_NONE + val chapters = details.getChapters(chapter.branch) ?: return PROGRESS_NONE + val chaptersCount = chapters.size + if (chaptersCount == 0) { + return PROGRESS_NONE + } + val chapterIndex = chapters.indexOfFirst { x -> x.id == history.chapterId } + val pagesCount = repo.getPages(chapter).size + if (pagesCount == 0) { + return PROGRESS_NONE + } + val pagePercent = (history.page + 1) / pagesCount.toFloat() + val ppc = 1f / chaptersCount + val result = ppc * chapterIndex + ppc * pagePercent + historyRepository.addOrUpdate( + manga = details, + chapterId = chapter.id, + page = history.page, + scroll = history.scroll, + percent = result, + ) + return result + } +} diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsViewModel.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsViewModel.kt index 7c1a699b5..d8465a55b 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsViewModel.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsViewModel.kt @@ -13,6 +13,7 @@ import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filterNot import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map @@ -38,6 +39,7 @@ import org.koitharu.kotatsu.details.data.MangaDetails import org.koitharu.kotatsu.details.domain.BranchComparator import org.koitharu.kotatsu.details.domain.DetailsInteractor import org.koitharu.kotatsu.details.domain.DetailsLoadUseCase +import org.koitharu.kotatsu.details.domain.ProgressUpdateUseCase import org.koitharu.kotatsu.details.domain.RelatedMangaUseCase import org.koitharu.kotatsu.details.ui.model.ChapterListItem import org.koitharu.kotatsu.details.ui.model.HistoryInfo @@ -70,6 +72,7 @@ class DetailsViewModel @Inject constructor( private val relatedMangaUseCase: RelatedMangaUseCase, private val extraProvider: ListExtraProvider, private val detailsLoadUseCase: DetailsLoadUseCase, + private val progressUpdateUseCase: ProgressUpdateUseCase, ) : BaseViewModel() { private val intent = MangaIntent(savedStateHandle) @@ -203,6 +206,13 @@ class DetailsViewModel @Inject constructor( onShowTip.call(Unit) } } + launchJob(Dispatchers.Default) { + val manga = details.firstOrNull { !it?.chapters.isNullOrEmpty() } ?: return@launchJob + val h = history.firstOrNull() + if (h != null) { + progressUpdateUseCase(manga.toManga()) + } + } } fun reload() {