Updated on 2026-08-14
This commit is contained in:
commit
f91ba3f7d3
13 changed files with 110 additions and 36 deletions
|
|
@ -14,6 +14,7 @@ sealed class MainScreen(
|
|||
|
||||
class ButtonScanCard : MainScreen("Button - Scan Card")
|
||||
class ButtonMyWallets : MainScreen("Button - My Wallets")
|
||||
class ButtonBuy : MainScreen("Button - Buy")
|
||||
|
||||
class EnableBiometrics(state: AnalyticsParam.OnOffState) : MainScreen(
|
||||
event = "Enable Biometric",
|
||||
|
|
|
|||
|
|
@ -68,16 +68,24 @@ sealed class Onboarding(
|
|||
}
|
||||
|
||||
class PinScreenOpened : Onboarding("Onboarding", "PIN screen opened")
|
||||
class PinCodeSet : Onboarding("Onboarding", "PIN code set")
|
||||
class ButtonSetPinCode : Onboarding("Onboarding", "Button - Set PIN Code")
|
||||
class CardConnectionScreenOpened : Onboarding("Onboarding", "Card Connection Screen Opened")
|
||||
class ButtonConnect : Onboarding("Onboarding", "Button - Connect")
|
||||
class PinCodeSet : Onboarding("Onboarding", "PIN code set")
|
||||
|
||||
class KYCScreenOpened : Onboarding("Onboarding", "KYC screen opened")
|
||||
class KYCStarted : Onboarding("Onboarding", "KYC started")
|
||||
class KYCInProgress : Onboarding("Onboarding", "KYC in progress")
|
||||
class KYCRejected : Onboarding("Onboarding", "KYC rejected")
|
||||
|
||||
class ClaimScreenOpened : Onboarding("Onboarding", "Claim screen opened")
|
||||
class ButtonClaim : Onboarding("Onboarding", "Button - Claim")
|
||||
class ClaimWasSuccessfully : Onboarding("Onboarding", "Claim was successfully")
|
||||
class ButtonChat: Onboarding("Onboarding", "Button - Chat")
|
||||
|
||||
class ButtonChat : Onboarding("Onboarding", "Button - Chat")
|
||||
|
||||
class NotEnoughGasError : Onboarding("Onboarding", "Not Enough Gas Error")
|
||||
class CardNotPassedError : Onboarding("Onboarding", "Card Not Passed Error")
|
||||
|
||||
class EnableBiometrics(state: AnalyticsParam.OnOffState) : Onboarding(
|
||||
category = "Onboarding / Biometric",
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import com.tangem.domain.common.ProductType
|
|||
import com.tangem.domain.common.ScanResponse
|
||||
import com.tangem.tap.common.analytics.converters.ParamCardCurrencyConverter
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||
import com.tangem.tap.common.analytics.events.IntroductionProcess
|
||||
import com.tangem.tap.common.analytics.events.MainScreen
|
||||
import com.tangem.tap.features.demo.DemoHelper
|
||||
|
||||
/**
|
||||
|
|
@ -17,7 +19,12 @@ class CardContextInterceptor(
|
|||
|
||||
override fun id(): String = CardContextInterceptor.id()
|
||||
|
||||
override fun canBeAppliedTo(event: AnalyticsEvent): Boolean = true
|
||||
override fun canBeAppliedTo(event: AnalyticsEvent): Boolean {
|
||||
return when (event) {
|
||||
is IntroductionProcess.ButtonScanCard, is MainScreen.ButtonScanCard -> false
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
|
||||
override fun intercept(params: MutableMap<String, String>) {
|
||||
scanResponse ?: return
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ object ScanCardProcessor {
|
|||
onWalletNotCreated()
|
||||
store.dispatch(GlobalAction.Onboarding.Start(scanResponse, canSkipBackup = false))
|
||||
store.dispatch(OnboardingSaltPayAction.SetDependencies(manager))
|
||||
store.dispatch(OnboardingSaltPayAction.Update)
|
||||
store.dispatch(OnboardingSaltPayAction.Update(withAnalytics = false))
|
||||
navigateTo(AppScreen.OnboardingWallet) { onProgressStateChange(it) }
|
||||
} else {
|
||||
delay(DELAY_SDK_DIALOG_CLOSE)
|
||||
|
|
|
|||
|
|
@ -63,7 +63,11 @@ sealed class BackupAction : Action {
|
|||
data class PrepareToWriteBackupCard(val cardNumber: Int) : BackupAction()
|
||||
data class WriteBackupCard(val cardNumber: Int) : BackupAction()
|
||||
|
||||
object FinishBackup : BackupAction()
|
||||
/**
|
||||
* It always calls for the SaltPay cards when resuming the activation process.
|
||||
*/
|
||||
data class FinishBackup(val withAnalytics: Boolean = true) : BackupAction()
|
||||
|
||||
object DiscardBackup : BackupAction()
|
||||
object DiscardSavedBackup : BackupAction()
|
||||
object ResumeFoundUnfinishedBackup : BackupAction()
|
||||
|
|
|
|||
|
|
@ -86,10 +86,11 @@ private fun handleWalletAction(action: Action, state: () -> AppState?, dispatch:
|
|||
|
||||
scanResponse.isSaltPay() -> {
|
||||
store.dispatch(OnboardingWalletAction.GetToSaltPayStep)
|
||||
store.dispatch(BackupAction.FinishBackup)
|
||||
store.dispatch(BackupAction.FinishBackup(withAnalytics = false))
|
||||
store.dispatch(OnboardingSaltPayAction.OnSwitchedToSaltPayProcess)
|
||||
}
|
||||
|
||||
else -> store.dispatch(BackupAction.FinishBackup)
|
||||
else -> store.dispatch(BackupAction.FinishBackup())
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
|
|
@ -314,7 +315,7 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction)
|
|||
is CompletionResult.Success -> {
|
||||
if (backupService.currentState == BackupService.State.Finished) {
|
||||
initSaltPayOnBackupFinishedIfNeeded(scanResponse, onboardingWalletState)
|
||||
store.dispatchOnMain(BackupAction.FinishBackup)
|
||||
store.dispatchOnMain(BackupAction.FinishBackup())
|
||||
} else {
|
||||
store.dispatchOnMain(BackupAction.PrepareToWriteBackupCard(action.cardNumber + 1))
|
||||
}
|
||||
|
|
@ -325,7 +326,9 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction)
|
|||
}
|
||||
}
|
||||
is BackupAction.FinishBackup -> {
|
||||
Analytics.send(Onboarding.Backup.Finished(backupState.backupCardsNumber))
|
||||
if (action.withAnalytics) {
|
||||
Analytics.send(Onboarding.Backup.Finished(backupState.backupCardsNumber))
|
||||
}
|
||||
if (!onboardingWalletState.isSaltPay) {
|
||||
Analytics.send(Onboarding.Finished())
|
||||
finishCardActivation(backupState, card)
|
||||
|
|
@ -357,7 +360,7 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction)
|
|||
is BackupAction.DismissBackup -> {
|
||||
Analytics.send(Onboarding.Backup.Skipped())
|
||||
if (onboardingWalletState.isSaltPay) throw UnsupportedOperationException()
|
||||
store.dispatch(BackupAction.FinishBackup)
|
||||
store.dispatch(BackupAction.FinishBackup())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -405,7 +408,7 @@ private fun initSaltPayOnBackupFinishedIfNeeded(
|
|||
card = scanResponse.card,
|
||||
).create()
|
||||
store.dispatchOnMain(OnboardingSaltPayAction.SetDependencies(manager))
|
||||
store.dispatchOnMain(OnboardingSaltPayAction.Update)
|
||||
store.dispatchOnMain(OnboardingSaltPayAction.Update(false))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ class GnosisRegistrator(
|
|||
private val atomicNonce = AtomicLong()
|
||||
|
||||
suspend fun checkHasGas(): Result<Boolean> {
|
||||
// return Result.Success(true) // test
|
||||
val wallet = walletManager.safeUpdate().successOr {
|
||||
return Result.Failure(BlockchainSdkError.WrappedThrowable(it.error))
|
||||
}
|
||||
|
|
@ -148,6 +149,7 @@ class GnosisRegistrator(
|
|||
}
|
||||
|
||||
suspend fun getAllowance(): Result<Amount> {
|
||||
// return Result.Success(Amount(BigDecimal(0.1), walletManager.wallet.blockchain)) // test
|
||||
return walletManager.getAllowance(addressTreasureSafe, token)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ package com.tangem.tap.features.onboarding.products.wallet.saltPay
|
|||
|
||||
import com.tangem.blockchain.common.BlockchainSdkError
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.tap.common.analytics.events.Onboarding
|
||||
import com.tangem.tap.common.extensions.dispatchDialogShow
|
||||
import com.tangem.tap.common.redux.AppDialog
|
||||
import com.tangem.tap.features.onboarding.products.wallet.saltPay.dialog.SaltPayDialog
|
||||
|
|
@ -17,8 +19,15 @@ class SaltPayExceptionHandler {
|
|||
when (throwable) {
|
||||
is SaltPayActivationError -> {
|
||||
val dialog = when (throwable) {
|
||||
is SaltPayActivationError.NoGas -> SaltPayDialog.Activation.NoGas
|
||||
is SaltPayActivationError.NoGas -> {
|
||||
Analytics.send(Onboarding.NotEnoughGasError())
|
||||
SaltPayDialog.Activation.NoGas
|
||||
}
|
||||
is SaltPayActivationError.PutVisaCard -> SaltPayDialog.Activation.PutVisaCard
|
||||
is SaltPayActivationError.CardNotPassed -> {
|
||||
Analytics.send(Onboarding.CardNotPassedError())
|
||||
SaltPayDialog.Activation.OnError(throwable)
|
||||
}
|
||||
else -> SaltPayDialog.Activation.OnError(throwable)
|
||||
}
|
||||
store.dispatchDialogShow(dialog)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,11 @@ import java.math.BigDecimal
|
|||
sealed class OnboardingSaltPayAction : Action {
|
||||
object Init : OnboardingSaltPayAction()
|
||||
|
||||
/**
|
||||
* Notification about the switching from the Wallet view to the SaltPay view.
|
||||
*/
|
||||
object OnSwitchedToSaltPayProcess : OnboardingSaltPayAction()
|
||||
|
||||
data class SetDependencies(
|
||||
val registrationManager: SaltPayActivationManager,
|
||||
) : OnboardingSaltPayAction()
|
||||
|
|
@ -20,7 +25,7 @@ sealed class OnboardingSaltPayAction : Action {
|
|||
|
||||
data class SetAccessCode(val accessCode: String?) : OnboardingSaltPayAction()
|
||||
|
||||
object Update : OnboardingSaltPayAction()
|
||||
data class Update(val withAnalytics: Boolean = true) : OnboardingSaltPayAction()
|
||||
object RegisterCard : OnboardingSaltPayAction()
|
||||
object OpenUtorgKYC : OnboardingSaltPayAction()
|
||||
object UtorgKYCRedirectSuccess : OnboardingSaltPayAction()
|
||||
|
|
@ -31,7 +36,11 @@ sealed class OnboardingSaltPayAction : Action {
|
|||
data class TrySetPin(val pin: String) : OnboardingSaltPayAction()
|
||||
data class SetPin(val pin: String) : OnboardingSaltPayAction()
|
||||
|
||||
data class SetStep(val newStep: SaltPayActivationStep) : OnboardingSaltPayAction()
|
||||
data class SetStep(
|
||||
val newStep: SaltPayActivationStep,
|
||||
val withAnalytics: Boolean = true,
|
||||
) : OnboardingSaltPayAction()
|
||||
|
||||
data class SetAmountToClaim(val amount: Amount?) : OnboardingSaltPayAction()
|
||||
data class SetTokenBalance(val balanceValue: BigDecimal) : OnboardingSaltPayAction()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,6 +79,9 @@ private fun handleOnboardingSaltPayAction(anyAction: Action, appState: () -> App
|
|||
onboardingManager.activationStarted(card.cardId)
|
||||
}
|
||||
}
|
||||
is OnboardingSaltPayAction.OnSwitchedToSaltPayProcess -> {
|
||||
sendAnalyticsScreenOpened(getState().step, newStep = SaltPayActivationStep.None)
|
||||
}
|
||||
is OnboardingSaltPayAction.Update -> {
|
||||
handleInProgress = true
|
||||
|
||||
|
|
@ -90,7 +93,7 @@ private fun handleOnboardingSaltPayAction(anyAction: Action, appState: () -> App
|
|||
}
|
||||
|
||||
handleInProgress = false
|
||||
dispatchOnMain(OnboardingSaltPayAction.SetStep(updateStep))
|
||||
dispatchOnMain(OnboardingSaltPayAction.SetStep(updateStep, action.withAnalytics))
|
||||
|
||||
if (updateStep == SaltPayActivationStep.Claim) {
|
||||
handleClaimRefreshInProgress = true
|
||||
|
|
@ -148,6 +151,7 @@ private fun handleOnboardingSaltPayAction(anyAction: Action, appState: () -> App
|
|||
return@launch
|
||||
}
|
||||
|
||||
Analytics.send(Onboarding.PinCodeSet())
|
||||
handleInProgress = false
|
||||
dispatchOnMain(OnboardingSaltPayAction.SetStep(SaltPayActivationStep.KycIntro))
|
||||
}
|
||||
|
|
@ -171,13 +175,13 @@ private fun handleOnboardingSaltPayAction(anyAction: Action, appState: () -> App
|
|||
}
|
||||
|
||||
handleInProgress = false
|
||||
dispatchOnMain(OnboardingSaltPayAction.Update)
|
||||
dispatchOnMain(OnboardingSaltPayAction.Update())
|
||||
}
|
||||
}
|
||||
is OnboardingSaltPayAction.TrySetPin -> {
|
||||
try {
|
||||
assertPinValid(action.pin, getState().pinLength)
|
||||
Analytics.send(Onboarding.PinCodeSet())
|
||||
Analytics.send(Onboarding.ButtonSetPinCode())
|
||||
store.dispatch(OnboardingSaltPayAction.SetPin(action.pin))
|
||||
store.dispatch(OnboardingSaltPayAction.SetStep(SaltPayActivationStep.CardRegistration))
|
||||
} catch (error: SaltPayActivationError) {
|
||||
|
|
@ -257,24 +261,22 @@ private fun handleOnboardingSaltPayAction(anyAction: Action, appState: () -> App
|
|||
}
|
||||
}
|
||||
is OnboardingSaltPayAction.SetStep -> {
|
||||
when (action.newStep) {
|
||||
SaltPayActivationStep.NeedPin -> Analytics.send(Onboarding.PinScreenOpened())
|
||||
SaltPayActivationStep.KycIntro -> Analytics.send(Onboarding.KYCScreenOpened())
|
||||
SaltPayActivationStep.KycStart -> Analytics.send(Onboarding.KYCStarted())
|
||||
SaltPayActivationStep.KycWaiting -> Analytics.send(Onboarding.KYCInProgress())
|
||||
SaltPayActivationStep.KycReject -> Analytics.send(Onboarding.KYCRejected())
|
||||
SaltPayActivationStep.Claim -> Analytics.send(Onboarding.ClaimScreenOpened())
|
||||
SaltPayActivationStep.ClaimSuccess, SaltPayActivationStep.Success -> {
|
||||
Analytics.send(Onboarding.Finished())
|
||||
val onboardingManager = getOnboardingManager().guard {
|
||||
// Null is possible if it is started from a standard pending backup and in this case
|
||||
// it is impossible to get here
|
||||
store.dispatchDebugErrorNotification("OnboardingManager can't be NULL")
|
||||
return
|
||||
}
|
||||
finishCardActivation(getOnboardingWalletState().backupState, onboardingManager.scanResponse.card)
|
||||
if (action.withAnalytics) {
|
||||
sendAnalyticsScreenOpened(getState().step, action.newStep)
|
||||
}
|
||||
if (action.newStep == SaltPayActivationStep.ClaimSuccess ||
|
||||
action.newStep == SaltPayActivationStep.Success
|
||||
) {
|
||||
val onboardingManager = getOnboardingManager().guard {
|
||||
// Null is possible if it is started from a standard pending backup and in this case
|
||||
// it is impossible to get here
|
||||
store.dispatchDebugErrorNotification("OnboardingManager can't be NULL")
|
||||
return
|
||||
}
|
||||
else -> {}
|
||||
finishCardActivation(
|
||||
getOnboardingWalletState().backupState,
|
||||
onboardingManager.scanResponse.card,
|
||||
)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
|
|
@ -283,6 +285,22 @@ private fun handleOnboardingSaltPayAction(anyAction: Action, appState: () -> App
|
|||
}
|
||||
}
|
||||
|
||||
private fun sendAnalyticsScreenOpened(currentStep: SaltPayActivationStep, newStep: SaltPayActivationStep) {
|
||||
if (currentStep == newStep) return
|
||||
|
||||
when (newStep) {
|
||||
SaltPayActivationStep.NeedPin -> Analytics.send(Onboarding.PinScreenOpened())
|
||||
SaltPayActivationStep.CardRegistration -> Analytics.send(Onboarding.CardConnectionScreenOpened())
|
||||
SaltPayActivationStep.KycIntro -> Analytics.send(Onboarding.KYCScreenOpened())
|
||||
SaltPayActivationStep.KycStart -> Analytics.send(Onboarding.KYCStarted())
|
||||
SaltPayActivationStep.KycWaiting -> Analytics.send(Onboarding.KYCInProgress())
|
||||
SaltPayActivationStep.KycReject -> Analytics.send(Onboarding.KYCRejected())
|
||||
SaltPayActivationStep.Claim -> Analytics.send(Onboarding.ClaimScreenOpened())
|
||||
SaltPayActivationStep.ClaimSuccess, SaltPayActivationStep.Success -> Analytics.send(Onboarding.Finished())
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun SaltPayActivationManager.update(
|
||||
currentStep: SaltPayActivationStep,
|
||||
currentAmountToClaim: Amount?,
|
||||
|
|
@ -369,6 +387,7 @@ private suspend fun getAmountToClaimIfNeeded(
|
|||
return amountToClaim
|
||||
}
|
||||
|
||||
// return Amount(BigDecimal(0.1), Blockchain.SaltPay)
|
||||
return when (val result = saltPayManager.getAmountToClaim()) {
|
||||
is Result.Success -> {
|
||||
Timber.d("getAmountToClaimIfNeeded: success: %s", result.data)
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ internal class OnboardingSaltPayView(
|
|||
if (state.backupState.backupStep == BackupStep.Finished) {
|
||||
// if backup finished -> switch OnboardingWalletStep to the SaltPay
|
||||
store.dispatch(OnboardingWalletAction.GetToSaltPayStep)
|
||||
store.dispatch(OnboardingSaltPayAction.OnSwitchedToSaltPayProcess)
|
||||
} else {
|
||||
// if not -> back to the standard backup process
|
||||
walletFragment.handleOnboardingStep(state)
|
||||
|
|
@ -228,7 +229,7 @@ internal class OnboardingSaltPayView(
|
|||
|
||||
btnKycAction.text = getText(R.string.onboarding_button_kyc_waiting)
|
||||
btnKycAction.setOnClickListener {
|
||||
store.dispatch(OnboardingSaltPayAction.Update)
|
||||
store.dispatch(OnboardingSaltPayAction.Update())
|
||||
}
|
||||
progressButton = SaltPayProgressButton(root)
|
||||
}
|
||||
|
|
@ -244,7 +245,7 @@ internal class OnboardingSaltPayView(
|
|||
btnOpenSupportChat.hide()
|
||||
btnKycAction.text = getText(R.string.onboarding_button_kyc_start)
|
||||
btnKycAction.setOnClickListener {
|
||||
store.dispatch(OnboardingSaltPayAction.Update)
|
||||
store.dispatch(OnboardingSaltPayAction.Update())
|
||||
}
|
||||
progressButton = SaltPayProgressButton(root)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.tap.features.sprinklr.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.foundation.layout.imePadding
|
||||
import androidx.compose.foundation.layout.systemBarsPadding
|
||||
|
|
@ -8,11 +9,18 @@ import androidx.compose.runtime.State
|
|||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.ui.fragments.ComposeFragment
|
||||
import com.tangem.tap.common.analytics.events.Chat
|
||||
|
||||
internal class SprinklrFragment : ComposeFragment<SprinklrScreenState>() {
|
||||
private val viewModel by viewModels<SprinklrViewModel>()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
Analytics.send(Chat.ScreenOpened())
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun provideState(): State<SprinklrScreenState> {
|
||||
return viewModel.state.collectAsState()
|
||||
|
|
|
|||
|
|
@ -3,10 +3,12 @@ package com.tangem.tap.features.wallet.ui.wallet.saltPay
|
|||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import com.skydoves.androidveil.VeilLayout
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.domain.common.extensions.debounce
|
||||
import com.tangem.domain.common.extensions.withMainContext
|
||||
import com.tangem.tap.common.ShimmerData
|
||||
import com.tangem.tap.common.ShimmerRecyclerAdapter
|
||||
import com.tangem.tap.common.analytics.events.MainScreen
|
||||
import com.tangem.tap.common.extensions.animateVisibility
|
||||
import com.tangem.tap.common.extensions.formatAmountAsSpannedString
|
||||
import com.tangem.tap.common.extensions.hide
|
||||
|
|
@ -144,6 +146,7 @@ class SaltPayWalletView : WalletView() {
|
|||
|
||||
btnBuy.show(tokenData.isAvailableToBuy)
|
||||
btnBuy.setOnClickListener {
|
||||
Analytics.send(MainScreen.ButtonBuy())
|
||||
store.dispatch(WalletAction.TradeCryptoAction.Buy(false))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue