diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/analytics/SendAnalyticEvents.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/analytics/SendAnalyticEvents.kt index b62f028e0a..2f48bcb034 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/analytics/SendAnalyticEvents.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/analytics/SendAnalyticEvents.kt @@ -1,9 +1,12 @@ package com.tangem.features.send.impl.presentation.analytics import com.tangem.core.analytics.models.AnalyticsEvent +import com.tangem.core.analytics.models.AnalyticsParam.Key.BLOCKCHAIN import com.tangem.core.analytics.models.AnalyticsParam.Key.SOURCE +import com.tangem.core.analytics.models.AnalyticsParam.Key.TOKEN import com.tangem.core.analytics.models.AnalyticsParam.Key.TYPE import com.tangem.core.analytics.models.AnalyticsParam.Key.VALIDATION +import com.tangem.core.analytics.models.AnalyticsParam.OnOffState /** * Send screen analytics @@ -13,24 +16,9 @@ internal sealed class SendAnalyticEvents( params: Map = mapOf(), ) : AnalyticsEvent(category = "Token / Send", event = event, params = params) { - /** Send screen opened */ - object SendOpened : SendAnalyticEvents(event = "Send Screen Opened") - - /** Next button clicked */ - data class NextButtonClicked(val source: SendScreenSource) : SendAnalyticEvents( - event = "Button - Next", - params = mapOf(SOURCE to source.name), - ) - - /** Back button clicked */ - data class BackButtonClicked(val source: SendScreenSource) : SendAnalyticEvents( - event = "Button - Back", - params = mapOf(SOURCE to source.name), - ) - // region Address /** Recipient address screen opened */ - object AddressScreenOpened : SendAnalyticEvents(event = "Address Screen Opened") + data object AddressScreenOpened : SendAnalyticEvents(event = "Address Screen Opened") /** Address to send entered */ data class AddressEntered(val source: EnterAddressSource, val isValid: Boolean) : SendAnalyticEvents( @@ -41,21 +29,13 @@ internal sealed class SendAnalyticEvents( ), ) - /** Paste from clipboard button clicked */ - data class PasteButtonClicked(val type: PasteType) : SendAnalyticEvents( - event = "Button - Paste", - params = mapOf( - TYPE to type.name, - ), - ) - /** Qr Code button clicked */ - object QrCodeButtonClicked : SendAnalyticEvents(event = "Button - QR Code") + data object QrCodeButtonClicked : SendAnalyticEvents(event = "Button - QR Code") // endregion // region Amount /** Amount screen opened */ - object AmountScreenOpened : SendAnalyticEvents(event = "Amount Screen Opened") + data object AmountScreenOpened : SendAnalyticEvents(event = "Amount Screen Opened") /** Selected currency */ data class SelectedCurrency(val type: SelectedCurrencyType) : SendAnalyticEvents( @@ -63,36 +43,36 @@ internal sealed class SendAnalyticEvents( params = mapOf(TYPE to type.value), ) - /** Currency selector button clicked */ - object SwapCurrencyButtonClicked : SendAnalyticEvents(event = "Button - Swap Currency") + /** Max amount button clicked */ + data object MaxAmountButtonClicked : SendAnalyticEvents(event = "Max Amount Taped") // endregion // region Fee /** Fee screen opened */ - object FeeScreenOpened : SendAnalyticEvents(event = "Fee Screen Opened") + data object FeeScreenOpened : SendAnalyticEvents(event = "Fee Screen Opened") /** Selected fee (send after next screen opened) */ - data class SelectedFee(val fee: String) : SendAnalyticEvents( + data class SelectedFee(val feeType: SelectedFeeType) : SendAnalyticEvents( event = "Fee Selected", - params = mapOf("Commission" to fee), + params = mapOf("Fee Type" to feeType.name), ) /** Custom fee selected */ - object CustomFeeButtonClicked : SendAnalyticEvents(event = "Custom Fee Clicked") + data object CustomFeeButtonClicked : SendAnalyticEvents(event = "Custom Fee Clicked") /** Custom fee edited */ - object GasPriceInserter : SendAnalyticEvents(event = "Gas Price Inserted") + data object GasPriceInserter : SendAnalyticEvents(event = "Gas Price Inserted") /** Subtract from amount selector switched (send after next screen opened) */ - object SubtractFromAmount : SendAnalyticEvents(event = "Subtract from Amount") + data class SubtractFromAmount(val status: Boolean) : SendAnalyticEvents( + event = "Subtract from Amount", + params = mapOf("Status" to if (status) OnOffState.On.value else OnOffState.Off.value), + ) // endregion // region Confirmation /** Confirmation screen opened */ - object ConfirmationScreenOpened : SendAnalyticEvents(event = "Confirm Screen Opened") - - /** Send transaction button clicked */ - object SendButtonClicked : SendAnalyticEvents(event = "Button - Send") + data object ConfirmationScreenOpened : SendAnalyticEvents(event = "Confirm Screen Opened") /** Screen reopened from confirmation screen */ data class ScreenReopened(val source: SendScreenSource) : SendAnalyticEvents( @@ -103,13 +83,31 @@ internal sealed class SendAnalyticEvents( // region Transaction Result /** Transaction send screen opened */ - object TransactionScreenOpened : SendAnalyticEvents(event = "Transaction Sent Screen Opened") + data object TransactionScreenOpened : SendAnalyticEvents(event = "Transaction Sent Screen Opened") /** Share button clicked */ - object ShareButtonClicked : SendAnalyticEvents(event = "Button - Share") + data object ShareButtonClicked : SendAnalyticEvents(event = "Button - Share") /** Expore button clicked */ - object ExploreButtonClicked : SendAnalyticEvents(event = "Button - Explore") + data object ExploreButtonClicked : SendAnalyticEvents(event = "Button - Explore") + + /** If not enough fee notification is present */ + data class NoticeNotEnoughFee(val token: String, val blockchain: String) : SendAnalyticEvents( + event = "Notice - Not Enough Fee", + params = mapOf(TOKEN to token, BLOCKCHAIN to blockchain), + ) + + /** If transaction delays notification is present */ + data class NoticeTransactionDelays(val token: String) : SendAnalyticEvents( + event = "Notice - Transaction Delays Are Possible", + params = mapOf(TOKEN to token), + ) + + /** If error occurs during send transactions */ + data class TransactionError(val token: String) : SendAnalyticEvents( + event = "Error - Transaction Rejected", + params = mapOf(TOKEN to token), + ) // endregion } @@ -125,12 +123,15 @@ internal enum class EnterAddressSource { RecentAddress, } -internal enum class PasteType { - Address, - Memo, -} - internal enum class SelectedCurrencyType(val value: String) { Token("Token"), AppCurrency("App Currency"), +} + +internal enum class SelectedFeeType { + Min, + Max, + Fixed, + Normal, + Custom, } \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/analytics/utils/SendOnNextScreenAnalyticSender.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/analytics/utils/SendOnNextScreenAnalyticSender.kt index 4fc8d719af..6ca1759174 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/analytics/utils/SendOnNextScreenAnalyticSender.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/analytics/utils/SendOnNextScreenAnalyticSender.kt @@ -1,7 +1,9 @@ package com.tangem.features.send.impl.presentation.analytics.utils +import com.tangem.blockchain.common.transaction.TransactionFee import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.features.send.impl.presentation.analytics.SelectedCurrencyType +import com.tangem.features.send.impl.presentation.analytics.SelectedFeeType import com.tangem.features.send.impl.presentation.analytics.SendAnalyticEvents import com.tangem.features.send.impl.presentation.state.SendUiState import com.tangem.features.send.impl.presentation.state.SendUiStateType @@ -21,12 +23,12 @@ internal class SendOnNextScreenAnalyticSender( if (selectedFee == FeeType.Custom && isCustomFeeEdited) { analyticsEventHandler.send(SendAnalyticEvents.GasPriceInserter) } - analyticsEventHandler.send(SendAnalyticEvents.SelectedFee(selectedFee.name)) + sendSelectedFeeAnalytics(feeSelectorState) } } SendUiStateType.Amount -> { val isFiatSelected = state.amountState?.amountTextField?.isFiatValue ?: return - val selectedCurrency = if (isFiatSelected) { + val selectedCurrency = if (!isFiatSelected) { SelectedCurrencyType.Token } else { SelectedCurrencyType.AppCurrency @@ -38,4 +40,17 @@ internal class SendOnNextScreenAnalyticSender( else -> Unit } } + + private fun sendSelectedFeeAnalytics(feeSelectorState: FeeSelectorState.Content) { + val type = when (feeSelectorState.fees) { + is TransactionFee.Single -> SelectedFeeType.Fixed + is TransactionFee.Choosable -> when (feeSelectorState.selectedFee) { + FeeType.Slow -> SelectedFeeType.Min + FeeType.Market -> SelectedFeeType.Normal + FeeType.Fast -> SelectedFeeType.Max + FeeType.Custom -> SelectedFeeType.Custom + } + } + analyticsEventHandler.send(SendAnalyticEvents.SelectedFee(type)) + } } \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/analytics/utils/SendRecipientAnalyticsSender.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/analytics/utils/SendRecipientAnalyticsSender.kt deleted file mode 100644 index 000f48dea1..0000000000 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/analytics/utils/SendRecipientAnalyticsSender.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.tangem.features.send.impl.presentation.analytics.utils - -import com.tangem.core.analytics.api.AnalyticsEventHandler -import com.tangem.features.send.impl.presentation.analytics.EnterAddressSource -import com.tangem.features.send.impl.presentation.analytics.PasteType -import com.tangem.features.send.impl.presentation.analytics.SendAnalyticEvents - -internal class SendRecipientAnalyticsSender( - private val analyticsEventHandler: AnalyticsEventHandler, -) { - - fun sendAddressAnalytics(type: EnterAddressSource?, isValidAddress: Boolean) { - type?.let { - if (type == EnterAddressSource.PasteButton) { - analyticsEventHandler.send(SendAnalyticEvents.PasteButtonClicked(PasteType.Address)) - } - analyticsEventHandler.send(SendAnalyticEvents.AddressEntered(it, isValidAddress)) - } - } - - fun sendMemoAnalytics(isPasted: Boolean) { - if (isPasted) { - analyticsEventHandler.send(SendAnalyticEvents.PasteButtonClicked(PasteType.Memo)) - } - } -} \ No newline at end of file diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendNotificationFactory.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendNotificationFactory.kt index 12ea309a87..20ad57bca1 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendNotificationFactory.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/SendNotificationFactory.kt @@ -2,12 +2,14 @@ package com.tangem.features.send.impl.presentation.state import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.transaction.TransactionFee +import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.ui.utils.BigDecimalFormatter import com.tangem.core.ui.utils.parseToBigDecimal import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.tokens.repository.CurrencyChecksRepository import com.tangem.domain.wallets.models.UserWallet +import com.tangem.features.send.impl.presentation.analytics.SendAnalyticEvents import com.tangem.features.send.impl.presentation.state.fee.FeeSelectorState import com.tangem.features.send.impl.presentation.state.fee.FeeType import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents @@ -30,6 +32,7 @@ internal class SendNotificationFactory( private val currencyChecksRepository: CurrencyChecksRepository, private val stateRouterProvider: Provider, private val clickIntents: SendClickIntents, + private val analyticsEventHandler: AnalyticsEventHandler, ) { fun create(): Flow> = stateRouterProvider().currentState @@ -285,6 +288,11 @@ internal class SendNotificationFactory( val customValue = customAmount.value.parseToBigDecimal(customAmount.decimals) if (feeSelectorState.selectedFee == FeeType.Custom && minimumValue > customValue) { add(SendNotification.Warning.FeeTooLow) + analyticsEventHandler.send( + SendAnalyticEvents.NoticeTransactionDelays( + cryptoCurrencyStatusProvider().currency.symbol, + ), + ) } } diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/StateRouter.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/StateRouter.kt index bf7b83183b..de09a0570e 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/StateRouter.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/StateRouter.kt @@ -3,7 +3,6 @@ package com.tangem.features.send.impl.presentation.state import androidx.fragment.app.FragmentManager import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.features.send.impl.presentation.analytics.SendAnalyticEvents -import com.tangem.features.send.impl.presentation.analytics.SendScreenSource import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.update @@ -32,51 +31,26 @@ internal class StateRouter( when { isSuccess -> popBackStack() isEditingDisabled -> when (type) { - SendUiStateType.Send -> { - analyticsEventsHandler.send(SendAnalyticEvents.BackButtonClicked(SendScreenSource.Fee)) - showFee() - } + SendUiStateType.Send -> showFee() else -> popBackStack() } else -> when (type) { - SendUiStateType.Amount -> { - analyticsEventsHandler.send(SendAnalyticEvents.BackButtonClicked(SendScreenSource.Address)) - continueToSend(::showRecipient) - } - SendUiStateType.Fee -> { - analyticsEventsHandler.send(SendAnalyticEvents.BackButtonClicked(SendScreenSource.Amount)) - continueToSend(::showAmount) - } - SendUiStateType.Send -> { - analyticsEventsHandler.send(SendAnalyticEvents.BackButtonClicked(SendScreenSource.Fee)) - continueToSend(::showFee) - } + SendUiStateType.Amount -> continueToSend(::showRecipient) + SendUiStateType.Fee -> continueToSend(::showAmount) + SendUiStateType.Send -> continueToSend(::showFee) else -> continueToSend(::popBackStack) } } } - fun onNextClick(): SendUiStateType { - val prevState = currentState.value.type + fun onNextClick() { when (currentState.value.type) { - SendUiStateType.Recipient -> { - analyticsEventsHandler.send(SendAnalyticEvents.NextButtonClicked(SendScreenSource.Amount)) - continueToSend(::showAmount) - } - SendUiStateType.Amount -> { - analyticsEventsHandler.send(SendAnalyticEvents.NextButtonClicked(SendScreenSource.Fee)) - continueToSend(::showFee) - } - SendUiStateType.Fee -> { - analyticsEventsHandler.send(SendAnalyticEvents.NextButtonClicked(SendScreenSource.Fee)) - showSend() - } - SendUiStateType.Send -> { - onBackClick() - } + SendUiStateType.Recipient -> continueToSend(::showAmount) + SendUiStateType.Amount -> continueToSend(::showFee) + SendUiStateType.Fee -> showSend() + SendUiStateType.Send -> onBackClick() else -> popBackStack() } - return prevState } fun onPrevClick() { @@ -84,14 +58,8 @@ internal class StateRouter( popBackStack() } else { when (currentState.value.type) { - SendUiStateType.Amount -> { - analyticsEventsHandler.send(SendAnalyticEvents.BackButtonClicked(SendScreenSource.Amount)) - showRecipient() - } - SendUiStateType.Fee -> { - analyticsEventsHandler.send(SendAnalyticEvents.BackButtonClicked(SendScreenSource.Fee)) - showAmount() - } + SendUiStateType.Amount -> showRecipient() + SendUiStateType.Fee -> showAmount() else -> popBackStack() } } diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeNotificationFactory.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeNotificationFactory.kt index 7b31b34d3d..d3fcad540b 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeNotificationFactory.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/state/fee/FeeNotificationFactory.kt @@ -3,6 +3,7 @@ package com.tangem.features.send.impl.presentation.state.fee import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.transaction.Fee import com.tangem.blockchain.common.transaction.TransactionFee +import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.ui.extensions.networkIconResId import com.tangem.core.ui.utils.parseToBigDecimal import com.tangem.domain.common.extensions.fromNetworkId @@ -11,6 +12,7 @@ import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.tokens.model.warnings.CryptoCurrencyWarning import com.tangem.domain.wallets.models.UserWallet import com.tangem.features.send.impl.R +import com.tangem.features.send.impl.presentation.analytics.SendAnalyticEvents import com.tangem.features.send.impl.presentation.state.SendUiState import com.tangem.features.send.impl.presentation.state.SendUiStateType import com.tangem.features.send.impl.presentation.state.StateRouter @@ -33,6 +35,7 @@ internal class FeeNotificationFactory( private val stateRouterProvider: Provider, private val clickIntents: SendClickIntents, private val getBalanceNotEnoughForFeeWarningUseCase: GetBalanceNotEnoughForFeeWarningUseCase, + private val analyticsEventHandler: AnalyticsEventHandler, ) { fun create() = stateRouterProvider().currentState @@ -97,7 +100,7 @@ internal class FeeNotificationFactory( is CryptoCurrencyWarning.BalanceNotEnoughForFee -> { add( SendFeeNotification.Error.ExceedsBalance( - warning.coinCurrency.networkIconResId, + networkIconId = warning.coinCurrency.networkIconResId, networkName = warning.coinCurrency.name, currencyName = cryptoCurrencyStatus.currency.name, feeName = warning.coinCurrency.name, @@ -111,6 +114,12 @@ internal class FeeNotificationFactory( }, ), ) + analyticsEventHandler.send( + SendAnalyticEvents.NoticeNotEnoughFee( + token = cryptoCurrencyStatus.currency.symbol, + blockchain = cryptoCurrencyStatus.currency.network.name, + ), + ) } is CryptoCurrencyWarning.CustomTokenNotEnoughForFee -> { val currency = warning.feeCurrency @@ -132,6 +141,12 @@ internal class FeeNotificationFactory( }, ), ) + analyticsEventHandler.send( + SendAnalyticEvents.NoticeNotEnoughFee( + token = warning.currency.symbol, + blockchain = warning.networkName, + ), + ) } else -> Unit } diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/recipient/SendRecipientContent.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/recipient/SendRecipientContent.kt index 4c490fb1bc..134cea2336 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/recipient/SendRecipientContent.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/ui/recipient/SendRecipientContent.kt @@ -78,7 +78,7 @@ internal fun SendRecipientContent(uiState: SendStates.RecipientState?, clickInte placeholder = placeholder, footer = stringResource(R.string.send_recipient_memo_footer), onValueChange = memoField.onValueChange, - onPasteClick = { clickIntents.onRecipientMemoValueChange(it, isPasted = true) }, + onPasteClick = clickIntents::onRecipientMemoValueChange, modifier = Modifier.padding(top = TangemTheme.dimens.spacing20), isError = memoField.isError, error = memoField.error, diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendClickIntents.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendClickIntents.kt index 9af06fb346..c35cf2ba2d 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendClickIntents.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendClickIntents.kt @@ -34,7 +34,7 @@ internal interface SendClickIntents { // region Recipient fun onRecipientAddressValueChange(value: String, type: EnterAddressSource? = null) - fun onRecipientMemoValueChange(value: String, isPasted: Boolean = false) + fun onRecipientMemoValueChange(value: String) // endregion // region Fee diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt index 4cbe0159d8..bbd3af4660 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt @@ -37,7 +37,6 @@ import com.tangem.features.send.impl.presentation.analytics.EnterAddressSource import com.tangem.features.send.impl.presentation.analytics.SendAnalyticEvents import com.tangem.features.send.impl.presentation.analytics.SendScreenSource import com.tangem.features.send.impl.presentation.analytics.utils.SendOnNextScreenAnalyticSender -import com.tangem.features.send.impl.presentation.analytics.utils.SendRecipientAnalyticsSender import com.tangem.features.send.impl.presentation.domain.AvailableWallet import com.tangem.features.send.impl.presentation.state.* import com.tangem.features.send.impl.presentation.state.amount.AmountStateFactory @@ -143,6 +142,7 @@ internal class SendViewModel @Inject constructor( stateRouterProvider = Provider { stateRouter }, clickIntents = this, getBalanceNotEnoughForFeeWarningUseCase = getBalanceNotEnoughForFeeWarningUseCase, + analyticsEventHandler = analyticsEventHandler, ) private val sendNotificationFactory = SendNotificationFactory( @@ -153,14 +153,13 @@ internal class SendViewModel @Inject constructor( stateRouterProvider = Provider { stateRouter }, currencyChecksRepository = currencyChecksRepository, clickIntents = this, + analyticsEventHandler = analyticsEventHandler, ) private val sendOnNextScreenAnalyticSender by lazy(LazyThreadSafetyMode.NONE) { SendOnNextScreenAnalyticSender(analyticsEventHandler) } - private val sendRecipientAnalyticsSender by lazy(LazyThreadSafetyMode.NONE) { - SendRecipientAnalyticsSender(analyticsEventHandler) - } + // todo convert to StateFlow var uiState: SendUiState by mutableStateOf(stateFactory.getInitialState()) private set @@ -188,7 +187,6 @@ internal class SendViewModel @Inject constructor( override fun onCreate(owner: LifecycleOwner) { onStateActive() - analyticsEventHandler.send(SendAnalyticEvents.SendOpened) } override fun onCleared() { @@ -415,11 +413,12 @@ internal class SendViewModel @Inject constructor( return } else { uiState = stateFactory.onSubtractSelect(false) + analyticsEventHandler.send(SendAnalyticEvents.SubtractFromAmount(false)) } } - val prevScreen = stateRouter.onNextClick() - sendOnNextScreenAnalyticSender.send(prevScreen, uiState) + sendOnNextScreenAnalyticSender.send(currentState.type, uiState) + stateRouter.onNextClick() } override fun onPrevClick() = stateRouter.onPrevClick() @@ -439,7 +438,6 @@ internal class SendViewModel @Inject constructor( // region amount state clicks override fun onCurrencyChangeClick(isFiat: Boolean) { - analyticsEventHandler.send(SendAnalyticEvents.SwapCurrencyButtonClicked) uiState = amountStateFactory.getOnCurrencyChangedState(isFiat) } @@ -449,6 +447,7 @@ internal class SendViewModel @Inject constructor( override fun onMaxValueClick() { uiState = amountStateFactory.getOnMaxAmountClick() + analyticsEventHandler.send(SendAnalyticEvents.MaxAmountButtonClicked) } // endregion @@ -475,19 +474,18 @@ internal class SendViewModel @Inject constructor( uiState = stateFactory.getOnRecipientAddressValidationStarted() val isValidAddress = validateAddress(value) uiState = stateFactory.getOnRecipientAddressValidState(value, isValidAddress) - sendRecipientAnalyticsSender.sendAddressAnalytics(type, isValidAddress) + type?.let { analyticsEventHandler.send(SendAnalyticEvents.AddressEntered(it, isValidAddress)) } } }.saveIn(addressValidationJobHolder) } - override fun onRecipientMemoValueChange(value: String, isPasted: Boolean) { + override fun onRecipientMemoValueChange(value: String) { viewModelScope.launch(dispatchers.main) { if (!checkIfXrpAddressValue(value)) { uiState = stateFactory.getOnRecipientMemoValueChange(value) uiState = stateFactory.getOnRecipientAddressValidationStarted() val isValidAddress = validateAddress(uiState.recipientState?.addressTextField?.value.orEmpty()) uiState = stateFactory.getOnRecipientMemoValidState(value, isValidAddress) - sendRecipientAnalyticsSender.sendMemoAnalytics(isPasted) } }.saveIn(addressValidationJobHolder) } @@ -542,6 +540,7 @@ internal class SendViewModel @Inject constructor( override fun onSubtractSelect() { uiState = stateFactory.onSubtractSelect(true) stateRouter.showSend() + analyticsEventHandler.send(SendAnalyticEvents.SubtractFromAmount(true)) } override fun onReadMoreClick() { @@ -598,25 +597,27 @@ internal class SendViewModel @Inject constructor( onCheckFeeUpdate() } sendIdleTimer = System.currentTimeMillis() - analyticsEventHandler.send(SendAnalyticEvents.SendButtonClicked) } override fun showAmount() { uiState = stateFactory.onSubtractSelect(false) stateRouter.showAmount(isFromConfirmation = true) analyticsEventHandler.send(SendAnalyticEvents.ScreenReopened(SendScreenSource.Amount)) + analyticsEventHandler.send(SendAnalyticEvents.SubtractFromAmount(false)) } override fun showRecipient() { uiState = stateFactory.onSubtractSelect(false) stateRouter.showRecipient(isFromConfirmation = true) analyticsEventHandler.send(SendAnalyticEvents.ScreenReopened(SendScreenSource.Address)) + analyticsEventHandler.send(SendAnalyticEvents.SubtractFromAmount(false)) } override fun showFee() { uiState = stateFactory.onSubtractSelect(false) stateRouter.showFee(isFromConfirmation = true) analyticsEventHandler.send(SendAnalyticEvents.ScreenReopened(SendScreenSource.Fee)) + analyticsEventHandler.send(SendAnalyticEvents.SubtractFromAmount(false)) } override fun showSend() { @@ -691,6 +692,7 @@ internal class SendViewModel @Inject constructor( error = error, onConsume = { uiState = eventStateFactory.onConsumeEventState() }, ) + analyticsEventHandler.send(SendAnalyticEvents.TransactionError(cryptoCurrency.symbol)) }, ifRight = { uiState = stateFactory.getSendingStateUpdate(isSending = false)