feat: add swipe gesture handling for drawer opening in ChatsListScreen
This commit is contained in:
@@ -242,6 +242,9 @@ fun ChatsListScreen(
|
||||
val textColor = remember(isDarkTheme) { if (isDarkTheme) Color.White else Color.Black }
|
||||
val secondaryTextColor =
|
||||
remember(isDarkTheme) { if (isDarkTheme) Color(0xFF8E8E8E) else Color(0xFF8E8E93) }
|
||||
val drawerGrabZonePx = with(androidx.compose.ui.platform.LocalDensity.current) { 88.dp.toPx() }
|
||||
val drawerOpenDistancePx = with(androidx.compose.ui.platform.LocalDensity.current) { 20.dp.toPx() }
|
||||
val drawerOpenVelocityThresholdPx = with(androidx.compose.ui.platform.LocalDensity.current) { 110.dp.toPx() }
|
||||
|
||||
// Protocol connection state
|
||||
val protocolState by ProtocolManager.state.collectAsState()
|
||||
@@ -417,7 +420,98 @@ fun ChatsListScreen(
|
||||
}
|
||||
|
||||
// Simple background
|
||||
Box(modifier = Modifier.fillMaxSize().background(backgroundColor).navigationBarsPadding()) {
|
||||
Box(
|
||||
modifier =
|
||||
Modifier.fillMaxSize()
|
||||
.background(backgroundColor)
|
||||
.navigationBarsPadding()
|
||||
.pointerInput(drawerState.isOpen, showRequestsScreen) {
|
||||
if (showRequestsScreen) return@pointerInput
|
||||
|
||||
val velocityTracker = VelocityTracker()
|
||||
val relaxedTouchSlop = viewConfiguration.touchSlop * 0.45f
|
||||
|
||||
awaitEachGesture {
|
||||
val down =
|
||||
awaitFirstDown(requireUnconsumed = false)
|
||||
|
||||
if (drawerState.isOpen || down.position.x > drawerGrabZonePx) {
|
||||
return@awaitEachGesture
|
||||
}
|
||||
|
||||
velocityTracker.resetTracking()
|
||||
velocityTracker.addPosition(
|
||||
down.uptimeMillis,
|
||||
down.position
|
||||
)
|
||||
var totalDragX = 0f
|
||||
var totalDragY = 0f
|
||||
var claimed = false
|
||||
|
||||
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
|
||||
velocityTracker.addPosition(
|
||||
change.uptimeMillis,
|
||||
change.position
|
||||
)
|
||||
|
||||
if (!claimed) {
|
||||
val distance =
|
||||
kotlin.math.sqrt(
|
||||
totalDragX *
|
||||
totalDragX +
|
||||
totalDragY *
|
||||
totalDragY
|
||||
)
|
||||
if (distance < relaxedTouchSlop)
|
||||
continue
|
||||
|
||||
val horizontalDominance =
|
||||
kotlin.math.abs(
|
||||
totalDragX
|
||||
) >
|
||||
kotlin.math.abs(
|
||||
totalDragY
|
||||
) * 1.15f
|
||||
if (
|
||||
totalDragX > 0 &&
|
||||
horizontalDominance
|
||||
) {
|
||||
claimed = true
|
||||
change.consume()
|
||||
} else {
|
||||
break
|
||||
}
|
||||
} else {
|
||||
change.consume()
|
||||
}
|
||||
}
|
||||
|
||||
val velocityX = velocityTracker.calculateVelocity().x
|
||||
val shouldOpenDrawer =
|
||||
claimed &&
|
||||
(totalDragX >=
|
||||
drawerOpenDistancePx ||
|
||||
velocityX >
|
||||
drawerOpenVelocityThresholdPx)
|
||||
|
||||
if (shouldOpenDrawer && drawerState.isClosed) {
|
||||
scope.launch { drawerState.open() }
|
||||
}
|
||||
}
|
||||
}
|
||||
) {
|
||||
ModalNavigationDrawer(
|
||||
drawerState = drawerState,
|
||||
gesturesEnabled = true, // 🔥 Явно включаем свайп для открытия drawer
|
||||
|
||||
Reference in New Issue
Block a user