From bae36dfbf5ba910c08984361d6d39bde70898b2e Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 3 Oct 2023 16:05:37 +0800 Subject: [PATCH] Updated on 2026-08-14 --- .../wallet/ui/components/common/WalletCard.kt | 48 ++++++++------ .../wallet/viewmodels/WalletViewModel.kt | 65 ++++++++----------- 2 files changed, 54 insertions(+), 59 deletions(-) diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletCard.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletCard.kt index d1c6cfeb73..4cd547a875 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletCard.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletCard.kt @@ -44,7 +44,6 @@ import com.tangem.core.ui.components.ResizableText import com.tangem.core.ui.components.wallets.RenameWalletDialogContent import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.resolveReference -import com.tangem.core.ui.res.TangemColorPalette import com.tangem.core.ui.res.TangemDimens import com.tangem.core.ui.res.TangemTheme import com.tangem.feature.wallet.impl.R @@ -66,6 +65,7 @@ internal fun WalletCard(state: WalletCardState, modifier: Modifier = Modifier) { name = state.title, onDeleteClick = { state.onDeleteClick(state.id) }, onRenameClick = { state.onRenameClick(state.id, it) }, + isLockedState = state is WalletCardState.LockedContent, modifier = modifier, ) { val (title, balance, additionalText, image) = createRefs() @@ -118,6 +118,7 @@ private fun CardContainer( name: String, onDeleteClick: () -> Unit, onRenameClick: (String) -> Unit, + isLockedState: Boolean, modifier: Modifier = Modifier, content: @Composable (ConstraintLayoutScope.() -> Unit), ) { @@ -132,24 +133,31 @@ private fun CardContainer( Surface( modifier = modifier .defaultMinSize(minHeight = TangemTheme.dimens.size108) - .onSizeChanged { itemHeight = with(density) { it.height.toDp() } } - .clip(shape = TangemTheme.shapes.roundedCornersXMedium) - .indication(interactionSource = interactionSource, indication = LocalIndication.current) - .pointerInput(true) { - detectTapGestures( - onLongPress = { - haptic.performHapticFeedback(HapticFeedbackType.LongPress) - isMenuVisible = true - pressOffset = DpOffset(x = it.x.toDp(), y = it.y.toDp()) - }, - onPress = { - val press = PressInteraction.Press(it) - interactionSource.emit(press) - tryAwaitRelease() - interactionSource.emit(PressInteraction.Release(press)) - }, - ) - }, + .then( + if (isLockedState) { + Modifier + } else { + Modifier + .onSizeChanged { itemHeight = with(density) { it.height.toDp() } } + .clip(shape = TangemTheme.shapes.roundedCornersXMedium) + .indication(interactionSource = interactionSource, indication = LocalIndication.current) + .pointerInput(true) { + detectTapGestures( + onLongPress = { + haptic.performHapticFeedback(HapticFeedbackType.LongPress) + isMenuVisible = true + pressOffset = DpOffset(x = it.x.toDp(), y = it.y.toDp()) + }, + onPress = { + val press = PressInteraction.Press(it) + interactionSource.emit(press) + tryAwaitRelease() + interactionSource.emit(PressInteraction.Release(press)) + }, + ) + } + }, + ), shape = TangemTheme.shapes.roundedCornersXMedium, color = TangemTheme.colors.background.primary, ) { @@ -229,7 +237,7 @@ private fun MenuItem(@StringRes textResId: Int, imageVector: ImageVector, onClic onClick = onClick, colors = MenuDefaults.itemColors( textColor = TangemTheme.colors.text.primary1, - trailingIconColor = TangemColorPalette.Dark6, + trailingIconColor = TangemTheme.colors.icon.primary1, ), ) } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt index d7176b704d..8d6d27d709 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt @@ -8,7 +8,6 @@ import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.address.AddressType import com.tangem.common.Provider import com.tangem.common.card.EllipticCurve -import com.tangem.common.doOnFailure import com.tangem.common.doOnSuccess import com.tangem.common.extensions.ByteArrayKey import com.tangem.common.extensions.isZero @@ -27,7 +26,10 @@ import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.balancehiding.IsBalanceHiddenUseCase import com.tangem.domain.balancehiding.ListenToFlipsUseCase -import com.tangem.domain.card.* +import com.tangem.domain.card.DerivePublicKeysUseCase +import com.tangem.domain.card.ScanCardProcessor +import com.tangem.domain.card.SetCardWasScannedUseCase +import com.tangem.domain.card.WasCardScannedUseCase import com.tangem.domain.common.CardTypesResolver import com.tangem.domain.common.configs.CardConfig import com.tangem.domain.common.util.cardTypesResolver @@ -88,9 +90,6 @@ internal class WalletViewModel @Inject constructor( private val selectWalletUseCase: SelectWalletUseCase, private val updateWalletUseCase: UpdateWalletUseCase, private val deleteWalletUseCase: DeleteWalletUseCase, - private val getBiometricsStatusUseCase: GetBiometricsStatusUseCase, - private val setAccessCodeRequestPolicyUseCase: SetAccessCodeRequestPolicyUseCase, - private val getAccessCodeSavingStatusUseCase: GetAccessCodeSavingStatusUseCase, private val getTokenListUseCase: GetTokenListUseCase, private val fetchTokenListUseCase: FetchTokenListUseCase, private val getPrimaryCurrencyStatusUpdatesUseCase: GetPrimaryCurrencyStatusUpdatesUseCase, @@ -384,42 +383,19 @@ internal class WalletViewModel @Inject constructor( class DerivationData(val derivations: Pair>) override fun onScanToUnlockWalletClick() { - scanToUpdateSelectedWallet() - } - - private fun scanToUpdateSelectedWallet(onSuccessSave: suspend (UserWallet) -> Unit = {}) { val state = uiState as? WalletState.ContentState ?: return - - val prevRequestPolicyStatus = getBiometricsStatusUseCase() - - // Update access the code policy according access code saving status - setAccessCodeRequestPolicyUseCase(isBiometricsRequestPolicy = getAccessCodeSavingStatusUseCase()) + val lockedWallet = getWallet(index = state.walletsListConfig.selectedWalletIndex) viewModelScope.launch(dispatchers.io) { - scanCardProcessor.scan( - cardId = getWallet(state.walletsListConfig.selectedWalletIndex).cardId, - allowsRequestAccessCodeFromRepository = true, - ) + scanCardProcessor.scan() .doOnSuccess { // If card's public key is null then user wallet will be null - val userWallet = UserWalletBuilder(scanResponse = it).build() + val unlockedWallet = UserWalletBuilder(scanResponse = it).build() - if (userWallet != null) { - saveWalletUseCase(userWallet = userWallet, canOverride = true) - .onLeft { - // Rollback policy if card saving was failed - setAccessCodeRequestPolicyUseCase(prevRequestPolicyStatus) - } - .onRight { onSuccessSave(userWallet) } - } else { - // Rollback policy if card saving was failed - setAccessCodeRequestPolicyUseCase(prevRequestPolicyStatus) + if (lockedWallet.walletId == unlockedWallet?.walletId) { + saveWalletUseCase(userWallet = unlockedWallet, canOverride = true) } } - .doOnFailure { - // Rollback policy if card scanning was failed - setAccessCodeRequestPolicyUseCase(prevRequestPolicyStatus) - } } } @@ -499,12 +475,14 @@ internal class WalletViewModel @Inject constructor( refreshContentJobHolder.update(job = null) viewModelScope.launch(dispatchers.main) { - val userWalletId = state.walletsListConfig.wallets[index].id + val userWallet = state.walletsListConfig.wallets[index] withContext(dispatchers.io) { - selectWalletUseCase(userWalletId = userWalletId) + if (userWallet !is WalletCardState.LockedContent) { + selectWalletUseCase(userWalletId = userWallet.id) + } } - val cacheState = WalletStateCache.getState(userWalletId = userWalletId) + val cacheState = WalletStateCache.getState(userWalletId = userWallet.id) if (cacheState != null && cacheState !is WalletLockedState) { uiState = cacheState.copySealed( walletsListConfig = state.walletsListConfig.copy( @@ -783,11 +761,20 @@ internal class WalletViewModel @Inject constructor( override fun onDeleteClick(userWalletId: UserWalletId) { val state = uiState as? WalletState.ContentState ?: return - viewModelScope.launch(dispatchers.io) { - val either = deleteWalletUseCase(userWalletId) + deleteWalletUseCase(userWalletId) - if (state.walletsListConfig.wallets.size <= 1 && either.isRight()) onBackClick() + popBackIfAllWalletsIsLocked(wallets = state.walletsListConfig.wallets) + } + } + + private fun popBackIfAllWalletsIsLocked(wallets: List) { + val unlockedWallet = wallets.count { it !is WalletCardState.LockedContent } + + if (unlockedWallet == 1) { + router.popBackStack( + screen = if (wallets.size > 1) AppScreen.Welcome else AppScreen.Home, + ) } }