diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/SettingsRow.kt b/core/ui/src/main/java/com/tangem/core/ui/components/SettingsRow.kt index 6b497b4af0..cb5266dce9 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/SettingsRow.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/SettingsRow.kt @@ -16,7 +16,7 @@ import com.tangem.core.ui.res.TangemTheme /** * [Show in Figma](https://www.figma.com/file/14ISV23YB1yVW1uNVwqrKv/Android?type=design&node-id=281-248&mode=design&t=bXqehWPHyATKcZEW-4) - * */ + **/ @Composable fun SimpleSettingsRow( title: String, @@ -26,10 +26,11 @@ fun SimpleSettingsRow( rowColors: RowColors = getDefaultRowColors(), enabled: Boolean = true, subtitle: String? = null, + redesign: Boolean = false, ) { Row( modifier = modifier - .height(TangemTheme.dimens.size56) + .height(if (redesign) TangemTheme.dimens.size48 else TangemTheme.dimens.size56) .fillMaxWidth() .clickable( onClick = { @@ -44,10 +45,16 @@ fun SimpleSettingsRow( Icon( painter = painterResource(id = icon), contentDescription = null, - modifier = Modifier.padding(horizontal = TangemTheme.dimens.spacing20), + modifier = Modifier + .padding(horizontal = if (redesign) TangemTheme.dimens.spacing12 else TangemTheme.dimens.spacing20), tint = rowColors.iconColor(enabled = enabled).value, ) - Column(modifier = Modifier.padding(end = TangemTheme.dimens.spacing20)) { + Column( + modifier = Modifier + .padding( + end = if (redesign) TangemTheme.dimens.spacing12 else TangemTheme.dimens.spacing20, + ), + ) { Text( text = title, style = TangemTheme.typography.subtitle1, diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/buttons/chip/Chip.kt b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/chip/Chip.kt new file mode 100644 index 0000000000..3826991070 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/buttons/chip/Chip.kt @@ -0,0 +1,73 @@ +package com.tangem.core.ui.components.buttons.chip + +import android.content.res.Configuration +import androidx.annotation.DrawableRes +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview +import com.tangem.core.ui.R +import com.tangem.core.ui.extensions.TextReference +import com.tangem.core.ui.extensions.resolveReference +import com.tangem.core.ui.extensions.stringReference +import com.tangem.core.ui.res.TangemTheme +import com.tangem.core.ui.res.TangemThemePreview + +@Composable +fun Chip(text: TextReference, @DrawableRes iconResId: Int, onClick: () -> Unit, modifier: Modifier = Modifier) { + Row( + modifier = modifier + .defaultMinSize( + minWidth = TangemTheme.dimens.size46, + minHeight = TangemTheme.dimens.size28, + ) + .clip(RoundedCornerShape(size = TangemTheme.dimens.size100)) + .clickable(onClick = onClick) + .background(color = TangemTheme.colors.background.tertiary) + .padding( + horizontal = TangemTheme.dimens.spacing12, + vertical = TangemTheme.dimens.spacing6, + ), + horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing4), + verticalAlignment = Alignment.CenterVertically, + ) { + Icon( + painter = painterResource(id = iconResId), + contentDescription = null, + modifier = Modifier.size(size = TangemTheme.dimens.size16), + tint = TangemTheme.colors.icon.secondary, + ) + + Text( + text = text.resolveReference(), + style = TangemTheme.typography.caption1, + color = TangemTheme.colors.text.secondary, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + } +} + +@Preview +@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +private fun Preview() { + TangemThemePreview { + Box(Modifier.background(TangemTheme.colors.background.action)) { + Chip( + text = stringReference("Chip Chip Chip"), + iconResId = R.drawable.ic_arrow_down_24, + onClick = {}, + ) + } + } +} \ No newline at end of file diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/MarketsTokenDetailsContent.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/MarketsTokenDetailsContent.kt index 23e21f4840..9bbdfb559c 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/MarketsTokenDetailsContent.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/MarketsTokenDetailsContent.kt @@ -122,6 +122,7 @@ private fun Content( IntervalSelector( trendInterval = state.selectedInterval, onIntervalClick = state.onSelectedIntervalChange, + isEnabled = state.body !is MarketsTokenDetailsUM.Body.Nothing, modifier = Modifier .padding(horizontal = TangemTheme.dimens.spacing16) .fillMaxWidth(), @@ -219,6 +220,7 @@ private fun TokenPriceText( @Composable private fun IntervalSelector( trendInterval: PriceChangeInterval, + isEnabled: Boolean, onIntervalClick: (PriceChangeInterval) -> Unit, modifier: Modifier = Modifier, ) { @@ -235,6 +237,7 @@ private fun IntervalSelector( color = TangemTheme.colors.button.secondary, initialSelectedItem = trendInterval, onClick = onIntervalClick, + isEnabled = isEnabled, modifier = modifier, ) { Box( @@ -249,7 +252,11 @@ private fun IntervalSelector( modifier = Modifier.align(Alignment.Center), text = it.getText().resolveReference(), style = TangemTheme.typography.caption1, - color = TangemTheme.colors.text.primary1, + color = if (isEnabled) { + TangemTheme.colors.text.primary1 + } else { + TangemTheme.colors.text.disabled + }, ) } } diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/components/LinksBlock.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/components/LinksBlock.kt index 92d905ff2e..cfbb51ec74 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/components/LinksBlock.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/components/LinksBlock.kt @@ -13,9 +13,7 @@ import androidx.compose.ui.util.fastForEach import com.tangem.core.ui.components.SmallButtonShimmer import com.tangem.core.ui.components.TextShimmer import com.tangem.core.ui.components.block.information.InformationBlock -import com.tangem.core.ui.components.buttons.SecondarySmallButton -import com.tangem.core.ui.components.buttons.SmallButtonConfig -import com.tangem.core.ui.components.buttons.common.TangemButtonIconPosition +import com.tangem.core.ui.components.buttons.chip.Chip import com.tangem.core.ui.components.inputrow.inner.DividerContainer import com.tangem.core.ui.extensions.stringReference import com.tangem.core.ui.res.TangemTheme @@ -98,12 +96,10 @@ private fun SubBlock( verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12), ) { links.fastForEach { - SecondarySmallButton( - config = SmallButtonConfig( - text = it.title, - onClick = { onLinkClick(it) }, - icon = TangemButtonIconPosition.Start(iconResId = it.iconRes), - ), + Chip( + text = it.title, + iconResId = it.iconRes, + onClick = { onLinkClick(it) }, ) } } diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/loader/PortfolioDataLoader.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/loader/PortfolioDataLoader.kt index 0685abffb7..db10d655ab 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/loader/PortfolioDataLoader.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/loader/PortfolioDataLoader.kt @@ -94,6 +94,7 @@ internal class PortfolioDataLoader @Inject constructor( } } } + .distinctUntilChanged() } private fun getSelectedAppCurrencyFlow(): Flow { diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/AddToPortfolioBSContentUMFactory.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/AddToPortfolioBSContentUMFactory.kt index e88ef7d966..763a431844 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/AddToPortfolioBSContentUMFactory.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/model/AddToPortfolioBSContentUMFactory.kt @@ -66,7 +66,6 @@ internal class AddToPortfolioBSContentUMFactory( portfolioData = portfolioData, selectedWalletId = selectedWallet.walletId, ), - // TODO maybe do not show wallets with already added token isWalletBlockVisible = portfolioData.walletsWithBalance.size > 1, ), ) diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/AddToPortfolioBottomSheet.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/AddToPortfolioBottomSheet.kt index f04e4206dc..19080cb275 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/AddToPortfolioBottomSheet.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/AddToPortfolioBottomSheet.kt @@ -128,13 +128,19 @@ private fun Content(state: AddToPortfolioBSContentUM, modifier: Modifier = Modif continueButtonAreaHeight = it.size.height }, enabled = state.continueButtonEnabled, + isTangemIconVisible = state.isScanCardNotificationVisible, onClick = state.onContinueButtonClick, ) } } @Composable -private fun ContinueButton(enabled: Boolean, onClick: () -> Unit, modifier: Modifier = Modifier) { +private fun ContinueButton( + enabled: Boolean, + isTangemIconVisible: Boolean, + onClick: () -> Unit, + modifier: Modifier = Modifier, +) { TangemButton( enabled = enabled, modifier = modifier @@ -146,7 +152,7 @@ private fun ContinueButton(enabled: Boolean, onClick: () -> Unit, modifier: Modi .navigationBarsPadding() .fillMaxWidth(), text = stringResource(R.string.common_continue), - icon = if (enabled) { + icon = if (enabled && isTangemIconVisible) { TangemButtonIconPosition.End(R.drawable.ic_tangem_24) } else { TangemButtonIconPosition.None diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/TokenActionsBottomSheet.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/TokenActionsBottomSheet.kt index 57a8133772..7dc8517cd8 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/TokenActionsBottomSheet.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/portfolio/impl/ui/TokenActionsBottomSheet.kt @@ -57,6 +57,7 @@ private fun Content(content: TokenActionsBSContentUM) { SimpleSettingsRow( title = action.text.resolveReference(), icon = action.iconRes, + redesign = true, onItemsClick = { content.onActionClick(action) }, ) } diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/MarketsList.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/MarketsList.kt index fa2964129f..375d444943 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/MarketsList.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/MarketsList.kt @@ -10,6 +10,7 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.drawBehind +import androidx.compose.ui.geometry.Offset import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalFocusManager @@ -20,6 +21,7 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.tangem.core.ui.components.Keyboard import com.tangem.core.ui.components.SpacerH12 +import com.tangem.core.ui.components.SpacerH8 import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig import com.tangem.core.ui.components.buttons.SecondarySmallButton import com.tangem.core.ui.components.buttons.SmallButtonConfig @@ -65,10 +67,13 @@ internal fun MarketsList( ) } +@Suppress("LongMethod") @Composable private fun Content(state: MarketsListUM, onHeaderSizeChange: (Dp) -> Unit, modifier: Modifier = Modifier) { val density = LocalDensity.current val background = LocalMainBottomSheetColor.current.value + val strokeColor = TangemTheme.colors.stroke.primary + val scrolledState = remember { mutableStateOf(false) } Column( modifier = modifier @@ -82,7 +87,7 @@ private fun Content(state: MarketsListUM, onHeaderSizeChange: (Dp) -> Unit, modi .padding( start = TangemTheme.dimens.spacing16, end = TangemTheme.dimens.spacing16, - bottom = TangemTheme.dimens.spacing4, + bottom = TangemTheme.dimens.spacing12, ) .onGloballyPositioned { if (it.size.height > 0) { @@ -93,23 +98,45 @@ private fun Content(state: MarketsListUM, onHeaderSizeChange: (Dp) -> Unit, modi }, state = state.searchBar, ) - Spacer(Modifier.height(TangemTheme.dimens.spacing20)) Column(Modifier.padding(horizontal = TangemTheme.dimens.size16)) { - Title(isInSearchMode = state.isInSearchMode) - AnimatedVisibility(state.isInSearchMode.not()) { + AnimatedVisibility( + visible = scrolledState.value.not(), + ) { Column { + SpacerH8() + Title(isInSearchMode = state.isInSearchMode) SpacerH12() - Options( - sortByTypeUM = state.selectedSortBy, - trendInterval = state.selectedInterval, - onIntervalClick = state.onIntervalClick, - onSortByClick = state.onSortByButtonClick, - ) } } + AnimatedVisibility(state.isInSearchMode.not()) { + Options( + modifier = Modifier.padding(bottom = TangemTheme.dimens.spacing12), + sortByTypeUM = state.selectedSortBy, + trendInterval = state.selectedInterval, + onIntervalClick = state.onIntervalClick, + onSortByClick = state.onSortByButtonClick, + ) + } } - SpacerH12() + val strokeWidth = TangemTheme.dimens.size0_5 + Box( + Modifier + .fillMaxWidth() + .height(strokeWidth) + .drawBehind { + // draw horizontal line + if (scrolledState.value) { + drawLine( + color = strokeColor, + start = Offset(0f, size.height), + end = Offset(size.width, size.height), + strokeWidth = strokeWidth.toPx(), + ) + } + }, + ) ItemsList( + scrolledState = scrolledState, isInSearchMode = state.isInSearchMode, state = state.list, ) @@ -184,10 +211,35 @@ private fun Options( } @Composable -private fun ItemsList(isInSearchMode: Boolean, state: ListUM, modifier: Modifier = Modifier) { +private fun ItemsList( + scrolledState: MutableState, + isInSearchMode: Boolean, + state: ListUM, + modifier: Modifier = Modifier, +) { val searchLazyListState = rememberLazyListState() val mainLazyListState = rememberLazyListState() + val mainScrolled by remember { + derivedStateOf { + mainLazyListState.firstVisibleItemScrollOffset > 0 + } + } + + val searchScrolledState by remember { + derivedStateOf { + searchLazyListState.firstVisibleItemScrollOffset > 0 + } + } + + LaunchedEffect(mainScrolled, isInSearchMode, searchScrolledState) { + scrolledState.value = if (isInSearchMode) { + searchScrolledState + } else { + mainScrolled + } + } + MarketsListLazyColumn( modifier = modifier, state = state,