fix: implement swipe gesture to open navigation drawer in ChatsListScreen

This commit is contained in:
k1ngsterr1
2026-02-03 03:43:10 +05:00
parent 4b8524f092
commit 3b553865cd
2 changed files with 42 additions and 16 deletions

View File

@@ -5,6 +5,10 @@ import androidx.compose.animation.*
import androidx.compose.animation.core.* import androidx.compose.animation.core.*
import androidx.compose.foundation.* import androidx.compose.foundation.*
import androidx.compose.foundation.gestures.detectHorizontalDragGestures 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.layout.*
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
@@ -25,6 +29,7 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.clipToBounds import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.input.pointer.positionChange
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
@@ -174,6 +179,15 @@ fun ChatsListScreen(
val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed) val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
// 🔥 Перехватываем системный back gesture - не закрываем приложение
// Если drawer открыт - закрываем его, иначе игнорируем
BackHandler(enabled = true) {
if (drawerState.isOpen) {
scope.launch { drawerState.close() }
}
// Если drawer закрыт - ничего не делаем (не выходим из приложения)
}
// 🔥 ВСЕГДА закрываем клавиатуру при появлении ChatsListScreen // 🔥 ВСЕГДА закрываем клавиатуру при появлении ChatsListScreen
// Используем DisposableEffect чтобы срабатывало при каждом появлении экрана // Используем DisposableEffect чтобы срабатывало при каждом появлении экрана
DisposableEffect(Unit) { DisposableEffect(Unit) {
@@ -935,7 +949,9 @@ fun ChatsListScreen(
val currentDialogs = chatsState.dialogs val currentDialogs = chatsState.dialogs
LazyColumn( LazyColumn(
modifier = Modifier.fillMaxSize().background(listBackgroundColor) modifier = Modifier
.fillMaxSize()
.background(listBackgroundColor)
) { ) {
if (requestsCount > 0) { if (requestsCount > 0) {
item( item(
@@ -1051,6 +1067,24 @@ fun ChatsListScreen(
} }
} // Close ModalNavigationDrawer } // Close ModalNavigationDrawer
// 🔥 Прозрачная зона слева для открытия drawer свайпом
// Расположена ПОВЕРХ всего контента
Box(
modifier = Modifier
.fillMaxHeight()
.width(40.dp)
.align(Alignment.CenterStart)
.pointerInput(drawerState) {
detectHorizontalDragGestures(
onHorizontalDrag = { _, dragAmount ->
if (dragAmount > 5) {
scope.launch { drawerState.open() }
}
}
)
}
)
// 🔥 Confirmation Dialogs // 🔥 Confirmation Dialogs
// Delete Dialog Confirmation // Delete Dialog Confirmation
@@ -1575,11 +1609,8 @@ fun SwipeableDialogItem(
.pointerInput(Unit) { .pointerInput(Unit) {
detectHorizontalDragGestures( detectHorizontalDragGestures(
onDragEnd = { onDragEnd = {
// Если свайпнули больше чем на // Если свайпнули больше чем на половину - фиксируем
// половину - фиксируем if (kotlin.math.abs(offsetX) > swipeWidthPx / 2) {
if (kotlin.math.abs(offsetX) >
swipeWidthPx / 2
) {
offsetX = -swipeWidthPx offsetX = -swipeWidthPx
} else { } else {
offsetX = 0f offsetX = 0f
@@ -1587,14 +1618,9 @@ fun SwipeableDialogItem(
}, },
onDragCancel = { offsetX = 0f }, onDragCancel = { offsetX = 0f },
onHorizontalDrag = { _, dragAmount -> onHorizontalDrag = { _, dragAmount ->
// Только свайп влево (отрицательное // Только свайп влево (отрицательное значение)
// значение)
val newOffset = offsetX + dragAmount val newOffset = offsetX + dragAmount
offsetX = offsetX = newOffset.coerceIn(-swipeWidthPx, 0f)
newOffset.coerceIn(
-swipeWidthPx,
0f
)
} }
) )
} }

View File

@@ -405,9 +405,9 @@ fun MessageBubble(
val combinedBackgroundColor = val combinedBackgroundColor =
if (isSelected) selectionBackgroundColor else highlightBackgroundColor if (isSelected) selectionBackgroundColor else highlightBackgroundColor
// Динамические отступы: больше между группами, меньше внутри группы // 🔥 Telegram-style отступы: минимальные внутри группы, чуть больше между группами
val topPadding = if (isGroupStart) 8.dp else 2.dp val topPadding = if (isGroupStart) 6.dp else 1.dp
val bottomPadding = 2.dp val bottomPadding = 1.dp
Row( Row(
modifier = modifier =