Updated on 2026-08-14

This commit is contained in:
Tangem 2025-08-21 17:21:54 +02:00
parent b8f3d5315f
commit 54e094abac
8 changed files with 145 additions and 4 deletions

View file

@ -93,6 +93,7 @@ internal class DefaultTokenReceiveComponent @AssistedInject constructor(
notificationConfigs = model.state.value.notificationConfigs,
showMemoDisclaimer = model.params.config.showMemoDisclaimer,
fullName = model.params.config.cryptoCurrency.network.name,
tokenName = model.getTokenName(),
),
)
TokenReceiveRoutes.Warning -> TokenReceiveWarningComponent(

View file

@ -39,5 +39,6 @@ internal class TokenReceiveAssetsComponent(
val onDismiss: () -> Unit,
val showMemoDisclaimer: Boolean,
val fullName: String,
val tokenName: String,
)
}

View file

@ -1,10 +1,14 @@
package com.tangem.features.tokenreceive.model
import androidx.compose.runtime.Stable
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.domain.tokens.model.analytics.TokenReceiveNewAnalyticsEvent
import com.tangem.features.tokenreceive.component.TokenReceiveAssetsComponent
import com.tangem.features.tokenreceive.entity.ReceiveAddress
import com.tangem.features.tokenreceive.ui.state.ReceiveAssetsUM
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.MutableStateFlow
@ -16,10 +20,21 @@ import javax.inject.Inject
internal class TokenReceiveAssetsModel @Inject constructor(
paramsContainer: ParamsContainer,
override val dispatchers: CoroutineDispatcherProvider,
analyticsEventHandler: AnalyticsEventHandler,
) : Model() {
private val params = paramsContainer.require<TokenReceiveAssetsComponent.TokenReceiveAssetsParams>()
init {
analyticsEventHandler.send(
TokenReceiveNewAnalyticsEvent.ReceiveScreenOpened(
token = params.tokenName,
blockchainName = params.fullName,
ensStatus = configureEnsStatus(),
),
)
}
internal val state: StateFlow<ReceiveAssetsUM>
field = MutableStateFlow<ReceiveAssetsUM>(
ReceiveAssetsUM(
@ -32,4 +47,13 @@ internal class TokenReceiveAssetsModel @Inject constructor(
fullName = params.fullName,
),
)
private fun configureEnsStatus(): AnalyticsParam.EnsStatus {
val hasEnsAddress = params.addresses.values.any { it.type == ReceiveAddress.Type.Ens }
return if (hasEnsAddress) {
AnalyticsParam.EnsStatus.FULL
} else {
AnalyticsParam.EnsStatus.EMPTY
}
}
}

View file

@ -3,6 +3,7 @@ package com.tangem.features.tokenreceive.model
import com.arkivanov.decompose.router.stack.StackNavigation
import com.arkivanov.decompose.router.stack.push
import com.tangem.common.ui.notifications.NotificationUM
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
@ -19,6 +20,7 @@ import com.tangem.domain.models.ReceiveAddressModel
import com.tangem.domain.models.ens.EnsAddress
import com.tangem.domain.models.network.Network
import com.tangem.domain.tokens.SaveViewedTokenReceiveWarningUseCase
import com.tangem.domain.tokens.model.analytics.TokenReceiveNewAnalyticsEvent
import com.tangem.domain.transaction.usecase.GetReverseResolvedEnsAddressUseCase
import com.tangem.features.tokenreceive.TokenReceiveComponent
import com.tangem.features.tokenreceive.component.TokenReceiveModelCallback
@ -35,6 +37,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import javax.inject.Inject
@Suppress("LongParameterList")
@ModelScoped
internal class TokenReceiveModel @Inject constructor(
private val clipboardManager: ClipboardManager,
@ -43,6 +46,7 @@ internal class TokenReceiveModel @Inject constructor(
private val saveViewedTokenReceiveWarningUseCase: SaveViewedTokenReceiveWarningUseCase,
paramsContainer: ParamsContainer,
override val dispatchers: CoroutineDispatcherProvider,
private val analyticsEventHandler: AnalyticsEventHandler,
) : Model(), TokenReceiveModelCallback {
private val iconStateConverter by lazy(::CryptoCurrencyToIconStateConverter)
@ -61,11 +65,18 @@ internal class TokenReceiveModel @Inject constructor(
}
override fun onQrCodeClick(id: Int) {
analyticsEventHandler.send(
TokenReceiveNewAnalyticsEvent.QrScreenOpened(
token = getTokenName(),
blockchainName = params.config.cryptoCurrency.network.name,
),
)
stackNavigation.push(configuration = TokenReceiveRoutes.QrCode(addressId = id))
}
override fun onCopyClick(id: Int) {
val addressToCopy = state.value.addresses[id] ?: return
sendCopyActionAnalytic(addressToCopy)
clipboardManager.setText(text = addressToCopy.value, isSensitive = true)
}
@ -85,6 +96,13 @@ internal class TokenReceiveModel @Inject constructor(
}
}
internal fun getTokenName(): String {
return when (val asset = params.config.asset) {
Asset.Currency -> params.config.cryptoCurrency.symbol
Asset.NFT -> asset.name
}
}
private fun mapAddresses(addresses: List<ReceiveAddressModel>): ImmutableMap<Int, ReceiveAddress> {
return buildMap {
addresses.mapIndexed { index, model ->
@ -151,10 +169,7 @@ internal class TokenReceiveModel @Inject constructor(
title = resourceReference(
R.string.receive_bottom_sheet_warning_title,
wrappedList(
when (val asset = params.config.asset) {
Asset.Currency -> params.config.cryptoCurrency.symbol
Asset.NFT -> asset.name
},
getTokenName(),
params.config.cryptoCurrency.network.name,
),
),
@ -183,4 +198,22 @@ internal class TokenReceiveModel @Inject constructor(
notificationConfigs = getNotifications().toImmutableList(),
)
}
private fun sendCopyActionAnalytic(receiveAddress: ReceiveAddress) {
val event = when (receiveAddress.type) {
is ReceiveAddress.Type.Default -> {
TokenReceiveNewAnalyticsEvent.ButtonCopyAddress(
token = getTokenName(),
blockchainName = params.config.cryptoCurrency.network.name,
)
}
ReceiveAddress.Type.Ens -> {
TokenReceiveNewAnalyticsEvent.ButtonCopyEns(
token = getTokenName(),
blockchainName = params.config.cryptoCurrency.network.name,
)
}
}
analyticsEventHandler.send(event)
}
}