Updated on 2026-08-14

This commit is contained in:
Tangem 2023-10-03 16:05:37 +08:00
parent 2d1f7a0cd2
commit bae36dfbf5
2 changed files with 54 additions and 59 deletions

View file

@ -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,
),
)
}

View file

@ -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<ByteArrayKey, List<DerivationPath>>)
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<WalletCardState>) {
val unlockedWallet = wallets.count { it !is WalletCardState.LockedContent }
if (unlockedWallet == 1) {
router.popBackStack(
screen = if (wallets.size > 1) AppScreen.Welcome else AppScreen.Home,
)
}
}