Сделал стабильное появление реквестов при оттягивании списка
This commit is contained in:
@@ -1797,6 +1797,13 @@ fun ChatsListScreen(
|
|||||||
var lastAutoScrolledVerificationId by remember {
|
var lastAutoScrolledVerificationId by remember {
|
||||||
mutableStateOf<String?>(null)
|
mutableStateOf<String?>(null)
|
||||||
}
|
}
|
||||||
|
val localDensity = LocalDensity.current
|
||||||
|
val requestsRevealThresholdPx =
|
||||||
|
remember(localDensity) { with(localDensity) { 56.dp.toPx() } }
|
||||||
|
val requestsHideThresholdPx =
|
||||||
|
remember(localDensity) { with(localDensity) { 16.dp.toPx() } }
|
||||||
|
val topOffsetTolerancePx =
|
||||||
|
remember(localDensity) { with(localDensity) { 3.dp.toPx() } }
|
||||||
|
|
||||||
AnimatedContent(
|
AnimatedContent(
|
||||||
targetState = showDownloadsScreen,
|
targetState = showDownloadsScreen,
|
||||||
@@ -2061,9 +2068,6 @@ fun ChatsListScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Track scroll direction to hide/show Requests
|
|
||||||
val hapticFeedback = LocalHapticFeedback.current
|
|
||||||
|
|
||||||
// When a new device confirmation banner appears at the top,
|
// When a new device confirmation banner appears at the top,
|
||||||
// smoothly bring the list to top so the banner is visible.
|
// smoothly bring the list to top so the banner is visible.
|
||||||
LaunchedEffect(pendingDeviceVerification?.deviceId) {
|
LaunchedEffect(pendingDeviceVerification?.deviceId) {
|
||||||
@@ -2087,31 +2091,94 @@ fun ChatsListScreen(
|
|||||||
lastAutoScrolledVerificationId = verificationId
|
lastAutoScrolledVerificationId = verificationId
|
||||||
}
|
}
|
||||||
|
|
||||||
// NestedScroll — ловим направление свайпа даже без скролла
|
// Pull-to-show/hide для реквестов: работаем только когда
|
||||||
// Для появления: накапливаем pull down дельту, нужен сильный жест
|
// список реально дотянут до верха и пользователь тянет вниз.
|
||||||
val requestsNestedScroll = remember(hapticFeedback) {
|
val requestsNestedScroll =
|
||||||
|
remember(
|
||||||
|
chatListState,
|
||||||
|
requestsCount,
|
||||||
|
requestsRevealThresholdPx,
|
||||||
|
requestsHideThresholdPx,
|
||||||
|
topOffsetTolerancePx,
|
||||||
|
hapticFeedback
|
||||||
|
) {
|
||||||
var accumulatedPullDown = 0f
|
var accumulatedPullDown = 0f
|
||||||
|
var hapticSent = false
|
||||||
object : androidx.compose.ui.input.nestedscroll.NestedScrollConnection {
|
object : androidx.compose.ui.input.nestedscroll.NestedScrollConnection {
|
||||||
|
fun isAtTop(): Boolean {
|
||||||
|
return chatListState.firstVisibleItemIndex == 0 &&
|
||||||
|
chatListState.firstVisibleItemScrollOffset <=
|
||||||
|
topOffsetTolerancePx.roundToInt()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onPreScroll(
|
override fun onPreScroll(
|
||||||
available: androidx.compose.ui.geometry.Offset,
|
available: androidx.compose.ui.geometry.Offset,
|
||||||
source: androidx.compose.ui.input.nestedscroll.NestedScrollSource
|
source: androidx.compose.ui.input.nestedscroll.NestedScrollSource
|
||||||
): androidx.compose.ui.geometry.Offset {
|
): androidx.compose.ui.geometry.Offset {
|
||||||
if (available.y < -10f) {
|
if (source != androidx.compose.ui.input.nestedscroll.NestedScrollSource.Drag ||
|
||||||
// Свайп вверх — прячем легко
|
requestsCount <= 0
|
||||||
|
) {
|
||||||
accumulatedPullDown = 0f
|
accumulatedPullDown = 0f
|
||||||
isRequestsVisible = false
|
hapticSent = false
|
||||||
} else if (available.y > 0f && !isRequestsVisible) {
|
return androidx.compose.ui.geometry.Offset.Zero
|
||||||
// Свайп вниз — накапливаем для появления
|
}
|
||||||
accumulatedPullDown += available.y
|
|
||||||
if (accumulatedPullDown > 120f) {
|
if (available.y < -requestsHideThresholdPx) {
|
||||||
|
// Свайп вверх — быстро прячем блок реквестов.
|
||||||
|
accumulatedPullDown = 0f
|
||||||
|
hapticSent = false
|
||||||
|
if (isRequestsVisible) {
|
||||||
|
isRequestsVisible = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return androidx.compose.ui.geometry.Offset.Zero
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPostScroll(
|
||||||
|
consumed: androidx.compose.ui.geometry.Offset,
|
||||||
|
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 (isRequestsVisible) {
|
||||||
|
accumulatedPullDown = 0f
|
||||||
|
hapticSent = false
|
||||||
|
return androidx.compose.ui.geometry.Offset.Zero
|
||||||
|
}
|
||||||
|
|
||||||
|
val pullDownDelta =
|
||||||
|
if (available.y > 0f && isAtTop())
|
||||||
|
available.y
|
||||||
|
else 0f
|
||||||
|
|
||||||
|
if (pullDownDelta > 0f) {
|
||||||
|
accumulatedPullDown =
|
||||||
|
(accumulatedPullDown +
|
||||||
|
pullDownDelta)
|
||||||
|
.coerceAtMost(
|
||||||
|
requestsRevealThresholdPx *
|
||||||
|
2f
|
||||||
|
)
|
||||||
|
if (accumulatedPullDown >= requestsRevealThresholdPx) {
|
||||||
isRequestsVisible = true
|
isRequestsVisible = true
|
||||||
accumulatedPullDown = 0f
|
accumulatedPullDown = 0f
|
||||||
hapticFeedback.performHapticFeedback(
|
if (!hapticSent) {
|
||||||
HapticFeedbackType.LongPress
|
hapticFeedback.performHapticFeedback(
|
||||||
)
|
HapticFeedbackType.LongPress
|
||||||
|
)
|
||||||
|
hapticSent = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (available.y <= 0f) {
|
} else if (available.y < 0f || !isAtTop()) {
|
||||||
accumulatedPullDown = 0f
|
accumulatedPullDown = 0f
|
||||||
|
hapticSent = false
|
||||||
}
|
}
|
||||||
return androidx.compose.ui.geometry.Offset.Zero
|
return androidx.compose.ui.geometry.Offset.Zero
|
||||||
}
|
}
|
||||||
@@ -2121,6 +2188,7 @@ fun ChatsListScreen(
|
|||||||
available: androidx.compose.ui.unit.Velocity
|
available: androidx.compose.ui.unit.Velocity
|
||||||
): androidx.compose.ui.unit.Velocity {
|
): androidx.compose.ui.unit.Velocity {
|
||||||
accumulatedPullDown = 0f
|
accumulatedPullDown = 0f
|
||||||
|
hapticSent = false
|
||||||
return androidx.compose.ui.unit.Velocity.Zero
|
return androidx.compose.ui.unit.Velocity.Zero
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user