diff --git a/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt b/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt
index 627056742..19bfbb066 100644
--- a/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt
@@ -11,12 +11,6 @@ import androidx.core.content.edit
import androidx.preference.PreferenceManager
import com.google.android.material.color.DynamicColors
import dagger.hilt.android.qualifiers.ApplicationContext
-import java.io.File
-import java.text.DateFormat
-import java.text.SimpleDateFormat
-import java.util.*
-import javax.inject.Inject
-import javax.inject.Singleton
import org.koitharu.kotatsu.BuildConfig
import org.koitharu.kotatsu.core.model.ZoomMode
import org.koitharu.kotatsu.core.network.DoHProvider
@@ -26,6 +20,14 @@ import org.koitharu.kotatsu.utils.ext.getEnumValue
import org.koitharu.kotatsu.utils.ext.observe
import org.koitharu.kotatsu.utils.ext.putEnumValue
import org.koitharu.kotatsu.utils.ext.toUriOrNull
+import java.io.File
+import java.text.DateFormat
+import java.text.SimpleDateFormat
+import java.util.Collections
+import java.util.EnumSet
+import java.util.Locale
+import javax.inject.Inject
+import javax.inject.Singleton
@Singleton
class AppSettings @Inject constructor(@ApplicationContext context: Context) {
@@ -206,6 +208,9 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
val isReaderBarEnabled: Boolean
get() = prefs.getBoolean(KEY_READER_BAR, true)
+ val isReaderSliderEnabled: Boolean
+ get() = prefs.getBoolean(KEY_READER_SLIDER, true)
+
val dnsOverHttps: DoHProvider
get() = prefs.getEnumValue(KEY_DOH, DoHProvider.NONE)
@@ -328,6 +333,7 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
const val KEY_INCOGNITO_MODE = "incognito"
const val KEY_SYNC = "sync"
const val KEY_READER_BAR = "reader_bar"
+ const val KEY_READER_SLIDER = "reader_slider"
const val KEY_SHORTCUTS = "dynamic_shortcuts"
const val KEY_READER_TAPS_LTR = "reader_taps_ltr"
const val KEY_LOCAL_LIST_ORDER = "local_order"
diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt
index abbc542cb..ffa7432ef 100644
--- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt
@@ -9,15 +9,23 @@ import android.transition.Fade
import android.transition.Slide
import android.transition.TransitionManager
import android.transition.TransitionSet
-import android.view.*
+import android.view.Gravity
+import android.view.KeyEvent
+import android.view.Menu
+import android.view.MenuItem
+import android.view.MotionEvent
+import android.view.View
+import android.view.WindowManager
import androidx.core.graphics.Insets
-import androidx.core.view.*
+import androidx.core.view.OnApplyWindowInsetsListener
+import androidx.core.view.WindowInsetsCompat
+import androidx.core.view.isGone
+import androidx.core.view.isVisible
+import androidx.core.view.updatePadding
import androidx.lifecycle.lifecycleScope
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint
-import java.util.concurrent.TimeUnit
-import javax.inject.Inject
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@@ -42,7 +50,16 @@ import org.koitharu.kotatsu.settings.SettingsActivity
import org.koitharu.kotatsu.utils.GridTouchHelper
import org.koitharu.kotatsu.utils.IdlingDetector
import org.koitharu.kotatsu.utils.ShareHelper
-import org.koitharu.kotatsu.utils.ext.*
+import org.koitharu.kotatsu.utils.ext.assistedViewModels
+import org.koitharu.kotatsu.utils.ext.getDisplayMessage
+import org.koitharu.kotatsu.utils.ext.getParcelableExtraCompat
+import org.koitharu.kotatsu.utils.ext.hasGlobalPoint
+import org.koitharu.kotatsu.utils.ext.isReportable
+import org.koitharu.kotatsu.utils.ext.observeWithPrevious
+import org.koitharu.kotatsu.utils.ext.postDelayed
+import org.koitharu.kotatsu.utils.ext.report
+import java.util.concurrent.TimeUnit
+import javax.inject.Inject
@AndroidEntryPoint
class ReaderActivity :
@@ -145,6 +162,7 @@ class ReaderActivity :
R.id.action_settings -> {
startActivity(SettingsActivity.newReaderSettingsIntent(this))
}
+
R.id.action_chapters -> {
ChaptersBottomSheet.show(
supportFragmentManager,
@@ -152,6 +170,7 @@ class ReaderActivity :
viewModel.getCurrentState()?.chapterId ?: 0L,
)
}
+
R.id.action_pages_thumbs -> {
val pages = viewModel.getCurrentChapterPages()
if (!pages.isNullOrEmpty()) {
@@ -165,6 +184,7 @@ class ReaderActivity :
return false
}
}
+
R.id.action_bookmark -> {
if (viewModel.isBookmarkAdded.value == true) {
viewModel.removeBookmark()
@@ -172,11 +192,13 @@ class ReaderActivity :
viewModel.addBookmark()
}
}
+
R.id.action_options -> {
viewModel.saveCurrentState(readerManager.currentReader?.getCurrentState())
val currentMode = readerManager.currentMode ?: return false
ReaderConfigBottomSheet.show(supportFragmentManager, currentMode)
}
+
else -> return super.onOptionsItemSelected(item)
}
return true
@@ -364,7 +386,7 @@ class ReaderActivity :
binding.toastView.showTemporary(uiState.chapterName, TOAST_DURATION)
}
}
- if (uiState.totalPages > 1 && uiState.currentPage < uiState.totalPages) {
+ if (uiState.isSliderAvailable()) {
binding.slider.valueTo = uiState.totalPages.toFloat() - 1
binding.slider.value = uiState.currentPage.toFloat()
binding.slider.isVisible = true
diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt
index 57e36e6ce..ea9abd350 100644
--- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt
@@ -10,10 +10,22 @@ import androidx.lifecycle.viewModelScope
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
-import java.util.*
-import javax.inject.Provider
-import kotlinx.coroutines.*
-import kotlinx.coroutines.flow.*
+import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.cancelAndJoin
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.flow.update
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.plus
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.base.domain.MangaDataRepository
import org.koitharu.kotatsu.base.domain.MangaIntent
@@ -21,7 +33,11 @@ import org.koitharu.kotatsu.base.ui.BaseViewModel
import org.koitharu.kotatsu.bookmarks.domain.Bookmark
import org.koitharu.kotatsu.bookmarks.domain.BookmarksRepository
import org.koitharu.kotatsu.core.parser.MangaRepository
-import org.koitharu.kotatsu.core.prefs.*
+import org.koitharu.kotatsu.core.prefs.AppSettings
+import org.koitharu.kotatsu.core.prefs.ReaderMode
+import org.koitharu.kotatsu.core.prefs.ScreenshotsPolicy
+import org.koitharu.kotatsu.core.prefs.observeAsFlow
+import org.koitharu.kotatsu.core.prefs.observeAsLiveData
import org.koitharu.kotatsu.history.domain.HistoryRepository
import org.koitharu.kotatsu.history.domain.PROGRESS_NONE
import org.koitharu.kotatsu.parsers.exception.NotFoundException
@@ -39,6 +55,8 @@ import org.koitharu.kotatsu.utils.ext.printStackTraceDebug
import org.koitharu.kotatsu.utils.ext.processLifecycleScope
import org.koitharu.kotatsu.utils.ext.requireValue
import org.koitharu.kotatsu.utils.ext.runCatchingCancellable
+import java.util.Date
+import javax.inject.Provider
private const val BOUNDS_PAGE_OFFSET = 2
private const val PREFETCH_LIMIT = 10
@@ -116,6 +134,10 @@ class ReaderViewModel @AssistedInject constructor(
init {
loadImpl()
+ settings.observe()
+ .onEach { key ->
+ if (key == AppSettings.KEY_READER_SLIDER) notifyStateChanged()
+ }.launchIn(viewModelScope)
}
override fun onCleared() {
@@ -348,6 +370,7 @@ class ReaderViewModel @AssistedInject constructor(
chaptersTotal = chapters.size(),
totalPages = if (chapter != null) chaptersLoader.getPagesCount(chapter.id) else 0,
currentPage = state?.page ?: 0,
+ isSliderEnabled = settings.isReaderSliderEnabled,
)
uiState.postValue(newState)
}
diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/ReaderUiState.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/ReaderUiState.kt
index 7014b1a5e..1ffe455ea 100644
--- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/ReaderUiState.kt
+++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/ReaderUiState.kt
@@ -7,8 +7,13 @@ data class ReaderUiState(
val chaptersTotal: Int,
val currentPage: Int,
val totalPages: Int,
+ private val isSliderEnabled: Boolean,
) {
+ fun isSliderAvailable(): Boolean {
+ return isSliderEnabled && totalPages > 1 && currentPage < totalPages
+ }
+
fun computePercent(): Float {
val ppc = 1f / chaptersTotal
val chapterIndex = chapterNumber - 1
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 16906a84e..1d9453ba7 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -389,4 +389,5 @@
You have unsaved changes, do you want to save or discard them?
Discard
No space left on device
+ Show page switching slider
diff --git a/app/src/main/res/xml/pref_reader.xml b/app/src/main/res/xml/pref_reader.xml
index dbbe245e0..1842876fa 100644
--- a/app/src/main/res/xml/pref_reader.xml
+++ b/app/src/main/res/xml/pref_reader.xml
@@ -45,6 +45,11 @@
android:key="reader_bar"
android:title="@string/reader_info_bar" />
+
+