diff --git a/features/wallet/impl/src/main/res/drawable/ic_currency_24.xml b/core/ui/src/main/res/drawable/ic_currency_24.xml similarity index 100% rename from features/wallet/impl/src/main/res/drawable/ic_currency_24.xml rename to core/ui/src/main/res/drawable/ic_currency_24.xml diff --git a/features/tokendetails/impl/build.gradle.kts b/features/tokendetails/impl/build.gradle.kts index 55d58498b5..1957acae29 100644 --- a/features/tokendetails/impl/build.gradle.kts +++ b/features/tokendetails/impl/build.gradle.kts @@ -31,6 +31,7 @@ dependencies { implementation(deps.arrow.core) implementation(deps.jodatime) implementation(deps.kotlin.immutable.collections) + implementation(deps.reKotlin) implementation(deps.tangem.blockchain) implementation(deps.tangem.card.core) implementation(deps.timber) diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/TokenDetailsPreviewData.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/TokenDetailsPreviewData.kt index 9122d3dfbd..b4af868ab8 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/TokenDetailsPreviewData.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/TokenDetailsPreviewData.kt @@ -1,16 +1,14 @@ package com.tangem.feature.tokendetails.presentation.tokendetails -import com.tangem.core.ui.components.buttons.actions.ActionButtonConfig import com.tangem.core.ui.components.marketprice.MarketPriceBlockState import com.tangem.core.ui.components.transactions.state.TxHistoryState -import com.tangem.core.ui.extensions.TextReference import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsBalanceBlockState import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsTopAppBarConfig import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenInfoBlockState +import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsActionButton import com.tangem.features.tokendetails.impl.R import kotlinx.collections.immutable.persistentListOf -import kotlinx.collections.immutable.toPersistentList import kotlinx.coroutines.flow.MutableStateFlow internal object TokenDetailsPreviewData { @@ -42,40 +40,20 @@ internal object TokenDetailsPreviewData { ), ) - // TODO: [REDACTED_JIRA] - val actionButtons = persistentListOf( - ActionButtonConfig( - text = TextReference.Str(value = "Buy"), - iconResId = R.drawable.ic_plus_24, - onClick = {}, - ), - ActionButtonConfig( - text = TextReference.Str(value = "Send"), - iconResId = R.drawable.ic_arrow_up_24, - onClick = {}, - ), - ActionButtonConfig( - text = TextReference.Str(value = "Receive"), - iconResId = R.drawable.ic_arrow_down_24, - onClick = {}, - ), - ActionButtonConfig( - text = TextReference.Str(value = "Exchange"), - iconResId = R.drawable.ic_exchange_vertical_24, - onClick = {}, - ), + private val actionButtons = persistentListOf( + TokenDetailsActionButton.Buy(enabled = true, onClick = {}), + TokenDetailsActionButton.Send(enabled = true, onClick = {}), + TokenDetailsActionButton.Receive(onClick = {}), + TokenDetailsActionButton.Swap(enabled = true, onClick = {}), ) - // TODO: [REDACTED_JIRA] - val disabledActionButtons = actionButtons.map { it.copy(enabled = false) }.toPersistentList() - - val balanceLoading = TokenDetailsBalanceBlockState.Loading(actionButtons = disabledActionButtons) + val balanceLoading = TokenDetailsBalanceBlockState.Loading(actionButtons = actionButtons) val balanceContent = TokenDetailsBalanceBlockState.Content( actionButtons = actionButtons, fiatBalance = "123,00$", cryptoBalance = "866,96 USDT", ) - val balanceError = TokenDetailsBalanceBlockState.Error(actionButtons = disabledActionButtons) + val balanceError = TokenDetailsBalanceBlockState.Error(actionButtons = actionButtons) private val marketPriceLoading = MarketPriceBlockState.Loading(currencyName = "USDT") diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/TokenDetailsBalanceBlockState.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/TokenDetailsBalanceBlockState.kt index a67edd1a61..2f066dae01 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/TokenDetailsBalanceBlockState.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/TokenDetailsBalanceBlockState.kt @@ -1,23 +1,31 @@ package com.tangem.feature.tokendetails.presentation.tokendetails.state -import com.tangem.core.ui.components.buttons.actions.ActionButtonConfig +import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsActionButton import kotlinx.collections.immutable.ImmutableList -sealed class TokenDetailsBalanceBlockState { +internal sealed class TokenDetailsBalanceBlockState { - abstract val actionButtons: ImmutableList + abstract val actionButtons: ImmutableList data class Loading( - override val actionButtons: ImmutableList, + override val actionButtons: ImmutableList, ) : TokenDetailsBalanceBlockState() data class Content( - override val actionButtons: ImmutableList, + override val actionButtons: ImmutableList, val fiatBalance: String, val cryptoBalance: String, ) : TokenDetailsBalanceBlockState() data class Error( - override val actionButtons: ImmutableList, + override val actionButtons: ImmutableList, ) : TokenDetailsBalanceBlockState() + + fun copyActionButtons(buttons: ImmutableList): TokenDetailsBalanceBlockState { + return when (this) { + is Content -> this.copy(actionButtons = buttons) + is Error -> this.copy(actionButtons = buttons) + is Loading -> this.copy(actionButtons = buttons) + } + } } \ No newline at end of file diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/TokenDetailsState.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/TokenDetailsState.kt index c3902dc328..7006b6c4ef 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/TokenDetailsState.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/TokenDetailsState.kt @@ -3,7 +3,7 @@ package com.tangem.feature.tokendetails.presentation.tokendetails.state import com.tangem.core.ui.components.marketprice.MarketPriceBlockState import com.tangem.core.ui.components.transactions.state.TxHistoryState -data class TokenDetailsState( +internal data class TokenDetailsState( val topAppBarConfig: TokenDetailsTopAppBarConfig, val tokenInfoBlockState: TokenInfoBlockState, val tokenBalanceBlockState: TokenDetailsBalanceBlockState, diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/components/TokenDetailsActionButton.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/components/TokenDetailsActionButton.kt new file mode 100644 index 0000000000..8af1d13a13 --- /dev/null +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/components/TokenDetailsActionButton.kt @@ -0,0 +1,87 @@ +package com.tangem.feature.tokendetails.presentation.tokendetails.state.components + +import androidx.compose.runtime.Immutable +import com.tangem.core.ui.components.buttons.actions.ActionButtonConfig +import com.tangem.core.ui.extensions.TextReference +import com.tangem.features.tokendetails.impl.R + +@Immutable +internal sealed class TokenDetailsActionButton(val config: ActionButtonConfig) { + + /** Lambda be invoked when manage button is clicked */ + abstract val onClick: () -> Unit + + /** + * Buy + * + * @property enabled button click availability + * @property onClick lambda be invoked when Buy button is clicked + */ + data class Buy(val enabled: Boolean, override val onClick: () -> Unit) : TokenDetailsActionButton( + config = ActionButtonConfig( + text = TextReference.Res(id = R.string.common_buy), + iconResId = R.drawable.ic_plus_24, + onClick = onClick, + enabled = enabled, + ), + ) + + /** + * Send + * + * @property enabled button click availability + * @property onClick lambda be invoked when Send button is clicked + */ + data class Send(val enabled: Boolean, override val onClick: () -> Unit) : TokenDetailsActionButton( + config = ActionButtonConfig( + text = TextReference.Res(id = R.string.common_send), + iconResId = R.drawable.ic_arrow_up_24, + onClick = onClick, + enabled = enabled, + ), + ) + + /** + * Receive + * + * @property onClick lambda be invoked when Receive button is clicked + */ + data class Receive(override val onClick: () -> Unit) : TokenDetailsActionButton( + config = ActionButtonConfig( + text = TextReference.Res(id = R.string.common_receive), + iconResId = R.drawable.ic_arrow_down_24, + onClick = onClick, + enabled = true, + ), + ) + + /** + * Sell + * + * @property enabled button click availability + * @property onClick lambda be invoked when Sell button is clicked + */ + data class Sell(val enabled: Boolean, override val onClick: () -> Unit) : TokenDetailsActionButton( + config = ActionButtonConfig( + 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) : TokenDetailsActionButton( + config = ActionButtonConfig( + text = TextReference.Res(id = R.string.common_swap), + iconResId = R.drawable.ic_exchange_vertical_24, + onClick = onClick, + enabled = enabled, + ), + ) +} \ No newline at end of file diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsActionButtonsConverter.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsActionButtonsConverter.kt new file mode 100644 index 0000000000..3cd4b2e4de --- /dev/null +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsActionButtonsConverter.kt @@ -0,0 +1,47 @@ +package com.tangem.feature.tokendetails.presentation.tokendetails.state.factory + +import com.tangem.common.Provider +import com.tangem.domain.tokens.model.TokenActionsState +import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState +import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsActionButton +import com.tangem.feature.tokendetails.presentation.tokendetails.viewmodels.TokenDetailsClickIntents +import com.tangem.utils.converter.Converter +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.toImmutableList + +internal class TokenDetailsActionButtonsConverter( + private val currentStateProvider: Provider, + private val clickIntents: TokenDetailsClickIntents, +) : Converter, TokenDetailsState> { + + override fun convert(value: List): TokenDetailsState { + val state = currentStateProvider() + return state.copy( + tokenBalanceBlockState = state.tokenBalanceBlockState.copyActionButtons(value.mapToManageButtons()), + ) + } + + private fun List.mapToManageButtons(): ImmutableList { + return this + .map { action -> + when (action) { + is TokenActionsState.ActionState.Buy -> { + TokenDetailsActionButton.Buy(enabled = action.enabled, onClick = clickIntents::onBuyClick) + } + is TokenActionsState.ActionState.Receive -> { + TokenDetailsActionButton.Receive(onClick = clickIntents::onReceiveClick) + } + is TokenActionsState.ActionState.Sell -> { + TokenDetailsActionButton.Sell(enabled = action.enabled, onClick = clickIntents::onSellClick) + } + is TokenActionsState.ActionState.Send -> { + TokenDetailsActionButton.Send(enabled = action.enabled, onClick = clickIntents::onSendClick) + } + is TokenActionsState.ActionState.Swap -> { + TokenDetailsActionButton.Swap(enabled = action.enabled, onClick = clickIntents::onSwapClick) + } + } + } + .toImmutableList() + } +} \ No newline at end of file diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsLoadedBalanceConverter.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsLoadedBalanceConverter.kt index 5c3be27d6a..85c51d80b2 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsLoadedBalanceConverter.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsLoadedBalanceConverter.kt @@ -8,13 +8,12 @@ import com.tangem.core.ui.utils.BigDecimalFormatter import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.tokens.error.CurrencyError import com.tangem.domain.tokens.model.CryptoCurrencyStatus -import com.tangem.feature.tokendetails.presentation.tokendetails.TokenDetailsPreviewData import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsBalanceBlockState import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState import com.tangem.utils.converter.Converter import java.math.BigDecimal -class TokenDetailsLoadedBalanceConverter( +internal class TokenDetailsLoadedBalanceConverter( private val currentStateProvider: Provider, private val appCurrencyProvider: Provider, ) : Converter, TokenDetailsState> { @@ -32,24 +31,27 @@ class TokenDetailsLoadedBalanceConverter( val state = currentStateProvider() val currencyName = state.marketPriceBlockState.currencyName return state.copy( - tokenBalanceBlockState = getBalanceState(status), + tokenBalanceBlockState = getBalanceState(state.tokenBalanceBlockState, status), marketPriceBlockState = getMarketPriceState(status = status.value, currencyName = currencyName), ) } - private fun getBalanceState(status: CryptoCurrencyStatus): TokenDetailsBalanceBlockState { + private fun getBalanceState( + currentState: TokenDetailsBalanceBlockState, + status: CryptoCurrencyStatus, + ): TokenDetailsBalanceBlockState { return when (status.value) { is CryptoCurrencyStatus.NoQuote, is CryptoCurrencyStatus.Loaded, -> { TokenDetailsBalanceBlockState.Content( - actionButtons = TokenDetailsPreviewData.actionButtons, + actionButtons = currentState.actionButtons, fiatBalance = formatFiatAmount(status.value, appCurrencyProvider()), cryptoBalance = formatCryptoAmount(status), ) } is CryptoCurrencyStatus.Loading -> { - TokenDetailsBalanceBlockState.Loading(TokenDetailsPreviewData.disabledActionButtons) + TokenDetailsBalanceBlockState.Loading(currentState.actionButtons) } is CryptoCurrencyStatus.MissedDerivation, is CryptoCurrencyStatus.NoAccount, @@ -57,7 +59,7 @@ class TokenDetailsLoadedBalanceConverter( // TODO: [REDACTED_JIRA] is CryptoCurrencyStatus.Unreachable, -> { - TokenDetailsBalanceBlockState.Error(TokenDetailsPreviewData.actionButtons) + TokenDetailsBalanceBlockState.Error(currentState.actionButtons) } } } diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsSkeletonStateConverter.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsSkeletonStateConverter.kt index 34823e4635..a02f4cc5fe 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsSkeletonStateConverter.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsSkeletonStateConverter.kt @@ -4,14 +4,16 @@ import com.tangem.core.ui.components.marketprice.MarketPriceBlockState import com.tangem.core.ui.components.transactions.state.TxHistoryState import com.tangem.core.ui.extensions.iconResId import com.tangem.domain.tokens.models.CryptoCurrency -import com.tangem.feature.tokendetails.presentation.tokendetails.TokenDetailsPreviewData import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsBalanceBlockState import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsTopAppBarConfig import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenInfoBlockState +import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsActionButton import com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.TokenDetailsSkeletonStateConverter.SkeletonModel import com.tangem.feature.tokendetails.presentation.tokendetails.viewmodels.TokenDetailsClickIntents import com.tangem.utils.converter.Converter +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.flow.MutableStateFlow internal class TokenDetailsSkeletonStateConverter( @@ -37,7 +39,7 @@ internal class TokenDetailsSkeletonStateConverter( }, ), tokenBalanceBlockState = TokenDetailsBalanceBlockState.Loading( - TokenDetailsPreviewData.disabledActionButtons, + actionButtons = createButtons(), ), marketPriceBlockState = MarketPriceBlockState.Loading(value.cryptoCurrency.name), txHistoryState = TxHistoryState.Content( @@ -48,5 +50,15 @@ internal class TokenDetailsSkeletonStateConverter( ) } + private fun createButtons(): ImmutableList { + return persistentListOf( + TokenDetailsActionButton.Buy(enabled = false, onClick = {}), + TokenDetailsActionButton.Send(enabled = false, onClick = {}), + TokenDetailsActionButton.Receive(onClick = {}), + TokenDetailsActionButton.Sell(enabled = false, onClick = {}), + TokenDetailsActionButton.Swap(enabled = false, onClick = {}), + ) + } + data class SkeletonModel(val cryptoCurrency: CryptoCurrency) } \ No newline at end of file diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsStateFactory.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsStateFactory.kt index 09c5094a0e..74cda4c7d8 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsStateFactory.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsStateFactory.kt @@ -6,6 +6,7 @@ import com.tangem.common.Provider import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.tokens.error.CurrencyError import com.tangem.domain.tokens.model.CryptoCurrencyStatus +import com.tangem.domain.tokens.model.TokenActionsState import com.tangem.domain.tokens.models.CryptoCurrency import com.tangem.domain.txhistory.models.TxHistoryItem import com.tangem.domain.txhistory.models.TxHistoryListError @@ -35,6 +36,13 @@ internal class TokenDetailsStateFactory( ) } + private val tokenDetailsButtonsConverter by lazy { + TokenDetailsActionButtonsConverter( + currentStateProvider = currentStateProvider, + clickIntents = clickIntents, + ) + } + private val loadingTransactionsStateConverter by lazy { TokenDetailsLoadingTxHistoryConverter(currentStateProvider = currentStateProvider, clickIntents = clickIntents) } @@ -60,6 +68,10 @@ internal class TokenDetailsStateFactory( return tokenDetailsLoadedBalanceConverter.convert(cryptoCurrencyEither) } + fun getManageButtonsState(actions: List): TokenDetailsState { + return tokenDetailsButtonsConverter.convert(actions) + } + fun getLoadingTxHistoryState(itemsCountEither: Either): TokenDetailsState { return loadingTransactionsStateConverter.convert(value = itemsCountEither) } diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/components/TokenDetailsBalanceBlock.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/components/TokenDetailsBalanceBlock.kt index df54b41461..b1b9ac832a 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/components/TokenDetailsBalanceBlock.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/components/TokenDetailsBalanceBlock.kt @@ -15,7 +15,9 @@ import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.utils.BigDecimalFormatter import com.tangem.feature.tokendetails.presentation.tokendetails.TokenDetailsPreviewData import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsBalanceBlockState +import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsActionButton import com.tangem.features.tokendetails.impl.R +import kotlinx.collections.immutable.toImmutableList @Composable internal fun TokenDetailsBalanceBlock(state: TokenDetailsBalanceBlockState, modifier: Modifier = Modifier) { @@ -51,7 +53,7 @@ internal fun TokenDetailsBalanceBlock(state: TokenDetailsBalanceBlockState, modi ) HorizontalActionChips( - buttons = state.actionButtons, + buttons = state.actionButtons.map(TokenDetailsActionButton::config).toImmutableList(), modifier = Modifier.padding(vertical = TangemTheme.dimens.spacing12), contentPadding = PaddingValues(horizontal = TangemTheme.dimens.spacing12), ) diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsClickIntents.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsClickIntents.kt index 4f1008ac8c..fba6130de7 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsClickIntents.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsClickIntents.kt @@ -7,4 +7,12 @@ interface TokenDetailsClickIntents : TxHistoryClickIntents { fun onBackClick() fun onMoreClick() + + fun onSendClick() + + fun onReceiveClick() + + fun onSellClick() + + fun onSwapClick() } \ No newline at end of file diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt index a417d04cf8..758750faca 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt @@ -9,11 +9,16 @@ import arrow.core.getOrElse import com.tangem.common.Provider import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase import com.tangem.domain.appcurrency.model.AppCurrency +import com.tangem.domain.redux.ReduxStateHolder +import com.tangem.domain.tokens.GetCryptoCurrencyActionsUseCase import com.tangem.domain.tokens.GetCurrencyUseCase +import com.tangem.domain.tokens.legacy.TradeCryptoAction +import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.tokens.models.CryptoCurrency import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.UserWalletId import com.tangem.domain.wallets.usecase.GetExploreUrlUseCase import com.tangem.domain.wallets.usecase.GetSelectedWalletUseCase import com.tangem.feature.tokendetails.presentation.router.InnerTokenDetailsRouter @@ -39,6 +44,8 @@ internal class TokenDetailsViewModel @Inject constructor( private val txHistoryItemsCountUseCase: GetTxHistoryItemsCountUseCase, private val txHistoryItemsUseCase: GetTxHistoryItemsUseCase, private val getExploreUrlUseCase: GetExploreUrlUseCase, + private val getCryptoCurrencyActionsUseCase: GetCryptoCurrencyActionsUseCase, + private val reduxStateHolder: ReduxStateHolder, savedStateHandle: SavedStateHandle, ) : ViewModel(), DefaultLifecycleObserver, TokenDetailsClickIntents { @@ -48,6 +55,8 @@ internal class TokenDetailsViewModel @Inject constructor( var router by Delegates.notNull() private val marketPriceJobHolder = JobHolder() + private var cryptoCurrencyStatus: CryptoCurrencyStatus? = null + private var wallet by Delegates.notNull() private val selectedAppCurrencyFlow: StateFlow = createSelectedAppCurrencyFlow() private val stateFactory = TokenDetailsStateFactory( @@ -61,26 +70,39 @@ internal class TokenDetailsViewModel @Inject constructor( private set override fun onCreate(owner: LifecycleOwner) { - updateContent(selectedWallet = getWallet(), refresh = false) + getWallet() + updateContent(selectedWallet = wallet, refresh = false) } - private fun getWallet(): UserWallet { + private fun getWallet() { return getSelectedWalletUseCase() .fold( ifLeft = { error("Can not get selected wallet $it") }, - ifRight = { it }, + ifRight = { wallet = it }, ) } private fun updateContent(selectedWallet: UserWallet, refresh: Boolean) { updateMarketPrice(selectedWallet = selectedWallet, refresh = refresh) + updateButtons(userWalletId = selectedWallet.walletId, currencyId = cryptoCurrency.id.value) updateTxHistory() } + private fun updateButtons(userWalletId: UserWalletId, currencyId: String) { + getCryptoCurrencyActionsUseCase(userWalletId = userWalletId, tokenId = currencyId) + .distinctUntilChanged() + .onEach { uiState = stateFactory.getManageButtonsState(actions = it.states) } + .flowOn(dispatchers.io) + .launchIn(viewModelScope) + } + private fun updateMarketPrice(selectedWallet: UserWallet, refresh: Boolean) { getCurrencyUseCase(userWalletId = selectedWallet.walletId, currencyId = cryptoCurrency.id, refresh = refresh) .distinctUntilChanged() - .onEach { uiState = stateFactory.getCurrencyLoadedBalanceState(it) } + .onEach { either -> + uiState = stateFactory.getCurrencyLoadedBalanceState(either) + either.onRight { status -> cryptoCurrencyStatus = status } + } .flowOn(dispatchers.io) .launchIn(viewModelScope) .saveIn(marketPriceJobHolder) @@ -129,16 +151,45 @@ internal class TokenDetailsViewModel @Inject constructor( } override fun onBuyClick() { - // TODO: [REDACTED_JIRA] + val status = cryptoCurrencyStatus ?: return + + reduxStateHolder.dispatch( + TradeCryptoAction.New.Buy( + userWallet = wallet, + cryptoCurrencyStatus = status, + appCurrencyCode = selectedAppCurrencyFlow.value.code, + ), + ) } override fun onReloadClick() { updateTxHistory() } + override fun onSendClick() { + reduxStateHolder.dispatch(TradeCryptoAction.New.Send) + } + + override fun onReceiveClick() { + // TODO: [REDACTED_JIRA] + } + + override fun onSellClick() { + val status = cryptoCurrencyStatus ?: return + reduxStateHolder.dispatch( + TradeCryptoAction.New.Sell( + cryptoCurrencyStatus = status, + appCurrencyCode = selectedAppCurrencyFlow.value.code, + ), + ) + } + + override fun onSwapClick() { + reduxStateHolder.dispatch(TradeCryptoAction.New.Swap(cryptoCurrency)) + } + override fun onExploreClick() { viewModelScope.launch { - val wallet = getWallet() router.openUrl( url = getExploreUrlUseCase( userWalletId = wallet.walletId, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/components/WalletManageButton.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/components/WalletManageButton.kt index 46f70a5b22..18b589196a 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/components/WalletManageButton.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/components/WalletManageButton.kt @@ -13,7 +13,7 @@ import com.tangem.feature.wallet.impl.R [REDACTED_AUTHOR] */ @Immutable -sealed class WalletManageButton(val config: ActionButtonConfig) { +internal sealed class WalletManageButton(val config: ActionButtonConfig) { /** Lambda be invoked when manage button is clicked */ abstract val onClick: () -> Unit