Updated on 2026-08-14

This commit is contained in:
Tangem 2025-07-03 17:25:02 +05:00
parent a1d92a5448
commit 0142f675ad
12 changed files with 428 additions and 55 deletions

View file

@ -18,6 +18,11 @@ internal sealed class CommonSendRoute : Route {
override val isEditMode: Boolean = true
}
@Serializable
data object ConfirmSuccess : CommonSendRoute() {
override val isEditMode: Boolean = false
}
@Serializable
data class Destination(
override val isEditMode: Boolean,

View file

@ -6,8 +6,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import com.arkivanov.decompose.extensions.compose.stack.Children
import com.arkivanov.decompose.extensions.compose.stack.animation.slide
import com.arkivanov.decompose.extensions.compose.stack.animation.stackAnimation
import com.arkivanov.decompose.extensions.compose.stack.animation.*
import com.arkivanov.decompose.router.stack.ChildStack
import com.tangem.common.ui.navigationButtons.NavigationUM
import com.tangem.core.ui.components.appbar.AppBarWithBackButtonAndIcon
@ -15,6 +14,8 @@ import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.features.send.v2.common.CommonSendRoute
import com.tangem.features.send.v2.send.confirm.SendConfirmComponent
import com.tangem.features.send.v2.send.success.SendConfirmSuccessComponent
@Composable
internal fun SendContent(
@ -32,12 +33,20 @@ internal fun SendContent(
SendAppBar(navigationUM = navigationUM)
Children(
stack = stackState,
animation = stackAnimation(slide()),
animation = stackAnimation { child ->
when (child.instance) {
is SendConfirmSuccessComponent -> fade(minAlpha = 1.0f)
is SendConfirmComponent -> fade()
else -> slide()
}
},
modifier = Modifier.weight(1f),
) {
it.instance.Content(Modifier.weight(1f))
}
SendNavigationButtons(navigationUM = navigationUM)
if (stackState.active.configuration != CommonSendRoute.ConfirmSuccess) {
SendNavigationButtons(navigationUM = navigationUM)
}
}
}

View file

@ -14,6 +14,7 @@ import com.arkivanov.decompose.value.subscribe
import com.tangem.common.ui.amountScreen.models.AmountState
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.context.child
import com.tangem.core.decompose.context.childByContext
import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.core.decompose.navigation.inner.InnerRouter
@ -30,11 +31,14 @@ import com.tangem.features.send.v2.common.utils.safeNextClick
import com.tangem.features.send.v2.impl.R
import com.tangem.features.send.v2.send.confirm.SendConfirmComponent
import com.tangem.features.send.v2.send.model.SendModel
import com.tangem.features.send.v2.send.success.SendConfirmSuccessComponent
import com.tangem.features.send.v2.subcomponents.amount.SendAmountComponent
import com.tangem.features.send.v2.subcomponents.amount.SendAmountComponentParams
import com.tangem.features.send.v2.subcomponents.fee.SendFeeBlockComponent
import com.tangem.features.send.v2.subcomponents.destination.DefaultSendDestinationComponent
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationComponentParams
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
import com.tangem.features.send.v2.subcomponents.destination.DefaultSendDestinationBlockComponent
import com.tangem.features.send.v2.subcomponents.fee.SendFeeComponent
import com.tangem.features.send.v2.subcomponents.fee.SendFeeComponentParams
import dagger.assisted.Assisted
@ -44,6 +48,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.launch
@Suppress("LargeClass")
internal class DefaultSendComponent @AssistedInject constructor(
@Assisted appComponentContext: AppComponentContext,
@Assisted private val params: SendComponent.Params,
@ -142,7 +147,8 @@ internal class DefaultSendComponent @AssistedInject constructor(
is CommonSendRoute.Destination -> getDestinationComponent(factoryContext, route)
is CommonSendRoute.Amount -> getAmountComponent(factoryContext, route)
is CommonSendRoute.Fee -> getFeeComponent(factoryContext)
CommonSendRoute.Confirm -> getConfirmComponent(factoryContext)
is CommonSendRoute.Confirm -> getConfirmComponent(factoryContext)
is CommonSendRoute.ConfirmSuccess -> getConfirmSuccessComponent(factoryContext)
}
private fun getDestinationComponent(
@ -288,6 +294,9 @@ internal class DefaultSendComponent @AssistedInject constructor(
callback = model,
predefinedValues = model.predefinedValues,
onLoadFee = model::loadFee,
onSendTransaction = {
innerRouter.replaceAll(CommonSendRoute.ConfirmSuccess)
},
),
)
} else {
@ -296,6 +305,69 @@ internal class DefaultSendComponent @AssistedInject constructor(
}
}
private fun getConfirmSuccessComponent(factoryContext: AppComponentContext): ComposableContentComponent {
val state = model.uiState.value
val sendAmount = (state.amountUM as? AmountState.Data)?.amountTextField?.cryptoAmount?.value
val destinationAddress = (state.destinationUM as? DestinationUM.Content)?.addressTextField?.value
val txUrl = (state.confirmUM as? ConfirmUM.Success)?.txUrl
val cryptoCurrencyStatus = model.cryptoCurrencyStatusFlow.value
val feeCryptoCurrencyStatus = model.feeCryptoCurrencyStatusFlow.value
if (sendAmount == null ||
destinationAddress == null ||
txUrl == null
) {
model.showAlertError()
return getStubComponent()
}
val destinationBlockComponent =
DefaultSendDestinationBlockComponent(
appComponentContext = child("sendConfirmDestinationBlock"),
params = SendDestinationComponentParams.DestinationBlockParams(
state = model.uiState.value.destinationUM,
analyticsCategoryName = analyticCategoryName,
userWalletId = model.userWallet.walletId,
cryptoCurrency = cryptoCurrencyStatus.currency,
blockClickEnableFlow = MutableStateFlow(true),
predefinedValues = model.predefinedValues,
),
onResult = { },
onClick = {},
)
val feeBlockComponent = SendFeeBlockComponent(
appComponentContext = child("sendConfirmFeeBlock"),
params = SendFeeComponentParams.FeeBlockParams(
state = model.uiState.value.feeUM,
analyticsCategoryName = analyticCategoryName,
userWallet = model.userWallet,
cryptoCurrencyStatus = cryptoCurrencyStatus,
feeCryptoCurrencyStatus = feeCryptoCurrencyStatus,
appCurrency = model.appCurrency,
sendAmount = sendAmount,
destinationAddress = destinationAddress,
blockClickEnableFlow = MutableStateFlow(true),
onLoadFee = model::loadFee,
),
onResult = { },
onClick = {},
)
return SendConfirmSuccessComponent(
appComponentContext = factoryContext,
params = SendConfirmSuccessComponent.Params(
sendUMFlow = model.uiState,
feeBlockComponent = feeBlockComponent,
destinationBlockComponent = destinationBlockComponent,
analyticsCategoryName = analyticCategoryName,
currentRoute = currentRoute,
txUrl = txUrl,
callback = model,
),
)
}
private fun getStubComponent() = StubComponent()
class StubComponent : ComposableContentComponent {

View file

@ -155,6 +155,7 @@ internal class SendConfirmComponent(
val isBalanceHidingFlow: StateFlow<Boolean>,
val predefinedValues: PredefinedValues,
val onLoadFee: suspend () -> Either<GetFeeError, TransactionFee>,
val onSendTransaction: () -> Unit,
)
interface ModelCallback {

View file

@ -291,6 +291,7 @@ internal class SendConfirmModel @Inject constructor(
isShowTapHelp = isShowTapHelp,
walletName = stringReference(userWallet.name),
).transform(uiState.value.confirmUM),
confirmData = confirmData,
)
}
updateConfirmNotifications()
@ -384,6 +385,10 @@ internal class SendConfirmModel @Inject constructor(
addTokenToWalletIfNeeded()
sendBalanceUpdater.scheduleUpdates()
sendAnalyticHelper.sendSuccessAnalytics(cryptoCurrency, uiState.value)
if (uiState.value.isRedesignEnabled) {
params.callback.onResult(uiState.value)
params.onSendTransaction()
}
},
)
}
@ -462,23 +467,35 @@ internal class SendConfirmModel @Inject constructor(
flow = uiState,
flow2 = params.currentRoute,
transform = { state, route -> state to route },
).filter { it.second is CommonSendRoute.Confirm }.onEach { (state, _) ->
).filter {
it.second is CommonSendRoute.Confirm
}.onEach { (state, _) ->
val amountUM = state.amountUM as? AmountState.Data
val confirmUM = state.confirmUM
val isReadyToSend = confirmUM is ConfirmUM.Content && !confirmUM.isSending
params.callback.onResult(
state.copy(
navigationUM = NavigationUM.Content(
title = resourceReference(
id = R.string.send_summary_title,
formatArgs = wrappedList(params.cryptoCurrencyStatus.currency.name),
),
title = if (state.isRedesignEnabled) {
stringReference("")
} else {
resourceReference(
id = R.string.send_summary_title,
formatArgs = wrappedList(params.cryptoCurrencyStatus.currency.name),
)
},
subtitle = if (uiState.value.isRedesignEnabled) {
null
} else {
amountUM?.title
},
backIconRes = R.drawable.ic_close_24,
backIconRes = if (state.isRedesignEnabled) {
when (confirmUM) {
is ConfirmUM.Success -> R.drawable.ic_close_24
else -> R.drawable.ic_back_24
}
} else {
R.drawable.ic_close_24
},
backIconClick = {
analyticsEventHandler.send(
CommonSendAnalyticEvents.CloseButtonClicked(
@ -490,31 +507,7 @@ internal class SendConfirmModel @Inject constructor(
)
appRouter.pop()
},
primaryButton = NavigationButton(
textReference = when (confirmUM) {
is ConfirmUM.Success -> resourceReference(R.string.common_close)
is ConfirmUM.Content -> if (confirmUM.isSending) {
resourceReference(R.string.send_sending)
} else {
resourceReference(R.string.common_send)
}
else -> resourceReference(R.string.common_send)
},
iconRes = R.drawable.ic_tangem_24.takeIf { isReadyToSend },
isEnabled = confirmUM.isPrimaryButtonEnabled,
isHapticClick = isReadyToSend,
onClick = {
when (confirmUM) {
is ConfirmUM.Success -> appRouter.pop()
is ConfirmUM.Content -> if (confirmUM.isSending) {
return@NavigationButton
} else {
onSendClick()
}
else -> return@NavigationButton
}
},
),
primaryButton = primaryButtonUM(),
prevButton = null,
secondaryPairButtonsUM = (
NavigationButton(
@ -533,6 +526,36 @@ internal class SendConfirmModel @Inject constructor(
}.launchIn(modelScope)
}
private fun primaryButtonUM(): NavigationButton {
val confirmUM = uiState.value.confirmUM
val isReadyToSend = confirmUM is ConfirmUM.Content && !confirmUM.isSending
return NavigationButton(
textReference = when (confirmUM) {
is ConfirmUM.Success -> resourceReference(R.string.common_close)
is ConfirmUM.Content -> if (confirmUM.isSending) {
resourceReference(R.string.send_sending)
} else {
resourceReference(R.string.common_send)
}
else -> resourceReference(R.string.common_send)
},
iconRes = R.drawable.ic_tangem_24.takeIf { isReadyToSend },
isEnabled = confirmUM.isPrimaryButtonEnabled,
isHapticClick = isReadyToSend,
onClick = {
when (confirmUM) {
is ConfirmUM.Success -> appRouter.pop()
is ConfirmUM.Content -> if (confirmUM.isSending) {
return@NavigationButton
} else {
onSendClick()
}
else -> return@NavigationButton
}
},
)
}
private companion object {
const val CHECK_FEE_UPDATE_DELAY = 10_000L
}

View file

@ -82,31 +82,36 @@ private fun LazyListScope.blocks(
) {
item(key = BLOCKS_KEY) {
Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
AnimatedVisibility(
visible = uiState.confirmUM is ConfirmUM.Success,
modifier = Modifier.padding(vertical = TangemTheme.dimens.spacing12),
) {
val wrappedConfirmUM = remember(this) { uiState.confirmUM as ConfirmUM.Success }
TransactionDoneTitle(
title = resourceReference(R.string.sent_transaction_sent_title),
subtitle = resourceReference(
R.string.send_date_format,
wrappedList(
wrappedConfirmUM.transactionDate.toTimeFormat(DateTimeFormatters.dateFormatter),
wrappedConfirmUM.transactionDate.toTimeFormat(),
),
),
modifier = Modifier.padding(vertical = 12.dp),
)
}
if (uiState.isRedesignEnabled) {
amountBlockComponent.Content(modifier = Modifier)
destinationBlockComponent.Content(modifier = Modifier)
} else {
TransactionDoneTitleAnimated(uiState)
destinationBlockComponent.Content(modifier = Modifier)
amountBlockComponent.Content(modifier = Modifier)
}
feeBlockComponent.Content(modifier = Modifier)
}
}
}
@Composable
internal fun TransactionDoneTitleAnimated(uiState: SendUM) {
AnimatedVisibility(
visible = uiState.confirmUM is ConfirmUM.Success,
modifier = Modifier.padding(vertical = 12.dp),
) {
val wrappedConfirmUM = remember(this) { uiState.confirmUM as ConfirmUM.Success }
TransactionDoneTitle(
title = resourceReference(R.string.sent_transaction_sent_title),
subtitle = resourceReference(
R.string.send_date_format,
wrappedList(
wrappedConfirmUM.transactionDate.toTimeFormat(DateTimeFormatters.dateFormatter),
wrappedConfirmUM.transactionDate.toTimeFormat(),
),
),
modifier = Modifier.padding(vertical = 12.dp),
)
}
}

View file

@ -4,6 +4,7 @@ import com.tangem.core.decompose.di.ModelComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.send.v2.send.confirm.model.SendConfirmModel
import com.tangem.features.send.v2.send.model.SendModel
import com.tangem.features.send.v2.send.success.model.SendConfirmSuccessModel
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
@ -23,4 +24,9 @@ internal interface CommonSendModelModule {
@IntoMap
@ClassKey(SendConfirmModel::class)
fun provideSendConfirmModel(model: SendConfirmModel): Model
@Binds
@IntoMap
@ClassKey(SendConfirmSuccessModel::class)
fun provideSendConfirmSuccessModel(model: SendConfirmSuccessModel): Model
}

View file

@ -46,6 +46,7 @@ import com.tangem.features.send.v2.common.CommonSendRoute
import com.tangem.features.send.v2.common.SendConfirmAlertFactory
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
import com.tangem.features.send.v2.send.confirm.SendConfirmComponent
import com.tangem.features.send.v2.send.success.SendConfirmSuccessComponent
import com.tangem.features.send.v2.send.ui.state.SendUM
import com.tangem.features.send.v2.subcomponents.amount.SendAmountComponent
import com.tangem.features.send.v2.subcomponents.amount.SendAmountUpdateQRTrigger
@ -65,7 +66,8 @@ internal interface SendComponentCallback :
SendAmountComponent.ModelCallback,
SendFeeComponent.ModelCallback,
SendDestinationComponent.ModelCallback,
SendConfirmComponent.ModelCallback
SendConfirmComponent.ModelCallback,
SendConfirmSuccessComponent.ModelCallback
@Stable
@ModelScoped
@ -382,5 +384,6 @@ internal class SendModel @Inject constructor(
confirmUM = ConfirmUM.Empty,
navigationUM = NavigationUM.Empty,
isRedesignEnabled = sendFeatureToggles.isSendRedesignEnabled,
confirmData = null,
)
}

View file

@ -0,0 +1,51 @@
package com.tangem.features.send.v2.send.success
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationBlockComponent
import com.tangem.features.send.v2.common.CommonSendRoute
import com.tangem.features.send.v2.send.success.model.SendConfirmSuccessModel
import com.tangem.features.send.v2.send.success.ui.SendConfirmSuccessContent
import com.tangem.features.send.v2.send.ui.state.SendUM
import com.tangem.features.send.v2.subcomponents.fee.SendFeeBlockComponent
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
internal class SendConfirmSuccessComponent(
appComponentContext: AppComponentContext,
params: Params,
) : ComposableContentComponent, AppComponentContext by appComponentContext {
private val model: SendConfirmSuccessModel = getOrCreateModel(params = params)
private val destinationBlockComponent: SendDestinationBlockComponent = params.destinationBlockComponent
private val feeBlockComponent: SendFeeBlockComponent = params.feeBlockComponent
@Composable
override fun Content(modifier: Modifier) {
val state by model.uiState.collectAsState()
SendConfirmSuccessContent(
sendUM = state,
destinationBlockComponent = destinationBlockComponent,
feeBlockComponent = feeBlockComponent,
)
}
data class Params(
val sendUMFlow: StateFlow<SendUM>,
val destinationBlockComponent: SendDestinationBlockComponent,
val feeBlockComponent: SendFeeBlockComponent,
val analyticsCategoryName: String,
val currentRoute: Flow<CommonSendRoute>,
val txUrl: String,
val callback: ModelCallback,
)
interface ModelCallback {
fun onResult(sendUM: SendUM)
}
}

View file

@ -0,0 +1,104 @@
package com.tangem.features.send.v2.send.success.model
import androidx.compose.runtime.Stable
import com.tangem.common.routing.AppRouter
import com.tangem.common.ui.navigationButtons.NavigationButton
import com.tangem.common.ui.navigationButtons.NavigationUM
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.navigation.share.ShareManager
import com.tangem.core.navigation.url.UrlOpener
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.features.send.v2.common.CommonSendRoute
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents.SendScreenSource
import com.tangem.features.send.v2.impl.R
import com.tangem.features.send.v2.send.success.SendConfirmSuccessComponent
import com.tangem.features.send.v2.send.ui.state.SendUM
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.*
import javax.inject.Inject
@Stable
@ModelScoped
internal class SendConfirmSuccessModel @Inject constructor(
paramsContainer: ParamsContainer,
override val dispatchers: CoroutineDispatcherProvider,
private val analyticsEventHandler: AnalyticsEventHandler,
private val appRouter: AppRouter,
private val urlOpener: UrlOpener,
private val shareManager: ShareManager,
) : Model() {
private val params: SendConfirmSuccessComponent.Params = paramsContainer.require()
private val _uiState = params.sendUMFlow
val uiState = _uiState
init {
configConfirmSuccessNavigation()
}
private fun configConfirmSuccessNavigation() {
combine(
flow = uiState,
flow2 = params.currentRoute,
transform = { state, route -> state to route },
).filter { it.second is CommonSendRoute.ConfirmSuccess }.onEach { (state, _) ->
params.callback.onResult(
state.copy(
navigationUM = NavigationUM.Content(
title = stringReference(""),
subtitle = null,
backIconRes = R.drawable.ic_close_24,
backIconClick = {
analyticsEventHandler.send(
CommonSendAnalyticEvents.CloseButtonClicked(
categoryName = params.analyticsCategoryName,
source = SendScreenSource.Confirm,
isFromSummary = true,
isValid = true,
),
)
appRouter.pop()
},
primaryButton = NavigationButton(
textReference = resourceReference(R.string.common_close),
iconRes = null,
isEnabled = true,
isHapticClick = false,
onClick = {
appRouter.pop()
},
),
prevButton = null,
secondaryPairButtonsUM = NavigationButton(
textReference = resourceReference(R.string.common_explore),
iconRes = R.drawable.ic_web_24,
onClick = ::onExploreClick,
) to NavigationButton(
textReference = resourceReference(R.string.common_share),
iconRes = R.drawable.ic_share_24,
onClick = ::onShareClick,
),
),
),
)
}.launchIn(modelScope)
}
private fun onExploreClick() {
analyticsEventHandler.send(CommonSendAnalyticEvents.ExploreButtonClicked(params.analyticsCategoryName))
urlOpener.openUrl(params.txUrl)
}
private fun onShareClick() {
analyticsEventHandler.send(CommonSendAnalyticEvents.ShareButtonClicked(params.analyticsCategoryName))
shareManager.shareText(params.txUrl)
}
interface ModelCallback {
fun onResult(sendUM: SendUM)
}
}

View file

@ -0,0 +1,92 @@
package com.tangem.features.send.v2.send.success.ui
import androidx.compose.animation.*
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.tangem.common.ui.amountScreen.ui.AmountBlock
import com.tangem.core.ui.components.SpacerHMax
import com.tangem.core.ui.components.transactions.TransactionDoneTitle
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.utils.DateTimeFormatters
import com.tangem.core.ui.utils.toPx
import com.tangem.core.ui.utils.toTimeFormat
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationBlockComponent
import com.tangem.features.send.v2.common.ui.SendNavigationButtons
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
import com.tangem.features.send.v2.impl.R
import com.tangem.features.send.v2.send.ui.state.SendUM
import com.tangem.features.send.v2.subcomponents.fee.SendFeeBlockComponent
import kotlinx.coroutines.delay
@Composable
internal fun SendConfirmSuccessContent(
sendUM: SendUM,
destinationBlockComponent: SendDestinationBlockComponent,
feeBlockComponent: SendFeeBlockComponent,
) {
var visible by remember { mutableStateOf(false) }
LaunchedEffect(Unit) {
delay(ANIMATION_DELAY)
visible = true
}
val height = ANIMATION_OFFSET.toPx().toInt()
AnimatedVisibility(
visible = visible,
enter = slideInVertically(
initialOffsetY = { height },
).plus(fadeIn()),
exit = slideOutVertically().plus(fadeOut()),
label = "Animate success content",
) {
Column {
Column(
modifier = Modifier
.padding(horizontal = TangemTheme.dimens.spacing16)
.scrollable(
state = rememberScrollState(),
orientation = Orientation.Horizontal,
),
verticalArrangement = Arrangement.spacedBy(12.dp),
) {
if (sendUM.confirmUM is ConfirmUM.Success) {
TransactionDoneTitle(
title = resourceReference(R.string.sent_transaction_sent_title),
subtitle = resourceReference(
R.string.send_date_format,
wrappedList(
sendUM.confirmUM.transactionDate.toTimeFormat(DateTimeFormatters.dateFormatter),
sendUM.confirmUM.transactionDate.toTimeFormat(),
),
),
modifier = Modifier.padding(vertical = 12.dp),
)
}
AmountBlock(
amountState = sendUM.amountUM,
isClickDisabled = true,
isEditingDisabled = true,
onClick = {},
)
destinationBlockComponent.Content(modifier = Modifier)
feeBlockComponent.Content(modifier = Modifier)
}
SpacerHMax()
SendNavigationButtons(navigationUM = sendUM.navigationUM)
}
}
}
private const val ANIMATION_DELAY = 600L
private val ANIMATION_OFFSET = (-40).dp

View file

@ -4,6 +4,7 @@ import com.tangem.common.ui.amountScreen.models.AmountState
import com.tangem.common.ui.navigationButtons.NavigationUM
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
import com.tangem.features.send.v2.send.confirm.model.ConfirmData
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeUM
internal data class SendUM(
@ -13,4 +14,5 @@ internal data class SendUM(
val confirmUM: ConfirmUM,
val navigationUM: NavigationUM,
val isRedesignEnabled: Boolean,
val confirmData: ConfirmData?,
)