Updated on 2026-08-14
This commit is contained in:
parent
0a09db0da8
commit
b90a305734
12 changed files with 75 additions and 49 deletions
|
|
@ -17,7 +17,7 @@ interface CardTypesResolver {
|
|||
|
||||
fun isStart2Coin(): Boolean
|
||||
|
||||
fun isDev(): Boolean
|
||||
fun isDevKit(): Boolean
|
||||
|
||||
fun isMultiwalletAllowed(): Boolean
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ internal class TangemCardTypesResolver(
|
|||
|
||||
override fun isStart2Coin(): Boolean = card.isStart2Coin
|
||||
|
||||
override fun isDev(): Boolean = card.firmwareVersion.type != FirmwareVersion.FirmwareType.Release
|
||||
override fun isDevKit(): Boolean = card.batchId == DEV_KIT_CARD_BATCH_ID
|
||||
|
||||
override fun isMultiwalletAllowed(): Boolean {
|
||||
return !isTangemTwins() && !card.isStart2Coin && !isTangemNote() &&
|
||||
|
|
@ -109,4 +109,9 @@ internal class TangemCardTypesResolver(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private companion object {
|
||||
|
||||
const val DEV_KIT_CARD_BATCH_ID = "CB83"
|
||||
}
|
||||
}
|
||||
|
|
@ -32,7 +32,7 @@ import java.util.UUID
|
|||
@Suppress("LargeClass")
|
||||
internal object WalletPreviewData {
|
||||
|
||||
val walletTopBarConfig by lazy { WalletTopBarConfig(onScanCardClick = {}, onMoreClick = {}) }
|
||||
val topBarConfig by lazy { WalletTopBarConfig(onDetailsClick = {}) }
|
||||
|
||||
val walletCardContentState by lazy {
|
||||
WalletCardState.Content(
|
||||
|
|
@ -326,7 +326,7 @@ internal object WalletPreviewData {
|
|||
val multicurrencyWalletScreenState by lazy {
|
||||
WalletMultiCurrencyState.Content(
|
||||
onBackClick = {},
|
||||
topBarConfig = walletTopBarConfig,
|
||||
topBarConfig = topBarConfig,
|
||||
walletsListConfig = walletListConfig,
|
||||
tokensListState = WalletTokensListState.Content(
|
||||
persistentListOf(
|
||||
|
|
@ -390,7 +390,7 @@ internal object WalletPreviewData {
|
|||
val singleWalletScreenState by lazy {
|
||||
WalletSingleCurrencyState.Content(
|
||||
onBackClick = {},
|
||||
topBarConfig = walletTopBarConfig,
|
||||
topBarConfig = topBarConfig,
|
||||
walletsListConfig = walletListConfig,
|
||||
pullToRefreshConfig = WalletPullToRefreshConfig(
|
||||
isRefreshing = false,
|
||||
|
|
|
|||
|
|
@ -21,13 +21,13 @@ internal object WalletImageResolver {
|
|||
fun resolve(userWallet: UserWallet): Int? {
|
||||
val cardTypesResolver = userWallet.scanResponse.cardTypesResolver
|
||||
return when {
|
||||
cardTypesResolver.isDev() -> R.drawable.ill_dev_120_106
|
||||
cardTypesResolver.isWallet2() -> userWallet.resolveWallet2()
|
||||
cardTypesResolver.isTangemWallet() -> R.drawable.ill_wallet_120_106
|
||||
cardTypesResolver.isWhiteWallet() -> R.drawable.ill_old_wallet_120_106
|
||||
cardTypesResolver.isTangemTwins() -> R.drawable.ill_twin_120_106
|
||||
cardTypesResolver.isStart2Coin() -> R.drawable.ill_start2coin_120_106
|
||||
cardTypesResolver.isTangemNote() -> resolveNote(blockchain = cardTypesResolver.getBlockchain())
|
||||
cardTypesResolver.isDevKit() -> R.drawable.ill_dev_120_106
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,10 @@ package com.tangem.feature.wallet.presentation.wallet.state
|
|||
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.event.StateEvent
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.*
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletNotification
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletPullToRefreshConfig
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletTopBarConfig
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletsListConfig
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package com.tangem.feature.wallet.presentation.wallet.state.components
|
|||
/**
|
||||
* Wallet screen top bar config
|
||||
*
|
||||
* @property onScanCardClick lambda be invoked when scan card button is clicked
|
||||
* @property onMoreClick lambda be invoked when more button is clicked
|
||||
* @property onDetailsClick lambda be invoked when details button is clicked
|
||||
*/
|
||||
data class WalletTopBarConfig(val onScanCardClick: () -> Unit, val onMoreClick: () -> Unit)
|
||||
internal data class WalletTopBarConfig(val onDetailsClick: () -> Unit)
|
||||
|
|
@ -55,7 +55,7 @@ internal class WalletLockedConverter(
|
|||
}
|
||||
|
||||
private fun WalletTopBarConfig.updateCallback(): WalletTopBarConfig {
|
||||
return copy(onMoreClick = clickIntents::onUnlockWalletNotificationClick)
|
||||
return copy(onDetailsClick = clickIntents::onUnlockWalletNotificationClick)
|
||||
}
|
||||
|
||||
private fun WalletPullToRefreshConfig.stopRefreshing(): WalletPullToRefreshConfig {
|
||||
|
|
|
|||
|
|
@ -81,10 +81,7 @@ internal class WalletSkeletonStateConverter(
|
|||
}
|
||||
|
||||
private fun createTopBarConfig(): WalletTopBarConfig {
|
||||
return WalletTopBarConfig(
|
||||
onScanCardClick = clickIntents::onScanCardClick,
|
||||
onMoreClick = clickIntents::onDetailsClick,
|
||||
)
|
||||
return WalletTopBarConfig(onDetailsClick = clickIntents::onDetailsClick)
|
||||
}
|
||||
|
||||
private fun createWalletsListConfig(value: SkeletonModel): WalletsListConfig {
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ internal class WalletsUnlockStateConverter(
|
|||
}
|
||||
|
||||
private fun WalletTopBarConfig.updateCallback(): WalletTopBarConfig {
|
||||
return copy(onMoreClick = clickIntents::onDetailsClick)
|
||||
return copy(onDetailsClick = clickIntents::onDetailsClick)
|
||||
}
|
||||
|
||||
private fun WalletsListConfig.unlockWallets(action: UnlockWalletAction): WalletsListConfig {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import com.tangem.core.ui.event.EventEffect
|
|||
import com.tangem.core.ui.event.StateEvent
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletEvent
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
@Composable
|
||||
internal fun WalletEventEffect(
|
||||
|
|
@ -24,7 +23,6 @@ internal fun WalletEventEffect(
|
|||
when (value) {
|
||||
is WalletEvent.ChangeWallet -> {
|
||||
onAutoScrollSet()
|
||||
delay(timeMillis = 800)
|
||||
walletsListState.animateScrollToItem(index = value.index)
|
||||
}
|
||||
is WalletEvent.ShowError -> {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import com.tangem.feature.wallet.presentation.wallet.state.components.WalletTopB
|
|||
/**
|
||||
* Wallet screen top bar
|
||||
*
|
||||
* @param config top bar config
|
||||
* @param config component config
|
||||
*/
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
|
|
@ -22,11 +22,8 @@ internal fun WalletTopBar(config: WalletTopBarConfig) {
|
|||
Icon(painter = painterResource(id = R.drawable.img_tangem_logo_90_24), contentDescription = null)
|
||||
},
|
||||
actions = {
|
||||
IconButton(onClick = config.onScanCardClick) {
|
||||
Icon(painter = painterResource(id = R.drawable.ic_tap_card_24), contentDescription = "Scan card")
|
||||
}
|
||||
IconButton(onClick = config.onMoreClick) {
|
||||
Icon(painter = painterResource(id = R.drawable.ic_more_vertical_24), contentDescription = "More")
|
||||
IconButton(onClick = config.onDetailsClick) {
|
||||
Icon(painter = painterResource(id = R.drawable.ic_more_vertical_24), contentDescription = null)
|
||||
}
|
||||
},
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
|
|
@ -42,7 +39,7 @@ internal fun WalletTopBar(config: WalletTopBarConfig) {
|
|||
@Composable
|
||||
private fun Preview_WalletTopBar_LightTheme() {
|
||||
TangemTheme(isDark = false) {
|
||||
WalletTopBar(config = WalletPreviewData.walletTopBarConfig)
|
||||
WalletTopBar(config = WalletPreviewData.topBarConfig)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -50,6 +47,6 @@ private fun Preview_WalletTopBar_LightTheme() {
|
|||
@Composable
|
||||
private fun Preview_WalletTopBar_DarkTheme() {
|
||||
TangemTheme(isDark = true) {
|
||||
WalletTopBar(config = WalletPreviewData.walletTopBarConfig)
|
||||
WalletTopBar(config = WalletPreviewData.topBarConfig)
|
||||
}
|
||||
}
|
||||
|
|
@ -164,7 +164,7 @@ internal class WalletViewModel @Inject constructor(
|
|||
|
||||
when (val action = walletsUpdateActionResolver.resolve(sourceList)) {
|
||||
is WalletsUpdateActionResolver.Action.Initialize -> {
|
||||
loadAndUpdateState(action.selectedWalletIndex)
|
||||
initializeAndLoadState(selectedWalletIndex = action.selectedWalletIndex)
|
||||
}
|
||||
is WalletsUpdateActionResolver.Action.UpdateWalletName -> {
|
||||
uiState = stateFactory.getStateWithUpdatedWalletName(name = action.name)
|
||||
|
|
@ -178,12 +178,18 @@ internal class WalletViewModel @Inject constructor(
|
|||
deleteWalletAndUpdateState(action = action)
|
||||
}
|
||||
is WalletsUpdateActionResolver.Action.AddWallet -> {
|
||||
loadAndUpdateState(action.selectedWalletIndex)
|
||||
scrollAndUpdateState(action.selectedWalletIndex)
|
||||
}
|
||||
is WalletsUpdateActionResolver.Action.Unknown -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
private fun initializeAndLoadState(selectedWalletIndex: Int) {
|
||||
uiState = stateFactory.getSkeletonState(wallets = wallets, selectedWalletIndex = selectedWalletIndex)
|
||||
|
||||
getContentItemsUpdates(index = selectedWalletIndex)
|
||||
}
|
||||
|
||||
private fun deleteWalletAndUpdateState(action: WalletsUpdateActionResolver.Action.DeleteWallet) {
|
||||
val cacheState = WalletStateCache.getState(userWalletId = action.selectedWalletId)
|
||||
if (cacheState != null) {
|
||||
|
|
@ -198,12 +204,22 @@ internal class WalletViewModel @Inject constructor(
|
|||
getContentItemsUpdates(action.selectedWalletIndex)
|
||||
}
|
||||
} else {
|
||||
loadAndUpdateState(selectedWalletIndex = action.selectedWalletIndex)
|
||||
/* It's impossible case because user can delete only visible state, but we support this case */
|
||||
scrollAndUpdateState(selectedWalletIndex = action.selectedWalletIndex)
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadAndUpdateState(selectedWalletIndex: Int) {
|
||||
uiState = stateFactory.getSkeletonState(wallets = wallets, selectedWalletIndex = selectedWalletIndex)
|
||||
private fun scrollAndUpdateState(selectedWalletIndex: Int) {
|
||||
uiState = stateFactory.getSkeletonState(
|
||||
wallets = wallets,
|
||||
selectedWalletIndex = selectedWalletIndex,
|
||||
)
|
||||
|
||||
uiState = stateFactory.getStateAndTriggerEvent(
|
||||
state = uiState,
|
||||
event = WalletEvent.ChangeWallet(index = selectedWalletIndex),
|
||||
setUiState = { uiState = it },
|
||||
)
|
||||
|
||||
getContentItemsUpdates(index = selectedWalletIndex)
|
||||
}
|
||||
|
|
@ -224,30 +240,42 @@ internal class WalletViewModel @Inject constructor(
|
|||
if (userWallet != null) {
|
||||
saveWalletUseCase(userWallet = userWallet, canOverride = false)
|
||||
.onLeft { saveWalletError ->
|
||||
when (saveWalletError) {
|
||||
is SaveWalletError.DataError -> Unit
|
||||
is SaveWalletError.WalletAlreadySaved -> {
|
||||
uiState = stateFactory.getStateAndTriggerEvent(
|
||||
state = uiState,
|
||||
event = WalletEvent.ShowError(
|
||||
text = TextReference.Res(saveWalletError.messageId),
|
||||
),
|
||||
setUiState = { uiState = it },
|
||||
)
|
||||
}
|
||||
}
|
||||
showErrorIfWalletNotSaved(
|
||||
error = saveWalletError,
|
||||
scannedWalletId = userWallet.walletId,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
.doOnFailure { tangemError ->
|
||||
}
|
||||
}
|
||||
|
||||
private fun showErrorIfWalletNotSaved(error: SaveWalletError, scannedWalletId: UserWalletId) {
|
||||
when (error) {
|
||||
is SaveWalletError.DataError -> Unit
|
||||
is SaveWalletError.WalletAlreadySaved -> {
|
||||
viewModelScope.launch(dispatchers.main) {
|
||||
val alreadySavedWalletIndex = (uiState as? WalletState.ContentState)?.walletsListConfig
|
||||
?.wallets?.indexOfFirst { it.id == scannedWalletId }
|
||||
|
||||
if (alreadySavedWalletIndex != null && alreadySavedWalletIndex != -1) {
|
||||
uiState = stateFactory.getStateAndTriggerEvent(
|
||||
state = uiState,
|
||||
event = WalletEvent.ChangeWallet(index = alreadySavedWalletIndex),
|
||||
setUiState = { uiState = it },
|
||||
)
|
||||
|
||||
// Delay between events
|
||||
delay(timeMillis = 500L)
|
||||
}
|
||||
|
||||
uiState = stateFactory.getStateAndTriggerEvent(
|
||||
state = uiState,
|
||||
event = WalletEvent.ShowError(
|
||||
text = TextReference.Str(tangemError.customMessage),
|
||||
),
|
||||
event = WalletEvent.ShowError(text = TextReference.Res(error.messageId)),
|
||||
setUiState = { uiState = it },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -372,8 +400,7 @@ internal class WalletViewModel @Inject constructor(
|
|||
getContentItemsUpdates(index)
|
||||
}
|
||||
} else {
|
||||
uiState = stateFactory.getSkeletonState(wallets = wallets, selectedWalletIndex = index)
|
||||
getContentItemsUpdates(index = index)
|
||||
initializeAndLoadState(selectedWalletIndex = index)
|
||||
}
|
||||
}
|
||||
.saveIn(onWalletChangeJobHolder)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue