Updated on 2026-08-14
This commit is contained in:
parent
3fbddfa8c7
commit
70d2f5ee06
14 changed files with 120 additions and 84 deletions
|
|
@ -2,6 +2,7 @@ package com.tangem.feature.wallet.presentation.wallet.state.factory
|
|||
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.tokens.model.TokenActionsState
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
import com.tangem.feature.wallet.presentation.common.state.TokenItemState
|
||||
|
|
@ -20,18 +21,15 @@ import kotlinx.collections.immutable.toImmutableList
|
|||
internal class TokenActionsProvider(private val clickIntents: WalletClickIntents) {
|
||||
|
||||
fun provideActions(tokenActions: TokenActionsState): ImmutableList<TokenActionButtonConfig> {
|
||||
return convertTokenActionsState(tokenActions)
|
||||
}
|
||||
|
||||
private fun convertTokenActionsState(
|
||||
tokenActionsState: TokenActionsState,
|
||||
): ImmutableList<TokenActionButtonConfig> {
|
||||
return tokenActionsState.states
|
||||
.map(::tokenActionStateMapper)
|
||||
return tokenActions.states
|
||||
.map { mapTokenActionState(it, tokenActions.cryptoCurrencyStatus) }
|
||||
.toImmutableList()
|
||||
}
|
||||
|
||||
private fun tokenActionStateMapper(actionsState: TokenActionsState.ActionState): TokenActionButtonConfig {
|
||||
private fun mapTokenActionState(
|
||||
actionsState: TokenActionsState.ActionState,
|
||||
cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
): TokenActionButtonConfig {
|
||||
val title: TextReference
|
||||
val icon: Int
|
||||
val action: () -> Unit
|
||||
|
|
@ -39,27 +37,27 @@ internal class TokenActionsProvider(private val clickIntents: WalletClickIntents
|
|||
is TokenActionsState.ActionState.Buy -> {
|
||||
title = resourceReference(R.string.common_buy)
|
||||
icon = R.drawable.ic_plus_24
|
||||
action = { }
|
||||
action = { clickIntents.onBuyClick(cryptoCurrencyStatus) }
|
||||
}
|
||||
is TokenActionsState.ActionState.Receive -> {
|
||||
title = resourceReference(R.string.common_receive)
|
||||
icon = R.drawable.ic_arrow_down_24
|
||||
action = { }
|
||||
action = { clickIntents.onReceiveClick(cryptoCurrencyStatus) }
|
||||
}
|
||||
is TokenActionsState.ActionState.Sell -> {
|
||||
title = resourceReference(R.string.common_sell)
|
||||
icon = R.drawable.ic_currency_24
|
||||
action = { }
|
||||
action = { clickIntents.onSellClick(cryptoCurrencyStatus) }
|
||||
}
|
||||
is TokenActionsState.ActionState.Send -> {
|
||||
title = resourceReference(R.string.common_send)
|
||||
icon = R.drawable.ic_arrow_up_24
|
||||
action = { }
|
||||
action = { clickIntents.onMultiCurrencySendClick(cryptoCurrencyStatus) }
|
||||
}
|
||||
is TokenActionsState.ActionState.Swap -> {
|
||||
title = resourceReference(R.string.common_swap)
|
||||
icon = R.drawable.ic_exchange_horizontal_24
|
||||
action = { }
|
||||
action = { clickIntents.onSwapClick(cryptoCurrencyStatus) }
|
||||
}
|
||||
}
|
||||
return TokenActionButtonConfig(
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ import kotlinx.collections.immutable.toPersistentList
|
|||
internal class WalletCryptoCurrencyActionsConverter(
|
||||
private val currentStateProvider: Provider<WalletState>,
|
||||
private val clickIntents: WalletClickIntents,
|
||||
) : Converter<List<TokenActionsState.ActionState>, WalletState> {
|
||||
) : Converter<TokenActionsState, WalletState> {
|
||||
|
||||
override fun convert(value: List<TokenActionsState.ActionState>): WalletState {
|
||||
override fun convert(value: TokenActionsState): WalletState {
|
||||
return when (val state = currentStateProvider()) {
|
||||
is WalletSingleCurrencyState.Content -> state.copy(buttons = value.mapToManageButtons())
|
||||
is WalletSingleCurrencyState.Locked,
|
||||
|
|
@ -26,23 +26,31 @@ internal class WalletCryptoCurrencyActionsConverter(
|
|||
}
|
||||
}
|
||||
|
||||
private fun List<TokenActionsState.ActionState>.mapToManageButtons(): PersistentList<WalletManageButton> {
|
||||
return this
|
||||
private fun TokenActionsState.mapToManageButtons(): PersistentList<WalletManageButton> {
|
||||
return this.states
|
||||
.mapNotNull { action ->
|
||||
when (action) {
|
||||
is TokenActionsState.ActionState.Buy -> {
|
||||
WalletManageButton.Buy(enabled = action.enabled, onClick = clickIntents::onBuyClick)
|
||||
WalletManageButton.Buy(
|
||||
enabled = action.enabled,
|
||||
onClick = { clickIntents.onBuyClick(cryptoCurrencyStatus) },
|
||||
)
|
||||
}
|
||||
is TokenActionsState.ActionState.Receive -> {
|
||||
WalletManageButton.Receive(onClick = clickIntents::onReceiveClick)
|
||||
WalletManageButton.Receive(
|
||||
onClick = { clickIntents.onReceiveClick(cryptoCurrencyStatus) },
|
||||
)
|
||||
}
|
||||
is TokenActionsState.ActionState.Sell -> {
|
||||
WalletManageButton.Sell(enabled = action.enabled, onClick = clickIntents::onSellClick)
|
||||
WalletManageButton.Sell(
|
||||
enabled = action.enabled,
|
||||
onClick = { clickIntents.onSellClick(cryptoCurrencyStatus) },
|
||||
)
|
||||
}
|
||||
is TokenActionsState.ActionState.Send -> {
|
||||
WalletManageButton.Send(
|
||||
enabled = action.enabled,
|
||||
onClick = clickIntents::onSingleCurrencySendClick,
|
||||
onClick = { clickIntents.onSingleCurrencySendClick(cryptoCurrencyStatus) },
|
||||
)
|
||||
}
|
||||
is TokenActionsState.ActionState.Swap -> null
|
||||
|
|
|
|||
|
|
@ -215,8 +215,16 @@ internal class WalletStateFactory(
|
|||
}
|
||||
}
|
||||
|
||||
fun getLoadingTxHistoryState(itemsCountEither: Either<TxHistoryStateError, Int>): WalletState {
|
||||
return loadingTransactionsStateConverter.convert(value = itemsCountEither)
|
||||
fun getLoadingTxHistoryState(
|
||||
itemsCountEither: Either<TxHistoryStateError, Int>,
|
||||
cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
): WalletState {
|
||||
return loadingTransactionsStateConverter.convert(
|
||||
WalletLoadingTxHistoryConverter.WalletLoadingTxHistoryModel(
|
||||
historyLoadingState = itemsCountEither,
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun getLoadedTxHistoryState(
|
||||
|
|
@ -233,8 +241,8 @@ internal class WalletStateFactory(
|
|||
return singleCurrencyLoadedBalanceConverter.convert(maybeCryptoCurrencyStatus)
|
||||
}
|
||||
|
||||
fun getSingleCurrencyManageButtonsState(actions: List<TokenActionsState.ActionState>): WalletState {
|
||||
return cryptoCurrencyActionsConverter.convert(value = actions)
|
||||
fun getSingleCurrencyManageButtonsState(actionsState: TokenActionsState): WalletState {
|
||||
return cryptoCurrencyActionsConverter.convert(value = actionsState)
|
||||
}
|
||||
|
||||
fun getStateByCurrencyStatusError(error: CurrencyStatusError): WalletState {
|
||||
|
|
|
|||
|
|
@ -2,41 +2,45 @@ package com.tangem.feature.wallet.presentation.wallet.state.factory.txhistory
|
|||
|
||||
import androidx.paging.PagingData
|
||||
import arrow.core.Either
|
||||
import com.tangem.common.Converter
|
||||
import com.tangem.common.Provider
|
||||
import com.tangem.core.ui.components.transactions.state.TransactionState
|
||||
import com.tangem.core.ui.components.transactions.state.TxHistoryState.*
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.txhistory.models.TxHistoryStateError
|
||||
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.viewmodels.WalletClickIntents
|
||||
import com.tangem.utils.converter.Converter
|
||||
import kotlinx.coroutines.flow.update
|
||||
|
||||
/**
|
||||
* Converter from loading tx history state to [WalletSingleCurrencyState.Content]
|
||||
*
|
||||
* @property currentStateProvider current state provider
|
||||
* @property clickIntents screen click intents
|
||||
* @property currentStateProvider current state provider
|
||||
* @property clickIntents screen click intents
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class WalletLoadingTxHistoryConverter(
|
||||
private val currentStateProvider: Provider<WalletState>,
|
||||
private val clickIntents: WalletClickIntents,
|
||||
) : Converter<Either<TxHistoryStateError, Int>, WalletState> {
|
||||
) : Converter<WalletLoadingTxHistoryConverter.WalletLoadingTxHistoryModel, WalletState> {
|
||||
|
||||
override fun convert(value: Either<TxHistoryStateError, Int>): WalletState {
|
||||
return value.fold(ifLeft = ::convertError, ifRight = ::convert)
|
||||
override fun convert(value: WalletLoadingTxHistoryModel): WalletState {
|
||||
return value.historyLoadingState.fold(
|
||||
ifLeft = { convertError(it, value.cryptoCurrencyStatus) },
|
||||
ifRight = ::convertRight,
|
||||
)
|
||||
}
|
||||
|
||||
private fun convertError(error: TxHistoryStateError): WalletState {
|
||||
private fun convertError(error: TxHistoryStateError, cryptoCurrencyStatus: CryptoCurrencyStatus): WalletState {
|
||||
val state = currentStateProvider()
|
||||
|
||||
return if (state is WalletSingleCurrencyState.Content) {
|
||||
state.copy(
|
||||
txHistoryState = when (error) {
|
||||
is TxHistoryStateError.EmptyTxHistories -> {
|
||||
Empty(onBuyClick = clickIntents::onBuyClick)
|
||||
Empty(onBuyClick = { clickIntents.onBuyClick(cryptoCurrencyStatus) })
|
||||
}
|
||||
is TxHistoryStateError.DataError -> {
|
||||
Error(onReloadClick = clickIntents::onReloadClick)
|
||||
|
|
@ -51,7 +55,7 @@ internal class WalletLoadingTxHistoryConverter(
|
|||
}
|
||||
}
|
||||
|
||||
private fun convert(value: Int): WalletState {
|
||||
private fun convertRight(value: Int): WalletState {
|
||||
val state = currentStateProvider()
|
||||
val txHistoryContent = (state as? WalletSingleCurrencyState.Content)?.txHistoryState as? Content
|
||||
|
||||
|
|
@ -71,4 +75,9 @@ internal class WalletLoadingTxHistoryConverter(
|
|||
|
||||
return state
|
||||
}
|
||||
|
||||
data class WalletLoadingTxHistoryModel(
|
||||
val historyLoadingState: Either<TxHistoryStateError, Int>,
|
||||
val cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
)
|
||||
}
|
||||
|
|
@ -1,12 +1,11 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.viewmodels
|
||||
|
||||
import com.tangem.core.ui.components.transactions.intents.TxHistoryClickIntents
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.tokens.models.CryptoCurrency
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
|
||||
@Suppress("TooManyFunctions")
|
||||
internal interface WalletClickIntents : TxHistoryClickIntents {
|
||||
internal interface WalletClickIntents {
|
||||
|
||||
fun onBackClick()
|
||||
|
||||
|
|
@ -56,9 +55,17 @@ internal interface WalletClickIntents : TxHistoryClickIntents {
|
|||
|
||||
fun onMultiCurrencySendClick(cryptoCurrencyStatus: CryptoCurrencyStatus)
|
||||
|
||||
fun onReceiveClick()
|
||||
fun onReceiveClick(cryptoCurrencyStatus: CryptoCurrencyStatus)
|
||||
|
||||
fun onSellClick()
|
||||
fun onSellClick(cryptoCurrencyStatus: CryptoCurrencyStatus)
|
||||
|
||||
fun onManageTokensClick()
|
||||
|
||||
fun onBuyClick(cryptoCurrencyStatus: CryptoCurrencyStatus)
|
||||
|
||||
fun onSwapClick(cryptoCurrencyStatus: CryptoCurrencyStatus)
|
||||
|
||||
fun onReloadClick()
|
||||
|
||||
fun onExploreClick()
|
||||
}
|
||||
|
|
@ -366,20 +366,23 @@ internal class WalletViewModel @Inject constructor(
|
|||
router.openOrganizeTokensScreen(walletId)
|
||||
}
|
||||
|
||||
override fun onBuyClick() {
|
||||
override fun onBuyClick(cryptoCurrencyStatus: CryptoCurrencyStatus) {
|
||||
val state = uiState as? WalletState.ContentState ?: return
|
||||
val status = singleWalletCryptoCurrencyStatus ?: return
|
||||
val wallet = getWallet(index = state.walletsListConfig.selectedWalletIndex)
|
||||
|
||||
reduxStateHolder.dispatch(
|
||||
TradeCryptoAction.New.Buy(
|
||||
userWallet = wallet,
|
||||
cryptoCurrencyStatus = status,
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
appCurrencyCode = selectedAppCurrencyFlow.value.code,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
override fun onSwapClick(cryptoCurrencyStatus: CryptoCurrencyStatus) {
|
||||
// todo implement onSwapClick [REDACTED_JIRA]
|
||||
}
|
||||
|
||||
override fun onSingleCurrencySendClick(cryptoCurrencyStatus: CryptoCurrencyStatus?) {
|
||||
val state = uiState as? WalletState.ContentState ?: return
|
||||
|
||||
|
|
@ -424,16 +427,14 @@ internal class WalletViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun onReceiveClick() {
|
||||
override fun onReceiveClick(cryptoCurrencyStatus: CryptoCurrencyStatus) {
|
||||
// TODO: [REDACTED_JIRA]
|
||||
}
|
||||
|
||||
override fun onSellClick() {
|
||||
val status = singleWalletCryptoCurrencyStatus ?: return
|
||||
|
||||
override fun onSellClick(cryptoCurrencyStatus: CryptoCurrencyStatus) {
|
||||
reduxStateHolder.dispatch(
|
||||
TradeCryptoAction.New.Sell(
|
||||
cryptoCurrencyStatus = status,
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
appCurrencyCode = selectedAppCurrencyFlow.value.code,
|
||||
),
|
||||
)
|
||||
|
|
@ -501,7 +502,7 @@ internal class WalletViewModel @Inject constructor(
|
|||
val userWallet = getWallet(state.walletsListConfig.selectedWalletIndex)
|
||||
viewModelScope.launch(dispatchers.io) {
|
||||
getCryptoCurrencyActionsUseCase
|
||||
.invoke(userWallet.walletId, cryptoCurrencyStatus.currency)
|
||||
.invoke(userWallet.walletId, cryptoCurrencyStatus)
|
||||
.take(count = 1)
|
||||
.collectLatest {
|
||||
uiState = stateFactory.getStateWithTokenActionBottomSheet(it)
|
||||
|
|
@ -591,7 +592,10 @@ internal class WalletViewModel @Inject constructor(
|
|||
viewModelScope.launch(dispatchers.io) {
|
||||
val txHistoryItemsCountEither = txHistoryItemsCountUseCase(network)
|
||||
|
||||
uiState = stateFactory.getLoadingTxHistoryState(itemsCountEither = txHistoryItemsCountEither)
|
||||
uiState = stateFactory.getLoadingTxHistoryState(
|
||||
itemsCountEither = txHistoryItemsCountEither,
|
||||
cryptoCurrencyStatus = singleWalletCryptoCurrencyStatus ?: return@launch,
|
||||
)
|
||||
|
||||
txHistoryItemsCountEither.onRight {
|
||||
uiState = stateFactory.getLoadedTxHistoryState(
|
||||
|
|
@ -613,7 +617,7 @@ internal class WalletViewModel @Inject constructor(
|
|||
|
||||
maybeCryptoCurrencyStatus.onRight { status ->
|
||||
singleWalletCryptoCurrencyStatus = status
|
||||
updateButtons(userWalletId = userWalletId, currency = status.currency)
|
||||
updateButtons(userWalletId = userWalletId, currencyStatus = status)
|
||||
updateTxHistory(status.currency.network)
|
||||
}
|
||||
}
|
||||
|
|
@ -622,10 +626,10 @@ internal class WalletViewModel @Inject constructor(
|
|||
.saveIn(marketPriceJobHolder)
|
||||
}
|
||||
|
||||
private fun updateButtons(userWalletId: UserWalletId, currency: CryptoCurrency) {
|
||||
getCryptoCurrencyActionsUseCase(userWalletId = userWalletId, cryptoCurrency = currency)
|
||||
private fun updateButtons(userWalletId: UserWalletId, currencyStatus: CryptoCurrencyStatus) {
|
||||
getCryptoCurrencyActionsUseCase(userWalletId = userWalletId, cryptoCurrencyStatus = currencyStatus)
|
||||
.distinctUntilChanged()
|
||||
.onEach { uiState = stateFactory.getSingleCurrencyManageButtonsState(actions = it.states) }
|
||||
.onEach { uiState = stateFactory.getSingleCurrencyManageButtonsState(actionsState = it) }
|
||||
.flowOn(dispatchers.io)
|
||||
.launchIn(viewModelScope)
|
||||
.saveIn(buttonsJobHolder)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue