Updated on 2026-08-14

This commit is contained in:
Tangem 2026-01-20 15:03:30 +01:00
parent fc5fbfca7f
commit e8c4e3a4a7
3 changed files with 79 additions and 5 deletions

View file

@ -6,19 +6,20 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.State import androidx.compose.runtime.State
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import com.arkivanov.decompose.extensions.compose.stack.Children 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.arkivanov.decompose.router.stack.ChildStack
import com.tangem.core.ui.components.bottomsheets.state.BottomSheetState import com.tangem.core.ui.components.bottomsheets.state.BottomSheetState
import com.tangem.core.ui.decompose.ComposableModularBottomSheetContentComponent import com.tangem.core.ui.decompose.ComposableModularBottomSheetContentComponent
import com.tangem.core.ui.res.LocalMainBottomSheetColor import com.tangem.core.ui.res.LocalMainBottomSheetColor
import com.tangem.core.ui.utils.WindowInsetsZero import com.tangem.core.ui.utils.WindowInsetsZero
import com.tangem.features.feed.components.FeedEntryChildFactory import com.tangem.features.feed.components.FeedEntryChildFactory
import com.tangem.features.feed.ui.utils.contentFeedEntryStackAnimation
import com.tangem.features.feed.ui.utils.topBarFeedEntryStackAnimation
@Composable @Composable
internal fun EntryContent( internal fun EntryContent(
@ -29,6 +30,8 @@ internal fun EntryContent(
) { ) {
val density = LocalDensity.current val density = LocalDensity.current
val background = LocalMainBottomSheetColor.current.value val background = LocalMainBottomSheetColor.current.value
val animationContent = remember { contentFeedEntryStackAnimation() }
val animationAppBar = remember { topBarFeedEntryStackAnimation() }
Surface(contentColor = background) { Surface(contentColor = background) {
Scaffold( Scaffold(
@ -52,7 +55,7 @@ internal fun EntryContent(
} }
}, },
stack = stackState.value, stack = stackState.value,
animation = stackAnimation(fade()), animation = animationAppBar,
) { child -> ) { child ->
child.instance.Title(bottomSheetState) child.instance.Title(bottomSheetState)
} }
@ -60,7 +63,7 @@ internal fun EntryContent(
content = { contentPadding -> content = { contentPadding ->
Children( Children(
stack = stackState.value, stack = stackState.value,
animation = stackAnimation(fade()), animation = animationContent,
) { child -> ) { child ->
child.instance.Content( child.instance.Content(
modifier = Modifier.padding(contentPadding), modifier = Modifier.padding(contentPadding),

View file

@ -48,7 +48,7 @@ import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
private const val SHOW_MORE_KEY = "privacyPolicy" private const val SHOW_MORE_KEY = "privacyPolicy"
private const val DELAY_FOR_FOCUS_REQUEST = 200L private const val DELAY_FOR_FOCUS_REQUEST = 500L
@Composable @Composable
internal fun TopBarWithSearch( internal fun TopBarWithSearch(

View file

@ -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)
}
}