Updated on 2026-08-14
This commit is contained in:
parent
c77fcafdc2
commit
b4b35916d9
7 changed files with 55 additions and 12 deletions
|
|
@ -314,12 +314,14 @@ object NotificationsFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("LongParameterList")
|
||||||
fun MutableList<NotificationUM>.addExceedsBalanceNotification(
|
fun MutableList<NotificationUM>.addExceedsBalanceNotification(
|
||||||
cryptoCurrencyWarning: CryptoCurrencyWarning?,
|
cryptoCurrencyWarning: CryptoCurrencyWarning?,
|
||||||
cryptoCurrencyStatus: CryptoCurrencyStatus,
|
cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||||
shouldMergeFeeNetworkName: Boolean,
|
shouldMergeFeeNetworkName: Boolean,
|
||||||
onClick: (CryptoCurrency) -> Unit,
|
onClick: (CryptoCurrency) -> Unit,
|
||||||
onAnalyticsEvent: (CryptoCurrency) -> Unit,
|
onAnalyticsEvent: (CryptoCurrency) -> Unit,
|
||||||
|
onResetAnalyticsEvent: (CryptoCurrency) -> Unit,
|
||||||
) {
|
) {
|
||||||
when (cryptoCurrencyWarning) {
|
when (cryptoCurrencyWarning) {
|
||||||
is CryptoCurrencyWarning.BalanceNotEnoughForFee -> {
|
is CryptoCurrencyWarning.BalanceNotEnoughForFee -> {
|
||||||
|
|
@ -357,7 +359,7 @@ object NotificationsFactory {
|
||||||
)
|
)
|
||||||
onAnalyticsEvent(cryptoCurrencyWarning.currency)
|
onAnalyticsEvent(cryptoCurrencyWarning.currency)
|
||||||
}
|
}
|
||||||
else -> Unit
|
else -> onResetAnalyticsEvent(cryptoCurrencyStatus.currency)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.tangem.core.analytics.api
|
||||||
|
|
||||||
|
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||||
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
|
class ResettableOneTimeEventSender(val analyticsEventHandler: AnalyticsEventHandler) {
|
||||||
|
|
||||||
|
private val sentEvents = ConcurrentHashMap<String, AnalyticsEvent>()
|
||||||
|
|
||||||
|
fun sendEventOnce(key: String, event: AnalyticsEvent) {
|
||||||
|
if (sentEvents[key] != null) return
|
||||||
|
analyticsEventHandler.send(event)
|
||||||
|
sentEvents[key] = event
|
||||||
|
}
|
||||||
|
|
||||||
|
fun reset(key: String) {
|
||||||
|
sentEvents.remove(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -40,7 +40,7 @@ class GetBalanceNotEnoughForFeeWarningUseCase(
|
||||||
val feePaidCurrency = currenciesRepository.getFeePaidCurrency(userWalletId, tokenStatus.currency.network)
|
val feePaidCurrency = currenciesRepository.getFeePaidCurrency(userWalletId, tokenStatus.currency.network)
|
||||||
val feeTokenBalance = feeStatus.value.amount ?: BigDecimal.ZERO
|
val feeTokenBalance = feeStatus.value.amount ?: BigDecimal.ZERO
|
||||||
|
|
||||||
val isFeePaidByCoin = tokenStatus.currency is CryptoCurrency.Token
|
val isSendingCurrencyToken = tokenStatus.currency is CryptoCurrency.Token
|
||||||
val isFeePaidByToken =
|
val isFeePaidByToken =
|
||||||
feePaidCurrency is FeePaidCurrency.Token && tokenStatus.currency.id != feePaidCurrency.tokenId
|
feePaidCurrency is FeePaidCurrency.Token && tokenStatus.currency.id != feePaidCurrency.tokenId
|
||||||
|
|
||||||
|
|
@ -49,10 +49,15 @@ class GetBalanceNotEnoughForFeeWarningUseCase(
|
||||||
feeStatus.currency is CryptoCurrency.Token
|
feeStatus.currency is CryptoCurrency.Token
|
||||||
|
|
||||||
val warning = when {
|
val warning = when {
|
||||||
|
isFeePaidByGaslessToken && feeTokenBalance == BigDecimal.ZERO -> {
|
||||||
|
CryptoCurrencyWarning.BalanceNotEnoughForFee(
|
||||||
|
tokenCurrency = tokenStatus.currency,
|
||||||
|
coinCurrency = feeStatus.currency,
|
||||||
|
)
|
||||||
|
}
|
||||||
feePaidCurrency is FeePaidCurrency.Coin &&
|
feePaidCurrency is FeePaidCurrency.Coin &&
|
||||||
isFeePaidByCoin &&
|
isSendingCurrencyToken &&
|
||||||
fee > feeTokenBalance &&
|
fee > feeTokenBalance -> {
|
||||||
!isFeePaidByGaslessToken -> {
|
|
||||||
CryptoCurrencyWarning.BalanceNotEnoughForFee(
|
CryptoCurrencyWarning.BalanceNotEnoughForFee(
|
||||||
tokenCurrency = tokenStatus.currency,
|
tokenCurrency = tokenStatus.currency,
|
||||||
coinCurrency = feeStatus.currency,
|
coinCurrency = feeStatus.currency,
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.tangem.features.send.v2.api.subcomponents.feeSelector.analytics
|
||||||
|
|
||||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||||
import com.tangem.core.analytics.models.AnalyticsParam
|
import com.tangem.core.analytics.models.AnalyticsParam
|
||||||
|
import com.tangem.core.analytics.models.AnalyticsParam.Key.BLOCKCHAIN
|
||||||
import com.tangem.core.analytics.models.AnalyticsParam.Key.FEE_TOKEN
|
import com.tangem.core.analytics.models.AnalyticsParam.Key.FEE_TOKEN
|
||||||
import com.tangem.core.analytics.models.AnalyticsParam.Key.FEE_TYPE
|
import com.tangem.core.analytics.models.AnalyticsParam.Key.FEE_TYPE
|
||||||
import com.tangem.core.analytics.models.AnalyticsParam.Key.SOURCE
|
import com.tangem.core.analytics.models.AnalyticsParam.Key.SOURCE
|
||||||
|
|
@ -21,6 +22,7 @@ sealed class CommonSendFeeAnalyticEvents(
|
||||||
val feeType: AnalyticsParam.FeeType,
|
val feeType: AnalyticsParam.FeeType,
|
||||||
val source: CommonSendSource,
|
val source: CommonSendSource,
|
||||||
val feeToken: String,
|
val feeToken: String,
|
||||||
|
val blockchain: String,
|
||||||
) : CommonSendFeeAnalyticEvents(
|
) : CommonSendFeeAnalyticEvents(
|
||||||
category = categoryName,
|
category = categoryName,
|
||||||
event = "Fee Selected",
|
event = "Fee Selected",
|
||||||
|
|
@ -28,15 +30,20 @@ sealed class CommonSendFeeAnalyticEvents(
|
||||||
FEE_TYPE to feeType.value,
|
FEE_TYPE to feeType.value,
|
||||||
SOURCE to source.analyticsName,
|
SOURCE to source.analyticsName,
|
||||||
FEE_TOKEN to feeToken,
|
FEE_TOKEN to feeToken,
|
||||||
|
BLOCKCHAIN to blockchain,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
/** Custom fee selected */
|
/** Custom fee selected */
|
||||||
data class CustomFeeButtonClicked(
|
data class CustomFeeButtonClicked(
|
||||||
override val categoryName: String,
|
override val categoryName: String,
|
||||||
|
val blockchain: String,
|
||||||
) : CommonSendFeeAnalyticEvents(
|
) : CommonSendFeeAnalyticEvents(
|
||||||
category = categoryName,
|
category = categoryName,
|
||||||
event = "Custom Fee Clicked",
|
event = "Custom Fee Clicked",
|
||||||
|
params = mapOf(
|
||||||
|
BLOCKCHAIN to blockchain,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
/** Custom fee edited */
|
/** Custom fee edited */
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import com.tangem.common.ui.notifications.NotificationsFactory.addReserveAmountE
|
||||||
import com.tangem.common.ui.notifications.NotificationsFactory.addTransactionLimitErrorNotification
|
import com.tangem.common.ui.notifications.NotificationsFactory.addTransactionLimitErrorNotification
|
||||||
import com.tangem.common.ui.notifications.NotificationsFactory.addValidateTransactionNotifications
|
import com.tangem.common.ui.notifications.NotificationsFactory.addValidateTransactionNotifications
|
||||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||||
|
import com.tangem.core.analytics.api.ResettableOneTimeEventSender
|
||||||
import com.tangem.core.decompose.di.ModelScoped
|
import com.tangem.core.decompose.di.ModelScoped
|
||||||
import com.tangem.core.decompose.model.Model
|
import com.tangem.core.decompose.model.Model
|
||||||
import com.tangem.core.decompose.model.ParamsContainer
|
import com.tangem.core.decompose.model.ParamsContainer
|
||||||
|
|
@ -82,6 +83,7 @@ internal class NotificationsModel @Inject constructor(
|
||||||
private val feeCryptoCurrencyStatus = params.notificationData.feeCryptoCurrencyStatus
|
private val feeCryptoCurrencyStatus = params.notificationData.feeCryptoCurrencyStatus
|
||||||
private val currency = cryptoCurrencyStatus.currency
|
private val currency = cryptoCurrencyStatus.currency
|
||||||
private val appCurrency = params.appCurrency
|
private val appCurrency = params.appCurrency
|
||||||
|
private val resettableOneTimeEventSender = ResettableOneTimeEventSender(analyticsEventHandler)
|
||||||
|
|
||||||
private var notificationData = params.notificationData
|
private var notificationData = params.notificationData
|
||||||
|
|
||||||
|
|
@ -250,13 +252,18 @@ internal class NotificationsModel @Inject constructor(
|
||||||
shouldMergeFeeNetworkName = BlockchainUtils.isArbitrum(currency.network.backendId),
|
shouldMergeFeeNetworkName = BlockchainUtils.isArbitrum(currency.network.backendId),
|
||||||
onClick = ::showTokenDetails,
|
onClick = ::showTokenDetails,
|
||||||
onAnalyticsEvent = {
|
onAnalyticsEvent = {
|
||||||
analyticsEventHandler.send(
|
val event = NotificationsAnalyticEvents.NoticeNotEnoughFee(
|
||||||
NotificationsAnalyticEvents.NoticeNotEnoughFee(
|
categoryName = analyticsCategoryName,
|
||||||
categoryName = analyticsCategoryName,
|
token = cryptoCurrencyStatus.currency.symbol,
|
||||||
token = cryptoCurrencyStatus.currency.symbol,
|
blockchain = cryptoCurrencyStatus.currency.network.name,
|
||||||
blockchain = cryptoCurrencyStatus.currency.network.name,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
resettableOneTimeEventSender.sendEventOnce(
|
||||||
|
key = EXCEEDS_BALANCE_EVENT,
|
||||||
|
event = event,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onResetAnalyticsEvent = {
|
||||||
|
resettableOneTimeEventSender.reset(EXCEEDS_BALANCE_EVENT)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if (!BlockchainUtils.isCardano(currency.network.rawId)) {
|
if (!BlockchainUtils.isCardano(currency.network.rawId)) {
|
||||||
|
|
@ -389,5 +396,6 @@ internal class NotificationsModel @Inject constructor(
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val TRON_FEE_NOTIFICATION_MAX_SHOW_COUNT = 3
|
const val TRON_FEE_NOTIFICATION_MAX_SHOW_COUNT = 3
|
||||||
|
private const val EXCEEDS_BALANCE_EVENT = "EXCEED_BALANCE_EVENT"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -235,6 +235,7 @@ internal class AddStakingNotificationsTransformer(
|
||||||
shouldMergeFeeNetworkName = BlockchainUtils.isArbitrum(network.backendId),
|
shouldMergeFeeNetworkName = BlockchainUtils.isArbitrum(network.backendId),
|
||||||
onClick = prevState.clickIntents::openTokenDetails,
|
onClick = prevState.clickIntents::openTokenDetails,
|
||||||
onAnalyticsEvent = { prevState.clickIntents.onNotEnoughFeeNotificationShow() },
|
onAnalyticsEvent = { prevState.clickIntents.onNotEnoughFeeNotificationShow() },
|
||||||
|
onResetAnalyticsEvent = { /*no-op*/ },
|
||||||
)
|
)
|
||||||
if (!BlockchainUtils.isCardano(network.rawId)) {
|
if (!BlockchainUtils.isCardano(network.rawId)) {
|
||||||
addDustWarningNotification(
|
addDustWarningNotification(
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,8 @@ internal class YieldSupplyNotificationsModel @Inject constructor(
|
||||||
blockchainId = cryptoCurrencyStatus.currency.network.backendId,
|
blockchainId = cryptoCurrencyStatus.currency.network.backendId,
|
||||||
),
|
),
|
||||||
onClick = ::openTokenDetails,
|
onClick = ::openTokenDetails,
|
||||||
onAnalyticsEvent = { },
|
onAnalyticsEvent = { /*no-op*/ },
|
||||||
|
onResetAnalyticsEvent = { /*no-op*/ },
|
||||||
)
|
)
|
||||||
|
|
||||||
addFeeUnreachableNotification(
|
addFeeUnreachableNotification(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue