Updated on 2026-08-14
This commit is contained in:
parent
aeb60e0cec
commit
f2f10fe950
23 changed files with 182 additions and 125 deletions
|
|
@ -4,6 +4,7 @@ import com.tangem.common.routing.AppRoute
|
|||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.analytics.models.Basic
|
||||
import com.tangem.core.analytics.models.event.OnboardingAnalyticsEvent
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.navigation.Router
|
||||
|
|
@ -98,6 +99,11 @@ internal class CreateWalletSelectionModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun onMobileWalletClick() {
|
||||
analyticsEventHandler.send(
|
||||
event = OnboardingAnalyticsEvent.Onboarding.ButtonMobileWallet(
|
||||
source = AnalyticsParam.ScreensSources.AddNewWallet.value,
|
||||
),
|
||||
)
|
||||
if (!isHotWalletCreationSupported()) {
|
||||
uiMessageSender.send(
|
||||
hotWalletCreationNotSupportedDialog(isHotWalletCreationSupported.getLeastVersionName()),
|
||||
|
|
@ -105,7 +111,7 @@ internal class CreateWalletSelectionModel @Inject constructor(
|
|||
return
|
||||
}
|
||||
|
||||
router.push(AppRoute.CreateMobileWallet)
|
||||
router.push(AppRoute.CreateMobileWallet(AnalyticsParam.ScreensSources.AddNewWallet.value))
|
||||
}
|
||||
|
||||
private fun onHardwareWalletClick() {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import com.tangem.common.routing.AppRouter
|
|||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.analytics.models.Basic
|
||||
import com.tangem.core.analytics.models.event.OnboardingAnalyticsEvent
|
||||
import com.tangem.core.decompose.di.GlobalUiMessageSender
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
|
|
@ -134,6 +135,11 @@ internal class CreateWalletStartModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun onStartWithMobileWalletClick() {
|
||||
analyticsEventHandler.send(
|
||||
event = OnboardingAnalyticsEvent.Onboarding.ButtonMobileWallet(
|
||||
source = AnalyticsParam.ScreensSources.CreateNewWallet.value,
|
||||
),
|
||||
)
|
||||
if (!isHotWalletCreationSupported()) {
|
||||
uiMessageSender.send(
|
||||
hotWalletCreationNotSupportedDialog(isHotWalletCreationSupported.getLeastVersionName()),
|
||||
|
|
@ -141,7 +147,7 @@ internal class CreateWalletStartModel @Inject constructor(
|
|||
return
|
||||
}
|
||||
|
||||
router.push(AppRoute.CreateMobileWallet)
|
||||
router.push(AppRoute.CreateMobileWallet(AnalyticsParam.ScreensSources.CreateNewWallet.value))
|
||||
}
|
||||
|
||||
private fun onBuyClick() {
|
||||
|
|
|
|||
|
|
@ -4,5 +4,9 @@ import com.tangem.core.decompose.factory.ComponentFactory
|
|||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
|
||||
interface CreateMobileWalletComponent : ComposableContentComponent {
|
||||
interface Factory : ComponentFactory<Unit, CreateMobileWalletComponent>
|
||||
data class Params(
|
||||
val source: String,
|
||||
)
|
||||
|
||||
interface Factory : ComponentFactory<Params, CreateMobileWalletComponent>
|
||||
}
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
package com.tangem.features.hotwallet.addexistingwallet.im.port.model
|
||||
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.analytics.models.event.OnboardingAnalyticsEvent
|
||||
import com.tangem.core.decompose.di.GlobalUiMessageSender
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
|
|
@ -37,6 +40,7 @@ internal class AddExistingWalletImportModel @Inject constructor(
|
|||
private val hotUserWalletBuilderFactory: HotUserWalletBuilder.Factory,
|
||||
private val saveUserWalletUseCase: SaveWalletUseCase,
|
||||
@GlobalUiMessageSender private val uiMessageSender: UiMessageSender,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
) : Model() {
|
||||
|
||||
private val params: AddExistingWalletImportComponent.Params = paramsContainer.require()
|
||||
|
|
@ -60,6 +64,7 @@ internal class AddExistingWalletImportModel @Inject constructor(
|
|||
}
|
||||
|
||||
init {
|
||||
analyticsEventHandler.send(OnboardingAnalyticsEvent.SeedPhrase.ImportSeedPhraseScreenOpened)
|
||||
importSeedPhraseUiStateBuilder = ImportSeedPhraseUiStateBuilder(
|
||||
modelScope = modelScope,
|
||||
mnemonicRepository = mnemonicRepository,
|
||||
|
|
@ -72,6 +77,7 @@ internal class AddExistingWalletImportModel @Inject constructor(
|
|||
)
|
||||
},
|
||||
onPassphraseInfoClick = ::onPassphraseInfoClick,
|
||||
onImportClick = { analyticsEventHandler.send(OnboardingAnalyticsEvent.SeedPhrase.ButtonImport) },
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -101,6 +107,23 @@ internal class AddExistingWalletImportModel @Inject constructor(
|
|||
}
|
||||
.onRight {
|
||||
setImportProgress(false)
|
||||
analyticsEventHandler.send(
|
||||
event = OnboardingAnalyticsEvent.Onboarding.Finished(
|
||||
source = AnalyticsParam.ScreensSources.ImportWallet.value,
|
||||
),
|
||||
)
|
||||
analyticsEventHandler.send(
|
||||
event = OnboardingAnalyticsEvent.CreateWallet.WalletCreatedSuccessfully(
|
||||
source = AnalyticsParam.ScreensSources.ImportWallet.value,
|
||||
creationType = OnboardingAnalyticsEvent.CreateWallet.WalletCreationType.SeedImport,
|
||||
seedPhraseLength = mnemonic.mnemonicComponents.size,
|
||||
passPhraseState = if (passphrase.isNullOrBlank()) {
|
||||
AnalyticsParam.EmptyFull.Empty
|
||||
} else {
|
||||
AnalyticsParam.EmptyFull.Full
|
||||
},
|
||||
),
|
||||
)
|
||||
params.callbacks.onWalletImported(userWallet.walletId)
|
||||
}
|
||||
}.onFailure {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import kotlinx.coroutines.CoroutineScope
|
|||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
internal class ImportSeedPhraseUiStateBuilder(
|
||||
private val modelScope: CoroutineScope,
|
||||
private val mnemonicRepository: MnemonicRepository,
|
||||
|
|
@ -24,6 +25,7 @@ internal class ImportSeedPhraseUiStateBuilder(
|
|||
private val updateUiState: ((AddExistingWalletImportUM) -> AddExistingWalletImportUM) -> Unit,
|
||||
private val importWallet: (mnemonic: Mnemonic, passphrase: String?) -> Unit,
|
||||
private val onPassphraseInfoClick: () -> Unit,
|
||||
private val onImportClick: () -> Unit,
|
||||
) {
|
||||
private val wordsCheckJobHolder = JobHolder()
|
||||
private var importedMnemonic: Mnemonic? = null
|
||||
|
|
@ -57,6 +59,7 @@ internal class ImportSeedPhraseUiStateBuilder(
|
|||
}
|
||||
|
||||
private fun onCreateWallet() {
|
||||
onImportClick()
|
||||
val mnemonic = importedMnemonic ?: return
|
||||
val passphrase = passphrase?.takeIf { it.isNotEmpty() }
|
||||
importWallet(mnemonic, passphrase)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
package com.tangem.features.hotwallet.createmobilewallet
|
||||
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.analytics.models.event.OnboardingAnalyticsEvent
|
||||
import com.tangem.core.analytics.utils.TrackingContextProxy
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.core.decompose.navigation.Router
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.ui.message.dialog.Dialogs.hotWalletCreationNotSupportedDialog
|
||||
|
|
@ -11,6 +15,7 @@ import com.tangem.domain.hotwallet.IsHotWalletCreationSupported
|
|||
import com.tangem.domain.wallets.builder.HotUserWalletBuilder
|
||||
import com.tangem.domain.wallets.usecase.SaveWalletUseCase
|
||||
import com.tangem.domain.wallets.usecase.SyncWalletWithRemoteUseCase
|
||||
import com.tangem.features.hotwallet.CreateMobileWalletComponent
|
||||
import com.tangem.features.hotwallet.createmobilewallet.entity.CreateMobileWalletUM
|
||||
import com.tangem.hot.sdk.TangemHotSdk
|
||||
import com.tangem.hot.sdk.model.HotAuth
|
||||
|
|
@ -28,6 +33,7 @@ import javax.inject.Inject
|
|||
@Suppress("LongParameterList")
|
||||
@ModelScoped
|
||||
internal class CreateMobileWalletModel @Inject constructor(
|
||||
paramsContainer: ParamsContainer,
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val hotUserWalletBuilderFactory: HotUserWalletBuilder.Factory,
|
||||
private val saveUserWalletUseCase: SaveWalletUseCase,
|
||||
|
|
@ -37,8 +43,11 @@ internal class CreateMobileWalletModel @Inject constructor(
|
|||
private val trackingContextProxy: TrackingContextProxy,
|
||||
private val isHotWalletCreationSupported: IsHotWalletCreationSupported,
|
||||
private val uiMessageSender: UiMessageSender,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
) : Model() {
|
||||
|
||||
private val params: CreateMobileWalletComponent.Params = paramsContainer.require()
|
||||
|
||||
internal val uiState: StateFlow<CreateMobileWalletUM>
|
||||
field = MutableStateFlow(
|
||||
CreateMobileWalletUM(
|
||||
|
|
@ -51,6 +60,8 @@ internal class CreateMobileWalletModel @Inject constructor(
|
|||
|
||||
init {
|
||||
trackingContextProxy.addHotWalletContext()
|
||||
analyticsEventHandler.send(OnboardingAnalyticsEvent.Onboarding.Started(source = params.source))
|
||||
analyticsEventHandler.send(OnboardingAnalyticsEvent.SeedPhrase.CreateMobileScreenOpened)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
|
|
@ -59,11 +70,13 @@ internal class CreateMobileWalletModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun onImportClick() {
|
||||
analyticsEventHandler.send(OnboardingAnalyticsEvent.SeedPhrase.ButtonImportWallet)
|
||||
checkHotWalletCreationSupported(notSupported = { return })
|
||||
router.push(AppRoute.AddExistingWallet)
|
||||
}
|
||||
|
||||
private fun onCreateClick() {
|
||||
analyticsEventHandler.send(OnboardingAnalyticsEvent.CreateWallet.ButtonCreateWallet)
|
||||
checkHotWalletCreationSupported(notSupported = { return })
|
||||
|
||||
modelScope.launch {
|
||||
|
|
@ -78,6 +91,16 @@ internal class CreateMobileWalletModel @Inject constructor(
|
|||
|
||||
saveUserWalletUseCase(userWallet)
|
||||
|
||||
analyticsEventHandler.send(OnboardingAnalyticsEvent.Onboarding.Finished(source = params.source))
|
||||
analyticsEventHandler.send(
|
||||
event = OnboardingAnalyticsEvent.CreateWallet.WalletCreatedSuccessfully(
|
||||
source = params.source,
|
||||
creationType = OnboardingAnalyticsEvent.CreateWallet.WalletCreationType.NewSeed,
|
||||
seedPhraseLength = SEED_PHRASE_LENGTH,
|
||||
passPhraseState = AnalyticsParam.EmptyFull.Empty,
|
||||
),
|
||||
)
|
||||
|
||||
launch(dispatchers.main + NonCancellable) {
|
||||
syncWalletWithRemoteUseCase(userWalletId = userWallet.walletId)
|
||||
}
|
||||
|
|
@ -99,4 +122,8 @@ internal class CreateMobileWalletModel @Inject constructor(
|
|||
notSupported()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val SEED_PHRASE_LENGTH = 12
|
||||
}
|
||||
}
|
||||
|
|
@ -15,7 +15,7 @@ import dagger.assisted.AssistedInject
|
|||
@Suppress("UnusedPrivateMember")
|
||||
internal class DefaultCreateMobileWalletComponent @AssistedInject constructor(
|
||||
@Assisted private val context: AppComponentContext,
|
||||
@Assisted private val params: Unit,
|
||||
@Assisted private val params: CreateMobileWalletComponent.Params,
|
||||
) : CreateMobileWalletComponent, AppComponentContext by context {
|
||||
|
||||
private val model: CreateMobileWalletModel = getOrCreateModel(params)
|
||||
|
|
@ -31,6 +31,9 @@ internal class DefaultCreateMobileWalletComponent @AssistedInject constructor(
|
|||
|
||||
@AssistedFactory
|
||||
interface Factory : CreateMobileWalletComponent.Factory {
|
||||
override fun create(context: AppComponentContext, params: Unit): DefaultCreateMobileWalletComponent
|
||||
override fun create(
|
||||
context: AppComponentContext,
|
||||
params: CreateMobileWalletComponent.Params,
|
||||
): DefaultCreateMobileWalletComponent
|
||||
}
|
||||
}
|
||||
|
|
@ -250,7 +250,7 @@ class MultiWalletBackupModel @Inject constructor(
|
|||
|
||||
private fun showCardVerificationFailedDialog(error: TangemSdkError.CardVerificationFailed) {
|
||||
analyticsEventHandler.send(
|
||||
event = OnboardingAnalyticsEvent.Onboarding.OfflineAttestationFailed(AnalyticsParam.ScreensSources.Backup),
|
||||
event = OnboardingAnalyticsEvent.Error.OfflineAttestationFailed(AnalyticsParam.ScreensSources.Backup),
|
||||
)
|
||||
|
||||
val resource = error.localizedDescriptionRes()
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ internal sealed class SendAnalyticEvents(
|
|||
val feeType: AnalyticsParam.FeeType,
|
||||
val blockchain: String,
|
||||
val nonceNotEmpty: Boolean,
|
||||
private val ensStatus: AnalyticsParam.EnsStatus,
|
||||
private val ensStatus: AnalyticsParam.EmptyFull,
|
||||
) : SendAnalyticEvents(
|
||||
event = "Transaction Sent Screen Opened",
|
||||
params = mapOf(
|
||||
|
|
@ -33,8 +33,8 @@ internal sealed class SendAnalyticEvents(
|
|||
BLOCKCHAIN to blockchain,
|
||||
NONCE to nonceNotEmpty.toString().capitalize(),
|
||||
ENS_ADDRESS to when (ensStatus) {
|
||||
AnalyticsParam.EnsStatus.EMPTY -> false.toString().capitalize()
|
||||
AnalyticsParam.EnsStatus.FULL -> true.toString().capitalize()
|
||||
AnalyticsParam.EmptyFull.Empty -> false.toString().capitalize()
|
||||
AnalyticsParam.EmptyFull.Full -> true.toString().capitalize()
|
||||
},
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -53,13 +53,13 @@ internal class SendAnalyticHelper @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun getEnsStatus(sendUM: SendUM): AnalyticsParam.EnsStatus {
|
||||
private fun getEnsStatus(sendUM: SendUM): AnalyticsParam.EmptyFull {
|
||||
val blockchainAddressForEns =
|
||||
(sendUM.destinationUM as? DestinationUM.Content)?.addressTextField?.isAddressEns
|
||||
return if (blockchainAddressForEns == true) {
|
||||
AnalyticsParam.EnsStatus.FULL
|
||||
AnalyticsParam.EmptyFull.Full
|
||||
} else {
|
||||
AnalyticsParam.EnsStatus.EMPTY
|
||||
AnalyticsParam.EmptyFull.Empty
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -56,12 +56,12 @@ internal class TokenReceiveAssetsModel @Inject constructor(
|
|||
),
|
||||
)
|
||||
|
||||
private fun configureEnsStatus(): AnalyticsParam.EnsStatus {
|
||||
private fun configureEnsStatus(): AnalyticsParam.EmptyFull {
|
||||
val hasEnsAddress = params.addresses.any { it.type == ReceiveAddress.Type.Ens }
|
||||
return if (hasEnsAddress) {
|
||||
AnalyticsParam.EnsStatus.FULL
|
||||
AnalyticsParam.EmptyFull.Full
|
||||
} else {
|
||||
AnalyticsParam.EnsStatus.EMPTY
|
||||
AnalyticsParam.EmptyFull.Empty
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import arrow.core.getOrElse
|
|||
import com.tangem.common.ui.expressStatus.ExpressStatusBottomSheetConfig
|
||||
import com.tangem.common.ui.tokens.TokenItemStateConverter.ApySource
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.analytics.models.event.MainScreenAnalyticsEvent
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.domain.models.account.Account
|
||||
|
|
@ -354,7 +355,7 @@ internal class WalletContentClickIntentsImplementor @Inject constructor(
|
|||
is WalletNFTItemUM.Content -> {
|
||||
analyticsEventHandler.send(
|
||||
NFTAnalyticsEvent.NFTListScreenOpened(
|
||||
state = NFTAnalyticsEvent.NFTListScreenOpened.State.Full,
|
||||
state = AnalyticsParam.EmptyFull.Full,
|
||||
allAssetsCount = state.allAssetsCount,
|
||||
collectionsCount = state.collectionsCount,
|
||||
noCollectionAssetsCount = state.noCollectionAssetsCount,
|
||||
|
|
@ -364,7 +365,7 @@ internal class WalletContentClickIntentsImplementor @Inject constructor(
|
|||
is WalletNFTItemUM.Empty -> {
|
||||
analyticsEventHandler.send(
|
||||
NFTAnalyticsEvent.NFTListScreenOpened(
|
||||
state = NFTAnalyticsEvent.NFTListScreenOpened.State.Empty,
|
||||
state = AnalyticsParam.EmptyFull.Empty,
|
||||
allAssetsCount = 0,
|
||||
collectionsCount = 0,
|
||||
noCollectionAssetsCount = 0,
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ sealed class WalletScreenAnalyticsEvent {
|
|||
},
|
||||
)
|
||||
|
||||
class TokenBalance(balance: AnalyticsParam.TokenBalanceState, token: String) : Basic(
|
||||
class TokenBalance(balance: AnalyticsParam.EmptyFull, token: String) : Basic(
|
||||
event = "Token Balance",
|
||||
params = mapOf(
|
||||
AnalyticsParam.STATE to balance.value,
|
||||
|
|
|
|||
|
|
@ -156,9 +156,9 @@ internal class TokenListAnalyticsSender @Inject constructor(
|
|||
-> {
|
||||
if (balanceWasSentMap[blockchain.currency] != true) {
|
||||
val tokenBalance = if (balanceStatus.amount.isZero()) {
|
||||
AnalyticsParam.TokenBalanceState.Empty
|
||||
AnalyticsParam.EmptyFull.Empty
|
||||
} else {
|
||||
AnalyticsParam.TokenBalanceState.Full
|
||||
AnalyticsParam.EmptyFull.Full
|
||||
}
|
||||
analyticsEventHandler.send(
|
||||
Basic.TokenBalance(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue