Updated on 2026-08-14

This commit is contained in:
Tangem 2024-07-31 12:57:35 +03:00
parent 63455a510b
commit af822f9d7a
12 changed files with 147 additions and 24 deletions

View file

@ -0,0 +1,31 @@
package com.tangem.tap.common.analytics
import com.tangem.core.analytics.Analytics
import com.tangem.core.analytics.utils.AnalyticsContextProxy
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.tap.common.extensions.addContext
import com.tangem.tap.common.extensions.eraseContext
import com.tangem.tap.common.extensions.removeContext
import com.tangem.tap.common.extensions.setContext
/**
[REDACTED_AUTHOR]
*/
internal class DefaultAnalyticsContextProxy : AnalyticsContextProxy {
override fun setContext(scanResponse: ScanResponse) {
Analytics.setContext(scanResponse)
}
override fun eraseContext() {
Analytics.eraseContext()
}
override fun addContext(scanResponse: ScanResponse) {
Analytics.addContext(scanResponse)
}
override fun removeContext() {
Analytics.removeContext()
}
}

View file

@ -1,6 +1,8 @@
package com.tangem.tap.di.analytics
import com.tangem.core.analytics.utils.AnalyticsContextProxy
import com.tangem.domain.analytics.ChangeCardAnalyticsContextUseCase
import com.tangem.tap.common.analytics.DefaultAnalyticsContextProxy
import com.tangem.tap.common.analytics.DefaultChangeCardAnalyticsContextUseCase
import dagger.Module
import dagger.Provides
@ -17,4 +19,8 @@ internal object AnalyticsModule {
fun provideChangeCardAnalyticsContextUseCase(): ChangeCardAnalyticsContextUseCase {
return DefaultChangeCardAnalyticsContextUseCase()
}
@Provides
@Singleton
fun provideAnalyticsContextProxy(): AnalyticsContextProxy = DefaultAnalyticsContextProxy()
}

View file

@ -60,7 +60,7 @@ internal sealed class SettingsItem(
data class LinkMoreCards(
override val onClick: () -> Unit,
) : SettingsItem(
iconResId = R.drawable.ic_more_cards,
iconResId = R.drawable.ic_more_cards_24,
title = resourceReference(R.string.details_row_title_create_backup),
)

View file

@ -1,5 +0,0 @@
<vector android:autoMirrored="true" android:height="24dp"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#000000" android:fillType="evenOdd" android:pathData="M21,11V16H7V11H21ZM21,8V6H7V8H21ZM22.41,4.59C22.04,4.21 21.53,4 21,4H7C5.89,4 5,4.89 5,6V16C5,17.1 5.89,18 7,18H21C21.53,18 22.04,17.79 22.41,17.41C22.79,17.04 23,16.53 23,16V6C23,5.47 22.79,4.96 22.41,4.59ZM18,20H3V9H1V20C1,20.53 1.21,21.04 1.59,21.41C1.96,21.79 2.47,22 3,22H18V20Z"/>
</vector>

View file

@ -15,6 +15,7 @@ dependencies {
/** Domain */
implementation(projects.domain.analytics)
implementation(projects.domain.models)
/** Other */
implementation(deps.kotlin.coroutines)

View file

@ -0,0 +1,17 @@
package com.tangem.core.analytics.utils
import com.tangem.domain.models.scan.ScanResponse
/**
[REDACTED_AUTHOR]
*/
interface AnalyticsContextProxy {
fun setContext(scanResponse: ScanResponse)
fun eraseContext()
fun addContext(scanResponse: ScanResponse)
fun removeContext()
}

View file

@ -0,0 +1,11 @@
<vector android:autoMirrored="true"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<path
android:fillColor="#000000"
android:fillType="evenOdd"
android:pathData="M21,11V16H7V11H21ZM21,8V6H7V8H21ZM22.41,4.59C22.04,4.21 21.53,4 21,4H7C5.89,4 5,4.89 5,6V16C5,17.1 5.89,18 7,18H21C21.53,18 22.04,17.79 22.41,17.41C22.79,17.04 23,16.53 23,16V6C23,5.47 22.79,4.96 22.41,4.59ZM18,20H3V9H1V20C1,20.53 1.21,21.04 1.59,21.41C1.96,21.79 2.47,22 3,22H18V20Z" />
</vector>

View file

@ -21,11 +21,13 @@ dependencies {
implementation(projects.core.ui)
implementation(projects.core.featuretoggles)
implementation(projects.core.navigation)
implementation(projects.core.analytics)
implementation(projects.core.analytics.models)
implementation(projects.common.routing)
/* Project - Domain */
implementation(projects.domain.legacy)
implementation(projects.domain.models)
implementation(projects.domain.wallets)
implementation(projects.domain.wallets.models)
@ -50,4 +52,5 @@ dependencies {
/* Other */
implementation(deps.kotlin.immutable.collections)
implementation(deps.timber)
implementation(deps.reKotlin)
}

View file

@ -0,0 +1,13 @@
package com.tangem.feature.walletsettings.analytics
import com.tangem.core.analytics.models.AnalyticsEvent
internal sealed class Settings(
category: String = "Settings",
event: String,
params: Map<String, String> = mapOf(),
error: Throwable? = null,
) : AnalyticsEvent(category, event, params, error) {
class ButtonCreateBackup : Settings(event = "Button - Create Backup")
}

View file

@ -19,8 +19,10 @@ internal class PreviewWalletSettingsComponent : WalletSettingsComponent {
userWalletId = UserWalletId("011"),
userWalletName = "My Wallet",
isReferralAvailable = true,
isLinkMoreCardsAvailable = true,
renameWallet = {},
forgetWallet = {},
onLinkMoreCardsClick = {},
),
)

View file

@ -5,6 +5,8 @@ import arrow.core.getOrElse
import com.arkivanov.decompose.router.slot.SlotNavigation
import com.arkivanov.decompose.router.slot.activate
import com.tangem.common.routing.AppRoute
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.analytics.utils.AnalyticsContextProxy
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
@ -16,9 +18,14 @@ import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.message.ContentMessage
import com.tangem.core.ui.message.SnackbarMessage
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.domain.redux.LegacyAction
import com.tangem.domain.redux.ReduxStateHolder
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.domain.wallets.usecase.DeleteWalletUseCase
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
import com.tangem.feature.walletsettings.analytics.Settings
import com.tangem.feature.walletsettings.component.WalletSettingsComponent
import com.tangem.feature.walletsettings.entity.DialogConfig
import com.tangem.feature.walletsettings.entity.WalletSettingsItemUM
@ -43,6 +50,9 @@ internal class WalletSettingsModel @Inject constructor(
private val deleteWalletUseCase: DeleteWalletUseCase,
private val itemsBuilder: ItemsBuilder,
override val dispatchers: CoroutineDispatcherProvider,
private val analyticsEventHandler: AnalyticsEventHandler,
private val analyticsContextProxy: AnalyticsContextProxy,
private val reduxStateHolder: ReduxStateHolder,
) : Model() {
val params: WalletSettingsComponent.Params = paramsContainer.require()
@ -75,6 +85,7 @@ internal class WalletSettingsModel @Inject constructor(
userWalletId = userWallet.walletId,
userWalletName = userWallet.name,
isReferralAvailable = userWallet.cardTypesResolver.isTangemWallet(),
isLinkMoreCardsAvailable = userWallet.scanResponse.card.backupStatus == CardDTO.BackupStatus.NoBackup,
renameWallet = { openRenameWalletDialog(userWallet, dialogNavigation) },
forgetWallet = {
messageSender.send(
@ -98,6 +109,9 @@ internal class WalletSettingsModel @Inject constructor(
},
)
},
onLinkMoreCardsClick = {
onLinkMoreCardsClick(scanResponse = userWallet.scanResponse)
},
)
private fun openRenameWalletDialog(userWallet: UserWallet, dialogNavigation: SlotNavigation<DialogConfig>) {
@ -126,4 +140,19 @@ internal class WalletSettingsModel @Inject constructor(
router.replaceAll(AppRoute.Home)
}
}
private fun onLinkMoreCardsClick(scanResponse: ScanResponse) {
analyticsEventHandler.send(Settings.ButtonCreateBackup())
analyticsContextProxy.addContext(scanResponse)
reduxStateHolder.dispatch(
LegacyAction.StartOnboardingProcess(
scanResponse = scanResponse,
canSkipBackup = false,
),
)
router.push(AppRoute.OnboardingWallet())
}
}

View file

@ -19,15 +19,18 @@ internal class ItemsBuilder @Inject constructor(
private val router: Router,
) {
@Suppress("LongParameterList")
fun buildItems(
userWalletId: UserWalletId,
userWalletName: String,
isLinkMoreCardsAvailable: Boolean,
isReferralAvailable: Boolean,
forgetWallet: () -> Unit,
renameWallet: () -> Unit,
onLinkMoreCardsClick: () -> Unit,
): PersistentList<WalletSettingsItemUM> = persistentListOf(
buildNameItem(userWalletName, renameWallet),
buildCardItem(userWalletId, isReferralAvailable),
buildCardItem(userWalletId, isLinkMoreCardsAvailable, isReferralAvailable, onLinkMoreCardsClick),
buildForgetItem(forgetWallet),
)
@ -38,26 +41,38 @@ internal class ItemsBuilder @Inject constructor(
onClick = renameWallet,
)
private fun buildCardItem(userWalletId: UserWalletId, isReferralAvailable: Boolean) =
WalletSettingsItemUM.WithItems(
id = "card",
description = resourceReference(R.string.settings_card_settings_footer),
blocks = buildList {
private fun buildCardItem(
userWalletId: UserWalletId,
isLinkMoreCardsAvailable: Boolean,
isReferralAvailable: Boolean,
onLinkMoreCardsClick: () -> Unit,
) = WalletSettingsItemUM.WithItems(
id = "card",
description = resourceReference(R.string.settings_card_settings_footer),
blocks = buildList {
if (isLinkMoreCardsAvailable) {
BlockUM(
text = resourceReference(R.string.card_settings_title),
iconRes = R.drawable.ic_card_settings_24,
onClick = { router.push(AppRoute.CardSettings(userWalletId)) },
text = resourceReference(R.string.details_row_title_create_backup),
iconRes = R.drawable.ic_more_cards_24,
onClick = onLinkMoreCardsClick,
).let(::add)
}
if (isReferralAvailable) {
BlockUM(
text = resourceReference(R.string.details_referral_title),
iconRes = R.drawable.ic_add_friends_24,
onClick = { router.push(AppRoute.ReferralProgram(userWalletId)) },
).let(::add)
}
}.toImmutableList(),
)
BlockUM(
text = resourceReference(R.string.card_settings_title),
iconRes = R.drawable.ic_card_settings_24,
onClick = { router.push(AppRoute.CardSettings(userWalletId)) },
).let(::add)
if (isReferralAvailable) {
BlockUM(
text = resourceReference(R.string.details_referral_title),
iconRes = R.drawable.ic_add_friends_24,
onClick = { router.push(AppRoute.ReferralProgram(userWalletId)) },
).let(::add)
}
}.toImmutableList(),
)
private fun buildForgetItem(forgetWallet: () -> Unit) = WalletSettingsItemUM.WithItems(
id = "forget",