Updated on 2026-08-14
This commit is contained in:
commit
54cd8b7cd7
17 changed files with 534 additions and 77 deletions
|
|
@ -50,5 +50,9 @@
|
|||
{
|
||||
"name": "HOT_WALLET_ENABLED",
|
||||
"version": "undefined"
|
||||
},
|
||||
{
|
||||
"name": "NFT_SEND_REDESIGN_ENABLED",
|
||||
"version": "undefined"
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -2,8 +2,9 @@ package com.tangem.features.nft.component
|
|||
|
||||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.domain.nft.models.NFTAsset
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.nft.models.NFTAsset
|
||||
|
||||
interface NFTDetailsBlockComponent : ComposableContentComponent {
|
||||
|
||||
|
|
@ -11,6 +12,8 @@ interface NFTDetailsBlockComponent : ComposableContentComponent {
|
|||
val userWalletId: UserWalletId,
|
||||
val nftAsset: NFTAsset,
|
||||
val nftCollectionName: String,
|
||||
val title: TextReference,
|
||||
val isSuccessScreen: Boolean,
|
||||
)
|
||||
|
||||
interface Factory : ComponentFactory<Params, NFTDetailsBlockComponent>
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ class DefaultNFTDetailsBlockComponent @AssistedInject constructor(
|
|||
assetName = stringReference(params.nftAsset.name.orEmpty()),
|
||||
collectionName = stringReference(params.nftCollectionName),
|
||||
assetImage = params.nftAsset.media?.imageUrl,
|
||||
title = params.title,
|
||||
isSuccessScreen = params.isSuccessScreen,
|
||||
networkIconRes = getActiveIconRes(params.nftAsset.network.rawId),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.SpacerWMax
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
|
|
@ -19,12 +20,15 @@ import com.tangem.core.ui.res.TangemThemePreview
|
|||
import com.tangem.features.nft.common.ui.NFTLogo
|
||||
import com.tangem.features.nft.impl.R
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@Composable
|
||||
internal fun NFTDetailsBlock(
|
||||
title: TextReference,
|
||||
assetName: TextReference,
|
||||
collectionName: TextReference,
|
||||
assetImage: String?,
|
||||
networkIconRes: Int,
|
||||
isSuccessScreen: Boolean,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
|
|
@ -35,20 +39,21 @@ internal fun NFTDetailsBlock(
|
|||
verticalArrangement = Arrangement.spacedBy(6.dp),
|
||||
) {
|
||||
Text(
|
||||
text = "NFT Asset",
|
||||
text = title.resolveReference(),
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
NFTLogo(
|
||||
assetImage,
|
||||
networkIconRes,
|
||||
background = TangemTheme.colors.background.action,
|
||||
)
|
||||
|
||||
if (isSuccessScreen) {
|
||||
NFTLogo(
|
||||
assetImage,
|
||||
networkIconRes,
|
||||
background = TangemTheme.colors.background.action,
|
||||
)
|
||||
}
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(2.dp),
|
||||
) {
|
||||
|
|
@ -63,6 +68,14 @@ internal fun NFTDetailsBlock(
|
|||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
}
|
||||
if (!isSuccessScreen) {
|
||||
SpacerWMax()
|
||||
NFTLogo(
|
||||
assetImage,
|
||||
networkIconRes,
|
||||
background = TangemTheme.colors.background.action,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -78,6 +91,8 @@ private fun NFTDetailsBlock_Preview() {
|
|||
collectionName = stringReference("NFT Collection"),
|
||||
assetImage = null,
|
||||
networkIconRes = R.drawable.img_polygon_22,
|
||||
title = stringReference("From My Wallet"),
|
||||
isSuccessScreen = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,5 +3,6 @@ package com.tangem.features.send.v2.api
|
|||
interface SendFeatureToggles {
|
||||
|
||||
val isSendRedesignEnabled: Boolean
|
||||
val isNFTSendRedesignEnabled: Boolean
|
||||
val isSendWithSwapEnabled: Boolean
|
||||
}
|
||||
|
|
@ -8,6 +8,8 @@ internal class DefaultSendFeatureToggles(
|
|||
) : SendFeatureToggles {
|
||||
override val isSendRedesignEnabled: Boolean
|
||||
get() = featureToggles.isFeatureEnabled("SEND_REDESIGN_ENABLED")
|
||||
override val isNFTSendRedesignEnabled: Boolean
|
||||
get() = featureToggles.isFeatureEnabled("NFT_SEND_REDESIGN_ENABLED")
|
||||
override val isSendWithSwapEnabled: Boolean
|
||||
get() = featureToggles.isFeatureEnabled("SEND_VIA_SWAP_ENABLED")
|
||||
}
|
||||
|
|
@ -56,7 +56,7 @@ internal fun SendConfirmSuccessContent(sendUM: SendUM, destinationBlockComponent
|
|||
.padding(horizontal = TangemTheme.dimens.spacing16)
|
||||
.scrollable(
|
||||
state = rememberScrollState(),
|
||||
orientation = Orientation.Horizontal,
|
||||
orientation = Orientation.Vertical,
|
||||
),
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ import com.tangem.core.decompose.model.getOrCreateModel
|
|||
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.features.nft.component.NFTDetailsBlockComponent
|
||||
import com.tangem.features.send.v2.api.NFTSendComponent
|
||||
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
|
||||
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationComponentParams
|
||||
|
|
@ -29,6 +28,7 @@ import com.tangem.features.send.v2.common.ui.state.ConfirmUM
|
|||
import com.tangem.features.send.v2.impl.R
|
||||
import com.tangem.features.send.v2.sendnft.confirm.NFTSendConfirmComponent
|
||||
import com.tangem.features.send.v2.sendnft.model.NFTSendModel
|
||||
import com.tangem.features.send.v2.sendnft.success.NFTSendSuccessComponent
|
||||
import com.tangem.features.send.v2.subcomponents.destination.DefaultSendDestinationComponent
|
||||
import com.tangem.features.send.v2.subcomponents.fee.SendFeeComponent
|
||||
import com.tangem.features.send.v2.subcomponents.fee.SendFeeComponentParams
|
||||
|
|
@ -42,7 +42,8 @@ import java.math.BigDecimal
|
|||
internal class DefaultNFTSendComponent @AssistedInject constructor(
|
||||
@Assisted appComponentContext: AppComponentContext,
|
||||
@Assisted private val params: NFTSendComponent.Params,
|
||||
private val nftDetailsBlockComponentFactory: NFTDetailsBlockComponent.Factory,
|
||||
private val nftSendConfirmComponentFactory: NFTSendConfirmComponent.Factory,
|
||||
private val nftSendSuccessComponentFactory: NFTSendSuccessComponent.Factory,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
) : NFTSendComponent, AppComponentContext by appComponentContext {
|
||||
|
||||
|
|
@ -121,6 +122,7 @@ internal class DefaultNFTSendComponent @AssistedInject constructor(
|
|||
is CommonSendRoute.Destination -> getDestinationComponent(factoryContext)
|
||||
is CommonSendRoute.Fee -> getFeeComponent(factoryContext)
|
||||
CommonSendRoute.Confirm -> getConfirmComponent(factoryContext)
|
||||
CommonSendRoute.ConfirmSuccess -> getSuccessComponent(factoryContext)
|
||||
else -> getStubComponent()
|
||||
}
|
||||
|
||||
|
|
@ -164,9 +166,8 @@ internal class DefaultNFTSendComponent @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun getConfirmComponent(factoryContext: AppComponentContext) = NFTSendConfirmComponent(
|
||||
private fun getConfirmComponent(factoryContext: AppComponentContext) = nftSendConfirmComponentFactory.create(
|
||||
appComponentContext = factoryContext,
|
||||
nftDetailsBlockComponentFactory = nftDetailsBlockComponentFactory,
|
||||
params = NFTSendConfirmComponent.Params(
|
||||
state = model.uiState.value,
|
||||
analyticsCategoryName = analyticsCategoryName,
|
||||
|
|
@ -180,9 +181,34 @@ internal class DefaultNFTSendComponent @AssistedInject constructor(
|
|||
currentRoute = model.currentRouteFlow.filterIsInstance<CommonSendRoute.Confirm>(),
|
||||
isBalanceHidingFlow = model.isBalanceHiddenFlow,
|
||||
onLoadFee = model::loadFee,
|
||||
onSendTransaction = { innerRouter.replaceAll(CommonSendRoute.ConfirmSuccess) },
|
||||
),
|
||||
)
|
||||
|
||||
private fun getSuccessComponent(factoryContext: AppComponentContext): ComposableContentComponent {
|
||||
val txUrl = (model.uiState.value.confirmUM as? ConfirmUM.Success)?.txUrl
|
||||
|
||||
if (txUrl == null) {
|
||||
model.showAlertError()
|
||||
return getStubComponent()
|
||||
}
|
||||
|
||||
return nftSendSuccessComponentFactory.create(
|
||||
appComponentContext = factoryContext,
|
||||
params = NFTSendSuccessComponent.Params(
|
||||
nftSendUMFlow = model.uiState,
|
||||
analyticsCategoryName = analyticsCategoryName,
|
||||
userWallet = model.userWallet,
|
||||
cryptoCurrencyStatus = model.cryptoCurrencyStatus,
|
||||
nftAsset = params.nftAsset,
|
||||
nftCollectionName = params.nftCollectionName,
|
||||
callback = model,
|
||||
currentRoute = model.currentRouteFlow.filterIsInstance<CommonSendRoute.ConfirmSuccess>(),
|
||||
txUrl = txUrl,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun getStubComponent() = ComposableContentComponent { }
|
||||
|
||||
private fun onChildBack() {
|
||||
|
|
|
|||
|
|
@ -10,17 +10,23 @@ import com.tangem.core.decompose.context.AppComponentContext
|
|||
import com.tangem.core.decompose.context.child
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.nft.models.NFTAsset
|
||||
import com.tangem.domain.transaction.error.GetFeeError
|
||||
import com.tangem.features.nft.component.NFTDetailsBlockComponent
|
||||
import com.tangem.features.send.v2.api.FeeSelectorBlockComponent
|
||||
import com.tangem.features.send.v2.api.SendNotificationsComponent
|
||||
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.params.FeeSelectorParams.FeeStateConfiguration
|
||||
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
|
||||
import com.tangem.features.send.v2.impl.R
|
||||
import com.tangem.features.send.v2.sendnft.confirm.model.NFTSendConfirmModel
|
||||
import com.tangem.features.send.v2.sendnft.confirm.ui.NFTSendConfirmContent
|
||||
import com.tangem.features.send.v2.sendnft.ui.state.NFTSendUM
|
||||
|
|
@ -28,13 +34,17 @@ import com.tangem.features.send.v2.subcomponents.destination.DefaultSendDestinat
|
|||
import com.tangem.features.send.v2.subcomponents.fee.SendFeeBlockComponent
|
||||
import com.tangem.features.send.v2.subcomponents.fee.SendFeeComponentParams
|
||||
import com.tangem.features.send.v2.subcomponents.notifications.DefaultSendNotificationsComponent
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.flow.*
|
||||
import java.math.BigDecimal
|
||||
|
||||
internal class NFTSendConfirmComponent(
|
||||
appComponentContext: AppComponentContext,
|
||||
params: Params,
|
||||
internal class NFTSendConfirmComponent @AssistedInject constructor(
|
||||
@Assisted appComponentContext: AppComponentContext,
|
||||
@Assisted params: Params,
|
||||
nftDetailsBlockComponentFactory: NFTDetailsBlockComponent.Factory,
|
||||
feeSelectorComponentFactory: FeeSelectorBlockComponent.Factory,
|
||||
) : ComposableContentComponent, AppComponentContext by appComponentContext {
|
||||
|
||||
private val model: NFTSendConfirmModel = getOrCreateModel(params = params)
|
||||
|
|
@ -74,12 +84,28 @@ internal class NFTSendConfirmComponent(
|
|||
onClick = model::showEditFee,
|
||||
)
|
||||
|
||||
private val feeSelectorBlockComponent = feeSelectorComponentFactory.create(
|
||||
context = child("NFTSendConfirmFeeSelectorBlock"),
|
||||
params = FeeSelectorParams.FeeSelectorBlockParams(
|
||||
state = model.uiState.value.feeSelectorUM,
|
||||
onLoadFee = params.onLoadFee,
|
||||
feeCryptoCurrencyStatus = params.feeCryptoCurrencyStatus,
|
||||
cryptoCurrencyStatus = params.cryptoCurrencyStatus,
|
||||
feeStateConfiguration = FeeStateConfiguration.None,
|
||||
feeDisplaySource = FeeSelectorParams.FeeDisplaySource.Screen,
|
||||
analyticsCategoryName = params.analyticsCategoryName,
|
||||
),
|
||||
onResult = model::onFeeResult,
|
||||
)
|
||||
|
||||
private val nftDetailsBlockComponent = nftDetailsBlockComponentFactory.create(
|
||||
context = child("NFTDetailsBlock"),
|
||||
params = NFTDetailsBlockComponent.Params(
|
||||
userWalletId = params.userWallet.walletId,
|
||||
nftAsset = params.nftAsset,
|
||||
nftCollectionName = params.nftCollectionName,
|
||||
isSuccessScreen = false,
|
||||
title = resourceReference(R.string.send_from_wallet_name, wrappedList(params.userWallet.name)),
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -126,6 +152,7 @@ internal class NFTSendConfirmComponent(
|
|||
nftSendUM = state,
|
||||
destinationBlockComponent = destinationBlockComponent,
|
||||
feeBlockComponent = feeBlockComponent,
|
||||
feeSelectorBlockComponent = feeSelectorBlockComponent,
|
||||
nftDetailsBlockComponent = nftDetailsBlockComponent,
|
||||
notificationsComponent = notificationsComponent,
|
||||
notificationsUM = notificationState,
|
||||
|
|
@ -145,9 +172,15 @@ internal class NFTSendConfirmComponent(
|
|||
val currentRoute: Flow<CommonSendRoute.Confirm>,
|
||||
val isBalanceHidingFlow: StateFlow<Boolean>,
|
||||
val onLoadFee: suspend () -> Either<GetFeeError, TransactionFee>,
|
||||
val onSendTransaction: () -> Unit,
|
||||
)
|
||||
|
||||
interface ModelCallback {
|
||||
fun onResult(nftSendUM: NFTSendUM)
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory {
|
||||
fun create(appComponentContext: AppComponentContext, params: Params): NFTSendConfirmComponent
|
||||
}
|
||||
}
|
||||
|
|
@ -33,6 +33,7 @@ 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.analytics.CommonSendAnalyticEvents
|
||||
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents.SendScreenSource
|
||||
import com.tangem.features.send.v2.api.callbacks.FeeSelectorModelCallback
|
||||
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
|
||||
import com.tangem.features.send.v2.api.subcomponents.notifications.SendNotificationsUpdateListener
|
||||
import com.tangem.features.send.v2.api.subcomponents.notifications.SendNotificationsUpdateTrigger
|
||||
|
|
@ -61,6 +62,7 @@ import kotlinx.coroutines.launch
|
|||
import timber.log.Timber
|
||||
import java.math.BigDecimal
|
||||
import javax.inject.Inject
|
||||
import com.tangem.features.send.v2.api.entity.FeeSelectorUM as FeeSelectorUMRedesigned
|
||||
|
||||
@Suppress("LongParameterList", "LargeClass")
|
||||
@ModelScoped
|
||||
|
|
@ -89,7 +91,7 @@ internal class NFTSendConfirmModel @Inject constructor(
|
|||
private val nftSendSuccessTrigger: NFTSendSuccessTrigger,
|
||||
private val sendFeeReloadTrigger: SendFeeReloadTrigger,
|
||||
sendBalanceUpdaterFactory: SendBalanceUpdater.Factory,
|
||||
) : Model(), NFTSendConfirmClickIntents, SendNotificationsComponent.ModelCallback {
|
||||
) : Model(), NFTSendConfirmClickIntents, SendNotificationsComponent.ModelCallback, FeeSelectorModelCallback {
|
||||
|
||||
private val params: NFTSendConfirmComponent.Params = paramsContainer.require()
|
||||
|
||||
|
|
@ -141,6 +143,12 @@ internal class NFTSendConfirmModel @Inject constructor(
|
|||
updateConfirmNotifications()
|
||||
}
|
||||
|
||||
override fun onFeeResult(feeSelectorUM: FeeSelectorUMRedesigned) {
|
||||
sendIdleTimer = SystemClock.elapsedRealtime()
|
||||
_uiState.update { it.copy(feeSelectorUM = feeSelectorUM) }
|
||||
updateConfirmNotifications()
|
||||
}
|
||||
|
||||
fun onDestinationResult(destinationUM: DestinationUM) {
|
||||
_uiState.update { it.copy(destinationUM = destinationUM) }
|
||||
updateConfirmNotifications()
|
||||
|
|
@ -400,13 +408,23 @@ internal class NFTSendConfirmModel @Inject constructor(
|
|||
).onEach { (state, _) ->
|
||||
val confirmUM = state.confirmUM
|
||||
val confirmUMContent = confirmUM as? ConfirmUM.Content
|
||||
val isReadyToSend = confirmUMContent != null && !confirmUM.isSending
|
||||
params.callback.onResult(
|
||||
state.copy(
|
||||
navigationUM = NavigationUM.Content(
|
||||
title = resourceReference(R.string.nft_send),
|
||||
subtitle = confirmUMContent?.walletName,
|
||||
backIconRes = R.drawable.ic_close_24,
|
||||
subtitle = if (uiState.value.isRedesignEnabled) {
|
||||
null
|
||||
} else {
|
||||
confirmUMContent?.walletName
|
||||
},
|
||||
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(
|
||||
|
|
@ -416,26 +434,13 @@ internal class NFTSendConfirmModel @Inject constructor(
|
|||
isValid = confirmUM.isPrimaryButtonEnabled,
|
||||
),
|
||||
)
|
||||
appRouter.pop()
|
||||
if (state.isRedesignEnabled) {
|
||||
router.pop()
|
||||
} else {
|
||||
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,
|
||||
isIconVisible = isReadyToSend,
|
||||
isEnabled = confirmUM.isPrimaryButtonEnabled,
|
||||
isHapticClick = isReadyToSend,
|
||||
onClick = {
|
||||
onNextClick(confirmUM)
|
||||
},
|
||||
),
|
||||
primaryButton = primaryButtonUM(),
|
||||
prevButton = null,
|
||||
secondaryPairButtonsUM = (
|
||||
NavigationButton(
|
||||
|
|
@ -454,21 +459,40 @@ internal class NFTSendConfirmModel @Inject constructor(
|
|||
}.launchIn(modelScope)
|
||||
}
|
||||
|
||||
private fun onNextClick(confirmUM: ConfirmUM) {
|
||||
when (confirmUM) {
|
||||
is ConfirmUM.Success -> {
|
||||
modelScope.launch {
|
||||
nftSendSuccessTrigger.triggerSuccessNFTSend()
|
||||
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)
|
||||
}
|
||||
appRouter.pop()
|
||||
}
|
||||
is ConfirmUM.Content -> if (confirmUM.isSending) {
|
||||
return
|
||||
} else {
|
||||
onSendClick()
|
||||
}
|
||||
else -> return
|
||||
}
|
||||
else -> resourceReference(R.string.common_send)
|
||||
},
|
||||
iconRes = R.drawable.ic_tangem_24,
|
||||
isIconVisible = isReadyToSend,
|
||||
isEnabled = confirmUM.isPrimaryButtonEnabled,
|
||||
isHapticClick = isReadyToSend,
|
||||
onClick = {
|
||||
when (confirmUM) {
|
||||
is ConfirmUM.Success -> {
|
||||
modelScope.launch {
|
||||
nftSendSuccessTrigger.triggerSuccessNFTSend()
|
||||
}
|
||||
appRouter.pop()
|
||||
}
|
||||
is ConfirmUM.Content -> if (confirmUM.isSending) {
|
||||
return@NavigationButton
|
||||
} else {
|
||||
onSendClick()
|
||||
}
|
||||
else -> return@NavigationButton
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.features.send.v2.sendnft.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.footers.SendingText
|
||||
import com.tangem.common.ui.notifications.NotificationUM
|
||||
|
|
@ -21,6 +23,7 @@ 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.nft.component.NFTDetailsBlockComponent
|
||||
import com.tangem.features.send.v2.api.FeeSelectorBlockComponent
|
||||
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
|
||||
import com.tangem.features.send.v2.common.ui.tapHelp
|
||||
import com.tangem.features.send.v2.impl.R
|
||||
|
|
@ -40,6 +43,7 @@ internal fun NFTSendConfirmContent(
|
|||
destinationBlockComponent: DefaultSendDestinationBlockComponent,
|
||||
nftDetailsBlockComponent: NFTDetailsBlockComponent,
|
||||
feeBlockComponent: SendFeeBlockComponent,
|
||||
feeSelectorBlockComponent: FeeSelectorBlockComponent,
|
||||
notificationsComponent: DefaultSendNotificationsComponent,
|
||||
notificationsUM: ImmutableList<NotificationUM>,
|
||||
) {
|
||||
|
|
@ -54,6 +58,7 @@ internal fun NFTSendConfirmContent(
|
|||
destinationBlockComponent = destinationBlockComponent,
|
||||
nftDetailsBlockComponent = nftDetailsBlockComponent,
|
||||
feeBlockComponent = feeBlockComponent,
|
||||
feeSelectorBlockComponent = feeSelectorBlockComponent,
|
||||
)
|
||||
if (confirmUM != null) {
|
||||
tapHelp(isDisplay = confirmUM.showTapHelp)
|
||||
|
|
@ -79,31 +84,45 @@ private fun LazyListScope.blocks(
|
|||
destinationBlockComponent: DefaultSendDestinationBlockComponent,
|
||||
nftDetailsBlockComponent: NFTDetailsBlockComponent,
|
||||
feeBlockComponent: SendFeeBlockComponent,
|
||||
feeSelectorBlockComponent: FeeSelectorBlockComponent,
|
||||
) {
|
||||
item(key = BLOCKS_KEY) {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
|
||||
AnimatedVisibility(
|
||||
visible = nftSendUM.confirmUM is ConfirmUM.Success,
|
||||
modifier = Modifier.padding(vertical = TangemTheme.dimens.spacing12),
|
||||
) {
|
||||
val wrappedConfirmUM = remember(this) { nftSendUM.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 (nftSendUM.isRedesignEnabled) {
|
||||
nftDetailsBlockComponent.Content(modifier = Modifier)
|
||||
destinationBlockComponent.Content(modifier = Modifier)
|
||||
feeSelectorBlockComponent.Content(
|
||||
modifier = Modifier
|
||||
.clip(TangemTheme.shapes.roundedCornersXMedium)
|
||||
.background(TangemTheme.colors.background.action),
|
||||
)
|
||||
} else {
|
||||
TransactionDoneTitleAnimated(nftSendUM = nftSendUM)
|
||||
destinationBlockComponent.Content(modifier = Modifier)
|
||||
nftDetailsBlockComponent.Content(modifier = Modifier)
|
||||
feeBlockComponent.Content(modifier = Modifier)
|
||||
}
|
||||
destinationBlockComponent.Content(modifier = Modifier)
|
||||
|
||||
nftDetailsBlockComponent.Content(modifier = Modifier)
|
||||
|
||||
feeBlockComponent.Content(modifier = Modifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TransactionDoneTitleAnimated(nftSendUM: NFTSendUM) {
|
||||
AnimatedVisibility(
|
||||
visible = nftSendUM.confirmUM is ConfirmUM.Success,
|
||||
modifier = Modifier.padding(vertical = 12.dp),
|
||||
) {
|
||||
val wrappedConfirmUM = remember(this) { nftSendUM.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),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import com.tangem.core.decompose.di.ModelComponent
|
|||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.features.send.v2.sendnft.confirm.model.NFTSendConfirmModel
|
||||
import com.tangem.features.send.v2.sendnft.model.NFTSendModel
|
||||
import com.tangem.features.send.v2.sendnft.success.model.NFTSendSuccessModel
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
|
|
@ -23,4 +24,9 @@ internal interface NFTSendModelModule {
|
|||
@IntoMap
|
||||
@ClassKey(NFTSendConfirmModel::class)
|
||||
fun provideNFTSendConfirmModel(model: NFTSendConfirmModel): Model
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(NFTSendSuccessModel::class)
|
||||
fun provideNFTSendSuccessModel(model: NFTSendSuccessModel): Model
|
||||
}
|
||||
|
|
@ -29,6 +29,8 @@ import com.tangem.domain.transaction.usecase.CreateNFTTransferTransactionUseCase
|
|||
import com.tangem.domain.transaction.usecase.GetFeeUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.features.send.v2.api.NFTSendComponent
|
||||
import com.tangem.features.send.v2.api.SendFeatureToggles
|
||||
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
|
||||
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationComponent
|
||||
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
|
||||
import com.tangem.features.send.v2.common.CommonSendRoute
|
||||
|
|
@ -36,6 +38,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.sendnft.confirm.NFTSendConfirmComponent
|
||||
import com.tangem.features.send.v2.sendnft.success.NFTSendSuccessComponent
|
||||
import com.tangem.features.send.v2.sendnft.ui.state.NFTSendUM
|
||||
import com.tangem.features.send.v2.subcomponents.fee.SendFeeComponent
|
||||
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeUM
|
||||
|
|
@ -70,7 +73,8 @@ internal class NFTSendModel @Inject constructor(
|
|||
private val getCardInfoUseCase: GetCardInfoUseCase,
|
||||
private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase,
|
||||
private val alertFactory: SendConfirmAlertFactory,
|
||||
) : Model(), SendNFTComponentCallback {
|
||||
private val sendFeatureToggles: SendFeatureToggles,
|
||||
) : Model(), SendNFTComponentCallback, NFTSendSuccessComponent.ModelCallback {
|
||||
|
||||
val params: NFTSendComponent.Params = paramsContainer.require()
|
||||
|
||||
|
|
@ -124,7 +128,7 @@ internal class NFTSendModel @Inject constructor(
|
|||
} else {
|
||||
when (currentRouteFlow.value) {
|
||||
is Destination -> router.push(Confirm)
|
||||
Confirm -> router.push(ConfirmSuccess)
|
||||
Confirm -> router.replaceAll(ConfirmSuccess)
|
||||
else -> onBackClick()
|
||||
}
|
||||
}
|
||||
|
|
@ -193,6 +197,13 @@ internal class NFTSendModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun showAlertError() {
|
||||
alertFactory.getGenericErrorState(
|
||||
onFailedTxEmailClick = ::onFailedTxEmailClick,
|
||||
popBack = router::pop,
|
||||
)
|
||||
}
|
||||
|
||||
private fun onFailedTxEmailClick(errorMessage: String? = null) {
|
||||
saveBlockchainErrorUseCase(
|
||||
error = BlockchainErrorInfo(
|
||||
|
|
@ -249,7 +260,9 @@ internal class NFTSendModel @Inject constructor(
|
|||
private fun initialState(): NFTSendUM = NFTSendUM(
|
||||
destinationUM = DestinationUM.Empty(),
|
||||
feeUM = FeeUM.Empty(),
|
||||
feeSelectorUM = FeeSelectorUM.Loading,
|
||||
confirmUM = ConfirmUM.Empty,
|
||||
navigationUM = NavigationUM.Empty,
|
||||
isRedesignEnabled = sendFeatureToggles.isNFTSendRedesignEnabled,
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
package com.tangem.features.send.v2.sendnft.success
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.context.child
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.nft.models.NFTAsset
|
||||
import com.tangem.features.nft.component.NFTDetailsBlockComponent
|
||||
import com.tangem.features.send.v2.api.entity.PredefinedValues
|
||||
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationBlockComponent
|
||||
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.impl.R
|
||||
import com.tangem.features.send.v2.sendnft.success.model.NFTSendSuccessModel
|
||||
import com.tangem.features.send.v2.sendnft.success.ui.NFTSendSuccessContent
|
||||
import com.tangem.features.send.v2.sendnft.ui.state.NFTSendUM
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
internal class NFTSendSuccessComponent @AssistedInject constructor(
|
||||
@Assisted appComponentContext: AppComponentContext,
|
||||
@Assisted params: Params,
|
||||
nftDetailsBlockComponentFactory: NFTDetailsBlockComponent.Factory,
|
||||
sendDestinationBlockComponentFactory: SendDestinationBlockComponent.Factory,
|
||||
) : ComposableContentComponent, AppComponentContext by appComponentContext {
|
||||
|
||||
private val model: NFTSendSuccessModel = getOrCreateModel(params = params)
|
||||
|
||||
private val nftDetailsBlockComponent = nftDetailsBlockComponentFactory.create(
|
||||
context = child("NFTDetailsSuccessBlock"),
|
||||
params = NFTDetailsBlockComponent.Params(
|
||||
userWalletId = params.userWallet.walletId,
|
||||
nftAsset = params.nftAsset,
|
||||
nftCollectionName = params.nftCollectionName,
|
||||
isSuccessScreen = true,
|
||||
title = resourceReference(R.string.nft_asset),
|
||||
),
|
||||
)
|
||||
|
||||
private val sendDestinationBlockComponent = sendDestinationBlockComponentFactory.create(
|
||||
context = child("NFTDestinationSuccessBlock"),
|
||||
params = DestinationBlockParams(
|
||||
state = model.uiState.value.destinationUM,
|
||||
analyticsCategoryName = params.analyticsCategoryName,
|
||||
userWalletId = params.userWallet.walletId,
|
||||
cryptoCurrency = params.cryptoCurrencyStatus.currency,
|
||||
blockClickEnableFlow = MutableStateFlow(false),
|
||||
predefinedValues = PredefinedValues.Empty,
|
||||
),
|
||||
onResult = {},
|
||||
onClick = {},
|
||||
)
|
||||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
val state by model.uiState.collectAsStateWithLifecycle()
|
||||
NFTSendSuccessContent(
|
||||
nftSendUM = state,
|
||||
destinationBlockComponent = sendDestinationBlockComponent,
|
||||
nftDetailsBlockComponent = nftDetailsBlockComponent,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
data class Params(
|
||||
val nftSendUMFlow: StateFlow<NFTSendUM>,
|
||||
val analyticsCategoryName: String,
|
||||
val currentRoute: Flow<CommonSendRoute>,
|
||||
val cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
val userWallet: UserWallet,
|
||||
val nftAsset: NFTAsset,
|
||||
val nftCollectionName: String,
|
||||
val txUrl: String,
|
||||
val callback: ModelCallback,
|
||||
)
|
||||
|
||||
interface ModelCallback {
|
||||
fun onResult(nftSendUM: NFTSendUM)
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory {
|
||||
fun create(appComponentContext: AppComponentContext, params: Params): NFTSendSuccessComponent
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
package com.tangem.features.send.v2.sendnft.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.api.analytics.CommonSendAnalyticEvents
|
||||
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents.SendScreenSource
|
||||
import com.tangem.features.send.v2.common.CommonSendRoute
|
||||
import com.tangem.features.send.v2.impl.R
|
||||
import com.tangem.features.send.v2.send.ui.state.SendUM
|
||||
import com.tangem.features.send.v2.sendnft.success.NFTSendSuccessComponent
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import javax.inject.Inject
|
||||
|
||||
@Stable
|
||||
@ModelScoped
|
||||
internal class NFTSendSuccessModel @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: NFTSendSuccessComponent.Params = paramsContainer.require()
|
||||
|
||||
val uiState = params.nftSendUMFlow
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
package com.tangem.features.send.v2.sendnft.success.ui
|
||||
|
||||
import androidx.compose.animation.*
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.gestures.Orientation
|
||||
import androidx.compose.foundation.gestures.scrollable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.common.ui.navigationButtons.NavigationButtonsBlockV2
|
||||
import com.tangem.core.ui.components.BottomFade
|
||||
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.nft.component.NFTDetailsBlockComponent
|
||||
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationBlockComponent
|
||||
import com.tangem.features.send.v2.common.ui.FeeBlock
|
||||
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
|
||||
import com.tangem.features.send.v2.impl.R
|
||||
import com.tangem.features.send.v2.sendnft.ui.state.NFTSendUM
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
@Composable
|
||||
internal fun NFTSendSuccessContent(
|
||||
nftSendUM: NFTSendUM,
|
||||
destinationBlockComponent: SendDestinationBlockComponent,
|
||||
nftDetailsBlockComponent: NFTDetailsBlockComponent,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
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",
|
||||
modifier = modifier,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(TangemTheme.colors.background.tertiary),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = TangemTheme.dimens.spacing16)
|
||||
.scrollable(
|
||||
state = rememberScrollState(),
|
||||
orientation = Orientation.Vertical,
|
||||
),
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
if (nftSendUM.confirmUM is ConfirmUM.Success) {
|
||||
TransactionDoneTitle(
|
||||
title = resourceReference(R.string.sent_transaction_sent_title),
|
||||
subtitle = resourceReference(
|
||||
R.string.send_date_format,
|
||||
wrappedList(
|
||||
nftSendUM.confirmUM.transactionDate.toTimeFormat(DateTimeFormatters.dateFormatter),
|
||||
nftSendUM.confirmUM.transactionDate.toTimeFormat(),
|
||||
),
|
||||
),
|
||||
modifier = Modifier.padding(vertical = 12.dp),
|
||||
)
|
||||
}
|
||||
nftDetailsBlockComponent.Content(modifier = Modifier)
|
||||
destinationBlockComponent.Content(modifier = Modifier)
|
||||
FeeBlock(feeSelectorUM = nftSendUM.feeSelectorUM)
|
||||
Spacer(Modifier.height(60.dp))
|
||||
}
|
||||
BottomFade(Modifier.align(Alignment.BottomCenter), TangemTheme.colors.background.tertiary)
|
||||
NavigationButtonsBlockV2(
|
||||
navigationUM = nftSendUM.navigationUM,
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomCenter)
|
||||
.padding(
|
||||
start = 16.dp,
|
||||
end = 16.dp,
|
||||
bottom = 16.dp,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private const val ANIMATION_DELAY = 600L
|
||||
private val ANIMATION_OFFSET = (-40).dp
|
||||
|
|
@ -1,13 +1,16 @@
|
|||
package com.tangem.features.send.v2.sendnft.ui.state
|
||||
|
||||
import com.tangem.common.ui.navigationButtons.NavigationUM
|
||||
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
|
||||
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.subcomponents.fee.ui.state.FeeUM
|
||||
|
||||
internal data class NFTSendUM(
|
||||
val destinationUM: DestinationUM,
|
||||
val feeUM: FeeUM,
|
||||
val feeSelectorUM: FeeSelectorUM,
|
||||
val confirmUM: ConfirmUM,
|
||||
val navigationUM: NavigationUM,
|
||||
val isRedesignEnabled: Boolean,
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue