Переделал механику реквестов: отдельный pull-gesture и ручка раскрытия
This commit is contained in:
@@ -1799,9 +1799,7 @@ fun ChatsListScreen(
|
||||
}
|
||||
val localDensity = LocalDensity.current
|
||||
val requestsRevealThresholdPx =
|
||||
remember(localDensity) { with(localDensity) { 24.dp.toPx() } }
|
||||
val requestsRevealInstantPx =
|
||||
remember(localDensity) { with(localDensity) { 8.dp.toPx() } }
|
||||
remember(localDensity) { with(localDensity) { 28.dp.toPx() } }
|
||||
val requestsHideThresholdPx =
|
||||
remember(localDensity) { with(localDensity) { 16.dp.toPx() } }
|
||||
|
||||
@@ -2091,89 +2089,79 @@ fun ChatsListScreen(
|
||||
lastAutoScrolledVerificationId = verificationId
|
||||
}
|
||||
|
||||
// Pull-to-show/hide для реквестов: работаем только когда
|
||||
// список реально дотянут до верха и пользователь тянет вниз.
|
||||
val requestsNestedScroll =
|
||||
remember(
|
||||
chatListState,
|
||||
requestsCount,
|
||||
requestsRevealThresholdPx,
|
||||
requestsRevealInstantPx,
|
||||
requestsHideThresholdPx,
|
||||
hapticFeedback
|
||||
) {
|
||||
var accumulatedPullDown = 0f
|
||||
var hapticSent = false
|
||||
object : androidx.compose.ui.input.nestedscroll.NestedScrollConnection {
|
||||
fun isAtTop(): Boolean {
|
||||
return !chatListState.canScrollBackward
|
||||
}
|
||||
|
||||
override fun onPreScroll(
|
||||
available: androidx.compose.ui.geometry.Offset,
|
||||
source: androidx.compose.ui.input.nestedscroll.NestedScrollSource
|
||||
): androidx.compose.ui.geometry.Offset {
|
||||
if (source != androidx.compose.ui.input.nestedscroll.NestedScrollSource.Drag ||
|
||||
requestsCount <= 0
|
||||
) {
|
||||
accumulatedPullDown = 0f
|
||||
hapticSent = false
|
||||
return androidx.compose.ui.geometry.Offset.Zero
|
||||
}
|
||||
|
||||
if (available.y < -requestsHideThresholdPx) {
|
||||
// Свайп вверх — быстро прячем блок реквестов.
|
||||
accumulatedPullDown = 0f
|
||||
hapticSent = false
|
||||
if (isRequestsVisible) {
|
||||
isRequestsVisible = false
|
||||
}
|
||||
} else if (available.y > 0f && !isRequestsVisible && isAtTop()) {
|
||||
// Pull down from top should always reopen requests.
|
||||
val shouldRevealInstantly =
|
||||
available.y >= requestsRevealInstantPx
|
||||
accumulatedPullDown =
|
||||
(accumulatedPullDown + available.y).coerceAtMost(
|
||||
requestsRevealThresholdPx
|
||||
)
|
||||
if (shouldRevealInstantly ||
|
||||
accumulatedPullDown >= requestsRevealThresholdPx
|
||||
) {
|
||||
isRequestsVisible = true
|
||||
accumulatedPullDown = 0f
|
||||
if (!hapticSent) {
|
||||
hapticFeedback.performHapticFeedback(
|
||||
HapticFeedbackType.LongPress
|
||||
)
|
||||
hapticSent = true
|
||||
}
|
||||
}
|
||||
} else if (available.y <= 0f || !isAtTop()) {
|
||||
accumulatedPullDown = 0f
|
||||
hapticSent = false
|
||||
}
|
||||
return androidx.compose.ui.geometry.Offset.Zero
|
||||
}
|
||||
|
||||
override suspend fun onPostFling(
|
||||
consumed: androidx.compose.ui.unit.Velocity,
|
||||
available: androidx.compose.ui.unit.Velocity
|
||||
): androidx.compose.ui.unit.Velocity {
|
||||
accumulatedPullDown = 0f
|
||||
hapticSent = false
|
||||
return androidx.compose.ui.unit.Velocity.Zero
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LazyColumn(
|
||||
state = chatListState,
|
||||
modifier =
|
||||
Modifier.fillMaxSize()
|
||||
.then(
|
||||
if (requestsCount > 0) Modifier.nestedScroll(requestsNestedScroll)
|
||||
else Modifier
|
||||
.pointerInput(
|
||||
requestsCount,
|
||||
isRequestsVisible,
|
||||
chatListState,
|
||||
requestsRevealThresholdPx,
|
||||
requestsHideThresholdPx
|
||||
) {
|
||||
if (requestsCount <= 0) return@pointerInput
|
||||
|
||||
awaitEachGesture {
|
||||
val down =
|
||||
awaitFirstDown(
|
||||
requireUnconsumed =
|
||||
false
|
||||
)
|
||||
var accumulatedPullDown = 0f
|
||||
|
||||
while (true) {
|
||||
val event =
|
||||
awaitPointerEvent()
|
||||
val change =
|
||||
event.changes
|
||||
.firstOrNull {
|
||||
it.id ==
|
||||
down
|
||||
.id
|
||||
}
|
||||
?: break
|
||||
if (change.changedToUpIgnoreConsumed()) {
|
||||
break
|
||||
}
|
||||
|
||||
val deltaY =
|
||||
change.positionChange()
|
||||
.y
|
||||
val atTop =
|
||||
!chatListState.canScrollBackward
|
||||
|
||||
if (isRequestsVisible &&
|
||||
atTop &&
|
||||
deltaY <
|
||||
-requestsHideThresholdPx
|
||||
) {
|
||||
isRequestsVisible = false
|
||||
accumulatedPullDown = 0f
|
||||
break
|
||||
}
|
||||
|
||||
if (!isRequestsVisible &&
|
||||
atTop &&
|
||||
deltaY > 0f
|
||||
) {
|
||||
accumulatedPullDown +=
|
||||
deltaY
|
||||
if (accumulatedPullDown >=
|
||||
requestsRevealThresholdPx
|
||||
) {
|
||||
isRequestsVisible = true
|
||||
hapticFeedback.performHapticFeedback(
|
||||
HapticFeedbackType.LongPress
|
||||
)
|
||||
break
|
||||
}
|
||||
} else if (deltaY < 0f || !atTop) {
|
||||
accumulatedPullDown = 0f
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.background(
|
||||
listBackgroundColor
|
||||
)
|
||||
@@ -2204,6 +2192,24 @@ fun ChatsListScreen(
|
||||
}
|
||||
|
||||
if (requestsCount > 0) {
|
||||
if (!isRequestsVisible) {
|
||||
item(key = "requests_reopen_handle") {
|
||||
RequestsRevealHandle(
|
||||
isDarkTheme = isDarkTheme,
|
||||
onClick = {
|
||||
isRequestsVisible = true
|
||||
hapticFeedback.performHapticFeedback(
|
||||
HapticFeedbackType.LongPress
|
||||
)
|
||||
}
|
||||
)
|
||||
Divider(
|
||||
color = dividerColor,
|
||||
thickness = 0.5.dp
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
item(key = "requests_section") {
|
||||
AnimatedVisibility(
|
||||
visible =
|
||||
@@ -4534,6 +4540,36 @@ fun TypingIndicatorSmall() {
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RequestsRevealHandle(isDarkTheme: Boolean, onClick: () -> Unit) {
|
||||
val textColor = if (isDarkTheme) Color(0xFF8E8E93) else Color(0xFF6C6C70)
|
||||
val iconColor = if (isDarkTheme) Color(0xFF7E7E84) else Color(0xFF8A8A90)
|
||||
|
||||
Row(
|
||||
modifier =
|
||||
Modifier.fillMaxWidth().clickable(onClick = onClick).padding(
|
||||
horizontal = TELEGRAM_DIALOG_AVATAR_START,
|
||||
vertical = 10.dp
|
||||
),
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Icon(
|
||||
imageVector = TablerIcons.ChevronDown,
|
||||
contentDescription = "Show requests",
|
||||
tint = iconColor,
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(6.dp))
|
||||
Text(
|
||||
text = "Pull down to show requests",
|
||||
color = textColor,
|
||||
fontSize = 13.sp,
|
||||
fontWeight = FontWeight.Medium
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** 📬 Секция Requests — Telegram Archived Chats style */
|
||||
@Composable
|
||||
fun RequestsSection(
|
||||
|
||||
Reference in New Issue
Block a user