Refactor code structure for improved readability and maintainability

This commit is contained in:
k1ngsterr1
2026-02-08 05:47:24 +05:00
parent 0eddd448c7
commit 0d0e1e2c22
2 changed files with 1527 additions and 1261 deletions

View File

@@ -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()
}
}
}
}