Updated on 2026-08-14
This commit is contained in:
parent
6b75b48f1e
commit
8e6eca1b4c
23 changed files with 327 additions and 216 deletions
|
|
@ -0,0 +1,61 @@
|
|||
package com.tangem.tap.domain
|
||||
|
||||
import com.tangem.core.analytics.utils.TrackingContextProxy
|
||||
import com.tangem.domain.card.repository.CardSdkConfigRepository
|
||||
import com.tangem.domain.common.wallets.UserWalletSelectedHandler
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.settings.repositories.SettingsRepository
|
||||
import com.tangem.sdk.api.TangemSdkManager
|
||||
import com.tangem.utils.coroutines.AppCoroutineScope
|
||||
import com.tangem.utils.coroutines.JobHolder
|
||||
import com.tangem.utils.coroutines.saveInAndJoin
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* Default implementation of [UserWalletSelectedHandler].
|
||||
*
|
||||
* Runs three side effects on every selection: updates the analytics tracking context, updates the
|
||||
* Tangem SDK displayed card-id numbers count (cold wallets only), and recomputes the access code
|
||||
* request policy (cold wallets only). Hot wallets trigger only the tracking-context update.
|
||||
*
|
||||
* Invocations are serialised via [JobHolder]: if a new [invoke] arrives while the previous one is
|
||||
* still running, the previous load is cancelled and the new one replaces it. The method suspends
|
||||
* until the newly launched load completes.
|
||||
*/
|
||||
@Singleton
|
||||
internal class DefaultUserWalletSelectedHandler @Inject constructor(
|
||||
private val trackingContextProxy: TrackingContextProxy,
|
||||
private val tangemSdkManager: TangemSdkManager,
|
||||
private val settingsRepository: SettingsRepository,
|
||||
private val cardSdkConfigRepository: CardSdkConfigRepository,
|
||||
private val appCoroutineScope: AppCoroutineScope,
|
||||
) : UserWalletSelectedHandler {
|
||||
|
||||
private val loadUserWalletDataJob: JobHolder = JobHolder()
|
||||
|
||||
override suspend fun invoke(userWallet: UserWallet) {
|
||||
appCoroutineScope.launch { loadUserWalletData(userWallet) }
|
||||
.saveInAndJoin(loadUserWalletDataJob)
|
||||
}
|
||||
|
||||
private suspend fun loadUserWalletData(userWallet: UserWallet) {
|
||||
trackingContextProxy.setContext(userWallet)
|
||||
|
||||
if (userWallet is UserWallet.Cold) {
|
||||
val scanResponse = userWallet.scanResponse
|
||||
tangemSdkManager.changeDisplayedCardIdNumbersCount(scanResponse)
|
||||
updateAccessCodeRequestPolicy(scanResponse)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun updateAccessCodeRequestPolicy(scanResponse: ScanResponse) {
|
||||
val shouldSaveAccessCodes = settingsRepository.shouldSaveAccessCodes()
|
||||
|
||||
cardSdkConfigRepository.setAccessCodeRequestPolicy(
|
||||
isBiometricsRequestPolicy = shouldSaveAccessCodes && scanResponse.card.isAccessCodeSet,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ import com.tangem.common.services.secure.SecureStorage
|
|||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.analytics.utils.TrackingContextProxy
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.domain.common.wallets.UserWalletSelectedHandler
|
||||
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
||||
import com.tangem.domain.hotwallet.repository.HotWalletRepository
|
||||
import com.tangem.domain.models.scan.serialization.*
|
||||
|
|
@ -32,6 +33,7 @@ import com.tangem.tap.tangemSdkManager
|
|||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.ProviderSuspend
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.Lazy
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
|
|
@ -56,6 +58,7 @@ internal object UserWalletsListRepositoryModule {
|
|||
analyticsEventHandler: AnalyticsEventHandler,
|
||||
hotWalletRepository: HotWalletRepository,
|
||||
mobileWalletPromoRepository: MobileWalletPromoRepository,
|
||||
userWalletSelectedHandler: Lazy<UserWalletSelectedHandler>,
|
||||
): UserWalletsListRepository {
|
||||
val moshi = buildMoshi()
|
||||
val secureStorage = buildSecureStorage(applicationContext = applicationContext)
|
||||
|
|
@ -107,6 +110,7 @@ internal object UserWalletsListRepositoryModule {
|
|||
analyticsEventHandler = analyticsEventHandler,
|
||||
hotWalletRepository = hotWalletRepository,
|
||||
mobileWalletPromoRepository = mobileWalletPromoRepository,
|
||||
userWalletSelectedHandler = userWalletSelectedHandler,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import com.tangem.core.analytics.utils.TrackingContextProxy
|
|||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||
import com.tangem.datasource.local.preferences.utils.getSyncOrDefault
|
||||
import com.tangem.domain.common.wallets.UserWalletSelectedHandler
|
||||
import com.tangem.domain.common.wallets.UserWalletTransformAction
|
||||
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
||||
import com.tangem.domain.common.wallets.UserWalletsListRepository.LockMethod
|
||||
|
|
@ -35,6 +36,7 @@ import com.tangem.tap.domain.userWalletList.utils.*
|
|||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.ProviderSuspend
|
||||
import com.tangem.utils.coroutines.runSuspendCatching
|
||||
import dagger.Lazy
|
||||
import com.tangem.utils.extensions.addOrReplace
|
||||
import com.tangem.utils.extensions.indexOfFirstOrNull
|
||||
import kotlinx.coroutines.NonCancellable
|
||||
|
|
@ -60,6 +62,7 @@ internal class DefaultUserWalletsListRepository(
|
|||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val hotWalletRepository: HotWalletRepository,
|
||||
private val mobileWalletPromoRepository: MobileWalletPromoRepository,
|
||||
private val userWalletSelectedHandler: Lazy<UserWalletSelectedHandler>,
|
||||
) : UserWalletsListRepository {
|
||||
|
||||
override val userWallets = MutableStateFlow<List<UserWallet>?>(null)
|
||||
|
|
@ -88,15 +91,13 @@ internal class DefaultUserWalletsListRepository(
|
|||
.map { wallets.updateWith(it) }
|
||||
}
|
||||
.doOnSuccess { loadedWallets ->
|
||||
userWallets.update { _ ->
|
||||
val selectedUserWalletId = selectedUserWalletRepository.get()
|
||||
selectedUserWallet.value = loadedWallets.firstOrNull { it.walletId == selectedUserWalletId }
|
||||
?: loadedWallets.firstOrNull()?.also {
|
||||
selectedUserWalletRepository.set(it.walletId)
|
||||
}
|
||||
|
||||
loadedWallets
|
||||
}
|
||||
val selectedUserWalletId = selectedUserWalletRepository.get()
|
||||
val initialSelection = loadedWallets.firstOrNull { it.walletId == selectedUserWalletId }
|
||||
?: loadedWallets.firstOrNull()?.also {
|
||||
selectedUserWalletRepository.set(it.walletId)
|
||||
}
|
||||
userWallets.value = loadedWallets
|
||||
setSelectedUserWallet(initialSelection)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -117,7 +118,7 @@ internal class DefaultUserWalletsListRepository(
|
|||
val userWallet = userWallets.value?.find { it.walletId == userWalletId }
|
||||
?: raise(SelectWalletError.UnableToSelectUserWallet)
|
||||
selectedUserWalletRepository.set(userWalletId)
|
||||
selectedUserWallet.value = userWallet
|
||||
setSelectedUserWallet(userWallet)
|
||||
userWallet
|
||||
}
|
||||
|
||||
|
|
@ -160,7 +161,7 @@ internal class DefaultUserWalletsListRepository(
|
|||
// update the selectedUserWallet state if it is the only wallet
|
||||
if (userWallets.value?.size == 1) {
|
||||
selectedUserWalletRepository.set(userWallet.walletId)
|
||||
selectedUserWallet.value = userWallet
|
||||
setSelectedUserWallet(userWallet)
|
||||
}
|
||||
|
||||
userWallet
|
||||
|
|
@ -223,20 +224,24 @@ internal class DefaultUserWalletsListRepository(
|
|||
|
||||
removeHotWalletsFromSDKAndRepos(userWalletIds)
|
||||
|
||||
userWallets.update { currentWallets ->
|
||||
val updatedWallets = currentWallets?.filter { userWalletIds.contains(it.walletId).not() }
|
||||
selectedUserWallet.update { currentSelected ->
|
||||
if (currentSelected == null) return@update null
|
||||
val newSelected = updatedWallets?.findAvailableUserWallet(
|
||||
currentWallets.indexOfFirstOrNull { it.walletId == currentSelected.walletId } ?: 0,
|
||||
)
|
||||
if (newSelected == null) {
|
||||
onAllWalletsDeleted()
|
||||
}
|
||||
selectedUserWalletRepository.set(newSelected?.walletId)
|
||||
newSelected
|
||||
val currentWallets = userWallets.value
|
||||
val currentSelected = selectedUserWallet.value
|
||||
val updatedWallets = currentWallets?.filter { userWalletIds.contains(it.walletId).not() }
|
||||
val newSelected = if (currentSelected == null) {
|
||||
null
|
||||
} else {
|
||||
updatedWallets?.findAvailableUserWallet(
|
||||
currentWallets.indexOfFirstOrNull { it.walletId == currentSelected.walletId } ?: 0,
|
||||
)
|
||||
}
|
||||
|
||||
userWallets.value = updatedWallets
|
||||
if (currentSelected != null) {
|
||||
if (newSelected == null) {
|
||||
onAllWalletsDeleted()
|
||||
}
|
||||
updatedWallets
|
||||
selectedUserWalletRepository.set(newSelected?.walletId)
|
||||
setSelectedUserWallet(newSelected)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -523,6 +528,18 @@ internal class DefaultUserWalletsListRepository(
|
|||
return tangemSdkManagerProvider.invoke().canUseBiometry && isBiometricAuthenticationUsed
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes [userWallet] into [selectedUserWallet] and invokes [userWalletSelectedHandler] when
|
||||
* the selected [UserWalletId] actually changes. Same-id refreshes stay silent.
|
||||
*/
|
||||
private suspend fun setSelectedUserWallet(userWallet: UserWallet?) {
|
||||
val previousId = selectedUserWallet.value?.walletId
|
||||
selectedUserWallet.value = userWallet
|
||||
if (userWallet != null && previousId != userWallet.walletId) {
|
||||
userWalletSelectedHandler.get().invoke(userWallet)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateWallets(block: (List<UserWallet>?) -> List<UserWallet>?) {
|
||||
userWallets.update { wallets ->
|
||||
val updated = block(wallets)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue