Fix reading history being double counted

Restore groups a backup's history entries by chapter before comparing them with the stored row, so a backup carrying one entry per copy of a duplicated chapter no longer adds its reading time more than once or moves the last read backwards. A removed history entry keeps its 0 instead of becoming NULL, a tracker's start date skips removed history, and the reader clears a session's start time before saving it, so overlapping saves can't count it twice.
This commit is contained in:
AntsyLich
2026-09-27 22:55:41 +06:00
parent 8bfa495f34
commit 553762fae8
3 changed files with 27 additions and 26 deletions
@@ -213,30 +213,32 @@ class RestoreRepositoryImpl(
this.copy(id = 0L, mangaId = 0L, dateFetch = 0L, dateUpload = 0L)
private suspend fun restoreHistory(manga: Manga, restoredHistory: List<RestoredHistory>) {
val toUpdate = restoredHistory.mapNotNull { history ->
val dbHistory = database.historyQueries
.getHistoryByChapterUrlAndMangaId(history.chapterUrl, manga.id)
.awaitAsOneOrNull()
if (dbHistory == null) {
val chapter = database.chaptersQueries
.getChapterByUrlAndMangaId(history.chapterUrl, manga.id)
val toUpdate = restoredHistory
.groupBy { it.chapterUrl }
.mapNotNull { (chapterUrl, copies) ->
val readAt = copies.maxOf { it.readAt?.time ?: 0L }
val readDuration = copies.sumOf { it.readDuration }
val dbHistory = database.historyQueries
.getHistoryByChapterUrlAndMangaId(chapterUrl, manga.id)
.awaitAsOneOrNull()
// Chapter doesn't exist; skip
?: return@mapNotNull null
// New history entry
return@mapNotNull Triple(chapter._id, history.readAt, history.readDuration)
}
// Update history entry
Triple(
dbHistory.chapter_id,
max(history.readAt?.time ?: 0L, dbHistory.last_read?.time ?: 0L)
.takeIf { it > 0L }
?.let { Date(it) },
max(history.readDuration, dbHistory.time_read) - dbHistory.time_read,
)
}
if (dbHistory == null) {
val chapter = database.chaptersQueries
.getChapterByUrlAndMangaId(chapterUrl, manga.id)
.awaitAsOneOrNull()
// Chapter doesn't exist; skip
?: return@mapNotNull null
// New history entry
return@mapNotNull Triple(chapter._id, Date(readAt), readDuration)
}
// Update history entry
Triple(
dbHistory.chapter_id,
Date(max(readAt, dbHistory.last_read?.time ?: 0L)),
max(readDuration, dbHistory.time_read) - dbHistory.time_read,
)
}
toUpdate.forEach { (chapterId, readAt, readDuration) ->
database.historyQueries.upsert(chapterId, readAt, readDuration)