Updated on 2026-08-14
This commit is contained in:
parent
22ad2ddc67
commit
281b5ec956
13 changed files with 371 additions and 20 deletions
|
|
@ -206,6 +206,7 @@ internal class DefaultSendComponent @AssistedInject constructor(
|
|||
childStack = childStack,
|
||||
)
|
||||
},
|
||||
isRedesignEnabled = model.uiState.value.isRedesignEnabled,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
|
|
@ -225,6 +226,7 @@ internal class DefaultSendComponent @AssistedInject constructor(
|
|||
return if (sendAmount != null && destinationAddress != null &&
|
||||
feeCryptoCurrencyStatus != null && cryptoCurrencyStatus != null
|
||||
) {
|
||||
// TODO Apply new component [REDACTED_TASK_KEY]
|
||||
SendFeeComponent(
|
||||
appComponentContext = factoryContext,
|
||||
params = SendFeeComponentParams.FeeParams(
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ internal class SendConfirmComponent(
|
|||
appCurrency = params.appCurrency,
|
||||
blockClickEnableFlow = blockClickEnableFlow.asStateFlow(),
|
||||
predefinedValues = params.predefinedValues,
|
||||
isRedesignEnabled = model.uiState.value.isRedesignEnabled,
|
||||
),
|
||||
onResult = model::onAmountResult,
|
||||
onClick = model::showEditAmount,
|
||||
|
|
|
|||
|
|
@ -454,6 +454,7 @@ internal class SendConfirmModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
@Suppress("LongMethod")
|
||||
private fun configConfirmNavigation() {
|
||||
combine(
|
||||
flow = uiState,
|
||||
|
|
@ -470,7 +471,11 @@ internal class SendConfirmModel @Inject constructor(
|
|||
id = R.string.send_summary_title,
|
||||
formatArgs = wrappedList(params.cryptoCurrencyStatus.currency.name),
|
||||
),
|
||||
subtitle = amountUM?.title,
|
||||
subtitle = if (uiState.value.isRedesignEnabled) {
|
||||
null
|
||||
} else {
|
||||
amountUM?.title
|
||||
},
|
||||
backIconRes = R.drawable.ic_close_24,
|
||||
backIconClick = {
|
||||
analyticsEventHandler.send(
|
||||
|
|
|
|||
|
|
@ -98,8 +98,13 @@ private fun LazyListScope.blocks(
|
|||
modifier = Modifier.padding(vertical = 12.dp),
|
||||
)
|
||||
}
|
||||
destinationBlockComponent.Content(modifier = Modifier)
|
||||
amountBlockComponent.Content(modifier = Modifier)
|
||||
if (uiState.isRedesignEnabled) {
|
||||
amountBlockComponent.Content(modifier = Modifier)
|
||||
destinationBlockComponent.Content(modifier = Modifier)
|
||||
} else {
|
||||
destinationBlockComponent.Content(modifier = Modifier)
|
||||
amountBlockComponent.Content(modifier = Modifier)
|
||||
}
|
||||
feeBlockComponent.Content(modifier = Modifier)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -364,5 +364,6 @@ internal class SendModel @Inject constructor(
|
|||
feeUM = FeeUM.Empty(),
|
||||
confirmUM = ConfirmUM.Empty,
|
||||
navigationUM = NavigationUM.Empty,
|
||||
isRedesignEnabled = sendFeatureToggles.isSendRedesignEnabled,
|
||||
)
|
||||
}
|
||||
|
|
@ -12,4 +12,5 @@ internal data class SendUM(
|
|||
val feeUM: FeeUM,
|
||||
val confirmUM: ConfirmUM,
|
||||
val navigationUM: NavigationUM,
|
||||
val isRedesignEnabled: Boolean,
|
||||
)
|
||||
|
|
@ -6,6 +6,7 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.common.ui.amountScreen.models.AmountState
|
||||
import com.tangem.common.ui.amountScreen.ui.AmountBlock
|
||||
import com.tangem.common.ui.amountScreen.ui.AmountBlockV2
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
|
|
@ -37,11 +38,24 @@ internal class SendAmountBlockComponent(
|
|||
val state by model.uiState.collectAsStateWithLifecycle()
|
||||
val isClickEnabled by params.blockClickEnableFlow.collectAsStateWithLifecycle()
|
||||
|
||||
AmountBlock(
|
||||
amountState = state,
|
||||
isClickDisabled = !isClickEnabled,
|
||||
isEditingDisabled = params.predefinedValues is PredefinedValues.Content.Deeplink,
|
||||
onClick = onClick,
|
||||
)
|
||||
if (params.isRedesignEnabled) {
|
||||
val amountState = state as? AmountState.Data ?: return
|
||||
|
||||
AmountBlockV2(
|
||||
amountState = state,
|
||||
currencyIconState = amountState.tokenIconState,
|
||||
isClickDisabled = !isClickEnabled,
|
||||
isEditingDisabled = params.predefinedValues is PredefinedValues.Content.Deeplink,
|
||||
onClick = onClick,
|
||||
modifier = modifier,
|
||||
)
|
||||
} else {
|
||||
AmountBlock(
|
||||
amountState = state,
|
||||
isClickDisabled = !isClickEnabled,
|
||||
isEditingDisabled = params.predefinedValues is PredefinedValues.Content.Deeplink,
|
||||
onClick = onClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@ internal sealed class SendAmountComponentParams {
|
|||
abstract val appCurrency: AppCurrency
|
||||
abstract val cryptoCurrencyStatus: CryptoCurrencyStatus
|
||||
abstract val predefinedValues: PredefinedValues
|
||||
abstract val isRedesignEnabled: Boolean
|
||||
|
||||
data class AmountParams(
|
||||
override val state: AmountState,
|
||||
|
|
@ -26,6 +27,7 @@ internal sealed class SendAmountComponentParams {
|
|||
override val appCurrency: AppCurrency,
|
||||
override val cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
override val predefinedValues: PredefinedValues,
|
||||
override val isRedesignEnabled: Boolean,
|
||||
val callback: ModelCallback,
|
||||
val currentRoute: Flow<CommonSendRoute.Amount>,
|
||||
val isBalanceHidingFlow: StateFlow<Boolean>,
|
||||
|
|
@ -40,6 +42,7 @@ internal sealed class SendAmountComponentParams {
|
|||
override val appCurrency: AppCurrency,
|
||||
override val cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
override val predefinedValues: PredefinedValues,
|
||||
override val isRedesignEnabled: Boolean,
|
||||
val blockClickEnableFlow: StateFlow<Boolean>,
|
||||
) : SendAmountComponentParams()
|
||||
}
|
||||
|
|
@ -40,6 +40,7 @@ internal class SendDestinationBlockComponent(
|
|||
destinationUM = state,
|
||||
isClickDisabled = !isClickEnabled,
|
||||
isEditingDisabled = params.predefinedValues is PredefinedValues.Content.Deeplink,
|
||||
isRedesignEnabled = (params.state as? DestinationUM.Content)?.isRedesignEnabled ?: false,
|
||||
onClick = onClick,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,38 @@
|
|||
package com.tangem.features.send.v2.subcomponents.destination.ui
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
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.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import com.tangem.core.ui.components.icons.identicon.IdentIcon
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.send.v2.impl.R
|
||||
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationRecipientListUM
|
||||
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationTextFieldUM
|
||||
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationUM
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
@Composable
|
||||
internal fun DestinationBlock(
|
||||
destinationUM: DestinationUM,
|
||||
isClickDisabled: Boolean,
|
||||
isEditingDisabled: Boolean,
|
||||
isRedesignEnabled: Boolean,
|
||||
onClick: () -> Unit,
|
||||
) {
|
||||
if (destinationUM !is DestinationUM.Content) return
|
||||
|
|
@ -33,8 +45,15 @@ internal fun DestinationBlock(
|
|||
.clickable(enabled = !isClickDisabled && !isEditingDisabled, onClick = onClick)
|
||||
.padding(TangemTheme.dimens.spacing12),
|
||||
) {
|
||||
AddressBlock(destinationUM.addressTextField)
|
||||
MemoBlock(destinationUM.memoTextField)
|
||||
if (isRedesignEnabled) {
|
||||
AddressWithMemoBlock(
|
||||
address = destinationUM.addressTextField,
|
||||
memo = destinationUM.memoTextField,
|
||||
)
|
||||
} else {
|
||||
AddressBlock(destinationUM.addressTextField)
|
||||
MemoBlock(destinationUM.memoTextField)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -84,4 +103,124 @@ private fun MemoBlock(memo: DestinationTextFieldUM.RecipientMemo?) {
|
|||
modifier = Modifier.padding(top = TangemTheme.dimens.spacing8),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun AddressWithMemoBlock(
|
||||
address: DestinationTextFieldUM.RecipientAddress,
|
||||
memo: DestinationTextFieldUM.RecipientMemo?,
|
||||
) {
|
||||
Text(
|
||||
text = stringResourceSafe(R.string.send_to_address),
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing24),
|
||||
modifier = Modifier.padding(top = TangemTheme.dimens.spacing8),
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.weight(1f),
|
||||
text = address.value,
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
IdentIcon(
|
||||
address = address.value,
|
||||
modifier = Modifier
|
||||
.size(TangemTheme.dimens.size36)
|
||||
.clip(RoundedCornerShape(TangemTheme.dimens.radius18))
|
||||
.background(TangemTheme.colors.background.tertiary),
|
||||
)
|
||||
}
|
||||
if (memo != null && memo.value.isNotBlank()) {
|
||||
Text(
|
||||
text = stringResourceSafe(R.string.send_memo, memo.value),
|
||||
style = TangemTheme.typography.caption2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
modifier = Modifier.padding(top = TangemTheme.dimens.spacing8),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun DestinationBlockPreview(
|
||||
@PreviewParameter(DestinationBlockPreviewProvider::class) state: DestinationUM.Content,
|
||||
) {
|
||||
TangemThemePreview {
|
||||
DestinationBlock(
|
||||
destinationUM = state,
|
||||
isClickDisabled = false,
|
||||
isEditingDisabled = false,
|
||||
isRedesignEnabled = state.isRedesignEnabled,
|
||||
onClick = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class DestinationBlockPreviewProvider : PreviewParameterProvider<DestinationUM.Content> {
|
||||
override val values: Sequence<DestinationUM.Content>
|
||||
get() = sequenceOf(
|
||||
DestinationUM.Content(
|
||||
isPrimaryButtonEnabled = true,
|
||||
addressTextField = DestinationTextFieldUM.RecipientAddress(
|
||||
value = "0x34B4492A412D84A6E606288f3Bd714b89135D4dE",
|
||||
keyboardOptions = KeyboardOptions.Default,
|
||||
placeholder = TextReference.Str("Enter address"),
|
||||
label = TextReference.Str("Recipient Address"),
|
||||
isError = false,
|
||||
error = null,
|
||||
isValuePasted = false,
|
||||
),
|
||||
memoTextField = DestinationTextFieldUM.RecipientMemo(
|
||||
value = "Test memo for transaction",
|
||||
keyboardOptions = KeyboardOptions.Default,
|
||||
placeholder = TextReference.Str("Enter memo (optional)"),
|
||||
label = TextReference.Str("Memo"),
|
||||
isError = false,
|
||||
error = null,
|
||||
disabledText = TextReference.Str("Memo disabled"),
|
||||
isEnabled = true,
|
||||
isValuePasted = false,
|
||||
),
|
||||
recent = emptyList<DestinationRecipientListUM>().toImmutableList(),
|
||||
wallets = emptyList<DestinationRecipientListUM>().toImmutableList(),
|
||||
networkName = "Ethereum",
|
||||
isValidating = false,
|
||||
isInitialized = true,
|
||||
isRedesignEnabled = false,
|
||||
),
|
||||
DestinationUM.Content(
|
||||
isPrimaryButtonEnabled = true,
|
||||
addressTextField = DestinationTextFieldUM.RecipientAddress(
|
||||
value = "0x34B4492A412D84A6E606288f3Bd714b89135D4dE",
|
||||
keyboardOptions = KeyboardOptions.Default,
|
||||
placeholder = TextReference.Str("Enter address"),
|
||||
label = TextReference.Str("Recipient Address"),
|
||||
isError = false,
|
||||
error = null,
|
||||
isValuePasted = false,
|
||||
),
|
||||
memoTextField = DestinationTextFieldUM.RecipientMemo(
|
||||
value = "Test memo for transaction",
|
||||
keyboardOptions = KeyboardOptions.Default,
|
||||
placeholder = TextReference.Str("Enter memo (optional)"),
|
||||
label = TextReference.Str("Memo"),
|
||||
isError = false,
|
||||
error = null,
|
||||
disabledText = TextReference.Str("Memo disabled"),
|
||||
isEnabled = true,
|
||||
isValuePasted = false,
|
||||
),
|
||||
recent = emptyList<DestinationRecipientListUM>().toImmutableList(),
|
||||
wallets = emptyList<DestinationRecipientListUM>().toImmutableList(),
|
||||
networkName = "Ethereum",
|
||||
isValidating = false,
|
||||
isInitialized = true,
|
||||
isRedesignEnabled = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue