Updated on 2026-08-14

This commit is contained in:
Tangem 2026-02-09 20:36:41 +05:00
parent d64383fc7d
commit 65a2f369c8
7 changed files with 31 additions and 7 deletions

View file

@ -71,7 +71,7 @@ class AppsFlyerReferralParamsHandler @Inject constructor(
private fun storeConversionData(refcode: String, campaign: String?) {
coroutineScope.launch {
mutex.withLock {
setShouldShowMobileWalletPromoUseCase()
setShouldShowMobileWalletPromoUseCase(true)
.onLeft { Timber.e(it) }
appsFlyerStore.storeIfAbsent(
value = AppsFlyerConversionData(refcode = refcode, campaign = campaign),

View file

@ -17,6 +17,7 @@ import com.tangem.domain.visa.model.VisaCardActivationStatus
import com.tangem.domain.wallets.hot.HotWalletAccessCodeAttemptsRepository
import com.tangem.domain.wallets.hot.HotWalletPasswordRequester
import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.feature.referral.domain.MobileWalletPromoRepository
import com.tangem.hot.sdk.TangemHotSdk
import com.tangem.sdk.storage.AndroidSecureStorage
import com.tangem.sdk.storage.AndroidSecureStorageV2
@ -130,6 +131,7 @@ internal object UserWalletsListManagerModule {
trackingContextProxy: TrackingContextProxy,
analyticsEventHandler: AnalyticsEventHandler,
hotWalletRepository: HotWalletRepository,
mobileWalletPromoRepository: MobileWalletPromoRepository,
): UserWalletsListRepository {
val moshi = buildMoshi()
val secureStorage = buildSecureStorage(applicationContext = applicationContext)
@ -180,6 +182,7 @@ internal object UserWalletsListManagerModule {
trackingContextProxy = trackingContextProxy,
analyticsEventHandler = analyticsEventHandler,
hotWalletRepository = hotWalletRepository,
mobileWalletPromoRepository = mobileWalletPromoRepository,
)
}

View file

@ -25,6 +25,7 @@ import com.tangem.domain.wallets.analytics.WalletSettingsAnalyticEvents
import com.tangem.domain.wallets.builder.UserWalletIdBuilder
import com.tangem.domain.wallets.hot.HotWalletAccessCodeAttemptsRepository
import com.tangem.domain.wallets.hot.HotWalletPasswordRequester
import com.tangem.feature.referral.domain.MobileWalletPromoRepository
import com.tangem.hot.sdk.TangemHotSdk
import com.tangem.hot.sdk.model.HotWalletId
import com.tangem.sdk.api.TangemSdkManager
@ -58,6 +59,7 @@ internal class DefaultUserWalletsListRepository(
private val trackingContextProxy: TrackingContextProxy,
private val analyticsEventHandler: AnalyticsEventHandler,
private val hotWalletRepository: HotWalletRepository,
private val mobileWalletPromoRepository: MobileWalletPromoRepository,
) : UserWalletsListRepository {
override val userWallets = MutableStateFlow<List<UserWallet>?>(null)
@ -126,6 +128,8 @@ internal class DefaultUserWalletsListRepository(
raise(SaveWalletError.WalletAlreadySaved(messageId = R.string.user_wallet_list_error_wallet_already_saved))
}
val isFirstWallet = userWallets.value?.isEmpty() == true
if (savePersistentInformation()) {
publicInformationRepository.save(userWallet, canOverride)
if (userWallet.isLocked.not()) {
@ -148,6 +152,10 @@ internal class DefaultUserWalletsListRepository(
wallets.addOrReplace(userWallet) { it.walletId == userWallet.walletId }
}
if (isFirstWallet) {
onFirstWalletCreated()
}
// update the selectedUserWallet state if it is the only wallet
if (userWallets.value?.size == 1) {
selectedUserWalletRepository.set(userWallet.walletId)
@ -221,6 +229,9 @@ internal class DefaultUserWalletsListRepository(
val newSelected = updatedWallets?.findAvailableUserWallet(
currentWallets.indexOfFirstOrNull { it.walletId == currentSelected.walletId } ?: 0,
)
if (newSelected == null) {
onAllWalletsDeleted()
}
selectedUserWalletRepository.set(newSelected?.walletId)
newSelected
}
@ -542,4 +553,14 @@ internal class DefaultUserWalletsListRepository(
private fun trackWalletUpgradeEvent() {
analyticsEventHandler.send(event = WalletSettingsAnalyticEvents.WalletUpgraded())
}
private suspend fun onFirstWalletCreated() {
// reset flag (that is set from AF deeplink) after creating a new wallet
mobileWalletPromoRepository.setShouldShowMobileWalletPromo(false)
}
private suspend fun onAllWalletsDeleted() {
// reset flag (that is set from AF deeplink) after removing the last wallet
mobileWalletPromoRepository.setShouldShowMobileWalletPromo(false)
}
}

View file

@ -26,7 +26,7 @@ class AppsFlyerReferralParamsHandlerTest {
private val appsFlyerStore: AppsFlyerStore = mockk(relaxUnitFun = true)
private val setShouldShowMobileWalletPromoUseCase: SetShouldShowMobileWalletPromoUseCase = mockk {
coEvery { this@mockk.invoke() } returns Unit.right()
coEvery { this@mockk.invoke(true) } returns Unit.right()
}
private val handler = AppsFlyerReferralParamsHandler(
appsFlyerStore = appsFlyerStore,

View file

@ -14,9 +14,9 @@ internal class DefaultMobileWalletPromoRepository @Inject constructor(
return appPreferencesStore.getSyncOrDefault(key = SHOULD_SHOW_MOBILE_WALLET_PROMO_KEY, default = false)
}
override suspend fun setShouldShowMobileWalletPromo(value: Boolean) {
override suspend fun setShouldShowMobileWalletPromo(shouldShowPromo: Boolean) {
appPreferencesStore.editData { preferences ->
preferences[SHOULD_SHOW_MOBILE_WALLET_PROMO_KEY] = value
preferences[SHOULD_SHOW_MOBILE_WALLET_PROMO_KEY] = shouldShowPromo
}
}

View file

@ -4,5 +4,5 @@ interface MobileWalletPromoRepository {
suspend fun shouldShowMobileWalletPromo(): Boolean
suspend fun setShouldShowMobileWalletPromo(value: Boolean)
suspend fun setShouldShowMobileWalletPromo(shouldShowPromo: Boolean)
}

View file

@ -9,10 +9,10 @@ class SetShouldShowMobileWalletPromoUseCase @Inject constructor(
private val userWalletsListRepository: UserWalletsListRepository,
) {
suspend operator fun invoke(): Either<Throwable, Unit> = Either.catch {
suspend operator fun invoke(shouldShowPromo: Boolean): Either<Throwable, Unit> = Either.catch {
val wallets = userWalletsListRepository.userWallets.value
if (wallets.isNullOrEmpty()) {
mobileWalletPromoRepository.setShouldShowMobileWalletPromo(true)
mobileWalletPromoRepository.setShouldShowMobileWalletPromo(shouldShowPromo)
}
}
}