Updated on 2026-08-14

This commit is contained in:
Tangem 2026-07-03 09:17:57 +02:00
parent 575081de3e
commit 49aede77dc
11 changed files with 67 additions and 68 deletions

View file

@ -111,7 +111,11 @@ private fun CurrencyNetworkName(text: TextReference, modifier: Modifier = Modifi
private fun AddToPortfolioButton(state: OnrampAddToPortfolioUM.AddButtonUM, modifier: Modifier = Modifier) {
TangemButton(
text = state.text.resolveReference(),
icon = TangemButtonIconPosition.End(iconResId = R.drawable.ic_tangem_24),
icon = if (state.isTangemIconVisible) {
TangemButtonIconPosition.End(iconResId = R.drawable.ic_tangem_24)
} else {
TangemButtonIconPosition.None
},
onClick = state.onClick,
colors = TangemButtonsDefaults.primaryButtonColors,
showProgress = state.isProgress,

View file

@ -12,4 +12,5 @@ internal data class TonInitializeAccountBottomSheetConfig(
val isButtonEnabled: Boolean,
val isButtonLoading: Boolean,
val feeState: FeeState,
val isColdWalletInteractionIconVisible: Boolean,
) : TangemBottomSheetConfigContent

View file

@ -25,6 +25,7 @@ internal class ShowTonInitializeBottomSheetTransformer(
isButtonEnabled = false,
feeState = FeeState.Loading,
isButtonLoading = false,
isColdWalletInteractionIconVisible = prevState.isColdWalletInteractionIconVisible,
),
),
)

View file

@ -101,23 +101,32 @@ internal fun TonInitializeAccountBottomSheet(config: TangemBottomSheetConfig) {
SpacerH(height = 20.dp)
TangemButton(
text = stringResourceSafe(R.string.common_activate),
icon = TangemButtonIconPosition.End(iconResId = R.drawable.ic_tangem_24),
onClick = content.onButtonClick,
colors = TangemButtonsDefaults.primaryButtonColors,
showProgress = content.feeState is FeeState.Loading || content.isButtonLoading,
enabled = content.isButtonEnabled,
size = TangemButtonSize.WideAction,
textStyle = TangemTheme.typography.subtitle1,
modifier = Modifier.fillMaxWidth(),
)
ActivateButton(content)
SpacerH(height = 8.dp)
}
}
}
@Composable
private fun ActivateButton(content: TonInitializeAccountBottomSheetConfig, modifier: Modifier = Modifier) {
TangemButton(
text = stringResourceSafe(R.string.common_activate),
icon = if (content.isColdWalletInteractionIconVisible) {
TangemButtonIconPosition.End(iconResId = R.drawable.ic_tangem_24)
} else {
TangemButtonIconPosition.None
},
onClick = content.onButtonClick,
colors = TangemButtonsDefaults.primaryButtonColors,
showProgress = content.feeState is FeeState.Loading || content.isButtonLoading,
enabled = content.isButtonEnabled,
size = TangemButtonSize.WideAction,
textStyle = TangemTheme.typography.subtitle1,
modifier = modifier.fillMaxWidth(),
)
}
// region Preview
@Composable
@Preview(showBackground = true, widthDp = 360)
@ -149,6 +158,7 @@ private fun Preview_TonInitializeAccountBottomSheetContent() {
isFeeApproximate = false,
isFeeConvertibleToFiat = true,
),
isColdWalletInteractionIconVisible = true,
),
),

View file

