From 06f2d51e87eaf7118caaf29748e8dc2ce0e253f3 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 29 Oct 2024 12:14:56 +0400 Subject: [PATCH] Updated on 2026-08-14 --- .../tangem/tap/routing/utils/ChildFactory.kt | 9 +++ .../com/tangem/common/routing/AppRoute.kt | 9 +-- .../GetSelectedAppCurrencyUseCase.kt | 9 +-- features/onramp/api/build.gradle.kts | 3 + .../onramp/component/BuyCryptoComponent.kt | 22 +++++++ features/onramp/impl/build.gradle.kts | 3 + .../onramp/buy/DefaultBuyCryptoComponent.kt | 65 +++++++++++++++++++ .../onramp/buy/di/BuyCryptoComponentModule.kt | 18 +++++ 8 files changed, 130 insertions(+), 8 deletions(-) create mode 100644 features/onramp/api/src/main/kotlin/com/tangem/features/onramp/component/BuyCryptoComponent.kt create mode 100644 features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/buy/DefaultBuyCryptoComponent.kt create mode 100644 features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/buy/di/BuyCryptoComponentModule.kt diff --git a/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt b/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt index cca2474fa1..06b53a8fd3 100644 --- a/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt +++ b/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt @@ -11,6 +11,7 @@ import com.tangem.features.disclaimer.api.components.DisclaimerComponent import com.tangem.features.managetokens.component.ManageTokensComponent import com.tangem.features.managetokens.component.ManageTokensSource import com.tangem.features.markets.details.MarketsTokenDetailsComponent +import com.tangem.features.onramp.component.BuyCryptoComponent import com.tangem.features.onramp.component.OnrampComponent import com.tangem.features.pushnotifications.api.navigation.PushNotificationsRouter import com.tangem.features.send.api.navigation.SendRouter @@ -48,6 +49,7 @@ internal class ChildFactory @Inject constructor( private val manageTokensComponentFactory: ManageTokensComponent.Factory, private val marketsTokenDetailsComponentFactory: MarketsTokenDetailsComponent.Factory, private val onrampComponentFactory: OnrampComponent.Factory, + private val buyCryptoComponentFactory: BuyCryptoComponent.Factory, private val sendRouter: SendRouter, private val tokenDetailsRouter: TokenDetailsRouter, private val walletRouter: WalletRouter, @@ -195,6 +197,13 @@ internal class ChildFactory @Inject constructor( componentFactory = onrampComponentFactory, ) } + is AppRoute.BuyCrypto -> { + route.asComponentChild( + contextProvider = contextProvider(route, contextFactory), + params = BuyCryptoComponent.Params(userWalletId = route.userWalletId), + componentFactory = buyCryptoComponentFactory, + ) + } } } diff --git a/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt b/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt index 94e8f8487c..c10a008033 100644 --- a/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt +++ b/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt @@ -117,10 +117,6 @@ sealed class AppRoute(val path: String) : Route { ) : AppRoute(path = "/details/security"), RouteBundleParams { override fun getBundle(): Bundle = bundle(serializer()) - - companion object { - const val USER_WALLET_ID_KEY = "userWalletId" - } } @Serializable @@ -291,4 +287,9 @@ sealed class AppRoute(val path: String) : Route { @Serializable data object Onramp : AppRoute(path = "/onramp") + + @Serializable + data class BuyCrypto( + val userWalletId: UserWalletId, + ) : AppRoute(path = "/buy_crypto/${userWalletId.stringValue}") } \ No newline at end of file diff --git a/domain/app-currency/src/main/kotlin/com/tangem/domain/appcurrency/GetSelectedAppCurrencyUseCase.kt b/domain/app-currency/src/main/kotlin/com/tangem/domain/appcurrency/GetSelectedAppCurrencyUseCase.kt index 4bd3a52e99..179973c048 100644 --- a/domain/app-currency/src/main/kotlin/com/tangem/domain/appcurrency/GetSelectedAppCurrencyUseCase.kt +++ b/domain/app-currency/src/main/kotlin/com/tangem/domain/appcurrency/GetSelectedAppCurrencyUseCase.kt @@ -6,10 +6,7 @@ import arrow.core.right import com.tangem.domain.appcurrency.error.SelectedAppCurrencyError import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.appcurrency.repository.AppCurrencyRepository -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.catch -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.onEmpty +import kotlinx.coroutines.flow.* class GetSelectedAppCurrencyUseCase( private val appCurrencyRepository: AppCurrencyRepository, @@ -21,4 +18,8 @@ class GetSelectedAppCurrencyUseCase( .catch { emit(SelectedAppCurrencyError.DataError(it).left()) } .onEmpty { emit(SelectedAppCurrencyError.NoAppCurrencySelected.left()) } } + + suspend fun invokeSync(): Either { + return invoke().firstOrNull() ?: SelectedAppCurrencyError.NoAppCurrencySelected.left() + } } \ No newline at end of file diff --git a/features/onramp/api/build.gradle.kts b/features/onramp/api/build.gradle.kts index a241d32468..cde16c9b92 100644 --- a/features/onramp/api/build.gradle.kts +++ b/features/onramp/api/build.gradle.kts @@ -14,6 +14,9 @@ dependencies { implementation(projects.core.decompose) implementation(projects.core.ui) + /* Project - Domain */ + implementation(projects.domain.wallets.models) + /* Compose */ implementation(deps.compose.runtime) } \ No newline at end of file diff --git a/features/onramp/api/src/main/kotlin/com/tangem/features/onramp/component/BuyCryptoComponent.kt b/features/onramp/api/src/main/kotlin/com/tangem/features/onramp/component/BuyCryptoComponent.kt new file mode 100644 index 0000000000..c627160e26 --- /dev/null +++ b/features/onramp/api/src/main/kotlin/com/tangem/features/onramp/component/BuyCryptoComponent.kt @@ -0,0 +1,22 @@ +package com.tangem.features.onramp.component + +import com.tangem.core.decompose.factory.ComponentFactory +import com.tangem.core.ui.decompose.ComposableContentComponent +import com.tangem.domain.wallets.models.UserWalletId + +/** + * Buy crypto component + * +[REDACTED_AUTHOR] + */ +interface BuyCryptoComponent : ComposableContentComponent { + + interface Factory : ComponentFactory + + /** + * Params + * + * @property userWalletId user wallet id + */ + data class Params(val userWalletId: UserWalletId) +} \ No newline at end of file diff --git a/features/onramp/impl/build.gradle.kts b/features/onramp/impl/build.gradle.kts index 8de571b7a7..042df5ae39 100644 --- a/features/onramp/impl/build.gradle.kts +++ b/features/onramp/impl/build.gradle.kts @@ -28,8 +28,10 @@ dependencies { implementation(projects.domain.appCurrency.models) implementation(projects.domain.balanceHiding) implementation(projects.domain.balanceHiding.models) + implementation(projects.domain.legacy) implementation(projects.domain.tokens) implementation(projects.domain.tokens.models) + implementation(projects.domain.wallets) implementation(projects.domain.wallets.models) /** DI */ @@ -54,5 +56,6 @@ dependencies { /** Other */ implementation(deps.decompose.ext.compose) implementation(deps.kotlin.immutable.collections) + implementation(deps.reKotlin) implementation(deps.timber) } \ No newline at end of file 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 new file mode 100644 index 0000000000..1c463d0cdf --- /dev/null +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/buy/DefaultBuyCryptoComponent.kt @@ -0,0 +1,65 @@ +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 dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject +import kotlinx.coroutines.launch + +@Stable +internal class DefaultBuyCryptoComponent @AssistedInject constructor( + onrampSelectTokenComponentFactory: OnrampSelectTokenComponent.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( + context = appComponentContext, + params = OnrampSelectTokenComponent.Params( + hasSearchBar = true, + userWalletId = params.userWalletId, + titleResId = R.string.common_buy, + onTokenClick = ::onTokenClick, + ), + ) + + @Composable + override fun Content(modifier: Modifier) { + 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 { + + override fun create(context: AppComponentContext, params: BuyCryptoComponent.Params): DefaultBuyCryptoComponent + } +} \ No newline at end of file diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/buy/di/BuyCryptoComponentModule.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/buy/di/BuyCryptoComponentModule.kt new file mode 100644 index 0000000000..d45a326a89 --- /dev/null +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/buy/di/BuyCryptoComponentModule.kt @@ -0,0 +1,18 @@ +package com.tangem.features.onramp.buy.di + +import com.tangem.features.onramp.buy.DefaultBuyCryptoComponent +import com.tangem.features.onramp.component.BuyCryptoComponent +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 BuyCryptoComponentModule { + + @Binds + @Singleton + fun bindBuyCryptoComponentFactory(factory: DefaultBuyCryptoComponent.Factory): BuyCryptoComponent.Factory +} \ No newline at end of file