Refactor reader progress/history logic
This commit is contained in:
parent
16cbcecd99
commit
226272f686
2 changed files with 59 additions and 66 deletions
|
@ -235,13 +235,18 @@ class ReaderActivity : BaseActivity() {
|
|||
readingModeToast?.cancel()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
viewModel.flushReadTimer()
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
/**
|
||||
* Set menu visibility again on activity resume to apply immersive mode again if needed.
|
||||
* Helps with rotations.
|
||||
*/
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
viewModel.setReadStartTime()
|
||||
viewModel.restartReadTimer()
|
||||
setMenuVisibility(viewModel.state.value.menuVisible, animate = false)
|
||||
}
|
||||
|
||||
|
@ -588,7 +593,7 @@ class ReaderActivity : BaseActivity() {
|
|||
* Sets the visibility of the menu according to [visible] and with an optional parameter to
|
||||
* [animate] the views.
|
||||
*/
|
||||
fun setMenuVisibility(visible: Boolean, animate: Boolean = true) {
|
||||
private fun setMenuVisibility(visible: Boolean, animate: Boolean = true) {
|
||||
viewModel.showMenus(visible)
|
||||
if (visible) {
|
||||
windowInsetsController.show(WindowInsetsCompat.Type.systemBars())
|
||||
|
@ -793,7 +798,6 @@ class ReaderActivity : BaseActivity() {
|
|||
* Called from the viewer whenever a [page] is marked as active. It updates the values of the
|
||||
* bottom menu and delegates the change to the presenter.
|
||||
*/
|
||||
@SuppressLint("SetTextI18n")
|
||||
fun onPageSelected(page: ReaderPage) {
|
||||
viewModel.onPageSelected(page)
|
||||
}
|
||||
|
@ -811,7 +815,7 @@ class ReaderActivity : BaseActivity() {
|
|||
* the viewer is reaching the beginning or end of a chapter or the transition page is active.
|
||||
*/
|
||||
fun requestPreloadChapter(chapter: ReaderChapter) {
|
||||
lifecycleScope.launchIO { viewModel.preloadChapter(chapter) }
|
||||
lifecycleScope.launchIO { viewModel.preload(chapter) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -898,7 +902,7 @@ class ReaderActivity : BaseActivity() {
|
|||
/**
|
||||
* Updates viewer inset depending on fullscreen reader preferences.
|
||||
*/
|
||||
fun updateViewerInset(fullscreen: Boolean) {
|
||||
private fun updateViewerInset(fullscreen: Boolean) {
|
||||
viewModel.state.value.viewer?.getView()?.applyInsetter {
|
||||
if (!fullscreen) {
|
||||
type(navigationBars = true, statusBars = true) {
|
||||
|
|
|
@ -57,7 +57,6 @@ import kotlinx.coroutines.flow.map
|
|||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.receiveAsFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import logcat.LogPriority
|
||||
import tachiyomi.core.util.lang.launchIO
|
||||
|
@ -314,12 +313,15 @@ class ReaderViewModel(
|
|||
* Called when the user changed to the given [chapter] when changing pages from the viewer.
|
||||
* It's used only to set this chapter as active.
|
||||
*/
|
||||
private suspend fun loadNewChapter(chapter: ReaderChapter) {
|
||||
private fun loadNewChapter(chapter: ReaderChapter) {
|
||||
val loader = loader ?: return
|
||||
|
||||
viewModelScope.launchIO {
|
||||
logcat { "Loading ${chapter.chapter.url}" }
|
||||
|
||||
withIOContext {
|
||||
flushReadTimer()
|
||||
restartReadTimer()
|
||||
|
||||
try {
|
||||
loadChapter(loader, chapter)
|
||||
} catch (e: Throwable) {
|
||||
|
@ -358,7 +360,7 @@ class ReaderViewModel(
|
|||
* Called when the viewers decide it's a good time to preload a [chapter] and improve the UX so
|
||||
* that the user doesn't have to wait too long to continue reading.
|
||||
*/
|
||||
private suspend fun preload(chapter: ReaderChapter) {
|
||||
suspend fun preload(chapter: ReaderChapter) {
|
||||
if (chapter.state is ReaderChapter.State.Loaded || chapter.state == ReaderChapter.State.Loading) {
|
||||
return
|
||||
}
|
||||
|
@ -397,9 +399,7 @@ class ReaderViewModel(
|
|||
|
||||
fun onViewerLoaded(viewer: Viewer?) {
|
||||
mutableState.update {
|
||||
it.copy(
|
||||
viewer = viewer,
|
||||
)
|
||||
it.copy(viewer = viewer)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -414,31 +414,19 @@ class ReaderViewModel(
|
|||
return
|
||||
}
|
||||
|
||||
val currentChapters = state.value.viewerChapters ?: return
|
||||
val pages = page.chapter.pages ?: return
|
||||
val selectedChapter = page.chapter
|
||||
val pages = selectedChapter.pages ?: return
|
||||
|
||||
// Save last page read and mark as read if needed
|
||||
saveReadingProgress()
|
||||
mutableState.update {
|
||||
it.copy(
|
||||
currentPage = page.index + 1,
|
||||
)
|
||||
}
|
||||
if (!incognitoMode) {
|
||||
selectedChapter.chapter.last_page_read = page.index
|
||||
if (selectedChapter.pages?.lastIndex == page.index) {
|
||||
selectedChapter.chapter.read = true
|
||||
updateTrackChapterRead(selectedChapter)
|
||||
deleteChapterIfNeeded(selectedChapter)
|
||||
}
|
||||
viewModelScope.launchNonCancellable {
|
||||
updateChapterProgress(page.index)
|
||||
}
|
||||
|
||||
if (selectedChapter != currentChapters.currChapter) {
|
||||
if (selectedChapter != getCurrentChapter()) {
|
||||
logcat { "Setting ${selectedChapter.chapter.url} as active" }
|
||||
setReadStartTime()
|
||||
viewModelScope.launch { loadNewChapter(selectedChapter) }
|
||||
loadNewChapter(selectedChapter)
|
||||
}
|
||||
|
||||
val inDownloadRange = page.number.toDouble() / pages.size > 0.25
|
||||
if (inDownloadRange) {
|
||||
downloadNextChapters()
|
||||
|
@ -508,42 +496,54 @@ class ReaderViewModel(
|
|||
}
|
||||
|
||||
/**
|
||||
* Called when reader chapter is changed in reader or when activity is paused.
|
||||
*/
|
||||
private fun saveReadingProgress() {
|
||||
getCurrentChapter()?.let {
|
||||
viewModelScope.launchNonCancellable {
|
||||
saveChapterProgress(it)
|
||||
saveChapterHistory(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves this [readerChapter] progress (last read page and whether it's read)
|
||||
* Saves the chapter progress (last read page and whether it's read)
|
||||
* if incognito mode isn't on.
|
||||
*/
|
||||
private suspend fun saveChapterProgress(readerChapter: ReaderChapter) {
|
||||
if (incognitoMode) return
|
||||
private suspend fun updateChapterProgress(pageIndex: Int) {
|
||||
val readerChapter = getCurrentChapter() ?: return
|
||||
|
||||
mutableState.update {
|
||||
it.copy(currentPage = pageIndex + 1)
|
||||
}
|
||||
|
||||
if (!incognitoMode) {
|
||||
readerChapter.requestedPage = pageIndex
|
||||
readerChapter.chapter.last_page_read = pageIndex
|
||||
|
||||
val chapter = readerChapter.chapter
|
||||
readerChapter.requestedPage = chapter.last_page_read
|
||||
updateChapter.await(
|
||||
ChapterUpdate(
|
||||
id = chapter.id!!,
|
||||
read = chapter.read,
|
||||
bookmark = chapter.bookmark,
|
||||
lastPageRead = chapter.last_page_read.toLong(),
|
||||
id = readerChapter.chapter.id!!,
|
||||
read = readerChapter.chapter.read,
|
||||
bookmark = readerChapter.chapter.bookmark,
|
||||
lastPageRead = readerChapter.chapter.last_page_read.toLong(),
|
||||
),
|
||||
)
|
||||
|
||||
if (readerChapter.pages?.lastIndex == pageIndex) {
|
||||
readerChapter.chapter.read = true
|
||||
updateTrackChapterRead(readerChapter)
|
||||
deleteChapterIfNeeded(readerChapter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun restartReadTimer() {
|
||||
chapterReadStartTime = Date().time
|
||||
}
|
||||
|
||||
fun flushReadTimer() {
|
||||
viewModelScope.launchNonCancellable {
|
||||
updateHistory()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves this [readerChapter] last read history if incognito mode isn't on.
|
||||
* Saves the chapter last read history if incognito mode isn't on.
|
||||
*/
|
||||
private suspend fun saveChapterHistory(readerChapter: ReaderChapter) {
|
||||
private suspend fun updateHistory() {
|
||||
if (incognitoMode) return
|
||||
|
||||
val readerChapter = getCurrentChapter() ?: return
|
||||
val chapterId = readerChapter.chapter.id!!
|
||||
val endTime = Date()
|
||||
val sessionReadDuration = chapterReadStartTime?.let { endTime.time - it } ?: 0
|
||||
|
@ -552,17 +552,6 @@ class ReaderViewModel(
|
|||
chapterReadStartTime = null
|
||||
}
|
||||
|
||||
fun setReadStartTime() {
|
||||
chapterReadStartTime = Date().time
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from the activity to preload the given [chapter].
|
||||
*/
|
||||
suspend fun preloadChapter(chapter: ReaderChapter) {
|
||||
preload(chapter)
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from the activity to load and set the next chapter as active.
|
||||
*/
|
||||
|
|
Reference in a new issue