From 101e609dec43ee0d38244f84dde7fd2f0679b6fc Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 30 Oct 2024 13:13:53 +0400 Subject: [PATCH] Updated on 2026-08-14 --- features/onramp/impl/build.gradle.kts | 1 + .../onramp/buy/DefaultBuyCryptoComponent.kt | 37 ++------ .../features/onramp/entity/OnrampOperation.kt | 12 +++ .../DefaultOnrampOperationComponent.kt | 84 +++++++++++++++++++ .../DefaultOnrampSelectTokenComponent.kt | 46 ---------- ...mponent.kt => OnrampOperationComponent.kt} | 15 ++-- .../di/OnrampOperationComponentModule.kt | 20 +++++ .../di/OnrampSelectTokenComponentModule.kt | 20 ----- .../onramp/sell/DefaultSellCryptoComponent.kt | 34 ++------ .../tokenlist/OnrampTokenListComponent.kt | 9 +- .../tokenlist/model/OnrampTokenListModel.kt | 18 +++- 11 files changed, 157 insertions(+), 139 deletions(-) create mode 100644 features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/entity/OnrampOperation.kt create mode 100644 features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/DefaultOnrampOperationComponent.kt delete mode 100644 features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/DefaultOnrampSelectTokenComponent.kt rename features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/{OnrampSelectTokenComponent.kt => OnrampOperationComponent.kt} (53%) create mode 100644 features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/di/OnrampOperationComponentModule.kt delete mode 100644 features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/di/OnrampSelectTokenComponentModule.kt diff --git a/features/onramp/impl/build.gradle.kts b/features/onramp/impl/build.gradle.kts index 042df5ae39..1ff3b4c39c 100644 --- a/features/onramp/impl/build.gradle.kts +++ b/features/onramp/impl/build.gradle.kts @@ -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) diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/buy/DefaultBuyCryptoComponent.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/buy/DefaultBuyCryptoComponent.kt index 1c463d0cdf..f8b1be4d51 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/buy/DefaultBuyCryptoComponent.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/buy/DefaultBuyCryptoComponent.kt @@ -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 { diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/entity/OnrampOperation.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/entity/OnrampOperation.kt new file mode 100644 index 0000000000..1a94304325 --- /dev/null +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/entity/OnrampOperation.kt @@ -0,0 +1,12 @@ +package com.tangem.features.onramp.entity + +/** + * Onramp operation + * +[REDACTED_AUTHOR] + */ +internal enum class OnrampOperation { + BUY, + SELL, + ; +} \ No newline at end of file diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/DefaultOnrampOperationComponent.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/DefaultOnrampOperationComponent.kt new file mode 100644 index 0000000000..429df40cb5 --- /dev/null +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/DefaultOnrampOperationComponent.kt @@ -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 + } +} \ No newline at end of file diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/DefaultOnrampSelectTokenComponent.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/DefaultOnrampSelectTokenComponent.kt deleted file mode 100644 index 50ec027209..0000000000 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/DefaultOnrampSelectTokenComponent.kt +++ /dev/null @@ -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 - } -} \ No newline at end of file diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/OnrampSelectTokenComponent.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/OnrampOperationComponent.kt similarity index 53% rename from features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/OnrampSelectTokenComponent.kt rename to features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/OnrampOperationComponent.kt index 69aa520462..3f6b4fc489 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/OnrampSelectTokenComponent.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/OnrampOperationComponent.kt @@ -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 + interface Factory : ComponentFactory /** * 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, ) } \ No newline at end of file diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/di/OnrampOperationComponentModule.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/di/OnrampOperationComponentModule.kt new file mode 100644 index 0000000000..b15e75f360 --- /dev/null +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/di/OnrampOperationComponentModule.kt @@ -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 +} \ No newline at end of file diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/di/OnrampSelectTokenComponentModule.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/di/OnrampSelectTokenComponentModule.kt deleted file mode 100644 index 01bece010d..0000000000 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/selecttoken/di/OnrampSelectTokenComponentModule.kt +++ /dev/null @@ -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 -} \ No newline at end of file diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/sell/DefaultSellCryptoComponent.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/sell/DefaultSellCryptoComponent.kt index b1a3589e6c..ffba48a738 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/sell/DefaultSellCryptoComponent.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/sell/DefaultSellCryptoComponent.kt @@ -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 { diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/OnrampTokenListComponent.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/OnrampTokenListComponent.kt index 8b924c893e..bcb5ab848a 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/OnrampTokenListComponent.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/OnrampTokenListComponent.kt @@ -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, diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/model/OnrampTokenListModel.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/model/OnrampTokenListModel.kt index efbb04ac25..fc6329296f 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/model/OnrampTokenListModel.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/model/OnrampTokenListModel.kt @@ -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 = 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.filterByAvailability(): List { - return this + return filter { + when (params.filterOperation) { + OnrampOperation.BUY -> { + rampStateManager.availableForBuy(scanResponse = scanResponse, cryptoCurrency = it.currency) + } + OnrampOperation.SELL -> rampStateManager.availableForSell(cryptoCurrency = it.currency) + } + } } } \ No newline at end of file