Updated on 2026-08-14

This commit is contained in:
Tangem 2024-12-25 14:23:27 +05:00
commit f3e60c8771
7 changed files with 35 additions and 12 deletions

View file

@ -21,7 +21,7 @@ sealed interface OnrampProviderWithQuote {
val availablePaymentMethods: List<OnrampPaymentMethod>,
) : Unavailable
data class Error(
data class AmountError(
override val provider: OnrampProvider,
val quoteError: OnrampQuote.AmountError,
) : Unavailable

View file

@ -40,7 +40,7 @@ class GetOnrampProviderWithQuoteUseCase(
toAmount = matchedQuote.toAmount,
fromAmount = matchedQuote.fromAmount,
)
is OnrampQuote.AmountError -> Unavailable.Error(
is OnrampQuote.AmountError -> Unavailable.AmountError(
provider = matchedQuote.provider,
quoteError = matchedQuote,
)

View file

@ -76,10 +76,13 @@ internal class SelectProviderModel @Inject constructor(
val filteredEmptyMethods = methods.mapNotNull { method ->
val providers = getOnrampProviderWithQuoteUseCase(method).getOrNull()
if (!providers.isNullOrEmpty()) {
val allErrorProviders = providers.all {
it is OnrampProviderWithQuote.Unavailable.NotSupportedPaymentMethod
}
PaymentProviderUM(
paymentMethod = method,
providers = providers.toProvidersListItems(),
)
).takeIf { !allErrorProviders }
} else {
null
}
@ -225,7 +228,7 @@ internal class SelectProviderModel @Inject constructor(
},
)
}
is OnrampProviderWithQuote.Unavailable.Error -> {
is OnrampProviderWithQuote.Unavailable.AmountError -> {
val quoteError = quote.quoteError
val amount = quoteError.error.requiredAmount.format {
crypto(symbol = quoteError.fromAmount.symbol, decimals = quoteError.fromAmount.decimals)
@ -307,7 +310,7 @@ internal class SelectProviderModel @Inject constructor(
is OnrampProviderWithQuote.Data -> it.toAmount.value
// negative difference to sort both when data and unavailable is present
is OnrampProviderWithQuote.Unavailable.Error -> {
is OnrampProviderWithQuote.Unavailable.AmountError -> {
when (val error = it.quoteError.error) {
is OnrampError.AmountError.TooSmallError -> it.quoteError.fromAmount.value - error.requiredAmount
is OnrampError.AmountError.TooBigError -> error.requiredAmount - it.quoteError.fromAmount.value

View file

@ -15,6 +15,7 @@ dependencies {
/** AndroidX */
implementation(deps.androidx.activity.compose)
implementation(deps.androidx.paging.runtime)
implementation(deps.androidx.fragment.ktx)
/** Compose */
implementation(deps.compose.accompanist.systemUiController)

View file

@ -3,10 +3,9 @@ package com.tangem.feature.tokendetails.presentation
import android.os.Bundle
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.arkivanov.decompose.defaultComponentContext
import androidx.fragment.app.viewModels
import com.tangem.common.routing.AppRoute
import com.tangem.common.routing.AppRouter
import com.tangem.common.routing.bundle.unbundle
@ -47,6 +46,8 @@ internal class TokenDetailsFragment : ComposeFragment() {
@Inject
internal lateinit var appRouter: AppRouter
private val viewModel by viewModels<TokenDetailsViewModel>()
private var tokenMarketBlockComponent: TokenMarketBlockComponent? = null
private val internalTokenDetailsRouter: InnerTokenDetailsRouter
@ -57,6 +58,9 @@ internal class TokenDetailsFragment : ComposeFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel.router = internalTokenDetailsRouter
lifecycle.addObserver(viewModel)
val cryptoCurrency: CryptoCurrency = arguments
?.getBundle(AppRoute.CurrencyDetails.CRYPTO_CURRENCY_KEY)
?.unbundle(CryptoCurrency.serializer())
@ -86,9 +90,6 @@ internal class TokenDetailsFragment : ComposeFragment() {
@Composable
override fun ScreenContent(modifier: Modifier) {
val viewModel = hiltViewModel<TokenDetailsViewModel>()
viewModel.router = this@TokenDetailsFragment.internalTokenDetailsRouter
LocalLifecycleOwner.current.lifecycle.addObserver(viewModel)
NavigationBar3ButtonsScrim()
TokenDetailsScreen(
state = viewModel.uiState.collectAsStateWithLifecycle().value,

View file

@ -221,6 +221,17 @@ internal class TokenDetailsViewModel @Inject constructor(
handleBalanceHiding(owner)
}
override fun onPause(owner: LifecycleOwner) {
expressTxStatusTaskScheduler.cancelTask()
expressTxJobHolder.cancel()
super.onPause(owner)
}
override fun onResume(owner: LifecycleOwner) {
subscribeOnExpressTransactionsUpdates()
super.onResume(owner)
}
override fun onCleared() {
expressTxStatusTaskScheduler.cancelTask()
expressTxJobHolder.cancel()

View file

@ -79,6 +79,7 @@ internal class WalletViewModel @Inject constructor(
private lateinit var router: InnerWalletRouter
private val walletsUpdateJobHolder = JobHolder()
private val refreshWalletJobHolder = JobHolder()
private val expressStatusJobHolder = JobHolder()
private var needToRefreshWallet = false
private var expressTxStatusTaskScheduler = SingleTaskScheduler<Unit>()
@ -233,10 +234,16 @@ internal class WalletViewModel @Inject constructor(
private fun subscribeToScreenBackgroundState() {
screenLifecycleProvider.isBackgroundState
.onEach { isBackground ->
expressTxStatusTaskScheduler.cancelTask()
expressStatusJobHolder.cancel()
refreshWalletJobHolder.cancel()
when {
isBackground -> needToRefreshTimer()
needToRefreshWallet && !isBackground -> triggerRefreshWalletQuotes()
needToRefreshWallet && !isBackground -> {
triggerRefreshWalletQuotes()
subscribeOnExpressTransactionsUpdates()
}
!isBackground -> subscribeOnExpressTransactionsUpdates()
}
}
.launchIn(viewModelScope)
@ -257,7 +264,7 @@ internal class WalletViewModel @Inject constructor(
onError = { /* no-op */ },
),
)
}
}.saveIn(expressStatusJobHolder)
}
private fun needToRefreshTimer() {