diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/EntryContent.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/EntryContent.kt index 0aaf292083..a8efdab5d9 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/EntryContent.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/EntryContent.kt @@ -6,19 +6,20 @@ import androidx.compose.material3.Scaffold import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.runtime.State +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.Dp import com.arkivanov.decompose.extensions.compose.stack.Children -import com.arkivanov.decompose.extensions.compose.stack.animation.fade -import com.arkivanov.decompose.extensions.compose.stack.animation.stackAnimation import com.arkivanov.decompose.router.stack.ChildStack import com.tangem.core.ui.components.bottomsheets.state.BottomSheetState import com.tangem.core.ui.decompose.ComposableModularBottomSheetContentComponent import com.tangem.core.ui.res.LocalMainBottomSheetColor import com.tangem.core.ui.utils.WindowInsetsZero import com.tangem.features.feed.components.FeedEntryChildFactory +import com.tangem.features.feed.ui.utils.contentFeedEntryStackAnimation +import com.tangem.features.feed.ui.utils.topBarFeedEntryStackAnimation @Composable internal fun EntryContent( @@ -29,6 +30,8 @@ internal fun EntryContent( ) { val density = LocalDensity.current val background = LocalMainBottomSheetColor.current.value + val animationContent = remember { contentFeedEntryStackAnimation() } + val animationAppBar = remember { topBarFeedEntryStackAnimation() } Surface(contentColor = background) { Scaffold( @@ -52,7 +55,7 @@ internal fun EntryContent( } }, stack = stackState.value, - animation = stackAnimation(fade()), + animation = animationAppBar, ) { child -> child.instance.Title(bottomSheetState) } @@ -60,7 +63,7 @@ internal fun EntryContent( content = { contentPadding -> Children( stack = stackState.value, - animation = stackAnimation(fade()), + animation = animationContent, ) { child -> child.instance.Content( modifier = Modifier.padding(contentPadding), diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/MarketsList.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/MarketsList.kt index 368afe2910..32e675caff 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/MarketsList.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/MarketsList.kt @@ -48,7 +48,7 @@ import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.delay private const val SHOW_MORE_KEY = "privacyPolicy" -private const val DELAY_FOR_FOCUS_REQUEST = 200L +private const val DELAY_FOR_FOCUS_REQUEST = 500L @Composable internal fun TopBarWithSearch( diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/utils/EntryContentAnimationTransitions.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/utils/EntryContentAnimationTransitions.kt new file mode 100644 index 0000000000..638e28ca11 --- /dev/null +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/utils/EntryContentAnimationTransitions.kt @@ -0,0 +1,71 @@ +package com.tangem.features.feed.ui.utils + +import androidx.compose.animation.core.tween +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.layout.layout +import androidx.compose.ui.unit.dp +import com.arkivanov.decompose.FaultyDecomposeApi +import com.arkivanov.decompose.extensions.compose.stack.animation.* +import com.tangem.core.ui.decompose.ComposableModularBottomSheetContentComponent +import com.tangem.core.ui.utils.toPx +import com.tangem.features.feed.components.FeedEntryChildFactory + +private const val DELAY_FOR_TRANSITION = 400 + +@OptIn(FaultyDecomposeApi::class) +internal fun topBarFeedEntryStackAnimation(): StackAnimation< + FeedEntryChildFactory.Child, + ComposableModularBottomSheetContentComponent, + > = + stackAnimation { to, from, _ -> + val isSearchToTokenList = + (to.configuration as? FeedEntryChildFactory.Child.TokenList)?.params?.shouldAlwaysShowSearchBar == true + val isFromSearchTokenList = + (from.configuration as? FeedEntryChildFactory.Child.TokenList)?.params?.shouldAlwaysShowSearchBar == true + if (isSearchToTokenList || isFromSearchTokenList) { + fade() + } else { + slide() + } + } + +@OptIn(FaultyDecomposeApi::class) +internal fun contentFeedEntryStackAnimation(): StackAnimation< + FeedEntryChildFactory.Child, + ComposableModularBottomSheetContentComponent, + > = + stackAnimation { to, from, _ -> + val isSearchToTokenList = + (to.configuration as? FeedEntryChildFactory.Child.TokenList)?.params?.shouldAlwaysShowSearchBar == true + val isFromSearchTokenList = + (from.configuration as? FeedEntryChildFactory.Child.TokenList)?.params?.shouldAlwaysShowSearchBar == true + if (isSearchToTokenList || isFromSearchTokenList) { + fadeAndSlideInt() + } else { + slide() + } + } + +private fun fadeAndSlideInt(): StackAnimator = + stackAnimator(animationSpec = tween(DELAY_FOR_TRANSITION)) { factor, _, content -> + val alpha = 1f - kotlin.math.abs(factor) + val slidePx = 32.dp.toPx() + val yOffset = when { + factor > 0 -> (slidePx * factor).toInt() + factor < 0 -> (slidePx * factor * -1).toInt() + else -> 0 + } + content( + Modifier + .alpha(alpha) + .offsetY(yOffset), + ) + } + +private fun Modifier.offsetY(pixels: Int): Modifier = layout { measurable, constraints -> + val placeable = measurable.measure(constraints) + layout(placeable.width, placeable.height) { + placeable.placeRelative(x = 0, y = pixels) + } +} \ No newline at end of file