Updated on 2026-08-14
This commit is contained in:
parent
e910d4cb3e
commit
126913bf0f
9 changed files with 115 additions and 132 deletions
|
|
@ -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<String, String> = 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,
|
||||
}
|
||||
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<StateRouter>,
|
||||
private val clickIntents: SendClickIntents,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
) {
|
||||
|
||||
fun create(): Flow<ImmutableList<SendNotification>> = 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,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<StateRouter>,
|
||||
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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue