Updated on 2026-08-14
This commit is contained in:
parent
488d1e2815
commit
101e609dec
11 changed files with 157 additions and 139 deletions
|
|
@ -29,6 +29,7 @@ dependencies {
|
|||
implementation(projects.domain.balanceHiding)
|
||||
implementation(projects.domain.balanceHiding.models)
|
||||
implementation(projects.domain.legacy)
|
||||
implementation(projects.domain.models)
|
||||
implementation(projects.domain.tokens)
|
||||
implementation(projects.domain.tokens.models)
|
||||
implementation(projects.domain.wallets)
|
||||
|
|
|
|||
|
|
@ -3,39 +3,27 @@ package com.tangem.features.onramp.buy
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.ui.Modifier
|
||||
import arrow.core.getOrElse
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.redux.ReduxStateHolder
|
||||
import com.tangem.domain.tokens.legacy.TradeCryptoAction
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
|
||||
import com.tangem.features.onramp.component.BuyCryptoComponent
|
||||
import com.tangem.features.onramp.impl.R
|
||||
import com.tangem.features.onramp.selecttoken.OnrampSelectTokenComponent
|
||||
import com.tangem.features.onramp.entity.OnrampOperation
|
||||
import com.tangem.features.onramp.selecttoken.OnrampOperationComponent
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Stable
|
||||
internal class DefaultBuyCryptoComponent @AssistedInject constructor(
|
||||
onrampSelectTokenComponentFactory: OnrampSelectTokenComponent.Factory,
|
||||
onrampOperationComponentFactory: OnrampOperationComponent.Factory,
|
||||
@Assisted private val appComponentContext: AppComponentContext,
|
||||
@Assisted private val params: BuyCryptoComponent.Params,
|
||||
private val reduxStateHolder: ReduxStateHolder,
|
||||
private val getWalletsUseCase: GetWalletsUseCase,
|
||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
) : BuyCryptoComponent {
|
||||
|
||||
private val selectTokenComponent: OnrampSelectTokenComponent = onrampSelectTokenComponentFactory.create(
|
||||
private val selectTokenComponent: OnrampOperationComponent = onrampOperationComponentFactory.create(
|
||||
context = appComponentContext,
|
||||
params = OnrampSelectTokenComponent.Params(
|
||||
params = OnrampOperationComponent.Params(
|
||||
operation = OnrampOperation.BUY,
|
||||
hasSearchBar = true,
|
||||
userWalletId = params.userWalletId,
|
||||
titleResId = R.string.common_buy,
|
||||
onTokenClick = ::onTokenClick,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -44,19 +32,6 @@ internal class DefaultBuyCryptoComponent @AssistedInject constructor(
|
|||
selectTokenComponent.Content(modifier = modifier)
|
||||
}
|
||||
|
||||
private fun onTokenClick(status: CryptoCurrencyStatus) {
|
||||
appComponentContext.componentScope.launch {
|
||||
reduxStateHolder.dispatch(
|
||||
TradeCryptoAction.Buy(
|
||||
userWallet = getWalletsUseCase.invokeSync().first { it.walletId == params.userWalletId },
|
||||
cryptoCurrencyStatus = status,
|
||||
appCurrencyCode = getSelectedAppCurrencyUseCase.invokeSync()
|
||||
.getOrElse { AppCurrency.Default }.code,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : BuyCryptoComponent.Factory {
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
package com.tangem.features.onramp.entity
|
||||
|
||||
/**
|
||||
* Onramp operation
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal enum class OnrampOperation {
|
||||
BUY,
|
||||
SELL,
|
||||
;
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
package com.tangem.features.onramp.selecttoken
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import arrow.core.getOrElse
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.context.child
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.redux.ReduxStateHolder
|
||||
import com.tangem.domain.tokens.legacy.TradeCryptoAction
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
|
||||
import com.tangem.features.onramp.entity.OnrampOperation
|
||||
import com.tangem.features.onramp.impl.R
|
||||
import com.tangem.features.onramp.selecttoken.ui.OnrampSelectToken
|
||||
import com.tangem.features.onramp.tokenlist.OnrampTokenListComponent
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
internal class DefaultOnrampOperationComponent @AssistedInject constructor(
|
||||
@Assisted appComponentContext: AppComponentContext,
|
||||
onrampTokenListComponentFactory: OnrampTokenListComponent.Factory,
|
||||
@Assisted private val params: OnrampOperationComponent.Params,
|
||||
private val reduxStateHolder: ReduxStateHolder,
|
||||
private val getWalletsUseCase: GetWalletsUseCase,
|
||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
) : AppComponentContext by appComponentContext, OnrampOperationComponent {
|
||||
|
||||
private val onrampTokenListComponent: OnrampTokenListComponent = onrampTokenListComponentFactory.create(
|
||||
context = child(key = "token_list"),
|
||||
params = OnrampTokenListComponent.Params(
|
||||
filterOperation = params.operation,
|
||||
hasSearchBar = params.hasSearchBar,
|
||||
userWalletId = params.userWalletId,
|
||||
onTokenClick = ::onTokenClick,
|
||||
),
|
||||
)
|
||||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
OnrampSelectToken(
|
||||
titleResId = when (params.operation) {
|
||||
OnrampOperation.BUY -> R.string.common_buy
|
||||
OnrampOperation.SELL -> R.string.common_sell
|
||||
},
|
||||
onBackClick = router::pop,
|
||||
onrampTokenListComponent = onrampTokenListComponent,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
private fun onTokenClick(status: CryptoCurrencyStatus) {
|
||||
componentScope.launch {
|
||||
val appCurrencyCode = getSelectedAppCurrencyUseCase.invokeSync().getOrElse { AppCurrency.Default }.code
|
||||
|
||||
reduxStateHolder.dispatch(
|
||||
when (params.operation) {
|
||||
OnrampOperation.BUY -> getBuyAction(status, appCurrencyCode)
|
||||
OnrampOperation.SELL -> TradeCryptoAction.Sell(status, appCurrencyCode)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getBuyAction(status: CryptoCurrencyStatus, appCurrencyCode: String): TradeCryptoAction {
|
||||
return TradeCryptoAction.Buy(
|
||||
userWallet = getWalletsUseCase.invokeSync().first { it.walletId == params.userWalletId },
|
||||
cryptoCurrencyStatus = status,
|
||||
appCurrencyCode = appCurrencyCode,
|
||||
)
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : OnrampOperationComponent.Factory {
|
||||
|
||||
override fun create(
|
||||
context: AppComponentContext,
|
||||
params: OnrampOperationComponent.Params,
|
||||
): DefaultOnrampOperationComponent
|
||||
}
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
package com.tangem.features.onramp.selecttoken
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.context.child
|
||||
import com.tangem.features.onramp.selecttoken.ui.OnrampSelectToken
|
||||
import com.tangem.features.onramp.tokenlist.OnrampTokenListComponent
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
|
||||
internal class DefaultOnrampSelectTokenComponent @AssistedInject constructor(
|
||||
@Assisted appComponentContext: AppComponentContext,
|
||||
onrampTokenListComponentFactory: OnrampTokenListComponent.Factory,
|
||||
@Assisted private val params: OnrampSelectTokenComponent.Params,
|
||||
) : AppComponentContext by appComponentContext, OnrampSelectTokenComponent {
|
||||
|
||||
private val onrampTokenListComponent: OnrampTokenListComponent = onrampTokenListComponentFactory.create(
|
||||
context = child(key = "token_list"),
|
||||
params = OnrampTokenListComponent.Params(
|
||||
hasSearchBar = params.hasSearchBar,
|
||||
userWalletId = params.userWalletId,
|
||||
onTokenClick = params.onTokenClick,
|
||||
),
|
||||
)
|
||||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
OnrampSelectToken(
|
||||
titleResId = params.titleResId,
|
||||
onBackClick = router::pop,
|
||||
onrampTokenListComponent = onrampTokenListComponent,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : OnrampSelectTokenComponent.Factory {
|
||||
|
||||
override fun create(
|
||||
context: AppComponentContext,
|
||||
params: OnrampSelectTokenComponent.Params,
|
||||
): DefaultOnrampSelectTokenComponent
|
||||
}
|
||||
}
|
||||
|
|
@ -1,32 +1,29 @@
|
|||
package com.tangem.features.onramp.selecttoken
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.features.onramp.entity.OnrampOperation
|
||||
|
||||
/**
|
||||
* Select token component
|
||||
* Base operation component
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
interface OnrampSelectTokenComponent : ComposableContentComponent {
|
||||
internal interface OnrampOperationComponent : ComposableContentComponent {
|
||||
|
||||
interface Factory : ComponentFactory<Params, OnrampSelectTokenComponent>
|
||||
interface Factory : ComponentFactory<Params, OnrampOperationComponent>
|
||||
|
||||
/**
|
||||
* Params
|
||||
*
|
||||
* @property operation operation
|
||||
* @property hasSearchBar flag that indicates if search bar should be shown
|
||||
* @property userWalletId id of multi-currency wallet
|
||||
* @property titleResId resource id of title
|
||||
* @property onTokenClick callback for token click
|
||||
*/
|
||||
data class Params(
|
||||
val operation: OnrampOperation,
|
||||
val hasSearchBar: Boolean,
|
||||
val userWalletId: UserWalletId,
|
||||
@StringRes val titleResId: Int,
|
||||
val onTokenClick: (CryptoCurrencyStatus) -> Unit,
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.tangem.features.onramp.selecttoken.di
|
||||
|
||||
import com.tangem.features.onramp.selecttoken.DefaultOnrampOperationComponent
|
||||
import com.tangem.features.onramp.selecttoken.OnrampOperationComponent
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
internal interface OnrampOperationComponentModule {
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindOnrampOperationComponentFactory(
|
||||
factory: DefaultOnrampOperationComponent.Factory,
|
||||
): OnrampOperationComponent.Factory
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
package com.tangem.features.onramp.selecttoken.di
|
||||
|
||||
import com.tangem.features.onramp.selecttoken.DefaultOnrampSelectTokenComponent
|
||||
import com.tangem.features.onramp.selecttoken.OnrampSelectTokenComponent
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
internal interface OnrampSelectTokenComponentModule {
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindOnrampSelectTokenComponentFactory(
|
||||
factory: DefaultOnrampSelectTokenComponent.Factory,
|
||||
): OnrampSelectTokenComponent.Factory
|
||||
}
|
||||
|
|
@ -3,37 +3,27 @@ package com.tangem.features.onramp.sell
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.ui.Modifier
|
||||
import arrow.core.getOrElse
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.redux.ReduxStateHolder
|
||||
import com.tangem.domain.tokens.legacy.TradeCryptoAction
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.features.onramp.component.SellCryptoComponent
|
||||
import com.tangem.features.onramp.impl.R
|
||||
import com.tangem.features.onramp.selecttoken.OnrampSelectTokenComponent
|
||||
import com.tangem.features.onramp.entity.OnrampOperation
|
||||
import com.tangem.features.onramp.selecttoken.OnrampOperationComponent
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Stable
|
||||
internal class DefaultSellCryptoComponent @AssistedInject constructor(
|
||||
onrampSelectTokenComponentFactory: OnrampSelectTokenComponent.Factory,
|
||||
onrampOperationComponentFactory: OnrampOperationComponent.Factory,
|
||||
@Assisted private val appComponentContext: AppComponentContext,
|
||||
@Assisted private val params: SellCryptoComponent.Params,
|
||||
private val reduxStateHolder: ReduxStateHolder,
|
||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
) : SellCryptoComponent {
|
||||
|
||||
private val selectTokenComponent: OnrampSelectTokenComponent = onrampSelectTokenComponentFactory.create(
|
||||
private val selectTokenComponent: OnrampOperationComponent = onrampOperationComponentFactory.create(
|
||||
context = appComponentContext,
|
||||
params = OnrampSelectTokenComponent.Params(
|
||||
params = OnrampOperationComponent.Params(
|
||||
operation = OnrampOperation.SELL,
|
||||
hasSearchBar = true,
|
||||
userWalletId = params.userWalletId,
|
||||
titleResId = R.string.common_sell,
|
||||
onTokenClick = ::onTokenClick,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -42,18 +32,6 @@ internal class DefaultSellCryptoComponent @AssistedInject constructor(
|
|||
selectTokenComponent.Content(modifier = modifier)
|
||||
}
|
||||
|
||||
private fun onTokenClick(status: CryptoCurrencyStatus) {
|
||||
appComponentContext.componentScope.launch {
|
||||
reduxStateHolder.dispatch(
|
||||
TradeCryptoAction.Sell(
|
||||
cryptoCurrencyStatus = status,
|
||||
appCurrencyCode = getSelectedAppCurrencyUseCase.invokeSync()
|
||||
.getOrElse { AppCurrency.Default }.code,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : SellCryptoComponent.Factory {
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import androidx.compose.ui.Modifier
|
|||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.features.onramp.entity.OnrampOperation
|
||||
|
||||
/** Token list component that present list of token for multi-currency wallet */
|
||||
@Stable
|
||||
|
|
@ -21,11 +22,13 @@ internal interface OnrampTokenListComponent {
|
|||
/**
|
||||
* Params
|
||||
*
|
||||
* @property hasSearchBar flag that indicates if search bar should be shown
|
||||
* @property userWalletId id of multi-currency wallet
|
||||
* @property onTokenClick callback for token click
|
||||
* @property filterOperation operation that is used to filter tokens by availability
|
||||
* @property hasSearchBar flag that indicates if search bar should be shown
|
||||
* @property userWalletId id of multi-currency wallet
|
||||
* @property onTokenClick callback for token click
|
||||
*/
|
||||
data class Params(
|
||||
val filterOperation: OnrampOperation,
|
||||
val hasSearchBar: Boolean,
|
||||
val userWalletId: UserWalletId,
|
||||
val onTokenClick: (CryptoCurrencyStatus) -> Unit,
|
||||
|
|
|
|||
|
|
@ -8,9 +8,12 @@ import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
|||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
||||
import com.tangem.domain.core.utils.getOrElse
|
||||
import com.tangem.domain.exchange.RampStateManager
|
||||
import com.tangem.domain.tokens.GetTokenListUseCase
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.tokens.model.TokenList
|
||||
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
|
||||
import com.tangem.features.onramp.entity.OnrampOperation
|
||||
import com.tangem.features.onramp.tokenlist.OnrampTokenListComponent
|
||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
|
||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUMController
|
||||
|
|
@ -32,11 +35,16 @@ internal class OnrampTokenListModel @Inject constructor(
|
|||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||
private val getTokenListUseCase: GetTokenListUseCase,
|
||||
private val getWalletsUseCase: GetWalletsUseCase,
|
||||
private val rampStateManager: RampStateManager,
|
||||
) : Model() {
|
||||
|
||||
val state: StateFlow<TokenListUM> = tokenListUMController.state
|
||||
|
||||
private val params: OnrampTokenListComponent.Params = paramsContainer.require()
|
||||
private val scanResponse by lazy {
|
||||
getWalletsUseCase.invokeSync().first { it.walletId == params.userWalletId }.scanResponse
|
||||
}
|
||||
|
||||
init {
|
||||
subscribeOnUpdateState()
|
||||
|
|
@ -98,8 +106,14 @@ internal class OnrampTokenListModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: [REDACTED_JIRA]
|
||||
private fun List<CryptoCurrencyStatus>.filterByAvailability(): List<CryptoCurrencyStatus> {
|
||||
return this
|
||||
return filter {
|
||||
when (params.filterOperation) {
|
||||
OnrampOperation.BUY -> {
|
||||
rampStateManager.availableForBuy(scanResponse = scanResponse, cryptoCurrency = it.currency)
|
||||
}
|
||||
OnrampOperation.SELL -> rampStateManager.availableForSell(cryptoCurrency = it.currency)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue