diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/DefaultSendComponent.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/DefaultSendComponent.kt index dd7a643b22..532911f4f6 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/DefaultSendComponent.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/DefaultSendComponent.kt @@ -21,6 +21,7 @@ import com.tangem.core.decompose.navigation.inner.InnerRouter import com.tangem.core.ui.decompose.ComposableContentComponent import com.tangem.core.ui.extensions.resourceReference import com.tangem.domain.tokens.model.CryptoCurrencyStatus +import com.tangem.features.send.v2.api.FeeSelectorBlockComponent import com.tangem.features.send.v2.api.SendComponent import com.tangem.features.send.v2.common.CommonSendRoute import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents @@ -53,6 +54,7 @@ internal class DefaultSendComponent @AssistedInject constructor( @Assisted appComponentContext: AppComponentContext, @Assisted private val params: SendComponent.Params, private val analyticsEventHandler: AnalyticsEventHandler, + private val feeSelectorComponentFactory: FeeSelectorBlockComponent.Factory, ) : SendComponent, AppComponentContext by appComponentContext { private val stackNavigation = StackNavigation() @@ -298,6 +300,7 @@ internal class DefaultSendComponent @AssistedInject constructor( innerRouter.replaceAll(CommonSendRoute.ConfirmSuccess) }, ), + feeSelectorComponentFactory = feeSelectorComponentFactory, ) } else { model.showAlertError() diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/SendConfirmComponent.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/SendConfirmComponent.kt index df576bb18f..5fdb4111a3 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/SendConfirmComponent.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/SendConfirmComponent.kt @@ -14,9 +14,11 @@ import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.transaction.error.GetFeeError import com.tangem.domain.wallets.models.UserWallet +import com.tangem.features.send.v2.api.FeeSelectorBlockComponent import com.tangem.features.send.v2.api.SendNotificationsComponent import com.tangem.features.send.v2.api.SendNotificationsComponent.Params.NotificationData import com.tangem.features.send.v2.api.entity.PredefinedValues +import com.tangem.features.send.v2.api.params.FeeSelectorParams import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationComponentParams.DestinationBlockParams import com.tangem.features.send.v2.common.CommonSendRoute import com.tangem.features.send.v2.common.ui.state.ConfirmUM @@ -35,6 +37,7 @@ import kotlinx.coroutines.flow.* internal class SendConfirmComponent( appComponentContext: AppComponentContext, params: Params, + private val feeSelectorComponentFactory: FeeSelectorBlockComponent.Factory, ) : ComposableContentComponent, AppComponentContext by appComponentContext { private val model: SendConfirmModel = getOrCreateModel(params = params) @@ -92,6 +95,18 @@ internal class SendConfirmComponent( onClick = model::showEditFee, ) + private val feeSelectorBlockComponent = feeSelectorComponentFactory.create( + context = appComponentContext, + params = FeeSelectorParams.FeeSelectorBlockParams( + state = model.uiState.value.feeSelectorUM, + onLoadFee = params.onLoadFee, + cryptoCurrencyStatus = params.cryptoCurrencyStatus, + suggestedFeeState = model.suggestedFeeState, + feeDisplaySource = FeeSelectorParams.FeeDisplaySource.Screen, + ), + onResult = model::onFeeResult, + ) + private val notificationsComponent = DefaultSendNotificationsComponent( appComponentContext = child("sendConfirmNotifications"), params = SendNotificationsComponent.Params( @@ -136,6 +151,7 @@ internal class SendConfirmComponent( destinationBlockComponent = destinationBlockComponent, amountBlockComponent = amountBlockComponent, feeBlockComponent = feeBlockComponent, + feeSelectorBlockComponent = feeSelectorBlockComponent, notificationsComponent = notificationsComponent, notificationsUM = notificationState, ) diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/SendConfirmModel.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/SendConfirmModel.kt index e4bfe5b26f..77a6703c4a 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/SendConfirmModel.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/SendConfirmModel.kt @@ -35,6 +35,9 @@ import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase import com.tangem.domain.utils.convertToSdkAmount import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.features.send.v2.api.SendNotificationsComponent.Params.NotificationData +import com.tangem.features.send.v2.api.callbacks.FeeSelectorModelCallback +import com.tangem.features.send.v2.api.params.FeeSelectorParams +import com.tangem.features.send.v2.api.entity.FeeSelectorUM as FeeSelectorUMRedesigned import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM import com.tangem.features.send.v2.common.CommonSendRoute import com.tangem.features.send.v2.common.SendBalanceUpdater @@ -92,7 +95,7 @@ internal class SendConfirmModel @Inject constructor( private val urlOpener: UrlOpener, private val shareManager: ShareManager, sendBalanceUpdaterFactory: SendBalanceUpdater.Factory, -) : Model(), SendConfirmClickIntents { +) : Model(), SendConfirmClickIntents, FeeSelectorModelCallback { private val params: SendConfirmComponent.Params = paramsContainer.require() @@ -115,6 +118,8 @@ internal class SendConfirmModel @Inject constructor( get() = uiState.value.feeUM as? FeeUM.Content private val feeSelectorUM get() = feeUM?.feeSelectorUM as? FeeSelectorUM.Content + private val feeUMV2 + get() = uiState.value.feeSelectorUM as? FeeSelectorUMRedesigned.Content val confirmData: ConfirmData get() = ConfirmData( @@ -129,6 +134,7 @@ internal class SendConfirmModel @Inject constructor( private var sendIdleTimer: Long = 0L private var isAmountSubtractAvailable = false + internal var suggestedFeeState: FeeSelectorParams.SuggestedFeeState = FeeSelectorParams.SuggestedFeeState.None init { modelScope.launch { @@ -303,13 +309,22 @@ internal class SendConfirmModel @Inject constructor( notificationsUpdateTrigger.hasErrorFlow .onEach { hasError -> _uiState.update { - val feeUM = it.feeUM as? FeeUM.Content - val feeSelectorUM = feeUM?.feeSelectorUM as? FeeSelectorUM.Content - it.copy( - confirmUM = (it.confirmUM as? ConfirmUM.Content)?.copy( - isPrimaryButtonEnabled = !hasError && feeSelectorUM != null, - ) ?: it.confirmUM, - ) + if (_uiState.value.isRedesignEnabled) { + val feeUM = it.feeSelectorUM as? FeeSelectorUMRedesigned.Content + it.copy( + confirmUM = (it.confirmUM as? ConfirmUM.Content)?.copy( + isPrimaryButtonEnabled = !hasError && feeUM != null, + ) ?: it.confirmUM, + ) + } else { + val feeUM = it.feeUM as? FeeUM.Content + val feeSelectorUM = feeUM?.feeSelectorUM as? FeeSelectorUM.Content + it.copy( + confirmUM = (it.confirmUM as? ConfirmUM.Content)?.copy( + isPrimaryButtonEnabled = !hasError && feeSelectorUM != null, + ) ?: it.confirmUM, + ) + } } } .launchIn(modelScope) @@ -319,9 +334,18 @@ internal class SendConfirmModel @Inject constructor( val amountValue = amountState?.amountTextField?.cryptoAmount?.value ?: return val destination = destinationUM?.addressTextField?.actualAddress ?: return val memo = destinationUM?.memoTextField?.value - val fee = feeSelectorUM?.selectedFee + val isRedesignEnabled = uiState.value.isRedesignEnabled + val fee = if (isRedesignEnabled) { + feeUMV2?.selectedFeeItem?.fee + } else { + feeSelectorUM?.selectedFee + } + val nonce = if (isRedesignEnabled) { + feeUMV2?.nonce + } else { + feeSelectorUM?.nonce + } val feeValue = fee?.amount?.value ?: return - val nonce = feeSelectorUM?.nonce val receivingAmount = checkAndCalculateSubtractedAmount( isAmountSubtractAvailable = isAmountSubtractAvailable, @@ -556,6 +580,12 @@ internal class SendConfirmModel @Inject constructor( ) } + override fun onFeeResult(feeSelectorUM: FeeSelectorUMRedesigned) { + sendIdleTimer = SystemClock.elapsedRealtime() + _uiState.update { it.copy(feeSelectorUM = feeSelectorUM) } + updateConfirmNotifications() + } + private companion object { const val CHECK_FEE_UPDATE_DELAY = 10_000L } diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/ui/SendConfirmContent.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/ui/SendConfirmContent.kt index 738c7e22ab..21e776b4ad 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/ui/SendConfirmContent.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/ui/SendConfirmContent.kt @@ -1,6 +1,7 @@ package com.tangem.features.send.v2.send.confirm.ui import androidx.compose.animation.AnimatedVisibility +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding @@ -9,6 +10,7 @@ import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip import androidx.compose.ui.unit.dp import com.tangem.common.ui.notifications.NotificationUM import com.tangem.core.ui.components.SpacerHMax @@ -19,6 +21,7 @@ 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.toTimeFormat +import com.tangem.features.send.v2.api.FeeSelectorBlockComponent import com.tangem.features.send.v2.common.ui.SendingText import com.tangem.features.send.v2.common.ui.state.ConfirmUM import com.tangem.features.send.v2.common.ui.tapHelp @@ -40,6 +43,7 @@ internal fun SendConfirmContent( destinationBlockComponent: DefaultSendDestinationBlockComponent, amountBlockComponent: SendAmountBlockComponent, feeBlockComponent: SendFeeBlockComponent, + feeSelectorBlockComponent: FeeSelectorBlockComponent, notificationsComponent: DefaultSendNotificationsComponent, notificationsUM: ImmutableList, ) { @@ -54,6 +58,7 @@ internal fun SendConfirmContent( destinationBlockComponent = destinationBlockComponent, amountBlockComponent = amountBlockComponent, feeBlockComponent = feeBlockComponent, + feeSelectorBlockComponent = feeSelectorBlockComponent, ) if (confirmUM != null) { tapHelp(isDisplay = confirmUM.showTapHelp) @@ -79,18 +84,24 @@ private fun LazyListScope.blocks( destinationBlockComponent: DefaultSendDestinationBlockComponent, amountBlockComponent: SendAmountBlockComponent, feeBlockComponent: SendFeeBlockComponent, + feeSelectorBlockComponent: FeeSelectorBlockComponent, ) { item(key = BLOCKS_KEY) { Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { if (uiState.isRedesignEnabled) { amountBlockComponent.Content(modifier = Modifier) destinationBlockComponent.Content(modifier = Modifier) + feeSelectorBlockComponent.Content( + modifier = Modifier + .clip(TangemTheme.shapes.roundedCornersXMedium) + .background(TangemTheme.colors.background.action), + ) } else { TransactionDoneTitleAnimated(uiState) destinationBlockComponent.Content(modifier = Modifier) amountBlockComponent.Content(modifier = Modifier) + feeBlockComponent.Content(modifier = Modifier) } - feeBlockComponent.Content(modifier = Modifier) } } } diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/model/SendModel.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/model/SendModel.kt index 96a985f08d..c9ecb3d667 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/model/SendModel.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/model/SendModel.kt @@ -39,6 +39,7 @@ import com.tangem.domain.wallets.models.requireColdWallet import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.features.send.v2.api.SendComponent import com.tangem.features.send.v2.api.SendFeatureToggles +import com.tangem.features.send.v2.api.entity.FeeSelectorUM import com.tangem.features.send.v2.api.entity.PredefinedValues import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationComponent import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM @@ -395,5 +396,6 @@ internal class SendModel @Inject constructor( navigationUM = NavigationUM.Empty, isRedesignEnabled = sendFeatureToggles.isSendRedesignEnabled, confirmData = null, + feeSelectorUM = FeeSelectorUM.Loading, ) } \ No newline at end of file diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/ui/state/SendUM.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/ui/state/SendUM.kt index df436f0170..3599e91e56 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/ui/state/SendUM.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/ui/state/SendUM.kt @@ -2,6 +2,7 @@ package com.tangem.features.send.v2.send.ui.state import com.tangem.common.ui.amountScreen.models.AmountState import com.tangem.common.ui.navigationButtons.NavigationUM +import com.tangem.features.send.v2.api.entity.FeeSelectorUM 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 @@ -11,6 +12,7 @@ internal data class SendUM( val amountUM: AmountState, val destinationUM: DestinationUM, val feeUM: FeeUM, + val feeSelectorUM: FeeSelectorUM, val confirmUM: ConfirmUM, val navigationUM: NavigationUM, val isRedesignEnabled: Boolean,