|
@@ -0,0 +1,86 @@
|
|
|
+package eu.kanade.domain.chapter.interactor
|
|
|
+
|
|
|
+import eu.kanade.domain.chapter.model.Chapter
|
|
|
+import eu.kanade.domain.chapter.model.ChapterUpdate
|
|
|
+import eu.kanade.domain.chapter.repository.ChapterRepository
|
|
|
+import eu.kanade.domain.download.interactor.DeleteDownload
|
|
|
+import eu.kanade.domain.manga.model.Manga
|
|
|
+import eu.kanade.domain.manga.repository.MangaRepository
|
|
|
+import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
|
|
+import eu.kanade.tachiyomi.util.system.logcat
|
|
|
+import kotlinx.coroutines.NonCancellable
|
|
|
+import kotlinx.coroutines.withContext
|
|
|
+import logcat.LogPriority
|
|
|
+
|
|
|
+class SetReadStatus(
|
|
|
+ private val preferences: PreferencesHelper,
|
|
|
+ private val deleteDownload: DeleteDownload,
|
|
|
+ private val mangaRepository: MangaRepository,
|
|
|
+ private val chapterRepository: ChapterRepository,
|
|
|
+) {
|
|
|
+
|
|
|
+ private val mapper = { chapter: Chapter, read: Boolean ->
|
|
|
+ ChapterUpdate(
|
|
|
+ read = read,
|
|
|
+ lastPageRead = if (!read) 0 else null,
|
|
|
+ id = chapter.id,
|
|
|
+ )
|
|
|
+ }
|
|
|
+
|
|
|
+ suspend fun await(read: Boolean, vararg values: Chapter): Result = withContext(NonCancellable) f@{
|
|
|
+ val chapters = values.filterNot { it.read == read }
|
|
|
+
|
|
|
+ if (chapters.isEmpty()) {
|
|
|
+ return@f Result.NoChapters
|
|
|
+ }
|
|
|
+
|
|
|
+ val manga = chapters.fold(mutableSetOf<Manga>()) { acc, chapter ->
|
|
|
+ if (acc.all { it.id != chapter.mangaId }) {
|
|
|
+ acc += mangaRepository.getMangaById(chapter.mangaId)
|
|
|
+ }
|
|
|
+ acc
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ chapterRepository.updateAll(
|
|
|
+ chapters.map { chapter ->
|
|
|
+ mapper(chapter, read)
|
|
|
+ },
|
|
|
+ )
|
|
|
+ } catch (e: Exception) {
|
|
|
+ logcat(LogPriority.ERROR, e)
|
|
|
+ return@f Result.InternalError(e)
|
|
|
+ }
|
|
|
+
|
|
|
+ if (read && preferences.removeAfterMarkedAsRead()) {
|
|
|
+ manga.forEach { manga ->
|
|
|
+ deleteDownload.awaitAll(
|
|
|
+ manga = manga,
|
|
|
+ values = chapters
|
|
|
+ .filter { manga.id == it.mangaId }
|
|
|
+ .toTypedArray(),
|
|
|
+ )
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Result.Success
|
|
|
+ }
|
|
|
+
|
|
|
+ suspend fun await(mangaId: Long, read: Boolean): Result = withContext(NonCancellable) f@{
|
|
|
+ return@f await(
|
|
|
+ read = read,
|
|
|
+ values = chapterRepository
|
|
|
+ .getChapterByMangaId(mangaId)
|
|
|
+ .toTypedArray(),
|
|
|
+ )
|
|
|
+ }
|
|
|
+
|
|
|
+ suspend fun await(manga: Manga, read: Boolean) =
|
|
|
+ await(manga.id, read)
|
|
|
+
|
|
|
+ sealed class Result {
|
|
|
+ object Success : Result()
|
|
|
+ object NoChapters : Result()
|
|
|
+ data class InternalError(val error: Throwable) : Result()
|
|
|
+ }
|
|
|
+}
|