Updated on 2026-08-14
This commit is contained in:
parent
564ab852c2
commit
575389311f
13 changed files with 333 additions and 170 deletions
|
|
@ -70,4 +70,12 @@ internal object TokensDomainModule {
|
|||
): ApplyTokenListSortingUseCase {
|
||||
return ApplyTokenListSortingUseCase(currenciesRepository, dispatchers)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ViewModelScoped
|
||||
fun provideGetCryptoCurrencyActionsUseCase(
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
): GetCryptoCurrencyActionsUseCase {
|
||||
return GetCryptoCurrencyActionsUseCase(dispatchers)
|
||||
}
|
||||
}
|
||||
|
|
@ -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) },
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
@ -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 = {}),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 = {}),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
@ -46,4 +46,10 @@ internal interface WalletClickIntents : TxHistoryClickIntents {
|
|||
fun onRenameClick(userWalletId: UserWalletId, name: String)
|
||||
|
||||
fun onDeleteClick(userWalletId: UserWalletId)
|
||||
|
||||
fun onSendClick()
|
||||
|
||||
fun onReceiveClick()
|
||||
|
||||
fun onSellClick()
|
||||
}
|
||||
|
|
@ -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(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue