From 69c93a650329c7eb6562cfd54df4291a0c8d09ee Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 22 Jun 2026 12:52:52 +0300 Subject: [PATCH] Updated on 2026-08-14 --- ...BalanceExitUntilCollapsedScrollBehavior.kt | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/core/ui/src/main/java/com/tangem/core/ui/ds/topbar/collapsing/WalletBalanceExitUntilCollapsedScrollBehavior.kt b/core/ui/src/main/java/com/tangem/core/ui/ds/topbar/collapsing/WalletBalanceExitUntilCollapsedScrollBehavior.kt index 6ac6a4743f..99f7321253 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/ds/topbar/collapsing/WalletBalanceExitUntilCollapsedScrollBehavior.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/ds/topbar/collapsing/WalletBalanceExitUntilCollapsedScrollBehavior.kt @@ -7,7 +7,9 @@ import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.gestures.ScrollScope import androidx.compose.foundation.gestures.scrollable import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.remember +import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.input.nestedscroll.NestedScrollConnection @@ -19,7 +21,10 @@ import androidx.compose.ui.unit.dp import com.tangem.core.ui.ds.topbar.collapsing.entity.TangemCollapsingAppBarState import com.tangem.core.ui.ds.topbar.collapsing.entity.TopBarScrollDirection import com.tangem.core.ui.ds.topbar.collapsing.entity.rememberTangemCollapsingAppBarState +import com.tangem.core.ui.haptic.TangemHapticEffect +import com.tangem.core.ui.res.LocalHapticManager import com.tangem.core.ui.utils.toPx +import kotlinx.coroutines.flow.drop import kotlin.math.abs import kotlin.math.absoluteValue @@ -48,6 +53,9 @@ fun rememberTangemExitUntilCollapsedScrollBehavior( partialHeightLimit = partialCollapsedHeight.toPx(), isTopOverscrollEnabled = isTopOverscrollEnabled, ) + + SnapThresholdHapticEffect(state = topBarState) + return exitUntilCollapsedScrollBehavior( state = topBarState, snapAnimationSpec = snapAnimationSpec, @@ -55,6 +63,35 @@ fun rememberTangemExitUntilCollapsedScrollBehavior( ) } +/** + * Provides a detent-style haptic feedback as the collapsing app bar crosses the threshold between its + * expanded and collapsed snap states + * + * @param state The state of the collapsing app bar to observe. + * @param snapThreshold The collapsed fraction (0f..1f) at which the haptic detent fires. Default is 0.5f, + * the midpoint between the collapse and expand snap thresholds. + */ +@Composable +private fun SnapThresholdHapticEffect( + state: TangemCollapsingAppBarState, + @Suppress("MagicNumber") snapThreshold: Float = 0.5f, +) { + val hapticManager = LocalHapticManager.current + LaunchedEffect(state, hapticManager, snapThreshold) { + snapshotFlow { state.collapsedFraction >= snapThreshold } + .drop(1) // skip the initial value so we only react to actual crossings + .collect { isPastThreshold -> + hapticManager.perform( + if (isPastThreshold) { + TangemHapticEffect.View.GestureThresholdActivate + } else { + TangemHapticEffect.View.GestureThresholdDeactivate + }, + ) + } + } +} + /** * A scroll behavior for a collapsing top app bar that collapses when scrolling up and expands when scrolling down. * When the user stops scrolling, the app bar will settle to either fully collapsed or fully expanded state