Reset lastPageRead when chapter is marked unread (#7475)

* Reset lastPageRead when chapter is marked unread

* Remove a bit of repetition in SetReadStatus

(cherry picked from commit 5159eabc5dfd77dd7e4a480c1982bd1d2e5fbb92)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt
This commit is contained in:
Andreas 2022-07-08 04:34:58 +02:00 committed by Jobobby04
parent 0263b9ee4e
commit 5869fa0b4f
7 changed files with 151 additions and 49 deletions

View File

@ -14,11 +14,13 @@ import eu.kanade.domain.category.interactor.UpdateCategory
import eu.kanade.domain.category.repository.CategoryRepository
import eu.kanade.domain.chapter.interactor.GetChapter
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
import eu.kanade.domain.chapter.interactor.SetReadStatus
import eu.kanade.domain.chapter.interactor.ShouldUpdateDbChapter
import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
import eu.kanade.domain.chapter.interactor.SyncChaptersWithTrackServiceTwoWay
import eu.kanade.domain.chapter.interactor.UpdateChapter
import eu.kanade.domain.chapter.repository.ChapterRepository
import eu.kanade.domain.download.interactor.DeleteDownload
import eu.kanade.domain.extension.interactor.GetExtensionLanguages
import eu.kanade.domain.extension.interactor.GetExtensionSources
import eu.kanade.domain.extension.interactor.GetExtensionUpdates
@ -94,6 +96,7 @@ class DomainModule : InjektModule {
addFactory { GetChapter(get()) }
addFactory { GetChapterByMangaId(get()) }
addFactory { UpdateChapter(get()) }
addFactory { SetReadStatus(get(), get(), get(), get(), get()) }
addFactory { ShouldUpdateDbChapter() }
addFactory { SyncChaptersWithSource(get(), get(), get(), get()) }
addFactory { SyncChaptersWithTrackServiceTwoWay(get(), get()) }
@ -105,6 +108,8 @@ class DomainModule : InjektModule {
addFactory { RemoveHistoryById(get()) }
addFactory { RemoveHistoryByMangaId(get()) }
addFactory { DeleteDownload(get(), get()) }
addFactory { GetExtensions(get(), get()) }
addFactory { GetExtensionSources(get()) }
addFactory { GetExtensionUpdates(get(), get()) }

View File

@ -0,0 +1,105 @@
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.source.SourceManager
import eu.kanade.tachiyomi.source.online.all.MergedSource
import eu.kanade.tachiyomi.util.system.logcat
import exh.source.MERGED_SOURCE_ID
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 sourceManager: SourceManager,
) {
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(),
)
}
// SY -->
private suspend fun awaitMerged(mangaId: Long, read: Boolean) = withContext(NonCancellable) f@{
val mergedSource = sourceManager.get(MERGED_SOURCE_ID) as MergedSource
return@f await(
read = read,
values = mergedSource
.getChapters(mangaId, dedupe = false)
.toTypedArray(),
)
}
suspend fun await(manga: Manga, read: Boolean) = if (manga.source == MERGED_SOURCE_ID) {
awaitMerged(manga.id, read)
} else {
await(manga.id, read)
}
// SY <--
sealed class Result {
object Success : Result()
object NoChapters : Result()
data class InternalError(val error: Throwable) : Result()
}
}

View File

@ -0,0 +1,21 @@
package eu.kanade.domain.download.interactor
import eu.kanade.domain.chapter.model.Chapter
import eu.kanade.domain.chapter.model.toDbChapter
import eu.kanade.domain.manga.model.Manga
import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.source.SourceManager
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.withContext
class DeleteDownload(
private val sourceManager: SourceManager,
private val downloadManager: DownloadManager,
) {
suspend fun awaitAll(manga: Manga, vararg values: Chapter) = withContext(NonCancellable) {
sourceManager.get(manga.source)?.let { source ->
downloadManager.deleteChapters(values.map { it.toDbChapter() }, manga, source)
}
}
}

View File

