diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/prefs/AppSettings.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/prefs/AppSettings.kt
index 7dc07c3cc..1d85d4f6d 100644
--- a/app/src/main/kotlin/org/koitharu/kotatsu/core/prefs/AppSettings.kt
+++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/prefs/AppSettings.kt
@@ -138,6 +138,13 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
get() = prefs.getBoolean(KEY_READER_DOUBLE_PAGES, false)
set(value) = prefs.edit { putBoolean(KEY_READER_DOUBLE_PAGES, value) }
+ val readerDoublePagesSensitivity: Float
+ get() = prefs.getFloat(KEY_READER_DOUBLE_PAGES_SENSITIVITY, 12f) / 10f
+
+ fun setReaderDoublePagesSensitivity(value: Float) {
+ prefs.edit { putFloat(KEY_READER_DOUBLE_PAGES_SENSITIVITY, value) }
+ }
+
val readerScreenOrientation: Int
get() = prefs.getString(KEY_READER_ORIENTATION, null)?.toIntOrNull()
?: ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
@@ -673,6 +680,7 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
const val KEY_REMOTE_SOURCES = "remote_sources"
const val KEY_LOCAL_STORAGE = "local_storage"
const val KEY_READER_DOUBLE_PAGES = "reader_double_pages"
+ const val KEY_READER_DOUBLE_PAGES_SENSITIVITY = "reader_double_pages_sensitivity"
const val KEY_READER_ZOOM_BUTTONS = "reader_zoom_buttons"
const val KEY_READER_CONTROL_LTR = "reader_taps_ltr"
const val KEY_READER_NAVIGATION_INVERTED = "reader_navigation_inverted"
diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/config/ReaderConfigSheet.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/config/ReaderConfigSheet.kt
index 577e9a9c7..60d89885f 100644
--- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/config/ReaderConfigSheet.kt
+++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/config/ReaderConfigSheet.kt
@@ -5,6 +5,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.CompoundButton
+import android.widget.SeekBar
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.isGone
import androidx.core.view.isVisible
@@ -89,6 +90,10 @@ class ReaderConfigSheet :
binding.switchPullGesture.isChecked = settings.isWebtoonPullGestureEnabled
binding.switchPullGesture.isEnabled = mode == ReaderMode.WEBTOON
+ binding.textSensitivity.isVisible = settings.isReaderDoubleOnLandscape
+ binding.seekbarSensitivity.isVisible = settings.isReaderDoubleOnLandscape
+ binding.seekbarSensitivity.progress = (settings.readerDoublePagesSensitivity * 100).toInt()
+
binding.checkableGroup.addOnButtonCheckedListener(this)
binding.buttonSavePage.setOnClickListener(this)
binding.buttonScreenRotate.setOnClickListener(this)
@@ -100,6 +105,16 @@ class ReaderConfigSheet :
binding.switchDoubleReader.setOnCheckedChangeListener(this)
binding.switchPullGesture.setOnCheckedChangeListener(this)
+ binding.seekbarSensitivity.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
+ override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
+ settings.setReaderDoublePagesSensitivity(progress / 10f)
+ }
+
+ override fun onStartTrackingTouch(seekBar: SeekBar?) {}
+
+ override fun onStopTrackingTouch(seekBar: SeekBar?) {}
+ })
+
viewModel.isBookmarkAdded.observe(viewLifecycleOwner) {
binding.buttonBookmark.setText(if (it) R.string.bookmark_remove else R.string.bookmark_add)
binding.buttonBookmark.setCompoundDrawablesRelativeWithIntrinsicBounds(
@@ -173,6 +188,8 @@ class ReaderConfigSheet :
R.id.switch_double_reader -> {
settings.isReaderDoubleOnLandscape = isChecked
+ viewBinding?.textSensitivity?.isVisible = isChecked
+ viewBinding?.seekbarSensitivity?.isVisible = isChecked
findParentCallback(Callback::class.java)?.onDoubleModeChanged(isChecked)
}
diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/doublepage/DoublePageSnapHelper.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/doublepage/DoublePageSnapHelper.kt
index cf9b4106b..697ba5eef 100644
--- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/doublepage/DoublePageSnapHelper.kt
+++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/doublepage/DoublePageSnapHelper.kt
@@ -11,11 +11,14 @@ import androidx.recyclerview.widget.OrientationHelper
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.SmoothScroller.ScrollVectorProvider
import androidx.recyclerview.widget.SnapHelper
+import org.koitharu.kotatsu.core.prefs.AppSettings
import kotlin.math.abs
+import kotlin.math.absoluteValue
import kotlin.math.max
import kotlin.math.roundToInt
+import kotlin.math.sign
-class DoublePageSnapHelper : SnapHelper() {
+class DoublePageSnapHelper(private val settings: AppSettings) : SnapHelper() {
private lateinit var recyclerView: RecyclerView
@@ -248,28 +251,27 @@ class DoublePageSnapHelper : SnapHelper() {
equal to zero.
*/
fun getPositionsToMove(llm: LinearLayoutManager, scroll: Int, itemSize: Int): Int {
- var positionsToMove: Int
- positionsToMove = roundUpToBlockSize(abs((scroll.toDouble()) / itemSize).roundToInt())
- if (positionsToMove < blockSize) {
- // Must move at least one block
- positionsToMove = blockSize
- } else if (positionsToMove > maxPositionsToMove) {
- // Clamp number of positions to move, so we don't get wild flinging.
- positionsToMove = maxPositionsToMove
+ val sensitivity = settings.readerDoublePagesSensitivity
+ var positionsToMove = (scroll.toDouble() / (itemSize * (2.5 - sensitivity))).roundToInt()
+
+ // Apply a maximum threshold
+ val maxPages = (4 * sensitivity).roundToInt().coerceAtLeast(1)
+ if (positionsToMove.absoluteValue > maxPages) {
+ positionsToMove = maxPages * positionsToMove.sign
}
- if (scroll < 0) {
- positionsToMove *= -1
+
+ // Apply a minimum threshold
+ if (positionsToMove == 0 && scroll.absoluteValue > itemSize * 0.2) {
+ positionsToMove = 1 * scroll.sign
}
- if (isRTL) {
- positionsToMove *= -1
- }
- return if (layoutDirectionHelper.isDirectionToBottom(scroll < 0)) {
- // Scrolling toward the bottom of data.
- roundDownToBlockSize(llm.findFirstVisibleItemPosition()) + positionsToMove
+
+ val currentPosition = if (layoutDirectionHelper.isDirectionToBottom(scroll < 0)) {
+ llm.findFirstVisibleItemPosition()
} else {
- roundDownToBlockSize(llm.findLastVisibleItemPosition()) + positionsToMove
+ llm.findLastVisibleItemPosition()
}
- // Scrolling toward the top of the data.
+ val targetPos = currentPosition + positionsToMove * 2
+ return roundDownToBlockSize(targetPos)
}
fun isDirectionToBottom(velocityNegative: Boolean): Boolean {
diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/doublepage/DoubleReaderFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/doublepage/DoubleReaderFragment.kt
index 035225161..71bf54c7d 100644
--- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/doublepage/DoubleReaderFragment.kt
+++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/doublepage/DoubleReaderFragment.kt
@@ -13,6 +13,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.yield
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.os.NetworkState
+import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.ui.list.lifecycle.RecyclerViewLifecycleDispatcher
import org.koitharu.kotatsu.core.util.ext.firstVisibleItemPosition
import org.koitharu.kotatsu.databinding.FragmentReaderDoubleBinding
@@ -33,6 +34,9 @@ open class DoubleReaderFragment : BaseReaderFragment
+
+
+
+
None
Reset settings to default values? This action cannot be undone.
Use two pages layout on landscape orientation (beta)
+ Two-Page Scroll Sensitivity
Default webtoon zoom out
Fullscreen mode
Hide system status and navigation bars