|
|
|
|
@ -6,7 +6,6 @@ import androidx.activity.result.ActivityResultLauncher
|
|
|
|
|
import androidx.lifecycle.LiveData
|
|
|
|
|
import androidx.lifecycle.MutableLiveData
|
|
|
|
|
import androidx.lifecycle.viewModelScope
|
|
|
|
|
import java.util.*
|
|
|
|
|
import kotlinx.coroutines.*
|
|
|
|
|
import kotlinx.coroutines.flow.*
|
|
|
|
|
import org.koitharu.kotatsu.R
|
|
|
|
|
@ -32,6 +31,7 @@ import org.koitharu.kotatsu.utils.SingleLiveEvent
|
|
|
|
|
import org.koitharu.kotatsu.utils.ext.asLiveDataDistinct
|
|
|
|
|
import org.koitharu.kotatsu.utils.ext.printStackTraceDebug
|
|
|
|
|
import org.koitharu.kotatsu.utils.ext.processLifecycleScope
|
|
|
|
|
import java.util.*
|
|
|
|
|
|
|
|
|
|
private const val BOUNDS_PAGE_OFFSET = 2
|
|
|
|
|
private const val PAGES_TRIM_THRESHOLD = 120
|
|
|
|
|
@ -135,13 +135,16 @@ class ReaderViewModel(
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO check performance
|
|
|
|
|
fun saveCurrentState(state: ReaderState? = null) {
|
|
|
|
|
if (state != null) {
|
|
|
|
|
currentState.value = state
|
|
|
|
|
}
|
|
|
|
|
val readerState = state ?: currentState.value ?: return
|
|
|
|
|
historyRepository.saveStateAsync(
|
|
|
|
|
mangaData.value ?: return,
|
|
|
|
|
state ?: currentState.value ?: return
|
|
|
|
|
manga = mangaData.value ?: return,
|
|
|
|
|
state = readerState,
|
|
|
|
|
percent = computePercent(readerState.chapterId, readerState.page)
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -223,7 +226,7 @@ class ReaderViewModel(
|
|
|
|
|
if (bookmarkJob?.isActive == true) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
bookmarkJob = launchJob {
|
|
|
|
|
bookmarkJob = launchJob(Dispatchers.Default) {
|
|
|
|
|
loadingJob?.join()
|
|
|
|
|
val state = checkNotNull(currentState.value)
|
|
|
|
|
val page = checkNotNull(getCurrentPage()) { "Page not found" }
|
|
|
|
|
@ -235,9 +238,10 @@ class ReaderViewModel(
|
|
|
|
|
scroll = state.scroll,
|
|
|
|
|
imageUrl = page.preview ?: pageLoader.getPageUrl(page),
|
|
|
|
|
createdAt = Date(),
|
|
|
|
|
percent = computePercent(state.chapterId, state.page),
|
|
|
|
|
)
|
|
|
|
|
bookmarksRepository.addBookmark(bookmark)
|
|
|
|
|
onShowToast.call(R.string.bookmark_added)
|
|
|
|
|
onShowToast.postCall(R.string.bookmark_added)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -279,7 +283,8 @@ class ReaderViewModel(
|
|
|
|
|
val pages = loadChapter(requireNotNull(currentState.value).chapterId)
|
|
|
|
|
// save state
|
|
|
|
|
currentState.value?.let {
|
|
|
|
|
historyRepository.addOrUpdate(manga, it.chapterId, it.page, it.scroll)
|
|
|
|
|
val percent = computePercent(it.chapterId, it.page)
|
|
|
|
|
historyRepository.addOrUpdate(manga, it.chapterId, it.page, it.scroll, percent)
|
|
|
|
|
shortcutsRepository.updateShortcuts()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -364,20 +369,32 @@ class ReaderViewModel(
|
|
|
|
|
it.printStackTraceDebug()
|
|
|
|
|
}.getOrDefault(defaultMode)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun computePercent(chapterId: Long, pageIndex: Int): Float {
|
|
|
|
|
val chapters = manga?.chapters ?: return -1f
|
|
|
|
|
val chaptersCount = chapters.size
|
|
|
|
|
val chapterIndex = chapters.indexOfFirst { x -> x.id == chapterId }
|
|
|
|
|
val pages = content.value?.pages ?: return -1f
|
|
|
|
|
val pagesCount = pages.count { x -> x.chapterId == chapterId }
|
|
|
|
|
val chapterPercent = (chapterIndex + 1) / chaptersCount.toFloat()
|
|
|
|
|
val pagePercent = (pageIndex + 1) / pagesCount.toFloat()
|
|
|
|
|
return pagePercent * chapterPercent // FIXME
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This function is not a member of the ReaderViewModel
|
|
|
|
|
* because it should work independently of the ViewModel's lifecycle.
|
|
|
|
|
*/
|
|
|
|
|
private fun HistoryRepository.saveStateAsync(manga: Manga, state: ReaderState): Job {
|
|
|
|
|
private fun HistoryRepository.saveStateAsync(manga: Manga, state: ReaderState, percent: Float): Job {
|
|
|
|
|
return processLifecycleScope.launch(Dispatchers.Default) {
|
|
|
|
|
runCatching {
|
|
|
|
|
addOrUpdate(
|
|
|
|
|
manga = manga,
|
|
|
|
|
chapterId = state.chapterId,
|
|
|
|
|
page = state.page,
|
|
|
|
|
scroll = state.scroll
|
|
|
|
|
scroll = state.scroll,
|
|
|
|
|
percent = percent,
|
|
|
|
|
)
|
|
|
|
|
}.onFailure {
|
|
|
|
|
it.printStackTraceDebug()
|
|
|
|
|
|