@ -3,38 +3,29 @@ package com.tangem.feature.tokendetails.presentation.tokendetails.model
import androidx.compose.runtime.Stable
import arrow.core.getOrElse
import arrow.core.right
import com.tangem.utils.logging.TangemLogger
import com.arkivanov.decompose.router.slot.SlotNavigation
import com.arkivanov.decompose.router.slot.activate
import com.arkivanov.decompose.router.slot.dismiss
import com.tangem.blockchain.common.address.AddressType
import com.tangem.domain.dynamicaddresses.IsDynamicAddressesAvailableUseCase
import com.tangem.domain.dynamicaddresses.IsXpubSupportedUseCase
import com.tangem.common.extensions.calculateSha256
import com.tangem.common.extensions.hexToBytes
import com.tangem.common.extensions.toHexString
import com.tangem.domain.dynamicaddresses.repository.DynamicAddressesRepository
import com.tangem.common.routing.AppRoute
import com.tangem.common.routing.AppRouter
import com.tangem.common.ui.bottomsheet.receive.AddressModel
import com.tangem.common.ui.bottomsheet.receive.mapToAddressModels
import com.tangem.features.rating.RatingComponent
import com.tangem.feature.swap.domain.SwapFeedbackUseCase
import com.tangem.feature.swap.domain.models.domain.SwapFeedbackParams
import com.tangem.features.swap.SwapFeatureToggles
import com.tangem.common.ui.tokens.getUnavailabilityReasonText
import com.tangem.common.ui.userwallet.converter.WalletIconUMConverter
import com.tangem.common.ui.userwallet.ext.walletInterationIcon
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.event.OfframpAnalyticsEvent
import com.tangem.core.decompose.di.GlobalUiMessageSender
import com.tangem.common.ui.userwallet.converter.WalletIconUMConverter
import com.tangem.domain.account.supplier.SingleAccountListSupplier
import com.tangem.domain.common.wallets.UserWalletsListRepository
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.decompose.ui.UiMessageSender
import com.tangem.core.navigation.url.UrlOpener
import com.tangem.common.ui.tokens.getUnavailabilityReasonText
import com.tangem.core.ui.DesignFeatureToggles
import com.tangem.core.ui.clipboard.ClipboardManager
import com.tangem.core.ui.ds.image.DeviceIconUM
@ -50,13 +41,18 @@ import com.tangem.domain.account.status.usecase.IsAccountsModeEnabledUseCase
import com.tangem.domain.account.status.usecase.IsCryptoCurrencyCouldHideUseCase
import com.tangem.domain.account.status.usecase.ManageCryptoCurrenciesUseCase
import com.tangem.domain.account.status.utils.CryptoCurrencyBalanceFetcher
import com.tangem.domain.account.supplier.SingleAccountListSupplier
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
import com.tangem.domain.card.IsWalletBackupProblematicUseCase
import com.tangem.domain.feedback.SendBackupProblemEmailUseCase
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.demo.IsDemoCardUseCase
import com.tangem.domain.dynamicaddresses.DynamicAddressesSupportedBlockchains
import com.tangem.domain.dynamicaddresses.IsDynamicAddressesAvailableUseCase
import com.tangem.domain.dynamicaddresses.IsXpubSupportedUseCase
import com.tangem.domain.dynamicaddresses.repository.DynamicAddressesRepository
import com.tangem.domain.feedback.SendBackupProblemEmailUseCase
import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.TokenReceiveNotification
import com.tangem.domain.models.account.Account
@ -89,41 +85,23 @@ import com.tangem.domain.transaction.error.SendTransactionError
import com.tangem.domain.transaction.usecase.*
import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase
import com.tangem.domain.txhistory.usecase.GetFixedTxHistoryItemsUseCase
import com.tangem.domain.wallets.usecase.GetExploreUrlUseCase
import com.tangem.domain.wallets.usecase.GetWalletIconUseCase
import com.tangem.domain.wallets.usecase.GetExtendedPublicKeyForCurrencyUseCase
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
import com.tangem.domain.wallets.usecase.NetworkHasDerivationUseCase
import com.tangem.domain.wallets.usecase.*
import com.tangem.domain.yield.supply.models.YieldSupplyRewardBalance
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetRewardsBalanceUseCase
import com.tangem.feature.swap.domain.SwapFeedbackUseCase
import com.tangem.feature.swap.domain.models.domain.SwapFeedbackParams
import com.tangem.feature.tokendetails.deeplink.TokenDetailsDeepLinkActionListener
import com.tangem.feature.tokendetails.domain.GetCurrencyWarningsUseCase
import com.tangem.feature.tokendetails.presentation.router.InnerTokenDetailsRouter
import com.tangem.feature.tokendetails.presentation.tokendetails.analytics.TokenDetailsCurrencyStatusAnalyticsSender
import com.tangem.feature.tokendetails.presentation.tokendetails.analytics.TokenDetailsNotificationsAnalyticsSender
import com.tangem.feature.tokendetails.presentation.tokendetails.route.TokenDetailsBottomSheetConfig
import com.tangem.feature.tokendetails.presentation.tokendetails.state.AddFundsUM
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenBalanceSegmentedButtonConfig
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsStateController
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsUM
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TransferUM
import com.tangem.feature.tokendetails.presentation.tokendetails.state.*
import com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.QuickTopUpBlockFactory
import com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.TokenDetailsStateFactory
import com.tangem.feature.tokendetails.presentation.tokendetails.state.transformer.InitializeWithCryptoCurrencyTransformer
import com.tangem.feature.tokendetails.presentation.tokendetails.state.transformer.SetBalanceTransformer
import com.tangem.feature.tokendetails.presentation.tokendetails.state.transformer.SetYieldSupplyBalanceTransformer
import com.tangem.feature.tokendetails.presentation.tokendetails.state.transformer.UpdateActionButtonsTransformer
import com.tangem.feature.tokendetails.presentation.tokendetails.state.transformer.UpdateAddFundsTransformer
import com.tangem.feature.tokendetails.presentation.tokendetails.state.transformer.UpdateTransferTransformer
import com.tangem.feature.tokendetails.presentation.tokendetails.state.transformer.UpdateZeroBalanceActionsTransformer
import com.tangem.feature.tokendetails.presentation.tokendetails.state.transformer.BindAddFundsActionButtonTransformer
import com.tangem.feature.tokendetails.presentation.tokendetails.state.transformer.BindTransferActionButtonTransformer
import com.tangem.feature.tokendetails.presentation.tokendetails.state.transformer.SetTopBarTitleTransformer
import com.tangem.feature.tokendetails.presentation.tokendetails.state.transformer.ToggleBalanceTypeTransformer
import com.tangem.feature.tokendetails.presentation.tokendetails.state.transformer.UpdateStakingNotificationTransformer
import com.tangem.feature.tokendetails.presentation.tokendetails.state.transformer.UpdateNotificationsTransformer
import com.tangem.feature.tokendetails.presentation.tokendetails.state.transformer.UpdateTopBarMenuTransformer
import com.tangem.feature.tokendetails.presentation.tokendetails.state.transformer.*
import com.tangem.features.rating.RatingComponent
import com.tangem.features.swap.SwapFeatureToggles
import com.tangem.features.tokendetails.ExpressTransactionsEvent
import com.tangem.features.tokendetails.ExpressTransactionsEventListener
import com.tangem.features.tokendetails.TokenDetailsComponent
@ -134,6 +112,7 @@ import com.tangem.features.yield.supply.api.analytics.YieldSupplyAnalytics
import com.tangem.utils.Provider
import com.tangem.utils.coroutines.*
import com.tangem.utils.extensions.isZero
import com.tangem.utils.logging.TangemLogger
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
@ -438,6 +417,7 @@ internal class TokenDetailsModel @Inject constructor(
UpdateNotificationsTransformer(
warnings = warnings,
clickIntents = this@TokenDetailsModel,
walletInteractionIcon = walletInterationIcon(userWallet),
),
)
}

