Updated on 2026-08-14

This commit is contained in:
Tangem 2024-11-02 21:24:46 +04:00
parent 1fc34657ce
commit bc8242f423
11 changed files with 57 additions and 22 deletions

View file

@ -5,6 +5,7 @@ import com.tangem.domain.card.repository.CardSdkConfigRepository
import com.tangem.domain.exchange.RampStateManager
import com.tangem.domain.tokens.GetPolkadotCheckHasImmortalUseCase
import com.tangem.domain.tokens.GetPolkadotCheckHasResetUseCase
import com.tangem.domain.tokens.repository.MarketCryptoCurrencyRepository
import com.tangem.domain.tokens.repository.PolkadotAccountHealthCheckRepository
import com.tangem.sdk.api.TangemSdkManager
import com.tangem.tap.domain.scanCard.repository.DefaultScanCardRepository
@ -39,8 +40,14 @@ internal object ActivityModule {
@Provides
@Singleton
fun provideDefaultRampManager(appStateHolder: AppStateHolder): RampStateManager {
return DefaultRampManager(appStateHolder.exchangeService)
fun provideDefaultRampManager(
appStateHolder: AppStateHolder,
marketCryptoCurrencyRepository: MarketCryptoCurrencyRepository,
): RampStateManager {
return DefaultRampManager(
exchangeService = appStateHolder.exchangeService,
marketsCryptoCurrencyRepository = marketCryptoCurrencyRepository,
)
}
@Provides

View file

@ -3,8 +3,13 @@ package com.tangem.tap.network.exchangeServices
import com.tangem.domain.exchange.RampStateManager
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.repository.MarketCryptoCurrencyRepository
import com.tangem.domain.wallets.models.UserWalletId
class DefaultRampManager(private val exchangeService: ExchangeService?) : RampStateManager {
class DefaultRampManager(
private val exchangeService: ExchangeService?,
private val marketsCryptoCurrencyRepository: MarketCryptoCurrencyRepository,
) : RampStateManager {
private val cryptoCurrencyConverter = CryptoCurrencyConverter()
override fun availableForBuy(scanResponse: ScanResponse, cryptoCurrency: CryptoCurrency): Boolean {
@ -19,4 +24,8 @@ class DefaultRampManager(private val exchangeService: ExchangeService?) : RampSt
currency = cryptoCurrencyConverter.convertBack(cryptoCurrency),
) ?: false
}
override suspend fun availableForSwap(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency): Boolean {
return marketsCryptoCurrencyRepository.isExchangeable(userWalletId, cryptoCurrency)
}
}

View file

@ -4,6 +4,7 @@ import android.content.res.Configuration
import androidx.annotation.DrawableRes
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import com.tangem.core.ui.R
import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM
@ -26,6 +27,7 @@ fun AppBarWithBackButton(
modifier: Modifier = Modifier,
text: String? = null,
@DrawableRes iconRes: Int? = null,
containerColor: Color = Color.Transparent,
) {
TangemTopAppBar(
modifier = modifier,
@ -34,6 +36,7 @@ fun AppBarWithBackButton(
iconRes = iconRes ?: R.drawable.ic_back_24,
onIconClicked = onBackClick,
),
containerColor = containerColor,
)
}

View file

@ -2,6 +2,7 @@ package com.tangem.domain.exchange
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.wallets.models.UserWalletId
/**
* Manager that holds info about available actions as Sell and Buy
@ -11,4 +12,6 @@ interface RampStateManager {
fun availableForBuy(scanResponse: ScanResponse, cryptoCurrency: CryptoCurrency): Boolean
fun availableForSell(cryptoCurrency: CryptoCurrency): Boolean
suspend fun availableForSwap(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency): Boolean
}

View file

@ -5,7 +5,6 @@ import androidx.compose.runtime.Stable
import androidx.compose.ui.Modifier
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.features.onramp.component.BuyCryptoComponent
import com.tangem.features.onramp.entity.OnrampOperation
import com.tangem.features.onramp.selecttoken.OnrampOperationComponent
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
@ -20,7 +19,7 @@ internal class DefaultBuyCryptoComponent @AssistedInject constructor(
private val selectTokenComponent: OnrampOperationComponent = onrampOperationComponentFactory.create(
context = appComponentContext,
params = OnrampOperationComponent.Params(operation = OnrampOperation.BUY, userWalletId = params.userWalletId),
params = OnrampOperationComponent.Params.Buy(userWalletId = params.userWalletId),
)
@Composable

View file

@ -8,5 +8,6 @@ package com.tangem.features.onramp.entity
internal enum class OnrampOperation {
BUY,
SELL,
SWAP,
;
}

View file

@ -32,7 +32,10 @@ internal class DefaultOnrampOperationComponent @AssistedInject constructor(
private val onrampTokenListComponent: OnrampTokenListComponent = onrampTokenListComponentFactory.create(
context = child(key = "token_list"),
params = OnrampTokenListComponent.Params(
filterOperation = params.operation,
filterOperation = when (params) {
is OnrampOperationComponent.Params.Buy -> OnrampOperation.BUY
is OnrampOperationComponent.Params.Sell -> OnrampOperation.SWAP
},
hasSearchBar = true,
userWalletId = params.userWalletId,
onTokenClick = { _, status -> onTokenClick(status) },
@ -42,9 +45,9 @@ internal class DefaultOnrampOperationComponent @AssistedInject constructor(
@Composable
override fun Content(modifier: Modifier) {
OnrampSelectToken(
titleResId = when (params.operation) {
OnrampOperation.BUY -> R.string.common_buy
OnrampOperation.SELL -> R.string.common_sell
titleResId = when (params) {
is OnrampOperationComponent.Params.Buy -> R.string.common_buy
is OnrampOperationComponent.Params.Sell -> R.string.common_sell
},
onBackClick = router::pop,
onrampTokenListComponent = onrampTokenListComponent,
@ -57,9 +60,9 @@ internal class DefaultOnrampOperationComponent @AssistedInject constructor(
val appCurrencyCode = getSelectedAppCurrencyUseCase.invokeSync().getOrElse { AppCurrency.Default }.code
reduxStateHolder.dispatch(
when (params.operation) {
OnrampOperation.BUY -> getBuyAction(status, appCurrencyCode)
OnrampOperation.SELL -> TradeCryptoAction.Sell(status, appCurrencyCode)
action = when (params) {
is OnrampOperationComponent.Params.Buy -> getBuyAction(status, appCurrencyCode)
is OnrampOperationComponent.Params.Sell -> TradeCryptoAction.Sell(status, appCurrencyCode)
},
)
}

View file

@ -3,7 +3,6 @@ package com.tangem.features.onramp.selecttoken
import com.tangem.core.decompose.factory.ComponentFactory
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.features.onramp.entity.OnrampOperation
/**
* Base operation component
@ -17,8 +16,14 @@ internal interface OnrampOperationComponent : ComposableContentComponent {
/**
* Params
*
* @property operation operation
* @property userWalletId id of multi-currency wallet
*/
data class Params(val operation: OnrampOperation, val userWalletId: UserWalletId)
sealed interface Params {
val userWalletId: UserWalletId
data class Buy(override val userWalletId: UserWalletId) : Params
data class Sell(override val userWalletId: UserWalletId) : Params
}
}

View file

@ -5,7 +5,6 @@ import androidx.compose.runtime.Stable
import androidx.compose.ui.Modifier
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.features.onramp.component.SellCryptoComponent
import com.tangem.features.onramp.entity.OnrampOperation
import com.tangem.features.onramp.selecttoken.OnrampOperationComponent
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
@ -20,7 +19,7 @@ internal class DefaultSellCryptoComponent @AssistedInject constructor(
private val selectTokenComponent: OnrampOperationComponent = onrampOperationComponentFactory.create(
context = appComponentContext,
params = OnrampOperationComponent.Params(operation = OnrampOperation.SELL, userWalletId = params.userWalletId),
params = OnrampOperationComponent.Params.Sell(userWalletId = params.userWalletId),
)
@Composable

View file

@ -50,10 +50,12 @@ internal class UpdateTokenItemsTransformer(
add(searchBarItem)
}
createGroupTitle(
textReference = resourceReference(id = R.string.exchange_tokens_available_tokens_header),
)
.let(::add)
if (availableItems.isNotEmpty()) {
createGroupTitle(
textReference = resourceReference(id = R.string.exchange_tokens_available_tokens_header),
)
.let(::add)
}
addAll(availableItems)
}

View file

@ -103,13 +103,17 @@ internal class OnrampTokenListModel @Inject constructor(
}
}
private fun List<CryptoCurrencyStatus>.filterByAvailability(): Map<Boolean, List<CryptoCurrencyStatus>> {
private suspend fun List<CryptoCurrencyStatus>.filterByAvailability(): Map<Boolean, List<CryptoCurrencyStatus>> {
return groupBy { status ->
val isAvailable = when (params.filterOperation) {
OnrampOperation.BUY -> {
rampStateManager.availableForBuy(scanResponse = scanResponse, cryptoCurrency = status.currency)
}
OnrampOperation.SELL -> rampStateManager.availableForSell(cryptoCurrency = status.currency)
OnrampOperation.SWAP -> rampStateManager.availableForSwap(
userWalletId = params.userWalletId,
cryptoCurrency = status.currency,
)
}
isAvailable &&