diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/account/AccountIcon.kt b/core/ui/src/main/java/com/tangem/core/ui/components/account/AccountIcon.kt index 001c7069af..3a7a35299c 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/account/AccountIcon.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/account/AccountIcon.kt @@ -32,7 +32,15 @@ import com.tangem.core.ui.res.TangemThemePreview import com.tangem.core.ui.res.TangemThemePreviewRedesign enum class AccountIconSize { - Default, Large, Medium, Small, ExtraSmall, RedesignedDefault, RedesignExtraSmall, RedesignLarge, Contact + Default, + Large, + Medium, + Small, + ExtraSmall, + RedesignedDefault, + RedesignExtraSmall, + ContactLarge, + ContactDefault, } /** @@ -132,8 +140,8 @@ fun AccountCharIcon(char: Char, color: Color, size: AccountIconSize, modifier: M AccountIconSize.ExtraSmall -> TangemTheme.typography.caption1 AccountIconSize.RedesignedDefault -> TangemTheme.typography2.headingSemibold28 AccountIconSize.RedesignExtraSmall -> TangemTheme.typography2.captionMedium11 - AccountIconSize.RedesignLarge -> TangemTheme.typography3.heading.medium - AccountIconSize.Contact -> TangemTheme.typography3.body.medium + AccountIconSize.ContactLarge -> TangemTheme.typography3.heading.medium + AccountIconSize.ContactDefault -> TangemTheme.typography3.body.medium } val textSize by animateFloatAsState( @@ -168,8 +176,8 @@ private fun AccountIconSize.iconSizeInDp(): Dp = when (this) { AccountIconSize.ExtraSmall -> 8.dp AccountIconSize.RedesignedDefault -> 20.dp AccountIconSize.RedesignExtraSmall -> 8.dp - AccountIconSize.RedesignLarge -> 32.dp - AccountIconSize.Contact -> 20.dp + AccountIconSize.ContactLarge -> 32.dp + AccountIconSize.ContactDefault -> 20.dp } fun AccountIconSize.toBoxSize(): Dp = when (this) { @@ -180,8 +188,8 @@ fun AccountIconSize.toBoxSize(): Dp = when (this) { AccountIconSize.ExtraSmall -> 14.dp AccountIconSize.RedesignedDefault -> 40.dp AccountIconSize.RedesignExtraSmall -> 16.dp - AccountIconSize.RedesignLarge -> 80.dp - AccountIconSize.Contact -> 40.dp + AccountIconSize.ContactLarge -> 80.dp + AccountIconSize.ContactDefault -> 40.dp } private fun AccountIconSize.boxShapeSizeInDp(): Dp = when (this) { @@ -192,8 +200,8 @@ private fun AccountIconSize.boxShapeSizeInDp(): Dp = when (this) { AccountIconSize.ExtraSmall -> 4.dp AccountIconSize.RedesignedDefault -> 12.dp AccountIconSize.RedesignExtraSmall -> 6.dp - AccountIconSize.RedesignLarge -> 80.dp - AccountIconSize.Contact -> 100.dp + AccountIconSize.ContactLarge -> 80.dp + AccountIconSize.ContactDefault -> 100.dp } @Preview(showBackground = true) @@ -236,9 +244,9 @@ private fun Sample() { AccountIconSize.Small -> AccountIconSize.ExtraSmall AccountIconSize.ExtraSmall -> AccountIconSize.RedesignedDefault AccountIconSize.RedesignedDefault -> AccountIconSize.RedesignExtraSmall - AccountIconSize.RedesignExtraSmall -> AccountIconSize.RedesignLarge - AccountIconSize.RedesignLarge -> AccountIconSize.Contact - AccountIconSize.Contact -> AccountIconSize.Default + AccountIconSize.RedesignExtraSmall -> AccountIconSize.ContactLarge + AccountIconSize.ContactLarge -> AccountIconSize.ContactDefault + AccountIconSize.ContactDefault -> AccountIconSize.Default } }) { Text("Change") } diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/bottomsheets/TangemBottomSheet.kt b/core/ui/src/main/java/com/tangem/core/ui/components/bottomsheets/TangemBottomSheet.kt index b597df325e..c7ca25ba10 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/bottomsheets/TangemBottomSheet.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/bottomsheets/TangemBottomSheet.kt @@ -36,12 +36,10 @@ import com.tangem.core.ui.components.bottomsheets.sheet.TangemBottomSheetDraggab import com.tangem.core.ui.components.sheetscaffold.TangemSheetState import com.tangem.core.ui.components.sheetscaffold.TangemSheetValue import com.tangem.core.ui.components.sheetscaffold.rememberSheetState -import com.tangem.core.ui.res.LocalBottomSheetAlwaysVisible -import com.tangem.core.ui.res.LocalWindowSize -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreviewRedesign +import com.tangem.core.ui.res.* import com.tangem.core.ui.test.BaseBottomSheetTestTags import com.tangem.core.ui.utils.WindowInsetsZero +import dev.chrisbanes.haze.rememberHazeState /** * Extra bottom inset that scrollable content under a [BasicBottomSheet] should reserve so it @@ -235,46 +233,48 @@ inline fun BasicBottomSheet( } val bsContent: @Composable ColumnScope.() -> Unit = { - val contentModifier = when (type) { - Default -> Modifier - .clip( - RoundedCornerShape( - topStart = TangemTheme.dimens2.x8, - topEnd = TangemTheme.dimens2.x8, - ), - ) - Modal -> Modifier - .padding( - start = TangemTheme.dimens2.x2, - end = TangemTheme.dimens2.x2, - bottom = bottomBarHeight, - ) - .clip(RoundedCornerShape(TangemTheme.dimens2.x8)) - } - - Column( - modifier = contentModifier - .background(containerColor) - .heightIn(max = maxHeight) - .testTag(BaseBottomSheetTestTags.CONTAINER), - ) { - Box(modifier = Modifier.fillMaxWidth()) { - title(model) - } - Box(modifier = Modifier.fillMaxWidth()) { - if (footer != null) { - FooterOverlay( - measuredFooterHeight = footerHeightDp, - onMeasureFooter = { newHeight -> - if (newHeight != footerHeightDp) { - footerHeightDp = newHeight - } - }, - footer = { footer(model) }, - content = { content(model) }, + CompositionLocalProvider(LocalHazeState provides rememberHazeState()) { + val contentModifier = when (type) { + Default -> Modifier + .clip( + RoundedCornerShape( + topStart = TangemTheme.dimens2.x8, + topEnd = TangemTheme.dimens2.x8, + ), ) - } else { - content(model) + Modal -> Modifier + .padding( + start = TangemTheme.dimens2.x2, + end = TangemTheme.dimens2.x2, + bottom = bottomBarHeight, + ) + .clip(RoundedCornerShape(TangemTheme.dimens2.x8)) + } + + Column( + modifier = contentModifier + .background(containerColor) + .heightIn(max = maxHeight) + .testTag(BaseBottomSheetTestTags.CONTAINER), + ) { + Box(modifier = Modifier.fillMaxWidth()) { + title(model) + } + Box(modifier = Modifier.fillMaxWidth()) { + if (footer != null) { + FooterOverlay( + measuredFooterHeight = footerHeightDp, + onMeasureFooter = { newHeight -> + if (newHeight != footerHeightDp) { + footerHeightDp = newHeight + } + }, + footer = { footer(model) }, + content = { content(model) }, + ) + } else { + content(model) + } } } } diff --git a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addaddress/model/AddAddressModel.kt b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addaddress/model/AddAddressModel.kt index 961c230e40..d78a02b92e 100644 --- a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addaddress/model/AddAddressModel.kt +++ b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addaddress/model/AddAddressModel.kt @@ -78,7 +78,6 @@ internal class AddAddressModel @Inject constructor( ChosenNetworks( address = validation.address, matched = matched, - displayed = displayedNetworks(matched, selected), selected = selectedNetworks(matched, selected), ) } @@ -86,7 +85,7 @@ internal class AddAddressModel @Inject constructor( .stateIn( modelScope, SharingStarted.Eagerly, - ChosenNetworks(address = "", matched = emptyList(), displayed = emptyList(), selected = emptyList()), + ChosenNetworks(address = "", matched = emptyList(), selected = emptyList()), ) /** @@ -161,7 +160,6 @@ internal class AddAddressModel @Inject constructor( UpdateAddressValidationTransformer( address = networks.address, matchedBlockchains = networks.matched, - displayedBlockchains = networks.displayed, selectedBlockchains = networks.selected, isMemoInvalid = memoInvalid, duplicateName = duplicate, @@ -263,12 +261,6 @@ internal class AddAddressModel @Inject constructor( ) } - /** What the network block shows: all matched networks until the user narrows them down, then the picked subset. */ - private fun displayedNetworks(matched: List, selected: Set?): List { - if (selected == null) return matched - return matched.filter { it.toNetworkId() in selected } - } - /** * What is actually selected for saving. A single matched network is auto-selected (there is nothing to choose and * the selection screen can't be opened); otherwise the user must pick explicitly before saving. @@ -290,7 +282,6 @@ internal class AddAddressModel @Inject constructor( private data class ChosenNetworks( val address: String, val matched: List, - val displayed: List, val selected: List, ) { /** The first selected network that supports a memo / destination tag, if any. */ diff --git a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addaddress/state/transformers/UpdateAddressInputTransformer.kt b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addaddress/state/transformers/UpdateAddressInputTransformer.kt index d1b7454081..9ec205852e 100644 --- a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addaddress/state/transformers/UpdateAddressInputTransformer.kt +++ b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addaddress/state/transformers/UpdateAddressInputTransformer.kt @@ -19,10 +19,11 @@ internal class UpdateAddressInputTransformer( ) : Transformer { override fun transform(prevState: AddAddressUM): AddAddressUM { - val chosenNetworkState = when { - value.isBlank() -> ChosenNetworkStateUM.Hidden - prevState.chosenNetworkStateUM is ChosenNetworkStateUM.Result -> prevState.chosenNetworkStateUM - else -> ChosenNetworkStateUM.Loading + val chosenNetworkState = when (prevState.chosenNetworkStateUM) { + is ChosenNetworkStateUM.Result, + ChosenNetworkStateUM.SelectNetwork, + -> if (value.isBlank()) ChosenNetworkStateUM.Hidden else prevState.chosenNetworkStateUM + else -> if (value.isBlank()) ChosenNetworkStateUM.Hidden else ChosenNetworkStateUM.Loading } val memoField = if (value.isBlank()) { prevState.memoField.copy(isVisible = false, value = "", isError = false) diff --git a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addaddress/state/transformers/UpdateAddressValidationTransformer.kt b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addaddress/state/transformers/UpdateAddressValidationTransformer.kt index 160e83b3b2..f434d824b2 100644 --- a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addaddress/state/transformers/UpdateAddressValidationTransformer.kt +++ b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addaddress/state/transformers/UpdateAddressValidationTransformer.kt @@ -15,20 +15,19 @@ import kotlinx.collections.immutable.toImmutableList /** * Reflects the result of validating an address (and its memo) in the UI. * - * [matchedBlockchains] are all supported networks the address resolves to. [displayedBlockchains] is what the network - * block shows — all matched networks until the user narrows them down on the SelectNetworks screen, then the picked - * subset. [selectedBlockchains] is what is actually chosen for saving (a single match is auto-selected; for several - * matches the user must pick explicitly). While the address is blank or matches nothing the network selector stays - * [ChosenNetworkStateUM.Hidden]; an invalid (non-empty, matching nothing) address surfaces the error in the field label. + * [matchedBlockchains] are all supported networks the address resolves to. [selectedBlockchains] is what is actually + * chosen for saving (a single match is auto-selected; for several matches the user must pick explicitly on the + * SelectNetworks screen). The network block shows only the selected networks — while several match but none is picked + * yet it prompts with [ChosenNetworkStateUM.SelectNetwork] rather than showing every matched network. While the address + * is blank or matches nothing the network selector stays [ChosenNetworkStateUM.Hidden]; an invalid (non-empty, matching + * nothing) address surfaces the error in the field label. * - * The confirm button is enabled only once at least one network is actually selected (and the memo, if any, is valid) — - * showing the available networks is not the same as selecting them. The memo field is shown when a selected network - * supports transaction extras; [isMemoInvalid] marks a malformed memo. + * The confirm button is enabled only once at least one network is actually selected (and the memo, if any, is valid). + * The memo field is shown when a selected network supports transaction extras; [isMemoInvalid] marks a malformed memo. */ internal class UpdateAddressValidationTransformer( private val address: String, private val matchedBlockchains: List, - private val displayedBlockchains: List, private val selectedBlockchains: List, private val isMemoInvalid: Boolean, private val duplicateName: String?, @@ -40,14 +39,14 @@ internal class UpdateAddressValidationTransformer( val isDuplicate = duplicateName != null val isError = isInvalidAddress || isDuplicate - val chosenNetworkState = if (hasMatch) { - ChosenNetworkStateUM.Result( - networkUMList = displayedBlockchains.map(ChosenNetworkConverter()::convert).toImmutableList(), + val chosenNetworkState = when { + !hasMatch -> ChosenNetworkStateUM.Hidden + selectedBlockchains.isEmpty() -> ChosenNetworkStateUM.SelectNetwork + else -> ChosenNetworkStateUM.Result( + networkUMList = selectedBlockchains.map(ChosenNetworkConverter()::convert).toImmutableList(), // A single matched network leaves nothing to choose, so the selection screen is not opened. isClickable = matchedBlockchains.size > 1, ) - } else { - ChosenNetworkStateUM.Hidden } val label = when { diff --git a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addaddress/ui/AddAddressContent.kt b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addaddress/ui/AddAddressContent.kt index f225531ff8..23a37ae02b 100644 --- a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addaddress/ui/AddAddressContent.kt +++ b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addaddress/ui/AddAddressContent.kt @@ -19,9 +19,8 @@ import com.tangem.core.ui.R import com.tangem.core.ui.components.SpacerH import com.tangem.core.ui.ds.button.TangemButtonType import com.tangem.core.ui.ds.button.TangemButtonUM -import com.tangem.core.ui.ds.image.TangemIconUM -import com.tangem.core.ui.ds.topbar.TangemTopBar import com.tangem.core.ui.ds2.button.TangemButton +import com.tangem.core.ui.ds2.topnavigation.TangemTopNavigation import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.stringResourceSafe @@ -36,19 +35,14 @@ internal fun AddAddressContent(state: AddAddressUM, modifier: Modifier = Modifie modifier = modifier .fillMaxSize() .background(color = TangemTheme.colors3.bg.primary) - .systemBarsPadding(), + .navigationBarsPadding(), horizontalAlignment = Alignment.CenterHorizontally, ) { - TangemTopBar( + TangemTopNavigation( title = resourceReference(R.string.address_book_add_address), - startContent = { - TangemButton( - iconStart = TangemIconUM.Icon(iconRes = R.drawable.ic_back_24), - onClick = state.onBackClick, - size = TangemButton.Size.X11, - variant = TangemButton.Variant.Material, - ) - }, + contentAlign = TangemTopNavigation.ContentAlign.Center, + blurBackground = false, + onBack = state.onBackClick, ) BoxWithConstraints( modifier = Modifier @@ -135,6 +129,7 @@ private fun NetworkSelector(chosenNetworkStateUM: AddAddressUM.ChosenNetworkStat when (networkState) { AddAddressUM.ChosenNetworkStateUM.Hidden -> Box(modifier = Modifier.fillMaxWidth()) AddAddressUM.ChosenNetworkStateUM.Loading, + AddAddressUM.ChosenNetworkStateUM.SelectNetwork, is AddAddressUM.ChosenNetworkStateUM.Result, -> NetworkBlock( modifier = Modifier diff --git a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addaddress/ui/NetworkBlock.kt b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addaddress/ui/NetworkBlock.kt index 4dd21d9cfa..eed88a4a84 100644 --- a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addaddress/ui/NetworkBlock.kt +++ b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addaddress/ui/NetworkBlock.kt @@ -46,8 +46,8 @@ internal fun NetworkBlock( chosenNetworkStateUM: AddAddressUM.ChosenNetworkStateUM, modifier: Modifier = Modifier, ) { - val isClickable = chosenNetworkStateUM is AddAddressUM.ChosenNetworkStateUM.Result && - chosenNetworkStateUM.isClickable + val isClickable = chosenNetworkStateUM is AddAddressUM.ChosenNetworkStateUM.SelectNetwork || + chosenNetworkStateUM is AddAddressUM.ChosenNetworkStateUM.Result && chosenNetworkStateUM.isClickable TangemRow( onClick = if (isClickable) onNetworkSelectClick else null, verticalAlignment = TangemRowVerticalAlignment.Center, @@ -62,6 +62,7 @@ internal fun NetworkBlock( endSlot = { when (chosenNetworkStateUM) { AddAddressUM.ChosenNetworkStateUM.Loading -> TangemLoader(size = TangemLoaderSize.X20) + AddAddressUM.ChosenNetworkStateUM.SelectNetwork -> SelectNetworkTextBlock() is AddAddressUM.ChosenNetworkStateUM.Result -> NetworkRow(chosenNetworkStateUM = chosenNetworkStateUM) AddAddressUM.ChosenNetworkStateUM.Hidden -> Unit } @@ -69,6 +70,18 @@ internal fun NetworkBlock( ) } +@Composable +private fun SelectNetworkTextBlock() { + Row(verticalAlignment = Alignment.CenterVertically) { + Text( + text = stringResourceSafe(R.string.address_book_select_network), + style = TangemTheme.typography3.body.medium, + color = TangemTheme.colors3.text.secondary, + ) + ChevronIcon() + } +} + @Composable private fun NetworkRow(chosenNetworkStateUM: AddAddressUM.ChosenNetworkStateUM.Result) { Row(verticalAlignment = Alignment.CenterVertically) { @@ -120,7 +133,7 @@ private fun OverlappingNetworkIcons(networks: ImmutableList) { modifier = Modifier .padding(start = NetworkIconStep * index) .networkIconRing() - .size(24.dp), + .size(20.dp), ) } if (remaining > 0) { @@ -129,7 +142,7 @@ private fun OverlappingNetworkIcons(networks: ImmutableList) { .padding(start = NetworkIconStep * visible.size) .networkIconRing() .background(color = TangemTheme.colors3.bg.tertiary) - .heightIn(min = 24.dp) + .heightIn(min = 20.dp) .padding(vertical = 2.dp, horizontal = 4.dp), contentAlignment = Alignment.Center, ) { @@ -155,7 +168,7 @@ private fun Modifier.networkIconRing(): Modifier = this private fun ChevronIcon() { Icon( modifier = Modifier - .padding(start = 8.dp) + .padding(start = 4.dp) .size(20.dp), tint = TangemTheme.colors3.icon.secondary, imageVector = ImageVector.vectorResource(id = R.drawable.ic_select_18_24), @@ -168,6 +181,11 @@ private fun ChevronIcon() { private fun Preview_NetworkBlock() { TangemThemePreviewRedesign { Column { + NetworkBlock( + onNetworkSelectClick = {}, + chosenNetworkStateUM = AddAddressUM.ChosenNetworkStateUM.SelectNetwork, + ) + SpacerH12() NetworkBlock( onNetworkSelectClick = {}, chosenNetworkStateUM = AddAddressUM.ChosenNetworkStateUM.Result( diff --git a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addaddress/ui/state/AddAddressUM.kt b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addaddress/ui/state/AddAddressUM.kt index b01a540f2f..77112b9597 100644 --- a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addaddress/ui/state/AddAddressUM.kt +++ b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addaddress/ui/state/AddAddressUM.kt @@ -43,6 +43,12 @@ internal data class AddAddressUM( /** A non-blank address is being validated against the supported networks. */ data object Loading : ChosenNetworkStateUM + /** + * The address matched several networks but the user hasn't picked any yet — the row prompts them to open the + * selection screen instead of showing network icons. + */ + data object SelectNetwork : ChosenNetworkStateUM + /** * A valid address resolved to [networkUMList] (the currently selected networks). [isClickable] is `false` when * the address matched only a single network — there is nothing to choose, so the network-selection screen is diff --git a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addressinfo/ui/AddressInfoBottomSheet.kt b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addressinfo/ui/AddressInfoBottomSheet.kt index 6cd5ad4408..de4bb11485 100644 --- a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addressinfo/ui/AddressInfoBottomSheet.kt +++ b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addressinfo/ui/AddressInfoBottomSheet.kt @@ -19,15 +19,14 @@ import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetType import com.tangem.core.ui.ds.image.TangemIcon import com.tangem.core.ui.ds.image.TangemIconUM -import com.tangem.core.ui.ds.topbar.TangemTopBar -import com.tangem.core.ui.ds.topbar.TangemTopBarType +import com.tangem.core.ui.ds2.button.Close import com.tangem.core.ui.ds2.button.TangemButton +import com.tangem.core.ui.ds2.topnavigation.TangemTopNavigation import com.tangem.core.ui.extensions.* import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreviewRedesign import com.tangem.core.ui.res.generated.icons.Icons import com.tangem.core.ui.res.generated.icons.ic_copy_20 -import com.tangem.core.ui.res.generated.icons.ic_cross_24 import com.tangem.features.addressbook.addressinfo.ui.state.AddressInfoUM import com.tangem.features.addressbook.impl.R @@ -42,16 +41,10 @@ internal fun AddressInfoBottomSheet(state: AddressInfoUM, onDismiss: () -> Unit) type = TangemBottomSheetType.Modal, containerColor = TangemTheme.colors3.bg.secondary, title = { - TangemTopBar( - type = TangemTopBarType.BottomSheet, - endContent = { - TangemButton( - iconStart = TangemIconUM.Icon(imageVector = Icons.ic_cross_24), - onClick = onDismiss, - size = TangemButton.Size.X11, - variant = TangemButton.Variant.Material, - ) - }, + TangemTopNavigation( + windowInsets = WindowInsets(0), + blurBackground = false, + endButton = { TangemButton.Close(onClick = onDismiss) }, ) }, content = { diff --git a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addressselector/ui/AddressSelectorBottomSheet.kt b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addressselector/ui/AddressSelectorBottomSheet.kt index e4b3437e51..190d75fafb 100644 --- a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addressselector/ui/AddressSelectorBottomSheet.kt +++ b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/addressselector/ui/AddressSelectorBottomSheet.kt @@ -21,11 +21,11 @@ import com.tangem.common.ui.account.AccountIconUM import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent +import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetType import com.tangem.core.ui.ds.image.TangemIcon import com.tangem.core.ui.ds.image.TangemIconUM -import com.tangem.core.ui.ds.topbar.TangemTopBar -import com.tangem.core.ui.ds.topbar.TangemTopBarType import com.tangem.core.ui.ds2.button.TangemButton +import com.tangem.core.ui.ds2.topnavigation.TangemTopNavigation import com.tangem.core.ui.ds2.row.TangemRow import com.tangem.core.ui.ds2.row.TangemRowText import com.tangem.core.ui.ds2.row.TangemRowTextRole @@ -51,18 +51,13 @@ internal fun AddressSelectorBottomSheet( content = TangemBottomSheetConfigContent.Empty, ), containerColor = TangemTheme.colors3.bg.primary, + type = TangemBottomSheetType.Modal, title = { - TangemTopBar( + TangemTopNavigation( title = resourceReference(R.string.address_book_choose_address), - type = TangemTopBarType.BottomSheet, - endContent = { - TangemButton( - iconStart = TangemIconUM.Icon(iconRes = R.drawable.ic_close_24), - onClick = onDismiss, - size = TangemButton.Size.X11, - variant = TangemButton.Variant.Material, - ) - }, + contentAlign = TangemTopNavigation.ContentAlign.Center, + blurBackground = false, + onClose = onDismiss, ) }, content = { diff --git a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/common/ui/ContactRow.kt b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/common/ui/ContactRow.kt index ac474389f0..5f1b32ed13 100644 --- a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/common/ui/ContactRow.kt +++ b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/common/ui/ContactRow.kt @@ -26,7 +26,7 @@ internal fun ContactRow(contact: ContactUM, modifier: Modifier = Modifier) { AccountIcon( name = stringReference(contact.name), icon = contact.icon, - size = AccountIconSize.Contact, + size = AccountIconSize.ContactDefault, ) }, titleSlot = { diff --git a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/editcontact/ui/EditContactContent.kt b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/editcontact/ui/EditContactContent.kt index c722cb6e5f..a2ac97bf78 100644 --- a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/editcontact/ui/EditContactContent.kt +++ b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/editcontact/ui/EditContactContent.kt @@ -8,11 +8,13 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.TextAutoSize import androidx.compose.material3.Icon import androidx.compose.material3.Text -import androidx.compose.runtime.Composable +import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.layout.onSizeChanged +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow @@ -28,16 +30,17 @@ import com.tangem.core.ui.components.account.AccountIconSize import com.tangem.core.ui.components.block.BlockCard import com.tangem.core.ui.components.block.TangemBlockCardColors import com.tangem.core.ui.components.fields.AutoSizeTextField +import com.tangem.core.ui.components.haze.hazeSourceTangem import com.tangem.core.ui.ds.button.TangemButtonType import com.tangem.core.ui.ds.button.TangemButtonUM import com.tangem.core.ui.ds.image.TangemIcon import com.tangem.core.ui.ds.image.TangemIconUM -import com.tangem.core.ui.ds.topbar.TangemTopBar import com.tangem.core.ui.ds2.button.TangemButton import com.tangem.core.ui.ds2.row.TangemRow import com.tangem.core.ui.ds2.row.TangemRowText import com.tangem.core.ui.ds2.row.TangemRowTextRole import com.tangem.core.ui.ds2.row.TangemRowVerticalAlignment +import com.tangem.core.ui.ds2.topnavigation.TangemTopNavigation import com.tangem.core.ui.extensions.* import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreviewRedesign @@ -53,31 +56,21 @@ import kotlinx.collections.immutable.toImmutableList @Composable internal fun EditContactContent(state: EditContactUM, modifier: Modifier = Modifier) { - Column( + Box( modifier = modifier .fillMaxSize() - .background(color = TangemTheme.colors3.bg.primary) - .imePadding() - .systemBarsPadding(), - horizontalAlignment = Alignment.CenterHorizontally, + .background(color = TangemTheme.colors3.bg.primary), ) { - TangemTopBar( - modifier = Modifier.statusBarsPadding(), - title = state.title, - endContent = { - TangemButton( - iconStart = TangemIconUM.Icon(iconRes = R.drawable.ic_close_24), - onClick = state.onCloseClick, - size = TangemButton.Size.X11, - variant = TangemButton.Variant.Material, - ) - }, - ) + var topBarHeightPx by remember { mutableIntStateOf(0) } + val topBarHeight = with(LocalDensity.current) { topBarHeightPx.toDp() } BoxWithConstraints( modifier = Modifier - .fillMaxWidth() - .weight(1f), + .fillMaxSize() + .hazeSourceTangem() + .background(color = TangemTheme.colors3.bg.primary) + .imePadding() + .navigationBarsPadding(), ) { val minContentHeight = maxHeight Column( @@ -88,7 +81,8 @@ internal fun EditContactContent(state: EditContactUM, modifier: Modifier = Modif Column( modifier = Modifier .heightIn(min = minContentHeight) - .padding(horizontal = 16.dp, vertical = 12.dp), + .padding(horizontal = 16.dp) + .padding(top = topBarHeight + 12.dp, bottom = 12.dp), ) { Column(verticalArrangement = Arrangement.spacedBy(16.dp)) { ContactSummary(state = state) @@ -110,6 +104,15 @@ internal fun EditContactContent(state: EditContactUM, modifier: Modifier = Modif } } } + + TangemTopNavigation( + modifier = Modifier + .align(Alignment.TopCenter) + .onSizeChanged { topBarHeightPx = it.height }, + title = state.title, + onClose = state.onCloseClick, + contentAlign = TangemTopNavigation.ContentAlign.Center, + ) } } @@ -297,7 +300,6 @@ private fun DeleteContactButton(onClick: () -> Unit, modifier: Modifier = Modifi text = stringResourceSafe(R.string.address_book_delete_contact), style = TangemTheme.typography3.body.medium, color = TangemTheme.colors3.text.status.error, - textAlign = TextAlign.Center, modifier = Modifier .fillMaxWidth() .padding(16.dp), @@ -333,7 +335,7 @@ private fun ContactSummary(state: EditContactUM) { AccountIcon( name = stringReference(avatarName), icon = state.portfolioIcon, - size = AccountIconSize.RedesignLarge, + size = AccountIconSize.ContactLarge, ) SpacerH(28.dp) diff --git a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/state/transformers/UpdateAddressBookListContentTransformer.kt b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/state/transformers/UpdateAddressBookListContentTransformer.kt index d5d13cb810..908725f5b9 100644 --- a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/state/transformers/UpdateAddressBookListContentTransformer.kt +++ b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/state/transformers/UpdateAddressBookListContentTransformer.kt @@ -95,7 +95,10 @@ internal class UpdateAddressBookListContentTransformer( isActive = false, onActiveChange = onActiveChange, onClearClick = onClearQuery, - onCloseClick = { onActiveChange(false) }, + onCloseClick = { + onClearQuery() + onActiveChange(false) + }, ) private fun buildChips(matchingWalletIds: List, effectiveSelected: String?) = buildList { diff --git a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/ui/AddressBookEmptyScreen.kt b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/ui/AddressBookEmptyScreen.kt index 50a6d9a30d..266131cf72 100644 --- a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/ui/AddressBookEmptyScreen.kt +++ b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/ui/AddressBookEmptyScreen.kt @@ -15,14 +15,13 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.tangem.core.ui.R import com.tangem.core.ui.ds.image.TangemIconUM -import com.tangem.core.ui.ds.topbar.TangemTopBar import com.tangem.core.ui.ds2.button.TangemButton +import com.tangem.core.ui.ds2.topnavigation.TangemTopNavigation import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.stringResourceSafe import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreviewRedesign import com.tangem.core.ui.res.generated.icons.Icons -import com.tangem.core.ui.res.generated.icons.ic_chevron_left_20 import com.tangem.core.ui.res.generated.icons.ic_sign_plus_20 @Composable @@ -35,17 +34,11 @@ internal fun AddressBookEmptyScreen( modifier = modifier, horizontalAlignment = Alignment.CenterHorizontally, ) { - TangemTopBar( - modifier = Modifier.statusBarsPadding(), + TangemTopNavigation( title = resourceReference(R.string.address_book_title), - startContent = { - TangemButton( - iconStart = TangemIconUM.Icon(imageVector = Icons.ic_chevron_left_20), - onClick = onBackClick, - size = TangemButton.Size.X11, - variant = TangemButton.Variant.Material, - ) - }, + contentAlign = TangemTopNavigation.ContentAlign.Center, + blurBackground = false, + onBack = onBackClick, ) NoContactInfo(onAddClick = onAddContactClick) } diff --git a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/ui/AddressBookListScreen.kt b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/ui/AddressBookListScreen.kt index 312c482ab2..23cf32ff3c 100644 --- a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/ui/AddressBookListScreen.kt +++ b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/ui/AddressBookListScreen.kt @@ -19,8 +19,8 @@ import androidx.compose.ui.unit.dp import com.tangem.core.ui.R import com.tangem.core.ui.decorations.roundedShapeItemDecoration import com.tangem.core.ui.ds.image.TangemIconUM -import com.tangem.core.ui.ds.topbar.TangemTopBar import com.tangem.core.ui.ds2.button.TangemButton +import com.tangem.core.ui.ds2.topnavigation.TangemTopNavigation import com.tangem.core.ui.ds2.search.TangemSearch import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.stringResourceSafe @@ -44,23 +44,15 @@ internal fun AddressBookListScreen( val density = LocalDensity.current val bottomBarHeight = with(density) { WindowInsets.systemBars.getBottom(this).toDp() } Column(modifier = modifier.fillMaxSize()) { - TangemTopBar( - modifier = Modifier.statusBarsPadding(), + TangemTopNavigation( title = resourceReference(R.string.address_book_title), - startContent = when (state.contentMode) { - is ContentMode.Default -> { - { - TangemButton( - iconStart = TangemIconUM.Icon(imageVector = Icons.ic_chevron_left_20), - onClick = onBackClick, - size = TangemButton.Size.X11, - variant = TangemButton.Variant.Material, - ) - } - } + contentAlign = TangemTopNavigation.ContentAlign.Center, + blurBackground = false, + onBack = when (state.contentMode) { + is ContentMode.Default -> onBackClick ContentMode.Select -> null }, - endContent = { + endButton = { TangemButton( iconStart = TangemIconUM.Icon( imageVector = when (state.contentMode) { diff --git a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/ui/AddressBookListShimmer.kt b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/ui/AddressBookListShimmer.kt index bae537f7ba..5c0c96a357 100644 --- a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/ui/AddressBookListShimmer.kt +++ b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/ui/AddressBookListShimmer.kt @@ -11,30 +11,20 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.tangem.core.ui.R import com.tangem.core.ui.components.RectangleShimmer -import com.tangem.core.ui.ds.image.TangemIconUM -import com.tangem.core.ui.ds.topbar.TangemTopBar -import com.tangem.core.ui.ds2.button.TangemButton import com.tangem.core.ui.ds2.shimmers.ProvideTangemShimmer +import com.tangem.core.ui.ds2.topnavigation.TangemTopNavigation import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreviewRedesign -import com.tangem.core.ui.res.generated.icons.Icons -import com.tangem.core.ui.res.generated.icons.ic_chevron_left_20 @Composable internal fun AddressBookListShimmer(onBackClick: () -> Unit, modifier: Modifier = Modifier) { Column(modifier = modifier.fillMaxSize()) { - TangemTopBar( - modifier = Modifier.statusBarsPadding(), + TangemTopNavigation( title = resourceReference(R.string.address_book_title), - startContent = { - TangemButton( - iconStart = TangemIconUM.Icon(imageVector = Icons.ic_chevron_left_20), - onClick = onBackClick, - size = TangemButton.Size.X11, - variant = TangemButton.Variant.Material, - ) - }, + contentAlign = TangemTopNavigation.ContentAlign.Center, + blurBackground = false, + onBack = onBackClick, ) ProvideTangemShimmer { Column( diff --git a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/selectnetworks/state/transformers/UpdateSelectNetworksInitialStateTransformer.kt b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/selectnetworks/state/transformers/UpdateSelectNetworksInitialStateTransformer.kt index 1eec6bc86e..fa409b0216 100644 --- a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/selectnetworks/state/transformers/UpdateSelectNetworksInitialStateTransformer.kt +++ b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/selectnetworks/state/transformers/UpdateSelectNetworksInitialStateTransformer.kt @@ -16,7 +16,10 @@ internal class UpdateSelectNetworksInitialStateTransformer( searchBar = prevState.searchBar.copy( onQueryChange = onQueryChange, onActiveChange = onActiveChange, - onCloseClick = { onActiveChange(false) }, + onCloseClick = { + onQueryChange("") + onActiveChange(false) + }, onClearClick = { onQueryChange("") }, ), doneButton = prevState.doneButton.copy(onClick = onDoneClick), diff --git a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/selectnetworks/ui/SelectNetworksContent.kt b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/selectnetworks/ui/SelectNetworksContent.kt index fbbb0f0675..859aa8dd7e 100644 --- a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/selectnetworks/ui/SelectNetworksContent.kt +++ b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/selectnetworks/ui/SelectNetworksContent.kt @@ -15,6 +15,7 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.remember @@ -28,16 +29,17 @@ import com.tangem.core.ui.R import com.tangem.core.ui.components.SpacerWMax import com.tangem.core.ui.ds.button.TangemButtonType import com.tangem.core.ui.ds.button.TangemButtonUM -import com.tangem.core.ui.ds.image.TangemIconUM -import com.tangem.core.ui.ds.topbar.TangemTopBar import com.tangem.core.ui.ds2.button.TangemButton import com.tangem.core.ui.ds2.checkbox.TangemCheckmark import com.tangem.core.ui.ds2.search.TangemSearch +import com.tangem.core.ui.ds2.topnavigation.TangemTopNavigation import com.tangem.core.ui.extensions.* import com.tangem.core.ui.haptic.TangemHapticEffect import com.tangem.core.ui.res.LocalHapticManager import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreviewRedesign +import com.tangem.core.ui.res.generated.icons.Icons +import com.tangem.core.ui.res.generated.icons.ic_search_24 import com.tangem.features.addressbook.selectnetworks.ui.state.SelectNetworksUM import com.tangem.features.addressbook.selectnetworks.ui.state.SelectNetworksUM.NetworkItemUM import kotlinx.collections.immutable.persistentListOf @@ -48,18 +50,13 @@ internal fun SelectNetworksContent(state: SelectNetworksUM, modifier: Modifier = modifier = modifier .fillMaxSize() .background(color = TangemTheme.colors3.bg.primary) - .systemBarsPadding(), + .navigationBarsPadding(), ) { - TangemTopBar( + TangemTopNavigation( title = resourceReference(R.string.common_choose_network), - startContent = { - TangemButton( - iconStart = TangemIconUM.Icon(iconRes = R.drawable.ic_back_24), - onClick = state.onBackClick, - size = TangemButton.Size.X11, - variant = TangemButton.Variant.Material, - ) - }, + contentAlign = TangemTopNavigation.ContentAlign.Center, + blurBackground = false, + onBack = state.onBackClick, ) TangemSearch( state = state.searchBar, @@ -67,46 +64,89 @@ internal fun SelectNetworksContent(state: SelectNetworksUM, modifier: Modifier = .fillMaxWidth() .padding(horizontal = 16.dp, vertical = 12.dp), ) - val doneButtonVerticalPadding = 12.dp - val doneButtonAreaHeight = 48.dp + doneButtonVerticalPadding * 2 - Box( + AnimatedContent( + targetState = state.networks.isNotEmpty(), modifier = Modifier .weight(1f) .fillMaxWidth(), - ) { - LazyColumn( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .padding(bottom = doneButtonAreaHeight) - .background( - color = TangemTheme.colors3.bg.secondary, - shape = RoundedCornerShape(24.dp), - ), - contentPadding = PaddingValues(horizontal = 16.dp), - ) { - item { - NetworksHeader( - selectAllButton = state.selectAllButton, - onSelectAllClick = state.onSelectAllClick, - ) - } - items(items = state.networks, key = NetworkItemUM::id) { item -> - NetworkRow(item = item) + ) { hasNetworks -> + Box(modifier = Modifier.fillMaxSize()) { + if (hasNetworks) { + Content(state = state) + } else { + NothingFoundContent(modifier = Modifier.fillMaxSize()) } } - TangemButton( - modifier = Modifier - .align(Alignment.BottomCenter) - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = doneButtonVerticalPadding) - .imePadding(), - onClick = state.doneButton.onClick, - isEnabled = state.doneButton.isEnabled, - size = TangemButton.Size.X12, - text = state.doneButton.text, + } + } +} + +@Composable +private fun BoxScope.Content(state: SelectNetworksUM, modifier: Modifier = Modifier) { + val doneButtonVerticalPadding = 12.dp + val doneButtonAreaHeight = 48.dp + doneButtonVerticalPadding * 2 + LazyColumn( + modifier = modifier + .fillMaxWidth() + .padding(horizontal = 16.dp) + .padding(bottom = doneButtonAreaHeight) + .background( + color = TangemTheme.colors3.bg.secondary, + shape = RoundedCornerShape(24.dp), + ), + contentPadding = PaddingValues(horizontal = 16.dp), + ) { + item { + NetworksHeader( + selectAllButton = state.selectAllButton, + onSelectAllClick = state.onSelectAllClick, ) } + items(items = state.networks, key = NetworkItemUM::id) { item -> + NetworkRow(item = item) + } + } + TangemButton( + modifier = Modifier + .align(Alignment.BottomCenter) + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = doneButtonVerticalPadding) + .imePadding(), + onClick = state.doneButton.onClick, + isEnabled = state.doneButton.isEnabled, + size = TangemButton.Size.X12, + text = state.doneButton.text, + ) +} + +@Composable +private fun NothingFoundContent(modifier: Modifier = Modifier) { + Column( + modifier = modifier + .fillMaxWidth() + .imePadding(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Box( + modifier = Modifier + .size(48.dp) + .background(color = TangemTheme.colors3.bg.opaque.primary, shape = CircleShape), + contentAlignment = Alignment.Center, + ) { + Icon( + imageVector = Icons.ic_search_24, + contentDescription = null, + tint = TangemTheme.colors3.icon.secondary, + modifier = Modifier.size(24.dp), + ) + } + Text( + modifier = Modifier.padding(top = 32.dp), + text = stringResourceSafe(R.string.address_book_search_no_results), + color = TangemTheme.colors3.text.secondary, + style = TangemTheme.typography3.caption.medium, + ) } } diff --git a/features/address-book/impl/src/test/kotlin/com/tangem/features/addressbook/addaddress/model/AddAddressModelTest.kt b/features/address-book/impl/src/test/kotlin/com/tangem/features/addressbook/addaddress/model/AddAddressModelTest.kt index adc273c7b7..ad500b11a5 100644 --- a/features/address-book/impl/src/test/kotlin/com/tangem/features/addressbook/addaddress/model/AddAddressModelTest.kt +++ b/features/address-book/impl/src/test/kotlin/com/tangem/features/addressbook/addaddress/model/AddAddressModelTest.kt @@ -241,7 +241,7 @@ internal class AddAddressModelTest { } @Test - fun `GIVEN address matching several networks WHEN validated THEN all shown AND clickable`() = runTest { + fun `GIVEN address matching several networks WHEN validated THEN prompts to select network`() = runTest { // Arrange every { supportedNetworksMatcher.match(ADDRESS) } returns listOf(Blockchain.Ethereum, Blockchain.BSC) val model = createModel(testScope = this) @@ -251,11 +251,8 @@ internal class AddAddressModelTest { model.state.value.onAddressChange(ADDRESS) advanceUntilIdle() - // Assert — all matched networks are shown by default; the block opens the selection screen to narrow them. - val result = model.state.value.chosenNetworkStateUM as ChosenNetworkStateUM.Result - assertThat(result.networkUMList.map { it.networkName }) - .containsExactly(Blockchain.Ethereum.fullName, Blockchain.BSC.fullName) - assertThat(result.isClickable).isTrue() + // Assert — nothing is selected yet, so the block only prompts the user to open the selection screen. + assertThat(model.state.value.chosenNetworkStateUM).isEqualTo(ChosenNetworkStateUM.SelectNetwork) } @Test @@ -348,19 +345,19 @@ internal class AddAddressModelTest { } @Test - fun `GIVEN resolved networks WHEN address edited THEN keeps result without flashing loading`() = runTest { - // Arrange + fun `GIVEN resolved networks WHEN address edited THEN keeps state without flashing loading`() = runTest { + // Arrange — several networks match, so the resolved state is the "select network" prompt. every { supportedNetworksMatcher.match(any()) } returns listOf(Blockchain.Ethereum, Blockchain.BSC) val model = createModel(testScope = this) model.state.value.onAddressChange(ADDRESS) advanceUntilIdle() - assertThat(model.state.value.chosenNetworkStateUM).isInstanceOf(ChosenNetworkStateUM.Result::class.java) + assertThat(model.state.value.chosenNetworkStateUM).isEqualTo(ChosenNetworkStateUM.SelectNetwork) // Act — keep typing; validation is pending again. model.state.value.onAddressChange(ADDRESS + "00") - // Assert — the resolved networks stay on screen (no spinner), but the button is blocked while validating. - assertThat(model.state.value.chosenNetworkStateUM).isInstanceOf(ChosenNetworkStateUM.Result::class.java) + // Assert — the resolved state stays on screen (no spinner), but the button is blocked while validating. + assertThat(model.state.value.chosenNetworkStateUM).isEqualTo(ChosenNetworkStateUM.SelectNetwork) assertThat(model.state.value.buttonUM.isEnabled).isFalse() } diff --git a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/portfolioselector/ui/PortfolioSelectorBS.kt b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/portfolioselector/ui/PortfolioSelectorBS.kt index 14db910070..abe307d960 100644 --- a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/portfolioselector/ui/PortfolioSelectorBS.kt +++ b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/portfolioselector/ui/PortfolioSelectorBS.kt @@ -9,15 +9,15 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp +import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent -import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet -import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle +import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetType +import com.tangem.core.ui.ds2.topnavigation.TangemTopNavigation import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview import com.tangem.core.ui.res.TangemThemePreviewRedesign -import com.tangem.features.commonfeatures.impl.R import com.tangem.features.commonfeatures.impl.portfolioselector.entity.PortfolioSelectorUM @Composable @@ -27,20 +27,21 @@ internal fun PortfolioSelectorBS( onBack: () -> Unit, modifier: Modifier = Modifier, ) { - TangemModalBottomSheet( + TangemBottomSheet( config = TangemBottomSheetConfig( isShown = true, onDismissRequest = onDismiss, content = TangemBottomSheetConfigContent.Empty, ), onBack = onBack, - scrollableContent = false, - containerColor = TangemTheme.colors.background.tertiary, + containerColor = TangemTheme.colors3.bg.primary, + type = TangemBottomSheetType.Modal, title = { - TangemModalBottomSheetTitle( + TangemTopNavigation( title = state.title, - startIconRes = R.drawable.ic_back_24, - onStartClick = onBack, + contentAlign = TangemTopNavigation.ContentAlign.Center, + blurBackground = false, + onClose = onDismiss, ) }, content = { diff --git a/features/send/impl/src/main/java/com/tangem/features/send/subcomponents/destination/ui/DestinationBlock.kt b/features/send/impl/src/main/java/com/tangem/features/send/subcomponents/destination/ui/DestinationBlock.kt index 12175f963f..abab591f14 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/subcomponents/destination/ui/DestinationBlock.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/subcomponents/destination/ui/DestinationBlock.kt @@ -88,15 +88,15 @@ private fun AddressWithMemoBlock( val contactIcon = address.contactIcon Column(modifier = Modifier.weight(1f)) { Text( - text = contactName ?: address.value, + text = address.value, style = TangemTheme.typography.body1, color = TangemTheme.colors.text.primary1, modifier = Modifier.testTag(SendConfirmScreenTestTags.RECIPIENT_ADDRESS), ) - val recipient = if (contactName != null) address.value else address.briefBlockchainAddress - if (!recipient.isNullOrBlank()) { + val blockchainAddress = address.briefBlockchainAddress + if (!blockchainAddress.isNullOrBlank()) { Text( - text = recipient, + text = blockchainAddress, style = TangemTheme.typography.caption2, color = TangemTheme.colors.text.tertiary, modifier = Modifier.testTag(SendConfirmScreenTestTags.BLOCKCHAIN_ADDRESS), @@ -107,7 +107,7 @@ private fun AddressWithMemoBlock( AccountIcon( name = stringReference(contactName), icon = contactIcon, - size = AccountIconSize.Medium, + size = AccountIconSize.ContactDefault, modifier = Modifier.testTag(SendConfirmScreenTestTags.RECIPIENT_ADDRESS_ICON), ) } else {