Refactor code structure for improved readability and maintainability
This commit is contained in:
@@ -4,10 +4,8 @@ import android.content.Context
|
||||
import androidx.compose.animation.*
|
||||
import androidx.compose.animation.core.*
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.gestures.detectHorizontalDragGestures
|
||||
import androidx.compose.foundation.gestures.awaitEachGesture
|
||||
import androidx.compose.foundation.gestures.awaitFirstDown
|
||||
import androidx.compose.foundation.gestures.horizontalDrag
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
@@ -28,6 +26,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.draw.clipToBounds
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.input.pointer.changedToUpIgnoreConsumed
|
||||
import androidx.compose.ui.input.pointer.pointerInput
|
||||
import androidx.compose.ui.input.pointer.positionChange
|
||||
import androidx.compose.ui.input.pointer.util.VelocityTracker
|
||||
@@ -1694,6 +1693,8 @@ fun SwipeableDialogItem(
|
||||
.background(backgroundColor)
|
||||
.pointerInput(Unit) {
|
||||
val velocityTracker = VelocityTracker()
|
||||
val touchSlop = viewConfiguration.touchSlop
|
||||
|
||||
awaitEachGesture {
|
||||
val down = awaitFirstDown(requireUnconsumed = false)
|
||||
|
||||
@@ -1701,22 +1702,58 @@ fun SwipeableDialogItem(
|
||||
if (isDrawerOpen) return@awaitEachGesture
|
||||
|
||||
velocityTracker.resetTracking()
|
||||
var started = false
|
||||
try {
|
||||
horizontalDrag(down.id) { change ->
|
||||
val dragAmount = change.positionChange().x
|
||||
var totalDragX = 0f
|
||||
var totalDragY = 0f
|
||||
var passedSlop = false
|
||||
var claimed = false
|
||||
|
||||
// First movement determines direction
|
||||
if (!started) {
|
||||
// Swipe right with actions closed — let drawer handle it
|
||||
if (dragAmount > 0 && offsetX == 0f) {
|
||||
return@horizontalDrag
|
||||
while (true) {
|
||||
val event = awaitPointerEvent()
|
||||
val change = event.changes.firstOrNull { it.id == down.id }
|
||||
?: break
|
||||
if (change.changedToUpIgnoreConsumed()) break
|
||||
|
||||
val delta = change.positionChange()
|
||||
totalDragX += delta.x
|
||||
totalDragY += delta.y
|
||||
|
||||
if (!passedSlop) {
|
||||
val dist = kotlin.math.sqrt(
|
||||
totalDragX * totalDragX + totalDragY * totalDragY
|
||||
)
|
||||
if (dist < touchSlop) continue
|
||||
|
||||
val dominated = kotlin.math.abs(totalDragX) >
|
||||
kotlin.math.abs(totalDragY) * 2.0f
|
||||
|
||||
when {
|
||||
// Horizontal left swipe — reveal action buttons
|
||||
dominated && totalDragX < 0 -> {
|
||||
passedSlop = true
|
||||
claimed = true
|
||||
onSwipeStarted()
|
||||
change.consume()
|
||||
}
|
||||
// Horizontal right swipe with buttons open — close them
|
||||
dominated && totalDragX > 0 && offsetX != 0f -> {
|
||||
passedSlop = true
|
||||
claimed = true
|
||||
change.consume()
|
||||
}
|
||||
// Right swipe with buttons closed — let drawer handle
|
||||
totalDragX > 0 && offsetX == 0f -> break
|
||||
// Vertical/diagonal — close buttons if open, let LazyColumn scroll
|
||||
else -> {
|
||||
if (offsetX != 0f) {
|
||||
offsetX = 0f
|
||||
onSwipeClosed()
|
||||
}
|
||||
break
|
||||
}
|
||||
started = true
|
||||
onSwipeStarted()
|
||||
}
|
||||
|
||||
val newOffset = offsetX + dragAmount
|
||||
} else {
|
||||
// Gesture is ours — update offset
|
||||
val newOffset = offsetX + delta.x
|
||||
offsetX = newOffset.coerceIn(-swipeWidthPx, 0f)
|
||||
velocityTracker.addPosition(
|
||||
change.uptimeMillis,
|
||||
@@ -1724,20 +1761,30 @@ fun SwipeableDialogItem(
|
||||
)
|
||||
change.consume()
|
||||
}
|
||||
} catch (_: Exception) {
|
||||
offsetX = 0f
|
||||
}
|
||||
|
||||
if (started) {
|
||||
// Snap animation
|
||||
if (claimed) {
|
||||
val velocity = velocityTracker.calculateVelocity().x
|
||||
// Telegram-like: fling left (-velocity) OR dragged past 1/3
|
||||
val shouldOpen = velocity < -300f ||
|
||||
kotlin.math.abs(offsetX) > swipeWidthPx / 3
|
||||
if (shouldOpen) {
|
||||
offsetX = -swipeWidthPx
|
||||
} else {
|
||||
offsetX = 0f
|
||||
onSwipeClosed()
|
||||
when {
|
||||
// Rightward fling — always close
|
||||
velocity > 150f -> {
|
||||
offsetX = 0f
|
||||
onSwipeClosed()
|
||||
}
|
||||
// Strong leftward fling — always open
|
||||
velocity < -300f -> {
|
||||
offsetX = -swipeWidthPx
|
||||
}
|
||||
// Past halfway — stay open
|
||||
kotlin.math.abs(offsetX) > swipeWidthPx / 2 -> {
|
||||
offsetX = -swipeWidthPx
|
||||
}
|
||||
// Less than halfway — close
|
||||
else -> {
|
||||
offsetX = 0f
|
||||
onSwipeClosed()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user