diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt index 398742e02f..313b521c59 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt @@ -22,6 +22,7 @@ import android.view.animation.AnimationUtils import android.widget.SeekBar import androidx.appcompat.app.AppCompatDelegate import androidx.core.graphics.ColorUtils +import androidx.core.view.GestureDetectorCompat import com.afollestad.materialdialogs.MaterialDialog import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView import com.google.android.material.bottomsheet.BottomSheetBehavior @@ -63,6 +64,7 @@ import eu.kanade.tachiyomi.util.view.collapse import eu.kanade.tachiyomi.util.view.doOnApplyWindowInsets import eu.kanade.tachiyomi.util.view.gone import eu.kanade.tachiyomi.util.view.hide +import eu.kanade.tachiyomi.util.view.isCollapsed import eu.kanade.tachiyomi.util.view.isExpanded import eu.kanade.tachiyomi.util.view.snack import eu.kanade.tachiyomi.util.view.updateLayoutParams @@ -336,6 +338,7 @@ class ReaderActivity : /** * Initializes the reader menu. It sets up click listeners and the initial visibility. */ + @SuppressLint("ClickableViewAccessibility") private fun initializeMenu() { // Set binding.toolbar setSupportActionBar(binding.toolbar) @@ -373,6 +376,28 @@ class ReaderActivity : } } + val gestureDetector = GestureDetectorCompat(this, ReaderNavGestureDetector(this)) + with(binding.readerNav) { + listOf(root, leftChapter, rightChapter, pageSeekbar).forEach { + it.setOnTouchListener { _, event -> + val result = gestureDetector.onTouchEvent(event) + if (event?.action == MotionEvent.ACTION_UP) { + if (!result) { + val sheetBehavior = binding.chaptersSheet.root.sheetBehavior + if (sheetBehavior?.state != BottomSheetBehavior.STATE_SETTLING && !sheetBehavior.isCollapsed()) { + binding.chaptersSheet.root.dispatchTouchEvent(event) + sheetBehavior?.collapse() + } + } + } else if ((event?.action != MotionEvent.ACTION_UP || event.action != MotionEvent.ACTION_DOWN) && result) { + event.action = MotionEvent.ACTION_CANCEL + return@setOnTouchListener false + } + result + } + } + } + // Init listeners on bottom menu binding.readerNav.pageSeekbar.setOnSeekBarChangeListener( object : SimpleSeekBarListener() { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderNavGestureDetector.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderNavGestureDetector.kt new file mode 100644 index 0000000000..acf0aa94c9 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderNavGestureDetector.kt @@ -0,0 +1,90 @@ +package eu.kanade.tachiyomi.ui.reader + +import android.view.GestureDetector +import android.view.MotionEvent +import eu.kanade.tachiyomi.util.system.dpToPx +import eu.kanade.tachiyomi.util.view.collapse +import eu.kanade.tachiyomi.util.view.expand +import kotlin.math.abs + +class ReaderNavGestureDetector(private val activity: ReaderActivity) : GestureDetector +.SimpleOnGestureListener() { + + private val lastPixel = 0f + private var buttonY: Float = 20f.dpToPx + private var hasScrollHorizontal = false + private var lockVertical = false + + override fun onDown(e: MotionEvent): Boolean { + lockVertical = false + hasScrollHorizontal = false + val modE = MotionEvent.obtain(e) + modE.setLocation(e.x, 56f.dpToPx) + activity.binding.chaptersSheet.root.dispatchTouchEvent(modE) + modE.recycle() + return false + } + + override fun onScroll( + e1: MotionEvent?, + e2: MotionEvent?, + distanceX: Float, + distanceY: Float + ): Boolean { + val newDistanceX = (e1?.rawX ?: 0f) - (e2?.rawX ?: 0f) + val newDistanceY = (e1?.rawY ?: 0f) - (e2?.rawY ?: 0f) + if ((!hasScrollHorizontal || lockVertical) && e2 != null) { + hasScrollHorizontal = abs(newDistanceX) > abs(newDistanceY) && abs(newDistanceX) > 80 + + val modE = MotionEvent.obtain(e2) + modE.setLocation( + e2.x, + buttonY + modE.y + + (if (activity.binding.readerNav.root.alpha == 0f) activity.binding.readerNav.root.height.toFloat() else 0f) + ) + activity.binding.chaptersSheet.root.dispatchTouchEvent(modE) + modE.recycle() + if (!lockVertical) { + lockVertical = abs(newDistanceX) < abs(newDistanceY) && abs(newDistanceY) > 150 + } + } + if (hasScrollHorizontal) { + activity.binding.chaptersSheet.root.sheetBehavior?.collapse() + } + return lockVertical + } + + override fun onFling( + e1: MotionEvent, + e2: MotionEvent, + velocityX: Float, + velocityY: Float + ): Boolean { + var result = false + val diffY = e2.rawY - e1.rawY + val diffX = e2.rawX - e1.rawX + val sheetBehavior = activity.binding.chaptersSheet.root.sheetBehavior + if (!hasScrollHorizontal && abs(diffX) < abs(diffY) + && (abs(diffY) > SWIPE_THRESHOLD || abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) + && diffY <= 0 + ) { + sheetBehavior?.expand() + result = true + } + + val modE = MotionEvent.obtain(e2) + modE.setLocation(lastPixel, buttonY + modE.y) + modE.action = MotionEvent.ACTION_UP + activity.binding.chaptersSheet.root.dispatchTouchEvent(modE) + modE.recycle() + if (!result) { + activity.binding.chaptersSheet.root.sheetBehavior?.collapse() + } + return result + } + + private companion object { + const val SWIPE_THRESHOLD = 500 + const val SWIPE_VELOCITY_THRESHOLD = 600 + } +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/chapter/ReaderChapterSheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/chapter/ReaderChapterSheet.kt index 0217e536dc..2e3348bbeb 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/chapter/ReaderChapterSheet.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/chapter/ReaderChapterSheet.kt @@ -128,8 +128,6 @@ class ReaderChapterSheet @JvmOverloads constructor(context: Context, attrs: Attr } binding.chapterRecycler.isClickable = state == BottomSheetBehavior.STATE_EXPANDED binding.chapterRecycler.isFocusable = state == BottomSheetBehavior.STATE_EXPANDED - binding.chapterRecycler.isClickable = state == BottomSheetBehavior.STATE_COLLAPSED - binding.chapterRecycler.isFocusable = state == BottomSheetBehavior.STATE_COLLAPSED // binding.webviewButton.visibleIf(state != BottomSheetBehavior.STATE_COLLAPSED) // binding.chaptersButton.visInvisIf(state != BottomSheetBehavior.STATE_EXPANDED) }