Updated on 2026-08-14

This commit is contained in:
Tangem 2025-07-01 20:34:06 +05:00
parent 772ec7b53a
commit 2f5b70dfaa
54 changed files with 261 additions and 202 deletions

View file

@ -1,4 +1,4 @@
package com.tangem.features.send.v2.common
package com.tangem.features.send.v2.api.entity
sealed class PredefinedValues {
data object Empty : PredefinedValues()

View file

@ -0,0 +1,8 @@
package com.tangem.features.send.v2.api.subcomponents.destination
/**
* Common route for destination
*/
interface DestinationRoute {
val isEditMode: Boolean
}

View file

@ -0,0 +1,10 @@
package com.tangem.features.send.v2.api.subcomponents.destination
import com.tangem.core.decompose.factory.ComponentFactory
import com.tangem.core.ui.decompose.ComposableContentComponent
interface SendDestinationBlockComponent : ComposableContentComponent {
interface Factory :
ComponentFactory<SendDestinationComponentParams.DestinationBlockParams, SendDestinationBlockComponent>
}

View file

@ -0,0 +1,15 @@
package com.tangem.features.send.v2.api.subcomponents.destination
import com.tangem.common.ui.navigationButtons.NavigationModelCallback
import com.tangem.core.decompose.factory.ComponentFactory
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
interface SendDestinationComponent : ComposableContentComponent {
interface ModelCallback : NavigationModelCallback {
fun onDestinationResult(destinationUM: DestinationUM)
}
interface Factory : ComponentFactory<SendDestinationComponentParams.DestinationParams, SendDestinationComponent>
}

View file

@ -1,16 +1,14 @@
package com.tangem.features.send.v2.subcomponents.destination
package com.tangem.features.send.v2.api.subcomponents.destination
import com.tangem.core.ui.extensions.TextReference
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.features.send.v2.common.CommonSendRoute
import com.tangem.features.send.v2.common.PredefinedValues
import com.tangem.features.send.v2.subcomponents.destination.SendDestinationComponent.ModelCallback
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationUM
import com.tangem.features.send.v2.api.entity.PredefinedValues
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
internal sealed class SendDestinationComponentParams {
sealed class SendDestinationComponentParams {
abstract val state: DestinationUM
abstract val analyticsCategoryName: String
@ -24,8 +22,8 @@ internal sealed class SendDestinationComponentParams {
override val userWalletId: UserWalletId,
val title: TextReference,
val isBalanceHidingFlow: StateFlow<Boolean>,
val currentRoute: Flow<CommonSendRoute.Destination>,
val callback: ModelCallback,
val currentRoute: Flow<DestinationRoute>,
val callback: SendDestinationComponent.ModelCallback,
val onBackClick: () -> Unit,
val onNextClick: () -> Unit,
) : SendDestinationComponentParams()

View file

@ -1,4 +1,4 @@
package com.tangem.features.send.v2.subcomponents.destination.ui.state
package com.tangem.features.send.v2.api.subcomponents.destination.entity
import androidx.annotation.DrawableRes
import androidx.compose.runtime.Immutable
@ -7,7 +7,7 @@ import com.tangem.domain.models.network.Network
import com.tangem.domain.wallets.models.UserWalletId
@Immutable
internal data class DestinationRecipientListUM(
data class DestinationRecipientListUM(
val id: String,
val title: TextReference = TextReference.Companion.EMPTY,
val subtitle: TextReference = TextReference.Companion.EMPTY,

View file

@ -1,11 +1,11 @@
package com.tangem.features.send.v2.subcomponents.destination.ui.state
package com.tangem.features.send.v2.api.subcomponents.destination.entity
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.runtime.Immutable
import com.tangem.core.ui.extensions.TextReference
@Immutable
internal sealed class DestinationTextFieldUM {
sealed class DestinationTextFieldUM {
/** Current value */
abstract val value: String

View file

@ -1,10 +1,10 @@
package com.tangem.features.send.v2.subcomponents.destination.ui.state
package com.tangem.features.send.v2.api.subcomponents.destination.entity
import androidx.compose.runtime.Immutable
import kotlinx.collections.immutable.ImmutableList
@Immutable
internal sealed class DestinationUM {
sealed class DestinationUM {
abstract val isPrimaryButtonEnabled: Boolean

View file

@ -1,6 +1,7 @@
package com.tangem.features.send.v2.common
import com.tangem.core.decompose.navigation.Route
import com.tangem.features.send.v2.api.subcomponents.destination.DestinationRoute
import kotlinx.serialization.Serializable
internal sealed class CommonSendRoute : Route {
@ -20,7 +21,7 @@ internal sealed class CommonSendRoute : Route {
@Serializable
data class Destination(
override val isEditMode: Boolean,
) : CommonSendRoute()
) : CommonSendRoute(), DestinationRoute
@Serializable
data class Amount(

View file

@ -1,7 +0,0 @@
package com.tangem.features.send.v2.common
import com.tangem.features.send.v2.common.ui.state.NavigationUM
internal interface SendNavigationModelCallback {
fun onNavigationResult(navigationUM: NavigationUM)
}

View file

@ -9,12 +9,12 @@ 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.router.stack.ChildStack
import com.tangem.common.ui.navigationButtons.NavigationUM
import com.tangem.core.ui.components.appbar.AppBarWithBackButtonAndIcon
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.common.ui.state.NavigationUM
@Composable
internal fun SendContent(

View file

@ -19,6 +19,8 @@ import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.unit.dp
import com.tangem.common.ui.navigationButtons.NavigationButton
import com.tangem.common.ui.navigationButtons.NavigationUM
import com.tangem.core.ui.R
import com.tangem.core.ui.components.SecondaryButtonIconStart
import com.tangem.core.ui.components.SpacerW12
@ -29,8 +31,6 @@ import com.tangem.core.ui.extensions.clickableSingle
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.utils.singleEvent
import com.tangem.features.send.v2.common.ui.state.NavigationUM
import com.tangem.features.send.v2.send.ui.state.ButtonsUM
@Composable
internal fun SendNavigationButtons(navigationUM: NavigationUM, modifier: Modifier = Modifier) {
@ -79,8 +79,8 @@ private fun SendNavigationButton(navigationUM: NavigationUM, modifier: Modifier
}
TangemButton(
modifier = Modifier.fillMaxWidth(),
text = primaryButton.text.resolveReference(),
icon = primaryButton.iconResId?.let {
text = primaryButton.textReference.resolveReference(),
icon = primaryButton.iconRes?.let {
TangemButtonIconPosition.End(it)
} ?: TangemButtonIconPosition.None,
enabled = primaryButton.isEnabled,
@ -96,7 +96,7 @@ private fun SendNavigationButton(navigationUM: NavigationUM, modifier: Modifier
}
@Composable
private fun SendDoneButtons(pairButtonsUM: ButtonsUM.SecondaryPairButtonsUM?, modifier: Modifier = Modifier) {
private fun SendDoneButtons(pairButtonsUM: Pair<NavigationButton, NavigationButton>?, modifier: Modifier = Modifier) {
val hapticFeedback = LocalHapticFeedback.current
AnimatedVisibility(
@ -106,26 +106,26 @@ private fun SendDoneButtons(pairButtonsUM: ButtonsUM.SecondaryPairButtonsUM?, mo
exit = slideOutVertically().plus(fadeOut()),
label = "Animate show sent state buttons",
) {
val wrappedPairButtonsUM = remember(this) { requireNotNull(pairButtonsUM) }
val (leftButton, rightButton) = remember(this) { requireNotNull(pairButtonsUM) }
Row(modifier = Modifier.padding(bottom = 12.dp)) {
SecondaryButtonIconStart(
text = wrappedPairButtonsUM.leftText.resolveReference(),
iconResId = wrappedPairButtonsUM.leftIconResId!!,
text = leftButton.textReference.resolveReference(),
iconResId = leftButton.iconRes!!,
onClick = {
singleEvent {
wrappedPairButtonsUM.onLeftClick()
leftButton.onClick()
}
},
modifier = Modifier.weight(1f),
)
SpacerW12()
SecondaryButtonIconStart(
text = wrappedPairButtonsUM.rightText.resolveReference(),
iconResId = wrappedPairButtonsUM.rightIconResId!!,
text = rightButton.textReference.resolveReference(),
iconResId = rightButton.iconRes!!,
onClick = {
singleEvent {
hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress)
wrappedPairButtonsUM.onRightClick()
rightButton.onClick()
}
},
modifier = Modifier.weight(1f),

View file

@ -1,23 +0,0 @@
package com.tangem.features.send.v2.common.ui.state
import androidx.annotation.DrawableRes
import androidx.compose.runtime.Immutable
import com.tangem.core.ui.extensions.TextReference
import com.tangem.features.send.v2.send.ui.state.ButtonsUM
@Immutable
internal sealed class NavigationUM {
data class Content(
val title: TextReference,
val subtitle: TextReference?,
@DrawableRes val backIconRes: Int,
val backIconClick: () -> Unit,
@DrawableRes val additionalIconRes: Int? = null,
val additionalIconClick: (() -> Unit)? = null,
val primaryButton: ButtonsUM.PrimaryButtonUM,
val prevButton: ButtonsUM.PrimaryButtonUM?,
val secondaryPairButtonsUM: ButtonsUM.SecondaryPairButtonsUM?,
) : NavigationUM()
data object Empty : NavigationUM()
}

View file

@ -32,9 +32,9 @@ import com.tangem.features.send.v2.send.confirm.SendConfirmComponent
import com.tangem.features.send.v2.send.model.SendModel
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.destination.SendDestinationComponent
import com.tangem.features.send.v2.subcomponents.destination.SendDestinationComponentParams
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationUM
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.fee.SendFeeComponent
import com.tangem.features.send.v2.subcomponents.fee.SendFeeComponentParams
import dagger.assisted.Assisted
@ -108,7 +108,7 @@ internal class DefaultSendComponent @AssistedInject constructor(
)
activeComponent.updateState(model.uiState.value.amountUM)
}
is SendDestinationComponent -> {
is DefaultSendDestinationComponent -> {
analyticsEventHandler.send(
CommonSendAnalyticEvents.AddressScreenOpened(categoryName = analyticCategoryName),
)
@ -148,7 +148,7 @@ internal class DefaultSendComponent @AssistedInject constructor(
private fun getDestinationComponent(
factoryContext: AppComponentContext,
route: CommonSendRoute,
): SendDestinationComponent = SendDestinationComponent(
): DefaultSendDestinationComponent = DefaultSendDestinationComponent(
appComponentContext = factoryContext,
params = SendDestinationComponentParams.DestinationParams(
state = model.uiState.value.destinationUM,

View file

@ -6,8 +6,8 @@ import com.tangem.core.analytics.models.Basic
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.features.send.v2.send.ui.state.SendUM
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationTextFieldUM
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationUM
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationTextFieldUM
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeSelectorUM
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeUM
import javax.inject.Inject

View file

@ -16,22 +16,21 @@ import com.tangem.domain.transaction.error.GetFeeError
import com.tangem.domain.wallets.models.UserWallet
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.subcomponents.destination.SendDestinationComponentParams.DestinationBlockParams
import com.tangem.features.send.v2.common.CommonSendRoute
import com.tangem.features.send.v2.common.PredefinedValues
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
import com.tangem.features.send.v2.send.confirm.model.SendConfirmModel
import com.tangem.features.send.v2.send.confirm.ui.SendConfirmContent
import com.tangem.features.send.v2.send.ui.state.SendUM
import com.tangem.features.send.v2.subcomponents.amount.SendAmountBlockComponent
import com.tangem.features.send.v2.subcomponents.amount.SendAmountComponentParams
import com.tangem.features.send.v2.subcomponents.destination.SendDestinationBlockComponent
import com.tangem.features.send.v2.subcomponents.destination.SendDestinationComponentParams.DestinationBlockParams
import com.tangem.features.send.v2.subcomponents.destination.DefaultSendDestinationBlockComponent
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 com.tangem.utils.extensions.orZero
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.flow.StateFlow
internal class SendConfirmComponent(
appComponentContext: AppComponentContext,
@ -43,7 +42,7 @@ internal class SendConfirmComponent(
private val blockClickEnableFlow = MutableStateFlow(false)
private val destinationBlockComponent =
SendDestinationBlockComponent(
DefaultSendDestinationBlockComponent(
appComponentContext = child("sendConfirmDestinationBlock"),
params = DestinationBlockParams(
state = model.uiState.value.destinationUM,

View file

@ -7,6 +7,8 @@ import com.tangem.blockchain.common.AmountType
import com.tangem.blockchain.common.TransactionData
import com.tangem.common.routing.AppRouter
import com.tangem.common.ui.amountScreen.models.AmountState
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
@ -33,13 +35,13 @@ 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.subcomponents.destination.entity.DestinationUM
import com.tangem.features.send.v2.common.CommonSendRoute
import com.tangem.features.send.v2.common.SendBalanceUpdater
import com.tangem.features.send.v2.common.SendConfirmAlertFactory
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.common.ui.state.ConfirmUM
import com.tangem.features.send.v2.common.ui.state.NavigationUM
import com.tangem.features.send.v2.impl.R
import com.tangem.features.send.v2.send.analytics.SendAnalyticHelper
import com.tangem.features.send.v2.send.confirm.SendConfirmComponent
@ -47,9 +49,7 @@ import com.tangem.features.send.v2.send.confirm.model.transformers.SendConfirmIn
import com.tangem.features.send.v2.send.confirm.model.transformers.SendConfirmSendingStateTransformer
import com.tangem.features.send.v2.send.confirm.model.transformers.SendConfirmSentStateTransformer
import com.tangem.features.send.v2.send.confirm.model.transformers.SendConfirmationNotificationsTransformer
import com.tangem.features.send.v2.send.ui.state.ButtonsUM
import com.tangem.features.send.v2.send.ui.state.SendUM
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationUM
import com.tangem.features.send.v2.subcomponents.fee.SendFeeCheckReloadListener
import com.tangem.features.send.v2.subcomponents.fee.SendFeeCheckReloadTrigger
import com.tangem.features.send.v2.subcomponents.fee.model.checkAndCalculateSubtractedAmount
@ -490,8 +490,8 @@ internal class SendConfirmModel @Inject constructor(
)
appRouter.pop()
},
primaryButton = ButtonsUM.PrimaryButtonUM(
text = when (confirmUM) {
primaryButton = NavigationButton(
textReference = when (confirmUM) {
is ConfirmUM.Success -> resourceReference(R.string.common_close)
is ConfirmUM.Content -> if (confirmUM.isSending) {
resourceReference(R.string.send_sending)
@ -500,30 +500,33 @@ internal class SendConfirmModel @Inject constructor(
}
else -> resourceReference(R.string.common_send)
},
iconResId = R.drawable.ic_tangem_24.takeIf { isReadyToSend },
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@PrimaryButtonUM
return@NavigationButton
} else {
onSendClick()
}
else -> return@PrimaryButtonUM
else -> return@NavigationButton
}
},
),
prevButton = null,
secondaryPairButtonsUM = ButtonsUM.SecondaryPairButtonsUM(
leftText = resourceReference(R.string.common_explore),
leftIconResId = R.drawable.ic_web_24,
onLeftClick = ::onExploreClick,
rightText = resourceReference(R.string.common_share),
rightIconResId = R.drawable.ic_share_24,
onRightClick = ::onShareClick,
).takeIf { confirmUM is ConfirmUM.Success },
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,
)
).takeIf { confirmUM is ConfirmUM.Success },
),
),
)

View file

@ -25,7 +25,7 @@ import com.tangem.features.send.v2.common.ui.tapHelp
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.amount.SendAmountBlockComponent
import com.tangem.features.send.v2.subcomponents.destination.SendDestinationBlockComponent
import com.tangem.features.send.v2.subcomponents.destination.DefaultSendDestinationBlockComponent
import com.tangem.features.send.v2.subcomponents.fee.SendFeeBlockComponent
import com.tangem.features.send.v2.subcomponents.notifications
import com.tangem.features.send.v2.subcomponents.notifications.DefaultSendNotificationsComponent
@ -37,7 +37,7 @@ private const val BLOCKS_KEY = "BLOCKS_KEY"
@Composable
internal fun SendConfirmContent(
sendUM: SendUM,
destinationBlockComponent: SendDestinationBlockComponent,
destinationBlockComponent: DefaultSendDestinationBlockComponent,
amountBlockComponent: SendAmountBlockComponent,
feeBlockComponent: SendFeeBlockComponent,
notificationsComponent: DefaultSendNotificationsComponent,
@ -76,7 +76,7 @@ internal fun SendConfirmContent(
private fun LazyListScope.blocks(
uiState: SendUM,
destinationBlockComponent: SendDestinationBlockComponent,
destinationBlockComponent: DefaultSendDestinationBlockComponent,
amountBlockComponent: SendAmountBlockComponent,
feeBlockComponent: SendFeeBlockComponent,
) {

View file

@ -6,6 +6,7 @@ import arrow.core.getOrElse
import arrow.core.left
import com.tangem.blockchain.common.transaction.TransactionFee
import com.tangem.common.ui.amountScreen.models.AmountState
import com.tangem.common.ui.navigationButtons.NavigationUM
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
@ -38,18 +39,17 @@ 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.PredefinedValues
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
import com.tangem.features.send.v2.common.PredefinedValues
import com.tangem.features.send.v2.common.SendConfirmAlertFactory
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
import com.tangem.features.send.v2.common.ui.state.NavigationUM
import com.tangem.features.send.v2.send.confirm.SendConfirmComponent
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
import com.tangem.features.send.v2.subcomponents.destination.SendDestinationComponent
import com.tangem.features.send.v2.subcomponents.destination.model.transformers.SendDestinationInitialStateTransformer
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationUM
import com.tangem.features.send.v2.subcomponents.fee.SendFeeComponent
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeUM
import com.tangem.utils.coroutines.CoroutineDispatcherProvider

View file

@ -1,9 +1,9 @@
package com.tangem.features.send.v2.send.ui.state
import com.tangem.common.ui.amountScreen.models.AmountState
import com.tangem.features.send.v2.common.ui.state.NavigationUM
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.subcomponents.destination.ui.state.DestinationUM
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeUM
internal data class SendUM(

View file

@ -28,9 +28,9 @@ import com.tangem.features.send.v2.common.utils.safeNextClick
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.subcomponents.destination.SendDestinationComponent
import com.tangem.features.send.v2.subcomponents.destination.SendDestinationComponentParams
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationUM
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.fee.SendFeeComponent
import com.tangem.features.send.v2.subcomponents.fee.SendFeeComponentParams
import dagger.assisted.Assisted
@ -93,7 +93,7 @@ internal class DefaultNFTSendComponent @AssistedInject constructor(
activeComponent.updateState(model.uiState.value)
}
}
is SendDestinationComponent -> {
is DefaultSendDestinationComponent -> {
analyticsEventHandler.send(
CommonSendAnalyticEvents.AddressScreenOpened(categoryName = analyticsCategoryName),
)
@ -132,7 +132,7 @@ internal class DefaultNFTSendComponent @AssistedInject constructor(
private fun getDestinationComponent(
factoryContext: AppComponentContext,
route: CommonSendRoute,
): SendDestinationComponent = SendDestinationComponent(
): DefaultSendDestinationComponent = DefaultSendDestinationComponent(
appComponentContext = factoryContext,
params = SendDestinationComponentParams.DestinationParams(
state = model.uiState.value.destinationUM,

View file

@ -6,8 +6,8 @@ import com.tangem.core.analytics.models.Basic
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.features.send.v2.sendnft.ui.state.NFTSendUM
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationTextFieldUM
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationUM
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationTextFieldUM
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeSelectorUM
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeUM
import javax.inject.Inject

View file

@ -18,13 +18,13 @@ import com.tangem.domain.wallets.models.UserWallet
import com.tangem.features.nft.component.NFTDetailsBlockComponent
import com.tangem.features.send.v2.api.SendNotificationsComponent
import com.tangem.features.send.v2.common.CommonSendRoute
import com.tangem.features.send.v2.common.PredefinedValues
import com.tangem.features.send.v2.api.entity.PredefinedValues
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
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
import com.tangem.features.send.v2.subcomponents.destination.SendDestinationBlockComponent
import com.tangem.features.send.v2.subcomponents.destination.SendDestinationComponentParams.DestinationBlockParams
import com.tangem.features.send.v2.subcomponents.destination.DefaultSendDestinationBlockComponent
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationComponentParams.DestinationBlockParams
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
@ -42,7 +42,7 @@ internal class NFTSendConfirmComponent(
private val blockClickEnableFlow = MutableStateFlow(false)
private val destinationBlockComponent =
SendDestinationBlockComponent(
DefaultSendDestinationBlockComponent(
appComponentContext = child("NFTSendConfirmDestinationBlock"),
params = DestinationBlockParams(
state = model.uiState.value.destinationUM,

View file

@ -4,6 +4,8 @@ import android.os.SystemClock
import arrow.core.getOrElse
import com.tangem.blockchain.common.TransactionData
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
@ -27,22 +29,20 @@ import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase
import com.tangem.domain.wallets.models.requireColdWallet
import com.tangem.features.nft.entity.NFTSendSuccessTrigger
import com.tangem.features.send.v2.api.SendNotificationsComponent.Params.NotificationData
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
import com.tangem.features.send.v2.common.SendConfirmAlertFactory
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.common.ui.state.ConfirmUM
import com.tangem.features.send.v2.common.ui.state.NavigationUM
import com.tangem.features.send.v2.impl.R
import com.tangem.features.send.v2.send.ui.state.ButtonsUM
import com.tangem.features.send.v2.sendnft.analytics.NFTSendAnalyticHelper
import com.tangem.features.send.v2.sendnft.confirm.NFTSendConfirmComponent
import com.tangem.features.send.v2.sendnft.confirm.model.transformers.NFTSendConfirmInitialStateTransformer
import com.tangem.features.send.v2.sendnft.confirm.model.transformers.NFTSendConfirmSendingStateTransformer
import com.tangem.features.send.v2.sendnft.confirm.model.transformers.NFTSendConfirmationNotificationsTransformer
import com.tangem.features.send.v2.sendnft.ui.state.NFTSendUM
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationUM
import com.tangem.features.send.v2.subcomponents.fee.SendFeeCheckReloadListener
import com.tangem.features.send.v2.subcomponents.fee.SendFeeCheckReloadTrigger
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeSelectorUM
@ -394,8 +394,8 @@ internal class NFTSendConfirmModel @Inject constructor(
)
appRouter.pop()
},
primaryButton = ButtonsUM.PrimaryButtonUM(
text = when (confirmUM) {
primaryButton = NavigationButton(
textReference = when (confirmUM) {
is ConfirmUM.Success -> resourceReference(R.string.common_close)
is ConfirmUM.Content -> if (confirmUM.isSending) {
resourceReference(R.string.send_sending)
@ -404,7 +404,7 @@ internal class NFTSendConfirmModel @Inject constructor(
}
else -> resourceReference(R.string.common_send)
},
iconResId = R.drawable.ic_tangem_24.takeIf { isReadyToSend },
iconRes = R.drawable.ic_tangem_24.takeIf { isReadyToSend },
isEnabled = confirmUM.isPrimaryButtonEnabled,
isHapticClick = isReadyToSend,
onClick = {
@ -412,14 +412,17 @@ internal class NFTSendConfirmModel @Inject constructor(
},
),
prevButton = null,
secondaryPairButtonsUM = ButtonsUM.SecondaryPairButtonsUM(
leftText = resourceReference(R.string.common_explore),
leftIconResId = R.drawable.ic_web_24,
onLeftClick = ::onExploreClick,
rightText = resourceReference(R.string.common_share),
rightIconResId = R.drawable.ic_share_24,
onRightClick = ::onShareClick,
).takeIf { confirmUM is ConfirmUM.Success },
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,
)
).takeIf { confirmUM is ConfirmUM.Success },
),
),
)

View file

@ -25,7 +25,7 @@ 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
import com.tangem.features.send.v2.sendnft.ui.state.NFTSendUM
import com.tangem.features.send.v2.subcomponents.destination.SendDestinationBlockComponent
import com.tangem.features.send.v2.subcomponents.destination.DefaultSendDestinationBlockComponent
import com.tangem.features.send.v2.subcomponents.fee.SendFeeBlockComponent
import com.tangem.features.send.v2.subcomponents.notifications
import com.tangem.features.send.v2.subcomponents.notifications.DefaultSendNotificationsComponent
@ -37,7 +37,7 @@ private const val BLOCKS_KEY = "BLOCKS_KEY"
@Composable
internal fun NFTSendConfirmContent(
nftSendUM: NFTSendUM,
destinationBlockComponent: SendDestinationBlockComponent,
destinationBlockComponent: DefaultSendDestinationBlockComponent,
nftDetailsBlockComponent: NFTDetailsBlockComponent,
feeBlockComponent: SendFeeBlockComponent,
notificationsComponent: DefaultSendNotificationsComponent,
@ -76,7 +76,7 @@ internal fun NFTSendConfirmContent(
private fun LazyListScope.blocks(
nftSendUM: NFTSendUM,
destinationBlockComponent: SendDestinationBlockComponent,
destinationBlockComponent: DefaultSendDestinationBlockComponent,
nftDetailsBlockComponent: NFTDetailsBlockComponent,
feeBlockComponent: SendFeeBlockComponent,
) {

View file

@ -5,6 +5,7 @@ import arrow.core.Either
import arrow.core.getOrElse
import arrow.core.left
import com.tangem.blockchain.common.transaction.TransactionFee
import com.tangem.common.ui.navigationButtons.NavigationUM
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
@ -30,14 +31,13 @@ import com.tangem.domain.wallets.models.UserWallet
import com.tangem.domain.wallets.models.requireColdWallet
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
import com.tangem.features.send.v2.api.NFTSendComponent
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
import com.tangem.features.send.v2.common.SendConfirmAlertFactory
import com.tangem.features.send.v2.common.ui.state.ConfirmUM
import com.tangem.features.send.v2.common.ui.state.NavigationUM
import com.tangem.features.send.v2.sendnft.confirm.NFTSendConfirmComponent
import com.tangem.features.send.v2.sendnft.ui.state.NFTSendUM
import com.tangem.features.send.v2.subcomponents.destination.SendDestinationComponent
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationUM
import com.tangem.features.send.v2.subcomponents.fee.SendFeeComponent
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeUM
import com.tangem.utils.coroutines.CoroutineDispatcherProvider

View file

@ -1,8 +1,8 @@
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.common.ui.state.NavigationUM
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationUM
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeUM
internal data class NFTSendUM(

View file

@ -10,7 +10,7 @@ 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
import com.tangem.features.send.v2.common.PredefinedValues
import com.tangem.features.send.v2.api.entity.PredefinedValues
import com.tangem.features.send.v2.subcomponents.amount.SendAmountComponentParams.AmountBlockParams
import com.tangem.features.send.v2.subcomponents.amount.model.SendAmountModel
import kotlinx.coroutines.flow.launchIn

View file

@ -7,11 +7,11 @@ import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.common.ui.amountScreen.AmountScreenContent
import com.tangem.common.ui.amountScreen.models.AmountState
import com.tangem.common.ui.navigationButtons.NavigationModelCallback
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.core.ui.res.TangemTheme
import com.tangem.features.send.v2.common.SendNavigationModelCallback
import com.tangem.features.send.v2.subcomponents.amount.SendAmountComponentParams.AmountParams
import com.tangem.features.send.v2.subcomponents.amount.model.SendAmountModel
@ -37,7 +37,7 @@ internal class SendAmountComponent(
)
}
interface ModelCallback : SendNavigationModelCallback {
interface ModelCallback : NavigationModelCallback {
fun onAmountResult(amountUM: AmountState, isResetPredefined: Boolean)
}
}

View file

@ -7,7 +7,7 @@ import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.features.send.v2.common.CommonSendRoute
import com.tangem.features.send.v2.common.PredefinedValues
import com.tangem.features.send.v2.api.entity.PredefinedValues
import com.tangem.features.send.v2.subcomponents.amount.SendAmountComponent.ModelCallback
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow

View file

@ -4,13 +4,14 @@ import androidx.compose.runtime.Stable
import arrow.core.getOrElse
import com.tangem.common.ui.amountScreen.AmountScreenClickIntents
import com.tangem.common.ui.amountScreen.converters.*
import com.tangem.common.ui.amountScreen.converters.field.AmountBoundaryUpdateTransformer
import com.tangem.common.ui.amountScreen.converters.field.AmountFieldChangeTransformer
import com.tangem.common.ui.amountScreen.converters.field.AmountFieldSetMaxAmountTransformer
import com.tangem.common.ui.amountScreen.converters.field.AmountBoundaryUpdateTransformer
import com.tangem.common.ui.amountScreen.converters.MaxEnterAmountConverter
import com.tangem.common.ui.amountScreen.models.AmountParameters
import com.tangem.common.ui.amountScreen.models.AmountState
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
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
@ -26,10 +27,8 @@ import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
import com.tangem.features.send.v2.api.SendFeatureToggles
import com.tangem.features.send.v2.common.PredefinedValues
import com.tangem.features.send.v2.common.ui.state.NavigationUM
import com.tangem.features.send.v2.api.entity.PredefinedValues
import com.tangem.features.send.v2.impl.R
import com.tangem.features.send.v2.send.ui.state.ButtonsUM
import com.tangem.features.send.v2.subcomponents.amount.SendAmountComponentParams
import com.tangem.features.send.v2.subcomponents.amount.SendAmountReduceListener
import com.tangem.features.send.v2.subcomponents.amount.SendAmountUpdateQRListener
@ -297,8 +296,8 @@ internal class SendAmountModel @Inject constructor(
R.drawable.ic_close_24
},
backIconClick = { params.onBackClick() },
primaryButton = ButtonsUM.PrimaryButtonUM(
text = if (route.isEditMode) {
primaryButton = NavigationButton(
textReference = if (route.isEditMode) {
resourceReference(R.string.common_continue)
} else {
resourceReference(R.string.common_next)
@ -312,9 +311,9 @@ internal class SendAmountModel @Inject constructor(
prevButton = if (params.isRedesignEnabled) {
null
} else {
ButtonsUM.PrimaryButtonUM(
text = TextReference.EMPTY,
iconResId = R.drawable.ic_back_24,
NavigationButton(
textReference = TextReference.EMPTY,
iconRes = R.drawable.ic_back_24,
isEnabled = true,
onClick = {
saveResult()

View file

@ -6,20 +6,24 @@ import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
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.common.PredefinedValues
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
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
import com.tangem.features.send.v2.subcomponents.destination.model.SendDestinationModel
import com.tangem.features.send.v2.subcomponents.destination.ui.DestinationBlock
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationUM
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
internal class SendDestinationBlockComponent(
appComponentContext: AppComponentContext,
private val params: SendDestinationComponentParams.DestinationBlockParams,
internal class DefaultSendDestinationBlockComponent @AssistedInject constructor(
@Assisted appComponentContext: AppComponentContext,
@Assisted private val params: SendDestinationComponentParams.DestinationBlockParams,
val onClick: () -> Unit,
val onResult: (DestinationUM) -> Unit,
) : ComposableContentComponent, AppComponentContext by appComponentContext {
) : SendDestinationBlockComponent, AppComponentContext by appComponentContext {
private val model: SendDestinationModel = getOrCreateModel(params = params)
@ -44,4 +48,12 @@ internal class SendDestinationBlockComponent(
onClick = onClick,
)
}
@AssistedFactory
interface Factory : SendDestinationBlockComponent.Factory {
override fun create(
context: AppComponentContext,
params: SendDestinationComponentParams.DestinationBlockParams,
): DefaultSendDestinationBlockComponent
}
}

View file

@ -6,16 +6,19 @@ import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
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.common.SendNavigationModelCallback
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationComponent
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.model.SendDestinationModel
import com.tangem.features.send.v2.subcomponents.destination.ui.SendDestinationContent
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationUM
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
internal class SendDestinationComponent(
appComponentContext: AppComponentContext,
private val params: SendDestinationComponentParams.DestinationParams,
) : ComposableContentComponent, AppComponentContext by appComponentContext {
internal class DefaultSendDestinationComponent @AssistedInject constructor(
@Assisted appComponentContext: AppComponentContext,
@Assisted private val params: SendDestinationComponentParams.DestinationParams,
) : SendDestinationComponent, AppComponentContext by appComponentContext {
private val model: SendDestinationModel = getOrCreateModel(params = params)
@ -29,7 +32,11 @@ internal class SendDestinationComponent(
SendDestinationContent(state = state, clickIntents = model, isBalanceHidden = isBalanceHidden)
}
interface ModelCallback : SendNavigationModelCallback {
fun onDestinationResult(destinationUM: DestinationUM)
@AssistedFactory
interface Factory : SendDestinationComponent.Factory {
override fun create(
context: AppComponentContext,
params: SendDestinationComponentParams.DestinationParams,
): DefaultSendDestinationComponent
}
}

View file

@ -0,0 +1,27 @@
package com.tangem.features.send.v2.subcomponents.destination.di
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationBlockComponent
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationComponent
import com.tangem.features.send.v2.subcomponents.destination.DefaultSendDestinationBlockComponent
import com.tangem.features.send.v2.subcomponents.destination.DefaultSendDestinationComponent
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
internal interface SendDestinationModule {
@Singleton
@Binds
fun provideSendDestinationComponentFactory(
impl: DefaultSendDestinationComponent.Factory,
): SendDestinationComponent.Factory
@Singleton
@Binds
fun provideSendDestinationBlockComponentFactory(
impl: DefaultSendDestinationBlockComponent.Factory,
): SendDestinationBlockComponent.Factory
}

View file

@ -3,6 +3,8 @@ package com.tangem.features.send.v2.subcomponents.destination.model
import androidx.compose.runtime.Stable
import arrow.core.getOrElse
import com.tangem.common.routing.AppRoute
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
@ -25,18 +27,16 @@ import com.tangem.domain.wallets.models.isLocked
import com.tangem.domain.wallets.models.isMultiCurrency
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
import com.tangem.features.send.v2.api.SendFeatureToggles
import com.tangem.features.send.v2.common.PredefinedValues
import com.tangem.features.send.v2.api.entity.PredefinedValues
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationComponentParams
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationComponentParams.DestinationBlockParams
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
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.common.ui.state.NavigationUM
import com.tangem.features.send.v2.impl.R
import com.tangem.features.send.v2.send.ui.state.ButtonsUM
import com.tangem.features.send.v2.subcomponents.destination.SendDestinationComponentParams
import com.tangem.features.send.v2.subcomponents.destination.SendDestinationComponentParams.DestinationBlockParams
import com.tangem.features.send.v2.subcomponents.destination.analytics.EnterAddressSource
import com.tangem.features.send.v2.subcomponents.destination.analytics.SendDestinationAnalyticEvents
import com.tangem.features.send.v2.subcomponents.destination.model.transformers.*
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationUM
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationWalletUM
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.coroutines.JobHolder
@ -335,8 +335,8 @@ internal class SendDestinationModel @Inject constructor(
} else {
::onQrCodeScanClick
},
primaryButton = ButtonsUM.PrimaryButtonUM(
text = if (route.isEditMode) {
primaryButton = NavigationButton(
textReference = if (route.isEditMode) {
resourceReference(R.string.common_continue)
} else {
resourceReference(R.string.common_next)
@ -347,10 +347,10 @@ internal class SendDestinationModel @Inject constructor(
params.onNextClick()
},
),
prevButton = if (isRedesignEnabled) {
ButtonsUM.PrimaryButtonUM(
text = TextReference.EMPTY,
iconResId = R.drawable.ic_back_24,
prevButton = if (!route.isEditMode && isRedesignEnabled) {
NavigationButton(
textReference = TextReference.EMPTY,
iconRes = R.drawable.ic_back_24,
isEnabled = true,
onClick = {
saveResult()

View file

@ -15,7 +15,7 @@ import com.tangem.features.send.v2.impl.R
import com.tangem.features.send.v2.subcomponents.destination.model.transformers.RECENT_DEFAULT_COUNT
import com.tangem.features.send.v2.subcomponents.destination.model.transformers.RECENT_KEY_TAG
import com.tangem.features.send.v2.subcomponents.destination.model.transformers.emptyListState
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationRecipientListUM
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationRecipientListUM
import com.tangem.utils.converter.Converter
import com.tangem.utils.extensions.isZero
import kotlinx.collections.immutable.ImmutableList

View file

@ -5,7 +5,7 @@ import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.features.send.v2.subcomponents.destination.model.transformers.WALLET_DEFAULT_COUNT
import com.tangem.features.send.v2.subcomponents.destination.model.transformers.WALLET_KEY_TAG
import com.tangem.features.send.v2.subcomponents.destination.model.transformers.emptyListState
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationRecipientListUM
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationRecipientListUM
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationWalletUM
import com.tangem.utils.converter.Converter
import kotlinx.collections.immutable.PersistentList

View file

@ -1,6 +1,6 @@
package com.tangem.features.send.v2.subcomponents.destination.model.transformers
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationRecipientListUM
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationRecipientListUM
import kotlinx.collections.immutable.toPersistentList
internal const val WALLET_DEFAULT_COUNT = 1

View file

@ -1,6 +1,6 @@
package com.tangem.features.send.v2.subcomponents.destination.model.transformers
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationUM
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
import com.tangem.utils.transformer.Transformer
internal class SendDestinationAddressTransformer(

View file

@ -7,8 +7,8 @@ import com.tangem.core.ui.extensions.resourceReference
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.network.Network
import com.tangem.features.send.v2.impl.R
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationTextFieldUM
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationUM
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationTextFieldUM
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
import com.tangem.utils.transformer.Transformer
internal class SendDestinationInitialStateTransformer(

View file

@ -1,6 +1,6 @@
package com.tangem.features.send.v2.subcomponents.destination.model.transformers
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationUM
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
import com.tangem.utils.transformer.Transformer
internal class SendDestinationMemoTransformer(

View file

@ -1,6 +1,6 @@
package com.tangem.features.send.v2.subcomponents.destination.model.transformers
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationUM
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
import com.tangem.utils.transformer.Transformer
internal class SendDestinationPredefinedStateTransformer(

View file

@ -4,7 +4,7 @@ import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.network.TxInfo
import com.tangem.features.send.v2.subcomponents.destination.model.converters.SendRecipientHistoryListConverter
import com.tangem.features.send.v2.subcomponents.destination.model.converters.SendRecipientWalletListConverter
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationUM
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationWalletUM
import com.tangem.utils.transformer.Transformer

View file

@ -6,8 +6,8 @@ import com.tangem.core.ui.extensions.resourceReference
import com.tangem.domain.transaction.error.AddressValidation
import com.tangem.domain.transaction.error.AddressValidationResult
import com.tangem.domain.transaction.error.ValidateMemoError
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
import com.tangem.features.send.v2.impl.R
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationUM
import com.tangem.utils.transformer.Transformer
import kotlinx.collections.immutable.toPersistentList
@ -34,6 +34,7 @@ internal class SendDestinationValidationResultTransformer(
val blockchainAddress =
(addressValidationResult.getOrNull() as? AddressValidation.Success.ValidNamedAddress)?.blockchainAddress
val memoField = state.memoTextField
return state.copy(
isValidating = false,
isPrimaryButtonEnabled = isValidAddress && isValidMemo,
@ -42,9 +43,9 @@ internal class SendDestinationValidationResultTransformer(
isError = state.addressTextField.value.isNotEmpty() && !isValidAddress,
blockchainAddress = blockchainAddress,
),
memoTextField = state.memoTextField?.copy(
value = state.memoTextField.value.takeIf { !shouldDisableMemo }.orEmpty(),
isError = state.memoTextField.value.isNotEmpty() && !isValidMemo,
memoTextField = memoField?.copy(
value = memoField.value.takeIf { !shouldDisableMemo }.orEmpty(),
isError = memoField.value.isNotEmpty() && !isValidMemo,
isEnabled = !shouldDisableMemo,
),
recent = state.recent.map { recent ->

View file

@ -1,6 +1,6 @@
package com.tangem.features.send.v2.subcomponents.destination.model.transformers
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationUM
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
import com.tangem.utils.transformer.Transformer
internal object SendDestinationValidationStartedTransformer : Transformer<DestinationUM> {

View file

@ -22,9 +22,9 @@ 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 com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationRecipientListUM
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationTextFieldUM
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
import kotlinx.collections.immutable.toImmutableList
@Composable

View file

@ -28,9 +28,9 @@ import com.tangem.core.ui.res.TangemTheme
import com.tangem.features.send.v2.impl.R
import com.tangem.features.send.v2.subcomponents.destination.analytics.EnterAddressSource
import com.tangem.features.send.v2.subcomponents.destination.model.SendDestinationClickIntents
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 com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationRecipientListUM
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationTextFieldUM
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
import kotlinx.collections.immutable.ImmutableList
private const val ADDRESS_FIELD_KEY = "ADDRESS_FIELD_KEY"

View file

@ -3,10 +3,10 @@ package com.tangem.features.send.v2.subcomponents.fee
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.common.ui.navigationButtons.NavigationModelCallback
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.common.SendNavigationModelCallback
import com.tangem.features.send.v2.subcomponents.fee.model.SendFeeModel
import com.tangem.features.send.v2.subcomponents.fee.ui.SendFeeContent
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeUM
@ -25,7 +25,7 @@ internal class SendFeeComponent(
SendFeeContent(state = state.value, clickIntents = model)
}
interface ModelCallback : SendNavigationModelCallback {
interface ModelCallback : NavigationModelCallback {
fun onFeeResult(feeUM: FeeUM)
}
}

View file

@ -2,6 +2,8 @@ package com.tangem.features.send.v2.subcomponents.fee.model
import androidx.compose.runtime.Stable
import com.tangem.blockchain.common.AmountType
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
@ -10,9 +12,7 @@ import com.tangem.core.navigation.url.UrlOpener
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.domain.transaction.usecase.IsFeeApproximateUseCase
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents.NonceInserted
import com.tangem.features.send.v2.common.ui.state.NavigationUM
import com.tangem.features.send.v2.impl.R
import com.tangem.features.send.v2.send.ui.state.ButtonsUM
import com.tangem.features.send.v2.subcomponents.fee.SendFeeCheckReloadListener
import com.tangem.features.send.v2.subcomponents.fee.SendFeeCheckReloadTrigger
import com.tangem.features.send.v2.subcomponents.fee.SendFeeComponentParams
@ -285,8 +285,8 @@ internal class SendFeeModel @Inject constructor(
subtitle = null,
backIconRes = R.drawable.ic_back_24,
backIconClick = params.onNextClick,
primaryButton = ButtonsUM.PrimaryButtonUM(
text = resourceReference(R.string.common_continue),
primaryButton = NavigationButton(
textReference = resourceReference(R.string.common_continue),
isEnabled = state.isPrimaryButtonEnabled,
onClick = ::onNextClick,
),

View file

@ -39,7 +39,7 @@ import com.tangem.features.swap.v2.impl.amount.model.converter.SwapAmountReadySt
import com.tangem.features.swap.v2.impl.amount.model.transformers.*
import com.tangem.features.swap.v2.impl.chooseprovider.SwapChooseProviderComponent
import com.tangem.features.swap.v2.impl.choosetoken.fromSupported.SwapChooseTokenNetworkListener
import com.tangem.features.swap.v2.impl.common.entity.NavigationUM
import com.tangem.common.ui.navigationButtons.NavigationUM
import com.tangem.features.swap.v2.impl.common.entity.SwapQuoteUM
import com.tangem.features.swap.v2.impl.common.entity.SwapQuoteUM.Content.DifferencePercent
import com.tangem.utils.coroutines.CoroutineDispatcherProvider

View file

@ -1,6 +1,6 @@
package com.tangem.features.swap.v2.impl.common
import com.tangem.features.swap.v2.impl.common.entity.NavigationUM
import com.tangem.common.ui.navigationButtons.NavigationUM
internal interface SwapNavigationModelCallback {
fun onNavigationResult(navigationUM: NavigationUM)

View file

@ -1,22 +0,0 @@
package com.tangem.features.swap.v2.impl.common.entity
import androidx.annotation.DrawableRes
import androidx.compose.runtime.Immutable
import com.tangem.common.ui.navigationButtons.NavigationButton
import com.tangem.core.ui.extensions.TextReference
@Immutable
internal sealed class NavigationUM {
data class Content(
val title: TextReference,
val subtitle: TextReference?,
@DrawableRes val backIconRes: Int,
val backIconClick: () -> Unit,
@DrawableRes val additionalIconRes: Int? = null,
val additionalIconClick: (() -> Unit)? = null,
val primaryButton: NavigationButton,
val secondaryPairButtonsUM: Pair<NavigationButton, NavigationButton>? = null,
) : NavigationUM()
data object Empty : NavigationUM()
}