diff --git a/domain/onramp/models/src/main/kotlin/com/tangem/domain/onramp/model/OnrampProviderWithQuote.kt b/domain/onramp/models/src/main/kotlin/com/tangem/domain/onramp/model/OnrampProviderWithQuote.kt index 2891d6072d..81a3c174d2 100644 --- a/domain/onramp/models/src/main/kotlin/com/tangem/domain/onramp/model/OnrampProviderWithQuote.kt +++ b/domain/onramp/models/src/main/kotlin/com/tangem/domain/onramp/model/OnrampProviderWithQuote.kt @@ -21,7 +21,7 @@ sealed interface OnrampProviderWithQuote { val availablePaymentMethods: List, ) : Unavailable - data class Error( + data class AmountError( override val provider: OnrampProvider, val quoteError: OnrampQuote.AmountError, ) : Unavailable diff --git a/domain/onramp/src/main/java/com/tangem/domain/onramp/GetOnrampProviderWithQuoteUseCase.kt b/domain/onramp/src/main/java/com/tangem/domain/onramp/GetOnrampProviderWithQuoteUseCase.kt index 1d6c6700d6..be975c49dd 100644 --- a/domain/onramp/src/main/java/com/tangem/domain/onramp/GetOnrampProviderWithQuoteUseCase.kt +++ b/domain/onramp/src/main/java/com/tangem/domain/onramp/GetOnrampProviderWithQuoteUseCase.kt @@ -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, ) diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/providers/model/SelectProviderModel.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/providers/model/SelectProviderModel.kt index e85759d361..bc077ed6a3 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/providers/model/SelectProviderModel.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/providers/model/SelectProviderModel.kt @@ -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 diff --git a/features/tokendetails/impl/build.gradle.kts b/features/tokendetails/impl/build.gradle.kts index 58596e7a24..cfaae5a6d2 100644 --- a/features/tokendetails/impl/build.gradle.kts +++ b/features/tokendetails/impl/build.gradle.kts @@ -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) diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/TokenDetailsFragment.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/TokenDetailsFragment.kt index 5b11ac88dd..3bd1955d4e 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/TokenDetailsFragment.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/TokenDetailsFragment.kt @@ -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() + 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() - viewModel.router = this@TokenDetailsFragment.internalTokenDetailsRouter - LocalLifecycleOwner.current.lifecycle.addObserver(viewModel) NavigationBar3ButtonsScrim() TokenDetailsScreen( state = viewModel.uiState.collectAsStateWithLifecycle().value, diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt index 3280261140..f0fedeec0a 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/viewmodels/TokenDetailsViewModel.kt @@ -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() diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt index 145ad36baa..b1dcff9ddd 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt @@ -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() @@ -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() {