@ -9,9 +9,9 @@ import eu.kanade.domain.category.interactor.SetMangaCategories
import eu.kanade.domain.category.model.Category
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
import eu.kanade.domain.chapter.interactor.GetMergedChapterByMangaId
import eu.kanade.domain.chapter.interactor.SetReadStatus
import eu.kanade.domain.chapter.interactor.UpdateChapter
import eu.kanade.domain.chapter.model.Chapter
import eu.kanade.domain.chapter.model.ChapterUpdate
import eu.kanade.domain.chapter.model.toDbChapter
import eu.kanade.domain.manga.interactor.GetLibraryManga
import eu.kanade.domain.manga.interactor.GetMergedMangaById
@ -78,6 +78,7 @@ class LibraryPresenter(
private val getTracks: GetTracks = Injekt.get(),
private val getCategories: GetCategories = Injekt.get(),
private val getChapterByMangaId: GetChapterByMangaId = Injekt.get(),
private val setReadStatus: SetReadStatus = Injekt.get(),
private val updateChapter: UpdateChapter = Injekt.get(),
private val updateManga: UpdateManga = Injekt.get(),
private val setMangaCategories: SetMangaCategories = Injekt.get(),
@ -753,40 +754,14 @@ class LibraryPresenter(
fun markReadStatus(mangas: List<Manga>, read: Boolean) {
mangas.forEach { manga ->
launchIO {
val chapters = if (manga.source == MERGED_SOURCE_ID) getMergedChaptersByMangaId.await(manga.id) else getChapterByMangaId.await(manga.id)
val toUpdate = chapters
.map { chapter ->
ChapterUpdate(
read = read,
lastPageRead = if (read) 0 else null,
id = chapter.id,
)
}
updateChapter.awaitAll(toUpdate)
if (read && preferences.removeAfterMarkedAsRead()) {
deleteChapters(manga, chapters)
}
setReadStatus.await(
manga = manga,
read = read,
)
}
}
}
private fun deleteChapters(manga: Manga, chapters: List<Chapter>) {
sourceManager.get(manga.source)?.let { source ->
// SY -->
if (source is MergedSource) {
val mergedMangas = runBlocking { getMergedMangaById.await(manga.id) }
val sources = mergedMangas.distinctBy { it.source }.map { sourceManager.getOrStub(it.source) }
chapters.groupBy { it.mangaId }.forEach { (mangaId, chapters) ->
val mergedManga = mergedMangas.firstOrNull { it.id == mangaId } ?: return@forEach
val mergedMangaSource = sources.firstOrNull { it.id == mergedManga.source } ?: return@forEach
downloadManager.deleteChapters(chapters.map { it.toDbChapter() }, mergedManga, mergedMangaSource)
}
} else /* SY <-- */ downloadManager.deleteChapters(chapters.map { it.toDbChapter() }, manga, source)
}
}
/**
* Remove the selected manga.
*

View File

@ -7,6 +7,7 @@ import eu.kanade.domain.category.interactor.GetCategories
import eu.kanade.domain.category.interactor.SetMangaCategories
import eu.kanade.domain.category.model.Category
import eu.kanade.domain.chapter.interactor.GetMergedChapterByMangaId
import eu.kanade.domain.chapter.interactor.SetReadStatus
import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
import eu.kanade.domain.chapter.interactor.SyncChaptersWithTrackServiceTwoWay
import eu.kanade.domain.chapter.interactor.UpdateChapter
@ -139,6 +140,7 @@ class MangaPresenter(
// SY <--
private val getDuplicateLibraryManga: GetDuplicateLibraryManga = Injekt.get(),
private val setMangaChapterFlags: SetMangaChapterFlags = Injekt.get(),
private val setReadStatus: SetReadStatus = Injekt.get(),
private val updateChapter: UpdateChapter = Injekt.get(),
private val updateManga: UpdateManga = Injekt.get(),
private val syncChaptersWithSource: SyncChaptersWithSource = Injekt.get(),
@ -937,13 +939,10 @@ class MangaPresenter(
*/
fun markChaptersRead(chapters: List<DomainChapter>, read: Boolean) {
presenterScope.launchIO {
val modified = chapters.filterNot { it.read == read }
modified
.map { ChapterUpdate(id = it.id, read = read) }
.let { updateChapter.awaitAll(it) }
if (read && preferences.removeAfterMarkedAsRead()) {
deleteChapters(modified)
}
setReadStatus.await(
read = read,
values = chapters.toTypedArray(),
)
}
}

View File

@ -249,9 +249,6 @@ class UpdatesController :
*/
private fun markAsRead(chapters: List<UpdatesItem>) {
presenter.markChapterRead(chapters, true)
if (presenter.preferences.removeAfterMarkedAsRead()) {
deleteChapters(chapters)
}
destroyActionModeIfNeeded()
}

View File

@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.recent.updates
import android.os.Bundle
import eu.kanade.data.DatabaseHandler
import eu.kanade.data.manga.mangaChapterMapper
import eu.kanade.domain.chapter.interactor.SetReadStatus
import eu.kanade.domain.chapter.interactor.UpdateChapter
import eu.kanade.domain.chapter.model.Chapter
import eu.kanade.domain.chapter.model.ChapterUpdate
@ -40,6 +41,7 @@ class UpdatesPresenter : BasePresenter<UpdatesController>() {
private val handler: DatabaseHandler by injectLazy()
private val updateChapter: UpdateChapter by injectLazy()
private val setReadStatus: SetReadStatus by injectLazy()
private val relativeTime: Int = preferences.relativeTime().get()
private val dateFormat: DateFormat = preferences.dateFormat()
@ -167,14 +169,12 @@ class UpdatesPresenter : BasePresenter<UpdatesController>() {
*/
fun markChapterRead(items: List<UpdatesItem>, read: Boolean) {
presenterScope.launchIO {
val toUpdate = items.map {
ChapterUpdate(
read = read,
lastPageRead = if (!read) 0 else null,
id = it.chapter.id,
)
}
updateChapter.awaitAll(toUpdate)
setReadStatus.await(
read = read,
values = items
.map { it.chapter }
.toTypedArray(),
)
}
}