fix : You can't scroll to next chapter if the manga only has one page (verified by shivam dont spam me is anything goes wrong)

This commit is contained in:
Ankit Grai 2024-10-19 00:21:09 +05:30 committed by GitHub
parent f9ce897197
commit b594258d28
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -8,6 +8,7 @@ import android.view.MotionEvent
import android.view.View import android.view.View
import android.view.ViewConfiguration import android.view.ViewConfiguration
import android.widget.FrameLayout import android.widget.FrameLayout
import kotlin.math.absoluteValue
class Swipy @JvmOverloads constructor( class Swipy @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null context: Context, attrs: AttributeSet? = null
@ -40,47 +41,33 @@ class Swipy @JvmOverloads constructor(
private var initialDown = 0f private var initialDown = 0f
private var initialMotion = 0f private var initialMotion = 0f
enum class VerticalPosition { enum class ScrollPosition {
Top,
None, None,
Bottom Start,
End,
Both
} }
enum class HorizontalPosition { private var scrollPos = ScrollPosition.None
Left,
None, private fun setScrollPosition() = child?.run {
Right val (top, bottom) = if (vertical)
!canScrollVertically(-1) to !canScrollVertically(1)
else
!canScrollHorizontally(-1) to !canScrollHorizontally(1)
scrollPos = when {
top && !bottom -> ScrollPosition.Start
!top && bottom -> ScrollPosition.End
top && bottom -> ScrollPosition.Both
else -> ScrollPosition.None
}
} }
private var horizontalPos = HorizontalPosition.None
private var verticalPos = VerticalPosition.None
private fun setChildPosition() {
child?.apply {
if (vertical) {
verticalPos = VerticalPosition.None
if (!canScrollVertically(1)) {
verticalPos = VerticalPosition.Bottom
}
if (!canScrollVertically(-1)) {
verticalPos = VerticalPosition.Top
}
} else {
horizontalPos = HorizontalPosition.None
if (!canScrollHorizontally(1)) {
horizontalPos = HorizontalPosition.Right
}
if (!canScrollHorizontally(-1)) {
horizontalPos = HorizontalPosition.Left
}
}
}
}
private fun canChildScroll(): Boolean { private fun canChildScroll(): Boolean {
setChildPosition() setScrollPosition()
return if (vertical) verticalPos == VerticalPosition.None return scrollPos == ScrollPosition.None
else horizontalPos == HorizontalPosition.None
} }
private fun onSecondaryPointerUp(ev: MotionEvent) { private fun onSecondaryPointerUp(ev: MotionEvent) {
@ -107,6 +94,7 @@ class Swipy @JvmOverloads constructor(
if (pointerIndex < 0) { if (pointerIndex < 0) {
return false return false
} }
initialDown = if (vertical) ev.getY(pointerIndex) else ev.getX(pointerIndex) initialDown = if (vertical) ev.getY(pointerIndex) else ev.getX(pointerIndex)
} }
@ -147,40 +135,26 @@ class Swipy @JvmOverloads constructor(
MotionEvent.ACTION_MOVE -> { MotionEvent.ACTION_MOVE -> {
pointerIndex = ev.findPointerIndex(activePointerId) pointerIndex = ev.findPointerIndex(activePointerId)
if (pointerIndex < 0) { if (pointerIndex < 0) return false
//("Got ACTION_MOVE event but have an invalid active pointer id.")
return false
}
val pos = if (vertical) ev.getY(pointerIndex) else ev.getX(pointerIndex) val pos = if (vertical) ev.getY(pointerIndex) else ev.getX(pointerIndex)
startDragging(pos) startDragging(pos)
if (isBeingDragged) {
val overscroll = (
if (vertical)
if (verticalPos == VerticalPosition.Top) pos - initialMotion else initialMotion - pos
else
if (horizontalPos == HorizontalPosition.Left) pos - initialMotion else initialMotion - pos
) * DRAG_RATE
if (overscroll > 0) { if (!isBeingDragged) return false
val overscroll = getDiff(pos) * DRAG_RATE
if (overscroll.absoluteValue <= 0) return false
parent.requestDisallowInterceptTouchEvent(true) parent.requestDisallowInterceptTouchEvent(true)
if (vertical) { if (vertical) {
val totalDragDistance = val dragDistance =
Resources.getSystem().displayMetrics.heightPixels / dragDivider Resources.getSystem().displayMetrics.heightPixels / dragDivider
if (verticalPos == VerticalPosition.Top) performSwiping(overscroll, dragDistance, topBeingSwiped, bottomBeingSwiped)
topBeingSwiped.invoke(overscroll * 2 / totalDragDistance)
else
bottomBeingSwiped.invoke(overscroll * 2 / totalDragDistance)
} else { } else {
val totalDragDistance = val dragDistance =
Resources.getSystem().displayMetrics.widthPixels / dragDivider Resources.getSystem().displayMetrics.widthPixels / dragDivider
if (horizontalPos == HorizontalPosition.Left) performSwiping(overscroll, dragDistance, leftBeingSwiped, rightBeingSwiped)
leftBeingSwiped.invoke(overscroll / totalDragDistance)
else
rightBeingSwiped.invoke(overscroll / totalDragDistance)
}
} else {
return false
}
} }
} }
@ -196,11 +170,11 @@ class Swipy @JvmOverloads constructor(
MotionEvent.ACTION_POINTER_UP -> onSecondaryPointerUp(ev) MotionEvent.ACTION_POINTER_UP -> onSecondaryPointerUp(ev)
MotionEvent.ACTION_UP -> { MotionEvent.ACTION_UP -> {
if (vertical) { if (vertical) {
topBeingSwiped.invoke(0f) topBeingSwiped(0f)
bottomBeingSwiped.invoke(0f) bottomBeingSwiped(0f)
} else { } else {
rightBeingSwiped.invoke(0f) rightBeingSwiped(0f)
leftBeingSwiped.invoke(0f) leftBeingSwiped(0f)
} }
pointerIndex = ev.findPointerIndex(activePointerId) pointerIndex = ev.findPointerIndex(activePointerId)
if (pointerIndex < 0) { if (pointerIndex < 0) {
@ -209,12 +183,7 @@ class Swipy @JvmOverloads constructor(
} }
if (isBeingDragged) { if (isBeingDragged) {
val pos = if (vertical) ev.getY(pointerIndex) else ev.getX(pointerIndex) val pos = if (vertical) ev.getY(pointerIndex) else ev.getX(pointerIndex)
val overscroll = ( val overscroll = getDiff(pos) * DRAG_RATE
if (vertical)
if (verticalPos == VerticalPosition.Top) pos - initialMotion else initialMotion - pos
else
if (horizontalPos == HorizontalPosition.Left) pos - initialMotion else initialMotion - pos
) * DRAG_RATE
isBeingDragged = false isBeingDragged = false
finishSpinner(overscroll) finishSpinner(overscroll)
} }
@ -227,34 +196,67 @@ class Swipy @JvmOverloads constructor(
return true return true
} }
private fun getDiff(pos: Float) = when (scrollPos) {
ScrollPosition.None -> 0f
ScrollPosition.Start, ScrollPosition.Both -> pos - initialMotion
ScrollPosition.End -> initialMotion - pos
}
private fun startDragging(pos: Float) { private fun startDragging(pos: Float) {
val posDiff = val posDiff = getDiff(pos).absoluteValue
if ((vertical && verticalPos == VerticalPosition.Top) || (!vertical && horizontalPos == HorizontalPosition.Left))
pos - initialDown
else
initialDown - pos
if (posDiff > touchSlop && !isBeingDragged) { if (posDiff > touchSlop && !isBeingDragged) {
initialMotion = initialDown + touchSlop initialMotion = initialDown + touchSlop
isBeingDragged = true isBeingDragged = true
} }
} }
private fun finishSpinner(overscrollDistance: Float) { private fun performSwiping(
overscrollDistance: Float,
totalDragDistance: Int,
startBlock: (Float) -> Unit,
endBlock: (Float) -> Unit
) {
val distance = overscrollDistance * 2 / totalDragDistance
when (scrollPos) {
ScrollPosition.Start -> startBlock(distance)
ScrollPosition.End -> endBlock(distance)
ScrollPosition.Both -> {
startBlock(distance)
endBlock(-distance)
}
else -> {}
}
}
private fun performSwipe(
overscrollDistance: Float,
totalDragDistance: Int,
startBlock: () -> Unit,
endBlock: () -> Unit
) {
fun check(distance: Float, block: () -> Unit) {
if (distance * 2 > totalDragDistance)
block.invoke()
}
when (scrollPos) {
ScrollPosition.Start -> check(overscrollDistance) { startBlock() }
ScrollPosition.End -> check(overscrollDistance) { endBlock() }
ScrollPosition.Both -> {
check(overscrollDistance) { startBlock() }
check(-overscrollDistance) { endBlock() }
}
else -> {}
}
}
private fun finishSpinner(overscrollDistance: Float) {
if (vertical) { if (vertical) {
val totalDragDistance = Resources.getSystem().displayMetrics.heightPixels / dragDivider val totalDragDistance = Resources.getSystem().displayMetrics.heightPixels / dragDivider
if (overscrollDistance * 2 > totalDragDistance) performSwipe(overscrollDistance, totalDragDistance, onTopSwiped, onBottomSwiped)
if (verticalPos == VerticalPosition.Top)
onTopSwiped.invoke()
else
onBottomSwiped.invoke()
} else { } else {
val totalDragDistance = Resources.getSystem().displayMetrics.widthPixels / dragDivider val totalDragDistance = Resources.getSystem().displayMetrics.widthPixels / dragDivider
if (overscrollDistance > totalDragDistance) performSwipe(overscrollDistance, totalDragDistance, onLeftSwiped, onRightSwiped)
if (horizontalPos == HorizontalPosition.Left)
onLeftSwiped.invoke()
else
onRightSwiped.invoke()
} }
} }
} }