View file

@ -1,5 +1,6 @@
package com.tangem.feature.tokendetails.presentation.tokendetails.state.transformer
import androidx.annotation.DrawableRes
import com.tangem.blockchain.common.Blockchain
import com.tangem.core.ui.R
import com.tangem.core.ui.ds.button.TangemButtonType
@ -31,6 +32,7 @@ import com.tangem.core.res.R as CoreResR
internal class UpdateNotificationsTransformer(
private val warnings: Set<CryptoCurrencyWarning>,
private val clickIntents: TokenDetailsClickIntents,
@DrawableRes private val walletInteractionIcon: Int?,
) : Transformer<TokenDetailsUM> {
override fun transform(prevState: TokenDetailsUM): TokenDetailsUM {
@ -170,10 +172,12 @@ internal class UpdateNotificationsTransformer(
TangemMessageButtonUM(
text = resourceReference(CoreResR.string.alert_button_try_again),
type = TangemButtonType.Primary,
tangemIconUM = TangemIconUM.Icon(
R.drawable.ic_tangem_24,
tintReference = { TangemTheme.colors2.graphic.neutral.primaryInverted },
),
tangemIconUM = walletInteractionIcon?.let { iconRes ->
TangemIconUM.Icon(
iconRes = iconRes,
tintReference = { TangemTheme.colors2.graphic.neutral.primaryInverted },
)
},
onClick = clickIntents::onRetryIncompleteTransactionClick,
),
),

View file

@ -11,13 +11,8 @@ import com.tangem.domain.tokens.model.warnings.DynamicAddressesWarnings
import com.tangem.domain.tokens.model.warnings.HederaWarnings
import com.tangem.domain.tokens.model.warnings.KaspaWarnings
import com.tangem.feature.tokendetails.presentation.tokendetails.model.TokenDetailsClickIntents
import com.tangem.feature.tokendetails.presentation.tokendetails.state.AddFundsUM
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsBalanceBlockUM
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsTopAppBarUM
import com.tangem.feature.tokendetails.presentation.tokendetails.state.*
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsTopAppBarUM.TitleState
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsUM
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TransferUM
import com.tangem.feature.tokendetails.presentation.tokendetails.state.ZeroBalanceActionsUM
import io.mockk.mockk
import io.mockk.verify
import kotlinx.collections.immutable.persistentListOf
@ -684,6 +679,7 @@ class UpdateNotificationsTransformerTest {
private fun createTransformer(warnings: Set<CryptoCurrencyWarning>) = UpdateNotificationsTransformer(
warnings = warnings,
clickIntents = clickIntents,
walletInteractionIcon = null,
)
private fun initialState(): TokenDetailsUM = TokenDetailsUM(

View file

@ -1,6 +1,7 @@
package com.tangem.features.walletconnect.transaction.components.send
import androidx.compose.runtime.Composable
import com.tangem.common.ui.userwallet.ext.walletInterationIcon
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
@ -26,6 +27,7 @@ internal class WcSendMultipleTransactionsComponent(
onDismissRequest = { model.popBack() },
content = TangemBottomSheetConfigContent.Empty,
),
walletInteractionIcon = walletInterationIcon(model.userWallet),
onConfirm = onConfirm,
onBack = { model.popBack() },
)

View file

@ -1,13 +1,10 @@
package com.tangem.features.walletconnect.transaction.converter
import com.tangem.common.ui.account.AccountTitleUM
import com.tangem.common.ui.userwallet.ext.walletInterationIcon
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.wallet.isHotWallet
import com.tangem.domain.walletconnect.model.WcBitcoinMethod
import com.tangem.domain.walletconnect.model.WcEthMethod
import com.tangem.domain.walletconnect.model.WcMethod
import com.tangem.domain.walletconnect.model.WcPsbtOutput
import com.tangem.domain.walletconnect.model.WcSolanaMethod
import com.tangem.domain.walletconnect.model.*
import com.tangem.domain.walletconnect.usecase.method.BlockAidTransactionCheck
import com.tangem.domain.walletconnect.usecase.method.WcMethodContext
import com.tangem.domain.walletconnect.usecase.method.WcSignState
@ -74,6 +71,7 @@ internal class WcSendTransactionUMConverter @Inject constructor(
}
},
feeErrorNotification = feeErrorNotification,
walletInteractionIcon = walletInterationIcon(value.context.session.wallet),
isHoldToConfirmEnabled = value.context.session.wallet.isHotWallet,
),
feeSelectorUM = when (value.feeState) {

View file

@ -12,7 +12,7 @@ internal data class WcGetAddressesUM(
val networkInfo: WcNetworkInfoUM,
val addresses: List<AddressInfo>,
val isLoading: Boolean,
@DrawableRes val walletInteractionIcon: Int,
@DrawableRes val walletInteractionIcon: Int?,
val onApprove: () -> Unit,
val onReject: () -> Unit,
) {

View file

@ -1,6 +1,7 @@
package com.tangem.features.walletconnect.transaction.ui.send
import android.content.res.Configuration
import androidx.annotation.DrawableRes
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
@ -32,6 +33,7 @@ import com.tangem.core.ui.res.TangemThemePreview
@Composable
internal fun WcSendMultipleTransactionsModalBottomSheet(
config: TangemBottomSheetConfig,
@DrawableRes walletInteractionIcon: Int?,
onConfirm: () -> Unit,
onBack: () -> Unit,
) {
@ -50,7 +52,7 @@ internal fun WcSendMultipleTransactionsModalBottomSheet(
.background(TangemTheme.colors.icon.informative.copy(alpha = 0.1f))
.padding(12.dp),
painter = rememberVectorPainter(
ImageVector.vectorResource(com.tangem.core.ui.R.drawable.ic_alert_24),
ImageVector.vectorResource(R.drawable.ic_alert_24),
),
tint = TangemTheme.colors.icon.attention,
contentDescription = null,
@ -78,7 +80,7 @@ internal fun WcSendMultipleTransactionsModalBottomSheet(
SpacerH8()
PrimaryButtonIconEnd(
modifier = Modifier.fillMaxWidth(),
iconResId = R.drawable.ic_tangem_24,
iconResId = walletInteractionIcon,
text = stringResourceSafe(R.string.common_send),
onClick = onConfirm,
)
@ -98,6 +100,7 @@ private fun WcSendTransactionBottomSheetPreview() {
onDismissRequest = {},
content = TangemBottomSheetConfigContent.Empty,
),
walletInteractionIcon = R.drawable.ic_tangem_24,
onConfirm = {},
onBack = {},
)