Updated on 2026-08-14

This commit is contained in:
Tangem 2023-08-24 16:21:28 +08:00
parent 564ab852c2
commit 575389311f
13 changed files with 333 additions and 170 deletions

View file

@ -70,4 +70,12 @@ internal object TokensDomainModule {
): ApplyTokenListSortingUseCase {
return ApplyTokenListSortingUseCase(currenciesRepository, dispatchers)
}
@Provides
@ViewModelScoped
fun provideGetCryptoCurrencyActionsUseCase(
dispatchers: CoroutineDispatcherProvider,
): GetCryptoCurrencyActionsUseCase {
return GetCryptoCurrencyActionsUseCase(dispatchers)
}
}

View file

@ -33,7 +33,7 @@ fun HorizontalActionChips(
) {
items(
items = buttons,
key = { config -> "${config.text.hashCode()} ${config.iconResId}" },
key = { config -> config.text.hashCode() },
itemContent = { ActionButton(config = it) },
)
}

View file

@ -1,5 +1,6 @@
package com.tangem.core.ui.components.buttons.actions
import androidx.compose.animation.animateColorAsState
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
@ -7,6 +8,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Icon
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@ -78,43 +80,52 @@ private fun Button(
modifier: Modifier = Modifier,
color: Color = TangemTheme.colors.button.secondary,
) {
val backgroundColor by animateColorAsState(
targetValue = if (config.enabled) color else TangemTheme.colors.button.disabled,
label = "Update background color",
)
Row(
modifier = modifier
.heightIn(min = TangemTheme.dimens.size36)
.clip(shape)
.background(
color = if (config.enabled) color else TangemTheme.colors.button.disabled,
shape = shape,
)
.background(color = backgroundColor, shape = shape)
.clickable(enabled = config.enabled, onClick = config.onClick)
.padding(
start = TangemTheme.dimens.spacing16,
end = TangemTheme.dimens.spacing24,
)
.padding(start = TangemTheme.dimens.spacing16, end = TangemTheme.dimens.spacing24)
.padding(vertical = TangemTheme.dimens.spacing8),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
) {
Icon(
painter = painterResource(id = config.iconResId),
contentDescription = null,
modifier = Modifier.size(size = TangemTheme.dimens.size20),
tint = when {
val iconTint by animateColorAsState(
targetValue = when {
!config.enabled -> TangemTheme.colors.icon.informative
config.dimContent -> TangemTheme.colors.icon.secondary
else -> TangemTheme.colors.icon.primary1
},
label = "Update tint color",
)
Icon(
painter = painterResource(id = config.iconResId),
contentDescription = null,
modifier = Modifier.size(size = TangemTheme.dimens.size20),
tint = iconTint,
)
SpacerW8()
Text(
text = config.text.resolveReference(),
color = when {
val textColor by animateColorAsState(
targetValue = when {
!config.enabled -> TangemTheme.colors.text.disabled
config.dimContent -> TangemTheme.colors.text.secondary
else -> TangemTheme.colors.text.primary1
},
label = "Update text color",
)
Text(
text = config.text.resolveReference(),
color = textColor,
overflow = TextOverflow.Ellipsis,
maxLines = 1,
style = TangemTheme.typography.button,

View file

@ -3,7 +3,9 @@ package com.tangem.domain.tokens
import com.tangem.domain.tokens.model.TokenActionsState
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
class GetCryptoCurrencyActionsUseCase(
private val dispatchers: CoroutineDispatcherProvider,
@ -22,10 +24,10 @@ class GetCryptoCurrencyActionsUseCase(
tokenId = tokenId,
states = listOf(
TokenActionsState.ActionState.Buy(true),
TokenActionsState.ActionState.Sell(true),
TokenActionsState.ActionState.Send(true),
TokenActionsState.ActionState.Receive(true),
TokenActionsState.ActionState.Swap(true),
TokenActionsState.ActionState.Sell(true),
TokenActionsState.ActionState.Swap(true),
),
)
}

View file

@ -277,13 +277,15 @@ internal object WalletPreviewData {
).toImmutableList(),
)
private val manageButtons = persistentListOf(
WalletManageButton.Buy(onClick = {}),
WalletManageButton.Send(onClick = {}),
WalletManageButton.Receive(onClick = {}),
WalletManageButton.Exchange(onClick = {}),
WalletManageButton.CopyAddress(onClick = {}),
)
private val manageButtons by lazy {
persistentListOf(
WalletManageButton.Buy(enabled = true, onClick = {}),
WalletManageButton.Send(enabled = true, onClick = {}),
WalletManageButton.Receive(onClick = {}),
WalletManageButton.Sell(enabled = true, onClick = {}),
WalletManageButton.Swap(enabled = true, onClick = {}),
)
}
val multicurrencyWalletScreenState by lazy {
WalletMultiCurrencyState.Content(

View file

@ -8,7 +8,7 @@ import com.tangem.feature.wallet.impl.R
/**
* Wallet manage button state
*
* @param config action config
* @property config action config
*
[REDACTED_AUTHOR]
*/
@ -16,87 +16,79 @@ import com.tangem.feature.wallet.impl.R
sealed class WalletManageButton(val config: ActionButtonConfig) {
/** Lambda be invoked when manage button is clicked */
abstract val onClick: (() -> Unit)?
abstract val onClick: () -> Unit
/**
* Buy
*
* @param onClick lambda be invoked when manage button is clicked
* @property enabled button click availability
* @property onClick lambda be invoked when Buy button is clicked
*/
data class Buy(override val onClick: (() -> Unit)? = null) : WalletManageButton(
data class Buy(val enabled: Boolean, override val onClick: () -> Unit) : WalletManageButton(
config = ActionButtonConfig(
text = TextReference.Res(id = R.string.common_buy),
iconResId = R.drawable.ic_plus_24,
onClick = onClick ?: {},
enabled = onClick != null,
),
)
/**
* Sell
*
* @param onClick lambda be invoked when manage button is clicked
*/
data class Sell(override val onClick: (() -> Unit)? = null) : WalletManageButton(
config = ActionButtonConfig(
text = TextReference.Res(id = R.string.common_sell),
iconResId = R.drawable.ic_currency_24,
onClick = onClick ?: {},
enabled = onClick != null,
onClick = onClick,
enabled = enabled,
),
)
/**
* Send
*
* @param onClick lambda be invoked when manage button is clicked
* @property enabled button click availability
* @property onClick lambda be invoked when Send button is clicked
*/
data class Send(override val onClick: (() -> Unit)? = null) : WalletManageButton(
data class Send(val enabled: Boolean, override val onClick: () -> Unit) : WalletManageButton(
config = ActionButtonConfig(
text = TextReference.Res(id = R.string.common_send),
iconResId = R.drawable.ic_arrow_up_24,
onClick = onClick ?: {},
enabled = onClick != null,
onClick = onClick,
enabled = enabled,
),
)
/**
* Receive
*
* @param onClick lambda be invoked when manage button is clicked
* @property onClick lambda be invoked when Receive button is clicked
*/
data class Receive(override val onClick: () -> Unit) : WalletManageButton(
config = ActionButtonConfig(
text = TextReference.Res(id = R.string.common_receive),
iconResId = R.drawable.ic_arrow_down_24,
onClick = onClick,
enabled = true,
),
)
/**
* Exchange
* Sell
*
* @param onClick lambda be invoked when manage button is clicked
* @property enabled button click availability
* @property onClick lambda be invoked when Sell button is clicked
*/
data class Exchange(override val onClick: (() -> Unit)? = null) : WalletManageButton(
data class Sell(val enabled: Boolean, override val onClick: () -> Unit) : WalletManageButton(
config = ActionButtonConfig(
text = TextReference.Res(id = R.string.common_exchange),
iconResId = R.drawable.ic_exchange_vertical_24,
onClick = onClick ?: {},
enabled = onClick != null,
),
)
/**
* Copy address
*
* @param onClick lambda be invoked when manage button is clicked
*/
data class CopyAddress(override val onClick: () -> Unit) : WalletManageButton(
config = ActionButtonConfig(
text = TextReference.Res(id = R.string.common_copy_address),
iconResId = R.drawable.ic_copy_24,
text = TextReference.Res(id = R.string.common_sell),
iconResId = R.drawable.ic_currency_24,
onClick = onClick,
enabled = enabled,
),
)
/**
* Swap
*
* @property enabled button click availability
* @property onClick lambda be invoked when Swap button is clicked
*/
data class Swap(val enabled: Boolean, override val onClick: () -> Unit) : WalletManageButton(
config = ActionButtonConfig(
text = TextReference.Res(id = R.string.common_swap),
iconResId = R.drawable.ic_exchange_vertical_24,
onClick = onClick,
enabled = enabled,
),
)
}

View file

@ -0,0 +1,50 @@
package com.tangem.feature.wallet.presentation.wallet.state.factory
import com.tangem.common.Provider
import com.tangem.domain.tokens.model.TokenActionsState
import com.tangem.feature.wallet.presentation.wallet.state.WalletMultiCurrencyState
import com.tangem.feature.wallet.presentation.wallet.state.WalletSingleCurrencyState
import com.tangem.feature.wallet.presentation.wallet.state.WalletState
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletManageButton
import com.tangem.feature.wallet.presentation.wallet.viewmodels.WalletClickIntents
import com.tangem.utils.converter.Converter
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
internal class WalletCryptoCurrencyActionsConverter(
private val currentStateProvider: Provider<WalletState>,
private val clickIntents: WalletClickIntents,
) : Converter<List<TokenActionsState.ActionState>, WalletState> {
override fun convert(value: List<TokenActionsState.ActionState>): WalletState {
return when (val state = currentStateProvider()) {
is WalletSingleCurrencyState.Content -> state.copy(buttons = value.mapToManageButtons())
is WalletSingleCurrencyState.Locked,
is WalletMultiCurrencyState,
is WalletState.Initial,
-> state
}
}
private fun List<TokenActionsState.ActionState>.mapToManageButtons(): ImmutableList<WalletManageButton> {
return this
.mapNotNull { action ->
when (action) {
is TokenActionsState.ActionState.Buy -> {
WalletManageButton.Buy(enabled = action.enabled, onClick = clickIntents::onBuyClick)
}
is TokenActionsState.ActionState.Receive -> {
WalletManageButton.Receive(onClick = clickIntents::onReceiveClick)
}
is TokenActionsState.ActionState.Sell -> {
WalletManageButton.Sell(enabled = action.enabled, onClick = clickIntents::onSellClick)
}
is TokenActionsState.ActionState.Send -> {
WalletManageButton.Send(enabled = action.enabled, onClick = clickIntents::onSellClick)
}
is TokenActionsState.ActionState.Swap -> null
}
}
.toImmutableList()
}
}

View file

@ -0,0 +1,110 @@
package com.tangem.feature.wallet.presentation.wallet.state.factory
import com.tangem.common.Provider
import com.tangem.domain.common.CardTypesResolver
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory
import com.tangem.feature.wallet.presentation.wallet.state.WalletMultiCurrencyState
import com.tangem.feature.wallet.presentation.wallet.state.WalletSingleCurrencyState
import com.tangem.feature.wallet.presentation.wallet.state.WalletState
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletCardState
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletManageButton
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletTopBarConfig
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletsListConfig
import com.tangem.feature.wallet.presentation.wallet.viewmodels.WalletClickIntents
import com.tangem.utils.converter.Converter
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
internal class WalletLockedConverter(
private val currentStateProvider: Provider<WalletState>,
private val currentCardTypeResolverProvider: Provider<CardTypesResolver>,
private val currentWalletProvider: Provider<UserWallet>,
private val clickIntents: WalletClickIntents,
) : Converter<Unit, WalletState> {
override fun convert(value: Unit): WalletState {
return when (val state = currentStateProvider()) {
is WalletState.ContentState -> {
val cardTypeResolver = currentCardTypeResolverProvider()
if (cardTypeResolver.isMultiwalletAllowed()) {
state.toMultiCurrencyLockedState(cardTypeResolver)
} else {
state.toSingleCurrencyLockedState(cardTypeResolver)
}
}
is WalletState.Initial -> state
}
}
private fun WalletState.ContentState.toMultiCurrencyLockedState(
cardTypeResolver: CardTypesResolver,
): WalletMultiCurrencyState.Locked {
return WalletMultiCurrencyState.Locked(
onBackClick = onBackClick,
topBarConfig = createTopBarConfig(),
walletsListConfig = createWalletsListConfig(cardTypeResolver),
pullToRefreshConfig = pullToRefreshConfig,
onUnlockWalletsNotificationClick = clickIntents::onUnlockWalletNotificationClick,
onUnlockClick = clickIntents::onUnlockWalletClick,
onScanClick = clickIntents::onScanCardClick,
)
}
private fun WalletState.ContentState.toSingleCurrencyLockedState(
cardTypeResolver: CardTypesResolver,
): WalletSingleCurrencyState.Locked {
return WalletSingleCurrencyState.Locked(
onBackClick = onBackClick,
topBarConfig = createTopBarConfig(),
walletsListConfig = createWalletsListConfig(cardTypeResolver),
pullToRefreshConfig = pullToRefreshConfig,
buttons = createButtons(),
onUnlockWalletsNotificationClick = clickIntents::onUnlockWalletNotificationClick,
onUnlockClick = clickIntents::onUnlockWalletClick,
onScanClick = clickIntents::onScanCardClick,
onExploreClick = clickIntents::onExploreClick,
)
}
private fun WalletState.ContentState.createTopBarConfig(): WalletTopBarConfig {
return topBarConfig.copy(onMoreClick = clickIntents::onUnlockWalletNotificationClick)
}
private fun WalletState.ContentState.createWalletsListConfig(
cardTypeResolver: CardTypesResolver,
): WalletsListConfig {
return walletsListConfig.copy(
wallets = walletsListConfig.wallets
.map { walletCardState ->
WalletCardState.LockedContent(
id = walletCardState.id,
title = walletCardState.title,
additionalInfo = if (cardTypeResolver.isMultiwalletAllowed()) {
WalletAdditionalInfoFactory.resolve(
cardTypesResolver = cardTypeResolver,
wallet = currentWalletProvider(),
)
} else {
null
},
imageResId = walletCardState.imageResId,
onRenameClick = walletCardState.onRenameClick,
onDeleteClick = walletCardState.onDeleteClick,
)
}
.toImmutableList(),
)
}
private fun createButtons(): ImmutableList<WalletManageButton> {
return persistentListOf(
WalletManageButton.Buy(enabled = false, onClick = {}),
WalletManageButton.Send(enabled = false, onClick = {}),
WalletManageButton.Receive(onClick = {}),
WalletManageButton.Sell(enabled = false, onClick = {}),
)
}
}

View file

@ -8,11 +8,8 @@ import com.tangem.feature.wallet.presentation.common.state.TokenItemState
import com.tangem.feature.wallet.presentation.wallet.state.WalletMultiCurrencyState
import com.tangem.feature.wallet.presentation.wallet.state.WalletSingleCurrencyState
import com.tangem.feature.wallet.presentation.wallet.state.WalletState
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletCardState
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletPullToRefreshConfig
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletTokensListState
import com.tangem.feature.wallet.presentation.wallet.state.components.*
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletTokensListState.TokensListItemState
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletsListConfig
import com.tangem.feature.wallet.presentation.wallet.viewmodels.WalletClickIntents
import com.tangem.utils.converter.Converter
import kotlinx.collections.immutable.ImmutableList
@ -36,22 +33,23 @@ internal class WalletRefreshStateConverter(
private fun WalletMultiCurrencyState.Content.getRefreshState(): WalletMultiCurrencyState.Content {
return copy(
walletsListConfig = getWalletsListConfig(),
pullToRefreshConfig = getPullToRefreshConfig(),
tokensListState = getTokenListState(),
walletsListConfig = createWalletsListConfig(),
pullToRefreshConfig = createPullToRefreshConfig(),
tokensListState = createTokenListState(),
)
}
private fun WalletSingleCurrencyState.Content.getRefreshState(): WalletSingleCurrencyState.Content {
return copy(
walletsListConfig = getWalletsListConfig(),
pullToRefreshConfig = getPullToRefreshConfig(),
txHistoryState = getTxHistoryState(),
walletsListConfig = createWalletsListConfig(),
pullToRefreshConfig = createPullToRefreshConfig(),
buttons = buttons.mapToDisabledButton(),
txHistoryState = createTxHistoryState(),
marketPriceBlockState = MarketPriceBlockState.Loading(currencyName = marketPriceBlockState.currencyName),
)
}
private fun WalletState.ContentState.getWalletsListConfig(): WalletsListConfig {
private fun WalletState.ContentState.createWalletsListConfig(): WalletsListConfig {
val selectedWallet = walletsListConfig.wallets[walletsListConfig.selectedWalletIndex]
val additionalInfo = if (currentCardTypeResolverProvider().isMultiwalletAllowed()) {
selectedWallet.additionalInfo
@ -74,11 +72,11 @@ internal class WalletRefreshStateConverter(
)
}
private fun WalletState.ContentState.getPullToRefreshConfig(): WalletPullToRefreshConfig {
private fun WalletState.ContentState.createPullToRefreshConfig(): WalletPullToRefreshConfig {
return pullToRefreshConfig.copy(isRefreshing = true)
}
private fun WalletMultiCurrencyState.Content.getTokenListState(): WalletTokensListState {
private fun WalletMultiCurrencyState.Content.createTokenListState(): WalletTokensListState {
return when (tokensListState) {
is WalletTokensListState.Content -> {
WalletTokensListState.Loading(
@ -100,7 +98,21 @@ internal class WalletRefreshStateConverter(
.toImmutableList()
}
private fun WalletSingleCurrencyState.Content.getTxHistoryState(): TxHistoryState {
private fun ImmutableList<WalletManageButton>.mapToDisabledButton(): ImmutableList<WalletManageButton> {
return this
.mapNotNull { button ->
when (button) {
is WalletManageButton.Buy -> button.copy(enabled = false)
is WalletManageButton.Send -> button.copy(enabled = false)
is WalletManageButton.Receive -> button
is WalletManageButton.Sell -> button.copy(enabled = false)
is WalletManageButton.Swap -> null
}
}
.toImmutableList()
}
private fun WalletSingleCurrencyState.Content.createTxHistoryState(): TxHistoryState {
if (txHistoryState is TxHistoryState.Content) {
txHistoryState.contentItems.update {
TxHistoryState.getDefaultLoadingTransactions(onExploreClick = clickIntents::onExploreClick)

View file

@ -63,7 +63,7 @@ internal class WalletSkeletonStateConverter(
pullToRefreshConfig = createPullToRefreshConfig(),
notifications = persistentListOf(),
bottomSheetConfig = null,
buttons = getButtons(),
buttons = createButtons(),
marketPriceBlockState = MarketPriceBlockState.Loading(currencyName = currencyName),
txHistoryState = TxHistoryState.Content(
contentItems = MutableStateFlow(
@ -127,15 +127,12 @@ internal class WalletSkeletonStateConverter(
return WalletPullToRefreshConfig(isRefreshing = false, onRefresh = clickIntents::onRefreshSwipe)
}
// TODO: [REDACTED_JIRA]
private fun getButtons(): ImmutableList<WalletManageButton> {
private fun createButtons(): ImmutableList<WalletManageButton> {
return persistentListOf(
WalletManageButton.Buy(),
WalletManageButton.Send(),
WalletManageButton.Buy(enabled = false, onClick = {}),
WalletManageButton.Send(enabled = false, onClick = {}),
WalletManageButton.Receive(onClick = {}),
WalletManageButton.Exchange(),
WalletManageButton.Sell(),
WalletManageButton.CopyAddress(onClick = {}),
WalletManageButton.Sell(enabled = false, onClick = {}),
)
}

View file

@ -8,26 +8,22 @@ import com.tangem.domain.common.CardTypesResolver
import com.tangem.domain.tokens.error.CurrencyError
import com.tangem.domain.tokens.error.TokenListError
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.model.TokenActionsState
import com.tangem.domain.tokens.model.TokenList
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.txhistory.models.TxHistoryListError
import com.tangem.domain.txhistory.models.TxHistoryStateError
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory
import com.tangem.feature.wallet.presentation.wallet.state.ActionsBottomSheetConfig
import com.tangem.feature.wallet.presentation.wallet.state.WalletMultiCurrencyState
import com.tangem.feature.wallet.presentation.wallet.state.WalletSingleCurrencyState
import com.tangem.feature.wallet.presentation.wallet.state.WalletState
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletBottomSheetConfig
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletCardState
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletManageButton
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletNotification
import com.tangem.feature.wallet.presentation.wallet.state.factory.txhistory.WalletLoadedTxHistoryConverter
import com.tangem.feature.wallet.presentation.wallet.state.factory.txhistory.WalletLoadingTxHistoryConverter
import com.tangem.feature.wallet.presentation.wallet.viewmodels.WalletClickIntents
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.Flow
/**
@ -83,6 +79,15 @@ internal class WalletStateFactory(
)
}
private val lockedConverter by lazy {
WalletLockedConverter(
currentStateProvider = currentStateProvider,
currentCardTypeResolverProvider = currentCardTypeResolverProvider,
currentWalletProvider = currentWalletProvider,
clickIntents = clickIntents,
)
}
private val refreshStateConverter by lazy {
WalletRefreshStateConverter(
currentStateProvider = currentStateProvider,
@ -91,6 +96,13 @@ internal class WalletStateFactory(
)
}
private val cryptoCurrencyActionsConverter by lazy {
WalletCryptoCurrencyActionsConverter(
currentStateProvider = currentStateProvider,
clickIntents = clickIntents,
)
}
fun getInitialState(): WalletState = WalletState.Initial(onBackClick = clickIntents::onBackClick)
fun getSkeletonState(wallets: List<UserWallet>, selectedWalletIndex: Int): WalletState {
@ -184,77 +196,7 @@ internal class WalletStateFactory(
return loadedTxHistoryConverter.convert(txHistoryEither)
}
fun getLockedState(): WalletState {
val cardTypeResolver = currentCardTypeResolverProvider()
val state = requireNotNull(currentStateProvider() as? WalletState.ContentState)
return if (cardTypeResolver.isMultiwalletAllowed()) {
WalletMultiCurrencyState.Locked(
onBackClick = state.onBackClick,
topBarConfig = state.topBarConfig.copy(
onMoreClick = clickIntents::onUnlockWalletNotificationClick,
),
walletsListConfig = state.walletsListConfig.copy(
wallets = state.walletsListConfig.wallets
.map { walletCardState ->
WalletCardState.LockedContent(
id = walletCardState.id,
title = walletCardState.title,
imageResId = walletCardState.imageResId,
additionalInfo = WalletAdditionalInfoFactory.resolve(
cardTypesResolver = cardTypeResolver,
wallet = currentWalletProvider(),
),
onRenameClick = walletCardState.onRenameClick,
onDeleteClick = walletCardState.onDeleteClick,
)
}
.toImmutableList(),
),
pullToRefreshConfig = state.pullToRefreshConfig,
onUnlockWalletsNotificationClick = clickIntents::onUnlockWalletNotificationClick,
onUnlockClick = clickIntents::onUnlockWalletClick,
onScanClick = clickIntents::onScanCardClick,
)
} else {
WalletSingleCurrencyState.Locked(
onBackClick = state.onBackClick,
topBarConfig = state.topBarConfig.copy(
onMoreClick = clickIntents::onUnlockWalletNotificationClick,
),
walletsListConfig = state.walletsListConfig.copy(
wallets = state.walletsListConfig.wallets
.map { walletCardState ->
WalletCardState.LockedContent(
id = walletCardState.id,
title = walletCardState.title,
imageResId = walletCardState.imageResId,
onRenameClick = walletCardState.onRenameClick,
onDeleteClick = walletCardState.onDeleteClick,
)
}
.toImmutableList(),
),
pullToRefreshConfig = state.pullToRefreshConfig,
buttons = getButtons(),
onUnlockWalletsNotificationClick = clickIntents::onUnlockWalletNotificationClick,
onUnlockClick = clickIntents::onUnlockWalletClick,
onScanClick = clickIntents::onScanCardClick,
onExploreClick = clickIntents::onExploreClick,
)
}
}
// TODO: [REDACTED_JIRA]
private fun getButtons(): ImmutableList<WalletManageButton> {
return persistentListOf(
WalletManageButton.Buy(),
WalletManageButton.Send(),
WalletManageButton.Receive(onClick = {}),
WalletManageButton.Exchange(),
WalletManageButton.Sell(),
WalletManageButton.CopyAddress(onClick = {}),
)
}
fun getLockedState(): WalletState = lockedConverter.convert(Unit)
fun getSingleCurrencyLoadedBalanceState(
cryptoCurrencyEither: Either<CurrencyError, CryptoCurrencyStatus>,
@ -267,4 +209,8 @@ internal class WalletStateFactory(
),
)
}
fun getSingleCurrencyManageButtonsState(actions: List<TokenActionsState.ActionState>): WalletState {
return cryptoCurrencyActionsConverter.convert(value = actions)
}
}

View file

@ -46,4 +46,10 @@ internal interface WalletClickIntents : TxHistoryClickIntents {
fun onRenameClick(userWalletId: UserWalletId, name: String)
fun onDeleteClick(userWalletId: UserWalletId)
fun onSendClick()
fun onReceiveClick()
fun onSellClick()
}

View file

@ -17,6 +17,7 @@ import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.common.util.derivationStyleProvider
import com.tangem.domain.demo.IsDemoCardUseCase
import com.tangem.domain.settings.IsUserAlreadyRateAppUseCase
import com.tangem.domain.tokens.GetCryptoCurrencyActionsUseCase
import com.tangem.domain.tokens.GetPrimaryCurrencyUseCase
import com.tangem.domain.tokens.GetTokenListUseCase
import com.tangem.domain.tokens.model.TokenList
@ -76,6 +77,7 @@ internal class WalletViewModel @Inject constructor(
private val getExploreUrlUseCase: GetExploreUrlUseCase,
private val unlockWalletsUseCase: UnlockWalletsUseCase,
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
private val getCryptoCurrencyActionsUseCase: GetCryptoCurrencyActionsUseCase,
private val dispatchers: CoroutineDispatcherProvider,
) : ViewModel(), DefaultLifecycleObserver, WalletClickIntents {
@ -112,6 +114,7 @@ internal class WalletViewModel @Inject constructor(
private val tokensJobHolder = JobHolder()
private val marketPriceJobHolder = JobHolder()
private val buttonsJobHolder = JobHolder()
private val notificationsJobHolder = JobHolder()
override fun onCreate(owner: LifecycleOwner) {
@ -178,8 +181,10 @@ internal class WalletViewModel @Inject constructor(
private fun updateSingleCurrencyContent(index: Int, isRefreshing: Boolean) {
val wallet = getWallet(index)
val blockchain = getCardTypeResolver(index).getBlockchain()
updateButtons(userWalletId = wallet.walletId, currencyId = blockchain.id)
updateTxHistory(
blockchain = getCardTypeResolver(index).getBlockchain(),
blockchain = blockchain,
derivationStyle = wallet.scanResponse.derivationStyleProvider.getDerivationStyle(),
)
updateMarketPrice(userWalletId = wallet.walletId, isRefreshing = isRefreshing)
@ -225,6 +230,15 @@ internal class WalletViewModel @Inject constructor(
.saveIn(marketPriceJobHolder)
}
private fun updateButtons(userWalletId: UserWalletId, currencyId: String) {
getCryptoCurrencyActionsUseCase(userWalletId = userWalletId, tokenId = currencyId)
.distinctUntilChanged()
.onEach { uiState = stateFactory.getSingleCurrencyManageButtonsState(actions = it.states) }
.flowOn(dispatchers.io)
.launchIn(viewModelScope)
.saveIn(buttonsJobHolder)
}
private fun updateNotifications(index: Int, tokenList: TokenList? = null) {
notificationsListFactory.create(
cardTypesResolver = getCardTypeResolver(index = index),
@ -338,6 +352,7 @@ internal class WalletViewModel @Inject constructor(
*/
tokensJobHolder.update(job = null)
marketPriceJobHolder.update(job = null)
buttonsJobHolder.update(job = null)
notificationsJobHolder.update(job = null)
val cacheState = WalletStateCache.getState(userWalletId = state.walletsListConfig.wallets[index].id)
@ -410,6 +425,18 @@ internal class WalletViewModel @Inject constructor(
// TODO: [REDACTED_JIRA]
}
override fun onSendClick() {
// TODO: [REDACTED_JIRA]
}
override fun onReceiveClick() {
// TODO: [REDACTED_JIRA]
}
override fun onSellClick() {
// TODO: [REDACTED_JIRA]
}
override fun onReloadClick() {
uiState = stateFactory.getStateAfterContentRefreshing()
updateSingleCurrencyContent(