mirror of
https://github.com/mihonapp/mihon.git
synced 2025-11-13 12:38:58 +01:00
Reader: Save reading progress with SQLDelight (#7185)
* Use SQLDelight in reader to update history * Move chapter progress to sqldelight * Review Changes Co-Authored-By: inorichi <len@kanade.eu> * Review Changes 2 Co-authored-by: FourTOne5 <59261191+FourTOne5@users.noreply.github.com> Co-authored-by: inorichi <len@kanade.eu>
This commit is contained in:
@@ -232,7 +232,7 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
presenter.saveProgress()
|
||||
presenter.saveCurrentChapterReadingProgress()
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
@@ -242,6 +242,7 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
|
||||
*/
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
presenter.setReadStartTime()
|
||||
setMenuVisibility(menuVisible, animate = false)
|
||||
}
|
||||
|
||||
|
||||
@@ -4,9 +4,12 @@ import android.app.Application
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import com.jakewharton.rxrelay.BehaviorRelay
|
||||
import eu.kanade.domain.chapter.interactor.UpdateChapter
|
||||
import eu.kanade.domain.chapter.model.ChapterUpdate
|
||||
import eu.kanade.domain.history.interactor.UpsertHistory
|
||||
import eu.kanade.domain.history.model.HistoryUpdate
|
||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.History
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
@@ -62,6 +65,8 @@ class ReaderPresenter(
|
||||
private val coverCache: CoverCache = Injekt.get(),
|
||||
private val preferences: PreferencesHelper = Injekt.get(),
|
||||
private val delayedTrackingStore: DelayedTrackingStore = Injekt.get(),
|
||||
private val upsertHistory: UpsertHistory = Injekt.get(),
|
||||
private val updateChapter: UpdateChapter = Injekt.get(),
|
||||
) : BasePresenter<ReaderActivity>() {
|
||||
|
||||
/**
|
||||
@@ -80,6 +85,11 @@ class ReaderPresenter(
|
||||
*/
|
||||
private var loader: ChapterLoader? = null
|
||||
|
||||
/**
|
||||
* The time the chapter was started reading
|
||||
*/
|
||||
private var chapterReadStartTime: Long? = null
|
||||
|
||||
/**
|
||||
* Subscription to prevent setting chapters as active from multiple threads.
|
||||
*/
|
||||
@@ -168,8 +178,7 @@ class ReaderPresenter(
|
||||
val currentChapters = viewerChaptersRelay.value
|
||||
if (currentChapters != null) {
|
||||
currentChapters.unref()
|
||||
saveChapterProgress(currentChapters.currChapter)
|
||||
saveChapterHistory(currentChapters.currChapter)
|
||||
saveReadingProgress(currentChapters.currChapter)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,7 +209,9 @@ class ReaderPresenter(
|
||||
*/
|
||||
fun onSaveInstanceStateNonConfigurationChange() {
|
||||
val currentChapter = getCurrentChapter() ?: return
|
||||
saveChapterProgress(currentChapter)
|
||||
launchIO {
|
||||
saveChapterProgress(currentChapter)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -397,7 +408,7 @@ class ReaderPresenter(
|
||||
|
||||
if (selectedChapter != currentChapters.currChapter) {
|
||||
logcat { "Setting ${selectedChapter.chapter.url} as active" }
|
||||
onChapterChanged(currentChapters.currChapter)
|
||||
saveReadingProgress(currentChapters.currChapter)
|
||||
loadNewChapter(selectedChapter)
|
||||
}
|
||||
}
|
||||
@@ -429,43 +440,57 @@ class ReaderPresenter(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a chapter changed from [fromChapter] to [toChapter]. It updates [fromChapter]
|
||||
* on the database.
|
||||
*/
|
||||
private fun onChapterChanged(fromChapter: ReaderChapter) {
|
||||
saveChapterProgress(fromChapter)
|
||||
saveChapterHistory(fromChapter)
|
||||
fun saveCurrentChapterReadingProgress() {
|
||||
getCurrentChapter()?.let { saveReadingProgress(it) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves this [chapter] progress (last read page and whether it's read).
|
||||
* Called when reader chapter is changed in reader or when activity is paused.
|
||||
*/
|
||||
private fun saveReadingProgress(readerChapter: ReaderChapter) {
|
||||
launchIO {
|
||||
saveChapterProgress(readerChapter)
|
||||
saveChapterHistory(readerChapter)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves this [readerChapter] progress (last read page and whether it's read).
|
||||
* If incognito mode isn't on or has at least 1 tracker
|
||||
*/
|
||||
private fun saveChapterProgress(chapter: ReaderChapter) {
|
||||
private suspend fun saveChapterProgress(readerChapter: ReaderChapter) {
|
||||
if (!incognitoMode || hasTrackers) {
|
||||
db.updateChapterProgress(chapter.chapter).asRxCompletable()
|
||||
.onErrorComplete()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe()
|
||||
val chapter = readerChapter.chapter
|
||||
updateChapter.await(
|
||||
ChapterUpdate(
|
||||
id = chapter.id!!,
|
||||
read = chapter.read,
|
||||
bookmark = chapter.bookmark,
|
||||
lastPageRead = chapter.last_page_read.toLong(),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves this [chapter] last read history if incognito mode isn't on.
|
||||
* Saves this [readerChapter] last read history if incognito mode isn't on.
|
||||
*/
|
||||
private fun saveChapterHistory(chapter: ReaderChapter) {
|
||||
private suspend fun saveChapterHistory(readerChapter: ReaderChapter) {
|
||||
if (!incognitoMode) {
|
||||
val history = History.create(chapter.chapter).apply { last_read = Date().time }
|
||||
db.upsertHistoryLastRead(history).asRxCompletable()
|
||||
.onErrorComplete()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe()
|
||||
val chapterId = readerChapter.chapter.id!!
|
||||
val readAt = Date()
|
||||
val sessionReadDuration = chapterReadStartTime?.let { readAt.time - it } ?: 0
|
||||
|
||||
upsertHistory.await(
|
||||
HistoryUpdate(chapterId, readAt, sessionReadDuration),
|
||||
).also {
|
||||
chapterReadStartTime = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun saveProgress() {
|
||||
getCurrentChapter()?.let { onChapterChanged(it) }
|
||||
fun setReadStartTime() {
|
||||
chapterReadStartTime = Date().time
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -633,7 +658,7 @@ class ReaderPresenter(
|
||||
* Shares the image of this [page] and notifies the UI with the path of the file to share.
|
||||
* The image must be first copied to the internal partition because there are many possible
|
||||
* formats it can come from, like a zipped chapter, in which case it's not possible to directly
|
||||
* get a path to the file and it has to be decompresssed somewhere first. Only the last shared
|
||||
* get a path to the file and it has to be decompressed somewhere first. Only the last shared
|
||||
* image will be kept so it won't be taking lots of internal disk space.
|
||||
*/
|
||||
fun shareImage(page: ReaderPage) {
|
||||
|
||||
Reference in New Issue
Block a user