Updated on 2026-08-14
This commit is contained in:
parent
e87d946e40
commit
a3a18854c8
48 changed files with 544 additions and 328 deletions
|
|
@ -4,10 +4,12 @@ import com.tangem.core.decompose.factory.ComponentFactory
|
|||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||
import com.tangem.domain.onramp.model.OnrampCountry
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
|
||||
internal interface ConfirmResidencyComponent : ComposableBottomSheetComponent {
|
||||
|
||||
data class Params(
|
||||
val userWalletId: UserWalletId,
|
||||
val cryptoCurrency: CryptoCurrency,
|
||||
val country: OnrampCountry,
|
||||
val onDismiss: () -> Unit,
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ internal class DefaultConfirmResidencyComponent @AssistedInject constructor(
|
|||
is ConfirmResidencyBottomSheetConfig.SelectCountry -> selectCountryComponentFactory.create(
|
||||
context = childByContext(componentContext),
|
||||
params = SelectCountryComponent.Params(
|
||||
userWalletId = params.userWalletId,
|
||||
cryptoCurrency = params.cryptoCurrency,
|
||||
onDismiss = { isCountrySelected ->
|
||||
// Dismiss country select sheet
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ internal class DefaultOnrampMainComponent @AssistedInject constructor(
|
|||
is OnrampMainBottomSheetConfig.ConfirmResidency -> confirmResidencyComponentFactory.create(
|
||||
context = childByContext(componentContext),
|
||||
params = ConfirmResidencyComponent.Params(
|
||||
userWalletId = params.userWalletId,
|
||||
cryptoCurrency = params.cryptoCurrency,
|
||||
country = config.country,
|
||||
onDismiss = {
|
||||
|
|
@ -65,6 +66,7 @@ internal class DefaultOnrampMainComponent @AssistedInject constructor(
|
|||
is OnrampMainBottomSheetConfig.CurrenciesList -> selectCurrencyComponentFactory.create(
|
||||
context = childByContext(componentContext),
|
||||
params = SelectCurrencyComponent.Params(
|
||||
userWallet = model.userWallet,
|
||||
cryptoCurrency = params.cryptoCurrency,
|
||||
onDismiss = model.bottomSheetNavigation::dismiss,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -57,6 +57,9 @@ internal class OnrampMainComponentModel @Inject constructor(
|
|||
) : Model(), OnrampIntents {
|
||||
|
||||
private val params: OnrampMainComponent.Params = paramsContainer.require()
|
||||
|
||||
val userWallet = getWalletsUseCase.invokeSync().first { it.walletId == params.userWalletId }
|
||||
|
||||
private val stateFactory = OnrampStateFactory(
|
||||
currentStateProvider = Provider { _state.value },
|
||||
cryptoCurrency = params.cryptoCurrency,
|
||||
|
|
@ -68,7 +71,6 @@ internal class OnrampMainComponentModel @Inject constructor(
|
|||
onrampIntents = this,
|
||||
cryptoCurrency = params.cryptoCurrency,
|
||||
)
|
||||
private val selectedUserWallet = getWalletsUseCase.invokeSync().first { it.walletId == params.userWalletId }
|
||||
private val _state: MutableStateFlow<OnrampMainComponentUM> = MutableStateFlow(
|
||||
value = stateFactory.getInitialState(
|
||||
currency = params.cryptoCurrency.name,
|
||||
|
|
@ -107,7 +109,7 @@ internal class OnrampMainComponentModel @Inject constructor(
|
|||
|
||||
private fun checkResidenceCountry() {
|
||||
modelScope.launch {
|
||||
checkOnrampAvailabilityUseCase()
|
||||
checkOnrampAvailabilityUseCase(userWallet)
|
||||
.onRight(::handleOnrampAvailability)
|
||||
.onLeft(::handleOnrampError)
|
||||
}
|
||||
|
|
@ -158,7 +160,7 @@ internal class OnrampMainComponentModel @Inject constructor(
|
|||
if (!state?.amountBlockState?.amountFieldModel?.fiatValue.isNullOrEmpty()) {
|
||||
_state.update { amountStateFactory.getAmountSecondaryLoadingState() }
|
||||
}
|
||||
fetchPairsUseCase.invoke(params.cryptoCurrency).fold(
|
||||
fetchPairsUseCase.invoke(userWallet, params.cryptoCurrency).fold(
|
||||
ifLeft = ::handleOnrampError,
|
||||
ifRight = { _state.update { amountStateFactory.getAmountSecondaryResetState() } },
|
||||
)
|
||||
|
|
@ -184,6 +186,7 @@ internal class OnrampMainComponentModel @Inject constructor(
|
|||
val content = state.value as? OnrampMainComponentUM.Content ?: return@runCatching
|
||||
if (content.amountBlockState.amountFieldModel.fiatAmount.value.isNullOrZero()) return@runCatching
|
||||
fetchQuotesUseCase.invoke(
|
||||
userWallet = userWallet,
|
||||
amount = content.amountBlockState.amountFieldModel.fiatAmount,
|
||||
cryptoCurrency = params.cryptoCurrency,
|
||||
).onLeft(::handleOnrampError)
|
||||
|
|
@ -216,7 +219,7 @@ internal class OnrampMainComponentModel @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onBuyClick(quote: OnrampProviderWithQuote.Data) {
|
||||
if (isDemoCardUseCase.invoke(selectedUserWallet.cardId)) {
|
||||
if (isDemoCardUseCase.invoke(userWallet.cardId)) {
|
||||
showDemoWarning()
|
||||
} else {
|
||||
val currentContentState = state.value as? OnrampMainComponentUM.Content ?: return
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import com.tangem.core.ui.extensions.wrappedList
|
|||
import com.tangem.core.ui.message.DialogMessage
|
||||
import com.tangem.domain.onramp.GetOnrampRedirectUrlUseCase
|
||||
import com.tangem.domain.onramp.model.error.OnrampError
|
||||
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
|
||||
import com.tangem.features.onramp.impl.R
|
||||
import com.tangem.features.onramp.redirect.OnrampRedirectComponent
|
||||
import com.tangem.features.onramp.redirect.entity.OnrampRedirectTopBarUM
|
||||
|
|
@ -29,6 +30,7 @@ internal class OnrampRedirectModel @Inject constructor(
|
|||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val urlOpener: UrlOpener,
|
||||
private val getOnrampRedirectUrlUseCase: GetOnrampRedirectUrlUseCase,
|
||||
private val getWalletsUseCase: GetWalletsUseCase,
|
||||
private val messageSender: UiMessageSender,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
router: Router,
|
||||
|
|
@ -36,6 +38,8 @@ internal class OnrampRedirectModel @Inject constructor(
|
|||
) : Model() {
|
||||
|
||||
private val params: OnrampRedirectComponent.Params = paramsContainer.require()
|
||||
private val selectedUserWallet = getWalletsUseCase.invokeSync().first { it.walletId == params.userWalletId }
|
||||
|
||||
val state = OnrampRedirectUM(
|
||||
topBarConfig = OnrampRedirectTopBarUM(
|
||||
title = combinedReference(
|
||||
|
|
@ -62,7 +66,7 @@ internal class OnrampRedirectModel @Inject constructor(
|
|||
fun getRedirectUrl(isDarkTheme: Boolean) {
|
||||
modelScope.launch {
|
||||
getOnrampRedirectUrlUseCase.invoke(
|
||||
userWalletId = params.userWalletId,
|
||||
userWallet = selectedUserWallet,
|
||||
quote = params.onrampProviderWithQuote,
|
||||
cryptoCurrency = params.cryptoCurrency,
|
||||
isDarkTheme = isDarkTheme,
|
||||
|
|
|
|||
|
|
@ -61,8 +61,9 @@ internal class DefaultOnrampComponent @AssistedInject constructor(
|
|||
OnrampChild.Settings -> settingsComponentFactory.create(
|
||||
context = childByContext(componentContext),
|
||||
params = OnrampSettingsComponent.Params(
|
||||
params.cryptoCurrency,
|
||||
navigation::pop,
|
||||
userWalletId = params.userWalletId,
|
||||
cryptoCurrency = params.cryptoCurrency,
|
||||
onBack = navigation::pop,
|
||||
),
|
||||
)
|
||||
OnrampChild.Main -> onrampMainComponentFactory.create(
|
||||
|
|
|
|||
|
|
@ -3,10 +3,15 @@ package com.tangem.features.onramp.selectcountry
|
|||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
|
||||
internal interface SelectCountryComponent : ComposableBottomSheetComponent {
|
||||
|
||||
data class Params(val cryptoCurrency: CryptoCurrency, val onDismiss: (Boolean) -> Unit)
|
||||
data class Params(
|
||||
val userWalletId: UserWalletId,
|
||||
val cryptoCurrency: CryptoCurrency,
|
||||
val onDismiss: (Boolean) -> Unit,
|
||||
)
|
||||
|
||||
interface Factory : ComponentFactory<Params, SelectCountryComponent>
|
||||
}
|
||||
|
|
@ -13,6 +13,7 @@ import com.tangem.domain.onramp.GetOnrampCountryUseCase
|
|||
import com.tangem.domain.onramp.OnrampSaveDefaultCountryUseCase
|
||||
import com.tangem.domain.onramp.analytics.OnrampAnalyticsEvent
|
||||
import com.tangem.domain.onramp.model.OnrampCountry
|
||||
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
|
||||
import com.tangem.features.onramp.impl.R
|
||||
import com.tangem.features.onramp.selectcountry.SelectCountryComponent
|
||||
import com.tangem.features.onramp.selectcountry.entity.CountryItemState
|
||||
|
|
@ -44,11 +45,15 @@ internal class OnrampSelectCountryModel @Inject constructor(
|
|||
private val saveDefaultCountryUseCase: OnrampSaveDefaultCountryUseCase,
|
||||
private val getOnrampCountryUseCase: GetOnrampCountryUseCase,
|
||||
private val fetchOnrampCountriesUseCase: FetchOnrampCountriesUseCase,
|
||||
getWalletsUseCase: GetWalletsUseCase,
|
||||
paramsContainer: ParamsContainer,
|
||||
) : Model() {
|
||||
|
||||
val state: StateFlow<CountryListUM> get() = controller.state
|
||||
private val params: SelectCountryComponent.Params = paramsContainer.require()
|
||||
private val userWallet = getWalletsUseCase.invokeSync().first { it.walletId == params.userWalletId }
|
||||
|
||||
val state: StateFlow<CountryListUM> get() = controller.state
|
||||
|
||||
private val controller = CountryListUMController(
|
||||
searchBarUM = createSearchBarUM(),
|
||||
loadingItems = loadingItems,
|
||||
|
|
@ -103,7 +108,7 @@ internal class OnrampSelectCountryModel @Inject constructor(
|
|||
|
||||
private fun updateCountriesList() {
|
||||
modelScope.launch {
|
||||
fetchOnrampCountriesUseCase().onLeft {
|
||||
fetchOnrampCountriesUseCase(userWallet).onLeft {
|
||||
controller.update(UpdateCountryItemsErrorTransformer(onRetry = ::onRetry))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,10 +3,15 @@ package com.tangem.features.onramp.selectcurrency
|
|||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
|
||||
internal interface SelectCurrencyComponent : ComposableBottomSheetComponent {
|
||||
|
||||
data class Params(val cryptoCurrency: CryptoCurrency, val onDismiss: () -> Unit)
|
||||
data class Params(
|
||||
val userWallet: UserWallet,
|
||||
val cryptoCurrency: CryptoCurrency,
|
||||
val onDismiss: () -> Unit,
|
||||
)
|
||||
|
||||
interface Factory : ComponentFactory<Params, SelectCurrencyComponent>
|
||||
}
|
||||
|
|
@ -97,7 +97,7 @@ internal class OnrampSelectCurrencyModel @Inject constructor(
|
|||
|
||||
private fun updateCurrenciesList() {
|
||||
modelScope.launch {
|
||||
fetchOnrampCurrenciesUseCase().onLeft {
|
||||
fetchOnrampCurrenciesUseCase(userWallet = params.userWallet).onLeft {
|
||||
controller.update(UpdateCurrencyItemsErrorTransformer(onRetry = ::onRetry))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,8 @@ internal class DefaultOnrampSettingsComponent @AssistedInject constructor(
|
|||
OnrampSettingsConfig.SelectCountry -> selectCountryComponentFactory.create(
|
||||
context = childByContext(componentContext),
|
||||
params = SelectCountryComponent.Params(
|
||||
params.cryptoCurrency,
|
||||
userWalletId = params.userWalletId,
|
||||
cryptoCurrency = params.cryptoCurrency,
|
||||
onDismiss = { model.bottomSheetNavigation.dismiss() },
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -3,10 +3,15 @@ package com.tangem.features.onramp.settings
|
|||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
|
||||
internal interface OnrampSettingsComponent : ComposableContentComponent {
|
||||
|
||||
data class Params(val cryptoCurrency: CryptoCurrency, val onBack: () -> Unit)
|
||||
data class Params(
|
||||
val userWalletId: UserWalletId,
|
||||
val cryptoCurrency: CryptoCurrency,
|
||||
val onBack: () -> Unit,
|
||||
)
|
||||
|
||||
interface Factory : ComponentFactory<Params, OnrampSettingsComponent>
|
||||
}
|
||||
|
|
@ -97,7 +97,7 @@ internal class OnrampSuccessComponentModel @Inject constructor(
|
|||
return
|
||||
}
|
||||
|
||||
getOnrampStatusUseCase(txId = transaction.txId)
|
||||
getOnrampStatusUseCase(userWallet = userWallet, txId = transaction.txId)
|
||||
.fold(
|
||||
ifLeft = { error ->
|
||||
analyticsEventHandler.sendOnrampErrorEvent(
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import com.tangem.domain.tokens.GetTokenListUseCase
|
|||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.tokens.model.TokenList
|
||||
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
|
||||
import com.tangem.feature.swap.domain.GetAvailablePairsUseCase
|
||||
import com.tangem.feature.swap.domain.models.domain.LeastTokenInfo
|
||||
import com.tangem.feature.swap.domain.models.domain.SwapPairLeast
|
||||
|
|
@ -52,11 +53,13 @@ internal class AvailableSwapPairsModel @Inject constructor(
|
|||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||
private val getAvailablePairsUseCase: GetAvailablePairsUseCase,
|
||||
private val getWalletsUseCase: GetWalletsUseCase,
|
||||
) : Model() {
|
||||
|
||||
val state: StateFlow<TokenListUM> = tokenListUMController.state
|
||||
|
||||
private var params: AvailableSwapPairsComponent.Params = paramsContainer.require()
|
||||
private val userWallet = getWalletsUseCase.invokeSync().first { it.walletId == params.userWalletId }
|
||||
|
||||
private val tokenListFlow = getTokenListUseCaseFlow()
|
||||
|
||||
|
|
@ -212,6 +215,7 @@ internal class AvailableSwapPairsModel @Inject constructor(
|
|||
availablePairsByNetworkFlow.update(networkInfo = networkInfo, state = lceLoading())
|
||||
|
||||
getAvailablePairsUseCase(
|
||||
userWallet = userWallet,
|
||||
initialCurrency = networkInfo,
|
||||
currencies = statuses.map(CryptoCurrencyStatus::currency),
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue