Build manga and chapter updates with a lambda and track assigned fields

MangaUpdate and ChapterUpdate are built with a lambda that records which fields were assigned, so an update writes only those fields.
This commit is contained in:
AntsyLich
2026-09-27 22:36:13 +06:00
parent 306befb214
commit f8fff318ba
21 changed files with 155 additions and 172 deletions
@@ -21,11 +21,10 @@ class SetReadStatus(
) {
private val mapper = { chapter: Chapter, read: Boolean ->
ChapterUpdate(
read = read,
lastPageRead = if (!read) 0 else null,
id = chapter.id,
)
ChapterUpdate(chapter.id) {
this.read = read
if (!read) lastPageRead = 0
}
}
suspend fun await(read: Boolean, vararg chapters: Chapter): Result = withNonCancellableContext {
@@ -14,20 +14,18 @@ class SetMangaViewerFlags(
suspend fun awaitSetReadingMode(id: Long, flag: Long) {
val manga = mangaRepository.getMangaById(id)
mangaRepository.update(
MangaUpdate(
id = id,
viewerFlags = manga.viewerFlags.setFlag(flag, ReadingMode.MASK.toLong()),
),
MangaUpdate(id) {
viewerFlags = manga.viewerFlags.setFlag(flag, ReadingMode.MASK.toLong())
},
)
}
suspend fun awaitSetOrientation(id: Long, flag: Long) {
val manga = mangaRepository.getMangaById(id)
mangaRepository.update(
MangaUpdate(
id = id,
viewerFlags = manga.viewerFlags.setFlag(flag, ReaderOrientation.MASK.toLong()),
),
MangaUpdate(id) {
viewerFlags = manga.viewerFlags.setFlag(flag, ReaderOrientation.MASK.toLong())
},
)
}
@@ -31,20 +31,19 @@ class UpdateManga(
window: Pair<Long, Long> = fetchInterval.getWindow(dateTime.date, timeZone),
): Boolean {
return mangaRepository.update(
fetchInterval.toMangaUpdate(manga, dateTime, timeZone, window),
fetchInterval.withFetchInterval(manga, dateTime, timeZone, window),
)
}
suspend fun awaitUpdateLastUpdate(mangaId: Long): Boolean {
return mangaRepository.update(MangaUpdate(id = mangaId, lastUpdate = Clock.System.now().toEpochMilliseconds()))
return mangaRepository.update(MangaUpdate(mangaId) { lastUpdate = Clock.System.now().toEpochMilliseconds() })
}
suspend fun awaitUpdateCoverLastModified(mangaId: Long): Boolean {
return mangaRepository.update(
MangaUpdate(
id = mangaId,
coverLastModified = Clock.System.now().toEpochMilliseconds(),
),
MangaUpdate(mangaId) {
coverLastModified = Clock.System.now().toEpochMilliseconds()
},
)
}
@@ -54,7 +53,10 @@ class UpdateManga(
false -> 0
}
return mangaRepository.update(
MangaUpdate(id = mangaId, favorite = favorite, dateAdded = dateAdded),
MangaUpdate(mangaId) {
this.favorite = favorite
this.dateAdded = dateAdded
},
)
}
}
@@ -8,7 +8,7 @@ import logcat.LogPriority
import tachiyomi.core.common.util.system.logcat
import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId
import tachiyomi.domain.chapter.interactor.UpdateChapter
import tachiyomi.domain.chapter.model.toChapterUpdate
import tachiyomi.domain.chapter.model.ChapterUpdate
import tachiyomi.domain.track.interactor.InsertTrack
import tachiyomi.domain.track.model.Track
import kotlin.math.max
@@ -35,7 +35,7 @@ class SyncChapterProgressWithTrack(
val chapterUpdates = sortedChapters
.filter { chapter -> chapter.chapterNumber <= remoteTrack.lastChapterRead && !chapter.read }
.map { it.copy(read = true).toChapterUpdate() }
.map { ChapterUpdate(it.id) { read = true } }
// only take into account continuous reading
val localLastRead = sortedChapters.takeWhile { it.read }.lastOrNull()?.chapterNumber ?: 0F
@@ -59,7 +59,7 @@ class MangaRestorer(
}
restoreRepository.restoreManga(entries) {
fetchInterval.toMangaUpdate(it, now, timeZone, currentFetchWindow)
fetchInterval.withFetchInterval(it, now, timeZone, currentFetchWindow)
}
}
}
@@ -25,7 +25,7 @@ import tachiyomi.core.common.util.lang.launchIO
import tachiyomi.domain.chapter.interactor.GetChapter
import tachiyomi.domain.chapter.interactor.UpdateChapter
import tachiyomi.domain.chapter.model.Chapter
import tachiyomi.domain.chapter.model.toChapterUpdate
import tachiyomi.domain.chapter.model.ChapterUpdate
import tachiyomi.domain.download.service.DownloadPreferences
import tachiyomi.domain.manga.interactor.GetManga
import tachiyomi.domain.manga.model.Manga
@@ -192,7 +192,6 @@ class NotificationReceiver : BroadcastReceiver() {
launchIO {
val toUpdate = chapterUrls.mapNotNull { getChapter.await(it, mangaId) }
.map {
val chapter = it.copy(read = true)
if (downloadPreferences.removeAfterMarkedAsRead.get()) {
val manga = getManga.await(mangaId)
if (manga != null) {
@@ -202,7 +201,7 @@ class NotificationReceiver : BroadcastReceiver() {
}
}
}
chapter.toChapterUpdate()
ChapterUpdate(it.id) { read = true }
}
updateChapter.awaitAll(toUpdate)
}
@@ -51,8 +51,8 @@ import tachiyomi.domain.library.service.LibraryPreferences
import tachiyomi.domain.manga.interactor.GetDuplicateLibraryManga
import tachiyomi.domain.manga.interactor.GetManga
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.manga.model.MangaUpdate
import tachiyomi.domain.manga.model.MangaWithChapterCount
import tachiyomi.domain.manga.model.toMangaUpdate
import tachiyomi.domain.source.interactor.GetRemoteManga
import tachiyomi.domain.source.service.SourceManager
import kotlin.time.Clock
@@ -233,22 +233,23 @@ class BrowseSourceViewModel(
*/
fun changeMangaFavorite(manga: Manga) {
viewModelScope.launch {
var new = manga.copy(
favorite = !manga.favorite,
dateAdded = when (manga.favorite) {
true -> 0
false -> Clock.System.now().toEpochMilliseconds()
},
)
if (!new.favorite) {
new = new.removeCovers(coverCache)
val update = if (manga.favorite) {
val coverLastModified = manga.removeCovers(coverCache).coverLastModified
MangaUpdate(manga.id) {
favorite = false
dateAdded = 0
if (coverLastModified != manga.coverLastModified) this.coverLastModified = coverLastModified
}
} else {
setMangaDefaultChapterFlags.await(manga)
addTracks.bindEnhancedTrackers(manga, sourceManager.getOrStub(manga.source))
MangaUpdate(manga.id) {
favorite = true
dateAdded = Clock.System.now().toEpochMilliseconds()
}
}
updateManga.await(new.toMangaUpdate())
updateManga.await(update)
}
}
@@ -571,10 +571,9 @@ class LibraryViewModel(
if (deleteFromLibrary) {
val toDelete = mangas.map {
it.removeCovers(coverCache)
MangaUpdate(
favorite = false,
id = it.id,
)
MangaUpdate(it.id) {
favorite = false
}
}
updateManga.awaitAll(toDelete)
}
@@ -812,7 +812,7 @@ class MangaViewModel(
viewModelScope.launchIO {
chapters
.filterNot { it.bookmark == bookmarked }
.map { ChapterUpdate(id = it.id, bookmark = bookmarked) }
.map { ChapterUpdate(it.id) { bookmark = bookmarked } }
.let { updateChapter.awaitAll(it) }
}
toggleAllSelection(false)
@@ -583,11 +583,10 @@ class ReaderViewModel(
}
updateChapter.await(
ChapterUpdate(
id = readerChapter.chapter.id!!,
read = readerChapter.chapter.read,
lastPageRead = readerChapter.chapter.last_page_read.toLong(),
),
ChapterUpdate(readerChapter.chapter.id!!) {
read = readerChapter.chapter.read
lastPageRead = readerChapter.chapter.last_page_read.toLong()
},
)
}
}
@@ -608,7 +607,7 @@ class ReaderViewModel(
chapter.isRecognizedNumber &&
chapter.chapterNumber.toFloat() == readerChapter.chapter.chapter_number
) {
ChapterUpdate(id = chapter.id, read = true)
ChapterUpdate(chapter.id) { read = true }
} else {
null
}
@@ -683,10 +682,9 @@ class ReaderViewModel(
viewModelScope.launchNonCancellable {
updateChapter.await(
ChapterUpdate(
id = chapter.id!!,
bookmark = bookmarked,
),
ChapterUpdate(chapter.id!!) {
bookmark = bookmarked
},
)
}
@@ -303,7 +303,7 @@ class UpdatesViewModel(
viewModelScope.launchIO {
updates
.filterNot { it.update.bookmark == bookmark }
.map { ChapterUpdate(id = it.update.chapterId, bookmark = bookmark) }
.map { ChapterUpdate(it.update.chapterId) { this.bookmark = bookmark } }
.let { updateChapter.awaitAll(it) }
}
toggleAllSelection(false)