Updated on 2026-08-14
This commit is contained in:
parent
9f7f0b519f
commit
3b1e642150
6 changed files with 73 additions and 24 deletions
|
|
@ -17,6 +17,7 @@ interface FeedEntryComponent : ComposableContentComponent {
|
|||
fun BottomSheetContent(
|
||||
bottomSheetState: State<BottomSheetState>,
|
||||
onHeaderSizeChange: (Dp) -> Unit,
|
||||
onExpandSheet: () -> Unit,
|
||||
modifier: Modifier,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -172,6 +172,7 @@ internal class DefaultFeedEntryComponent @AssistedInject constructor(
|
|||
override fun BottomSheetContent(
|
||||
bottomSheetState: State<BottomSheetState>,
|
||||
onHeaderSizeChange: (Dp) -> Unit,
|
||||
onExpandSheet: () -> Unit,
|
||||
modifier: Modifier,
|
||||
) {
|
||||
val bsState by bottomSheetState
|
||||
|
|
@ -191,6 +192,7 @@ internal class DefaultFeedEntryComponent @AssistedInject constructor(
|
|||
bottomSheetState = bottomSheetState,
|
||||
stackState = stackStack,
|
||||
onHeaderSizeChange = onHeaderSizeChange,
|
||||
onExpandSheet = onExpandSheet,
|
||||
isOpenedInBottomSheet = true,
|
||||
)
|
||||
}
|
||||
|
|
@ -213,6 +215,7 @@ internal class DefaultFeedEntryComponent @AssistedInject constructor(
|
|||
bottomSheetState = bottomSheetState,
|
||||
stackState = stack.subscribeAsState(),
|
||||
onHeaderSizeChange = {},
|
||||
onExpandSheet = {},
|
||||
isOpenedInBottomSheet = false,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.features.feed.ui
|
||||
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Surface
|
||||
|
|
@ -9,6 +10,7 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.layout.onGloballyPositioned
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.semantics.clearAndSetSemantics
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.arkivanov.decompose.ExperimentalDecomposeApi
|
||||
|
|
@ -33,6 +35,7 @@ internal fun EntryContent(
|
|||
bottomSheetState: State<BottomSheetState>,
|
||||
stackState: State<ChildStack<FeedEntryChildFactory.Child, ComposableModularBottomSheetContentComponent>>,
|
||||
onHeaderSizeChange: (Dp) -> Unit,
|
||||
onExpandSheet: () -> Unit,
|
||||
isOpenedInBottomSheet: Boolean,
|
||||
) {
|
||||
if (LocalRedesignEnabled.current) {
|
||||
|
|
@ -40,6 +43,7 @@ internal fun EntryContent(
|
|||
bottomSheetState = bottomSheetState,
|
||||
stackState = stackState,
|
||||
onHeaderSizeChange = onHeaderSizeChange,
|
||||
onExpandSheet = onExpandSheet,
|
||||
isOpenedInBottomSheet = isOpenedInBottomSheet,
|
||||
)
|
||||
} else {
|
||||
|
|
@ -47,6 +51,7 @@ internal fun EntryContent(
|
|||
bottomSheetState = bottomSheetState,
|
||||
stackState = stackState,
|
||||
onHeaderSizeChange = onHeaderSizeChange,
|
||||
onExpandSheet = onExpandSheet,
|
||||
isOpenedInBottomSheet = isOpenedInBottomSheet,
|
||||
)
|
||||
}
|
||||
|
|
@ -57,6 +62,7 @@ private fun EntryContentV1(
|
|||
bottomSheetState: State<BottomSheetState>,
|
||||
stackState: State<ChildStack<FeedEntryChildFactory.Child, ComposableModularBottomSheetContentComponent>>,
|
||||
onHeaderSizeChange: (Dp) -> Unit,
|
||||
onExpandSheet: () -> Unit,
|
||||
isOpenedInBottomSheet: Boolean,
|
||||
) {
|
||||
val density = LocalDensity.current
|
||||
|
|
@ -68,7 +74,7 @@ private fun EntryContentV1(
|
|||
containerColor = background,
|
||||
contentWindowInsets = WindowInsetsZero,
|
||||
topBar = {
|
||||
Children(
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.then(
|
||||
if (!isOpenedInBottomSheet) {
|
||||
|
|
@ -84,10 +90,17 @@ private fun EntryContentV1(
|
|||
}
|
||||
}
|
||||
},
|
||||
stack = stackState.value,
|
||||
animation = stackAnimation,
|
||||
) { child ->
|
||||
child.instance.Title(bottomSheetState)
|
||||
) {
|
||||
Children(
|
||||
stack = stackState.value,
|
||||
animation = stackAnimation,
|
||||
) { child ->
|
||||
child.instance.Title(bottomSheetState)
|
||||
}
|
||||
CollapsedTitleClickOverlay(
|
||||
bottomSheetState = bottomSheetState,
|
||||
onExpandSheet = onExpandSheet,
|
||||
)
|
||||
}
|
||||
},
|
||||
content = { contentPadding ->
|
||||
|
|
@ -111,6 +124,7 @@ private fun EntryContentV2(
|
|||
bottomSheetState: State<BottomSheetState>,
|
||||
stackState: State<ChildStack<FeedEntryChildFactory.Child, ComposableModularBottomSheetContentComponent>>,
|
||||
onHeaderSizeChange: (Dp) -> Unit,
|
||||
onExpandSheet: () -> Unit,
|
||||
isOpenedInBottomSheet: Boolean,
|
||||
) {
|
||||
val density = LocalDensity.current
|
||||
|
|
@ -142,7 +156,7 @@ private fun EntryContentV2(
|
|||
bottomSheetState = bottomSheetState,
|
||||
)
|
||||
}
|
||||
AnimatedContent(
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.align(Alignment.TopStart)
|
||||
.then(
|
||||
|
|
@ -161,14 +175,37 @@ private fun EntryContentV2(
|
|||
}
|
||||
}
|
||||
},
|
||||
targetState = stackState.value.active,
|
||||
transitionSpec = animationAppBar,
|
||||
contentKey = { it.key },
|
||||
label = "FeedEntryAppBar",
|
||||
) { state ->
|
||||
state.instance.Title(bottomSheetState)
|
||||
) {
|
||||
AnimatedContent(
|
||||
targetState = stackState.value.active,
|
||||
transitionSpec = animationAppBar,
|
||||
contentKey = { it.key },
|
||||
label = "FeedEntryAppBar",
|
||||
) { state ->
|
||||
state.instance.Title(bottomSheetState)
|
||||
}
|
||||
CollapsedTitleClickOverlay(
|
||||
bottomSheetState = bottomSheetState,
|
||||
onExpandSheet = onExpandSheet,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BoxScope.CollapsedTitleClickOverlay(bottomSheetState: State<BottomSheetState>, onExpandSheet: () -> Unit) {
|
||||
if (bottomSheetState.value == BottomSheetState.COLLAPSED) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.matchParentSize()
|
||||
.clickable(
|
||||
interactionSource = null,
|
||||
indication = null,
|
||||
onClick = onExpandSheet,
|
||||
)
|
||||
.clearAndSetSemantics {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -260,10 +260,11 @@ internal class WalletComponent @AssistedInject constructor(
|
|||
WalletScreen2(
|
||||
state = uiState,
|
||||
tangemPayComponent = tangemPayMainBlockComponent,
|
||||
bottomSheetContent = {
|
||||
bottomSheetContent = { onExpandSheet ->
|
||||
BottomSheetContent(
|
||||
bottomSheetState = bottomSheetState,
|
||||
onHeaderSizeChange = { headerSize = it },
|
||||
onExpandSheet = onExpandSheet,
|
||||
modifier = modifier,
|
||||
)
|
||||
},
|
||||
|
|
@ -275,10 +276,11 @@ internal class WalletComponent @AssistedInject constructor(
|
|||
state = uiState,
|
||||
promoBannersBlockComponent = promoBannersBlockComponent,
|
||||
tangemPayComponent = tangemPayMainBlockComponent,
|
||||
bottomSheetContent = {
|
||||
bottomSheetContent = { onExpandSheet ->
|
||||
BottomSheetContent(
|
||||
bottomSheetState = bottomSheetState,
|
||||
onHeaderSizeChange = { headerSize = it },
|
||||
onExpandSheet = onExpandSheet,
|
||||
modifier = modifier,
|
||||
)
|
||||
},
|
||||
|
|
@ -305,11 +307,13 @@ internal class WalletComponent @AssistedInject constructor(
|
|||
private fun BottomSheetContent(
|
||||
bottomSheetState: State<BottomSheetState>,
|
||||
onHeaderSizeChange: (Dp) -> Unit,
|
||||
onExpandSheet: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
feedEntryComponent.BottomSheetContent(
|
||||
bottomSheetState = bottomSheetState,
|
||||
onHeaderSizeChange = onHeaderSizeChange,
|
||||
onExpandSheet = onExpandSheet,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ internal fun WalletScreen(
|
|||
state: WalletScreenState,
|
||||
tangemPayComponent: TangemPayMainBlockComponent,
|
||||
promoBannersBlockComponent: ComposableContentComponent? = null,
|
||||
bottomSheetContent: @Composable (() -> Unit),
|
||||
bottomSheetContent: @Composable (onExpandSheet: () -> Unit) -> Unit,
|
||||
bottomSheetHeaderHeightProvider: () -> Dp,
|
||||
onBottomSheetStateChange: (BottomSheetState) -> Unit,
|
||||
) {
|
||||
|
|
@ -139,7 +139,7 @@ private fun WalletContent(
|
|||
promoBannersBlockComponent: ComposableContentComponent? = null,
|
||||
bottomSheetHeaderHeightProvider: () -> Dp,
|
||||
onBottomSheetStateChange: (BottomSheetState) -> Unit,
|
||||
bottomSheetContent: @Composable (() -> Unit),
|
||||
bottomSheetContent: @Composable (onExpandSheet: () -> Unit) -> Unit,
|
||||
) {
|
||||
/*
|
||||
* Don't pass key to remember, because it will brake scroll animation.
|
||||
|
|
@ -295,7 +295,7 @@ private inline fun BaseScaffoldWithMarkets(
|
|||
snackbarHostState: SnackbarHostState,
|
||||
bottomSheetHeaderHeightProvider: () -> Dp,
|
||||
noinline onBottomSheetStateChange: (BottomSheetState) -> Unit,
|
||||
crossinline bottomSheetContent: @Composable () -> Unit,
|
||||
crossinline bottomSheetContent: @Composable (onExpandSheet: () -> Unit) -> Unit,
|
||||
crossinline content: @Composable (PaddingValues) -> Unit,
|
||||
) {
|
||||
val isKeyboardVisible by rememberIsKeyboardVisible()
|
||||
|
|
@ -382,7 +382,7 @@ private inline fun BaseScaffoldWithMarkets(
|
|||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
// expand bottom sheet when clicked on the header
|
||||
// expand bottom sheet when clicked on the drag handle
|
||||
.clickable(
|
||||
enabled = bottomSheetState.currentValue == TangemSheetValue.PartiallyExpanded,
|
||||
indication = null,
|
||||
|
|
@ -400,7 +400,9 @@ private inline fun BaseScaffoldWithMarkets(
|
|||
isSearchFieldFocused = it.isFocused
|
||||
},
|
||||
) {
|
||||
bottomSheetContent()
|
||||
bottomSheetContent {
|
||||
coroutineScope.launch { bottomSheetState.expand() }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ internal fun WalletScreen2(
|
|||
state: WalletScreenState,
|
||||
tangemPayComponent: TangemPayMainBlockComponent,
|
||||
modifier: Modifier = Modifier,
|
||||
bottomSheetContent: @Composable (() -> Unit),
|
||||
bottomSheetContent: @Composable (onExpandSheet: () -> Unit) -> Unit,
|
||||
bottomSheetHeaderHeightProvider: () -> Dp,
|
||||
onBottomSheetStateChange: (BottomSheetState) -> Unit,
|
||||
) {
|
||||
|
|
@ -162,7 +162,7 @@ private fun WalletContent2(
|
|||
modifier: Modifier = Modifier,
|
||||
bottomSheetHeaderHeightProvider: () -> Dp,
|
||||
onBottomSheetStateChange: (BottomSheetState) -> Unit,
|
||||
bottomSheetContent: @Composable (() -> Unit),
|
||||
bottomSheetContent: @Composable (onExpandSheet: () -> Unit) -> Unit,
|
||||
) {
|
||||
val density = LocalDensity.current
|
||||
val bottomBarHeight = with(density) { WindowInsets.systemBars.getBottom(this).toDp() }
|
||||
|
|
@ -343,7 +343,7 @@ private inline fun BaseScaffoldWithMarkets(
|
|||
modifier: Modifier = Modifier,
|
||||
noinline onBottomSheetStateChange: (BottomSheetState) -> Unit,
|
||||
crossinline appBarContent: @Composable () -> Unit,
|
||||
crossinline bottomSheetContent: @Composable () -> Unit,
|
||||
crossinline bottomSheetContent: @Composable (onExpandSheet: () -> Unit) -> Unit,
|
||||
crossinline content: @Composable (PaddingValues, TangemSheetState) -> Unit,
|
||||
) {
|
||||
val density = LocalDensity.current
|
||||
|
|
@ -384,7 +384,9 @@ private inline fun BaseScaffoldWithMarkets(
|
|||
isSearchFieldFocused = focusState.isFocused
|
||||
},
|
||||
) {
|
||||
bottomSheetContent()
|
||||
bottomSheetContent {
|
||||
coroutineScope.launch { bottomSheetState.expand() }
|
||||
}
|
||||
}
|
||||
},
|
||||
content = { paddingValues ->
|
||||
|
|
@ -456,7 +458,7 @@ private fun BottomSheet(
|
|||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier
|
||||
// expand bottom sheet when clicked on the header
|
||||
// expand bottom sheet when clicked on the drag handle
|
||||
.clickable(
|
||||
enabled = bottomSheetState.currentValue == TangemSheetValue.PartiallyExpanded,
|
||||
indication = null,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue