Updated on 2026-08-14

This commit is contained in:
Tangem 2023-10-02 12:45:20 +03:00
parent 56590d9345
commit f6c6c5faed
6 changed files with 27 additions and 29 deletions

View file

@ -40,7 +40,6 @@ internal class DefaultNetworksRepository(
override fun getNetworkStatusesUpdates(
userWalletId: UserWalletId,
networks: Set<Network>,
refresh: Boolean,
): Flow<Set<NetworkStatus>> = channelFlow {
launch(dispatchers.io) {
networksStatusesStore.get(userWalletId)
@ -48,7 +47,7 @@ internal class DefaultNetworksRepository(
}
withContext(dispatchers.io) {
fetchNetworksStatusesIfCacheExpired(userWalletId, networks, refresh)
fetchNetworksStatusesIfCacheExpired(userWalletId, networks, false)
}
}.cancellable()

View file

@ -37,17 +37,15 @@ class GetCurrencyStatusUpdatesUseCase(
operator fun invoke(
userWalletId: UserWalletId,
currencyId: CryptoCurrency.ID,
refresh: Boolean,
): Flow<Either<CurrencyStatusError, CryptoCurrencyStatus>> {
return flow {
emitAll(getCurrency(userWalletId, currencyId, refresh))
emitAll(getCurrency(userWalletId, currencyId))
}.flowOn(dispatchers.io)
}
private suspend fun getCurrency(
userWalletId: UserWalletId,
currencyId: CryptoCurrency.ID,
refresh: Boolean,
): Flow<Either<CurrencyStatusError, CryptoCurrencyStatus>> {
val operations = CurrenciesStatusesOperations(
currenciesRepository = currenciesRepository,
@ -56,7 +54,7 @@ class GetCurrencyStatusUpdatesUseCase(
userWalletId = userWalletId,
)
return operations.getCurrencyStatusFlow(currencyId, refresh).map { maybeCurrency ->
return operations.getCurrencyStatusFlow(currencyId).map { maybeCurrency ->
maybeCurrency.mapLeft(CurrenciesStatusesOperations.Error::mapToCurrencyError)
}
}

View file

@ -67,16 +67,13 @@ internal class CurrenciesStatusesOperations(
}
}
suspend fun getCurrencyStatusFlow(
currencyId: CryptoCurrency.ID,
refresh: Boolean = false,
): Flow<Either<Error, CryptoCurrencyStatus>> {
suspend fun getCurrencyStatusFlow(currencyId: CryptoCurrency.ID): Flow<Either<Error, CryptoCurrencyStatus>> {
val currency = recover(
block = { getMultiCurrencyWalletCurrency(currencyId) },
recover = { return flowOf(it.left()) },
)
return getCurrencyStatusFlow(currency, refresh)
return getCurrencyStatusFlow(currency)
}
suspend fun getNetworkCoinFlow(networkId: Network.ID): Flow<Either<Error, CryptoCurrencyStatus>> {
@ -97,10 +94,7 @@ internal class CurrenciesStatusesOperations(
return getCurrencyStatusFlow(currency)
}
private fun getCurrencyStatusFlow(
currency: CryptoCurrency,
refresh: Boolean = false,
): Flow<Either<Error, CryptoCurrencyStatus>> {
private fun getCurrencyStatusFlow(currency: CryptoCurrency): Flow<Either<Error, CryptoCurrencyStatus>> {
val (networks, currenciesIds) = getIds(nonEmptyListOf(currency))
val quoteFlow = getQuotes(currenciesIds)
@ -111,7 +105,7 @@ internal class CurrenciesStatusesOperations(
}
}
val statusFlow = getNetworksStatuses(networks, refresh)
val statusFlow = getNetworksStatuses(networks)
.map { maybeStatuses ->
maybeStatuses.flatMap { statuses ->
statuses.singleOrNull { it.network == currency.network }?.right()
@ -210,11 +204,8 @@ internal class CurrenciesStatusesOperations(
.onEmpty { emit(Error.EmptyQuotes.left()) }
}
private fun getNetworksStatuses(
networks: NonEmptySet<Network>,
refresh: Boolean = false,
): Flow<Either<Error, Set<NetworkStatus>>> {
return networksRepository.getNetworkStatusesUpdates(userWalletId, networks, refresh)
private fun getNetworksStatuses(networks: NonEmptySet<Network>): Flow<Either<Error, Set<NetworkStatus>>> {
return networksRepository.getNetworkStatusesUpdates(userWalletId, networks)
.map<Set<NetworkStatus>, Either<Error, Set<NetworkStatus>>> { it.right() }
.catch { emit(Error.DataError(it).left()) }
.onEmpty { emit(Error.EmptyNetworksStatuses.left()) }

View file

@ -16,14 +16,9 @@ interface NetworksRepository {
*
* @param userWalletId The unique identifier of the user wallet.
* @param networks A set of network which statuses are to be retrieved.
* @param refresh A boolean flag indicating whether the data should be refreshed from remote.
* @return A [Flow] emitting a set of [NetworkStatus] objects corresponding to the specified networks.
*/
fun getNetworkStatusesUpdates(
userWalletId: UserWalletId,
networks: Set<Network>,
refresh: Boolean = false,
): Flow<Set<NetworkStatus>>
fun getNetworkStatusesUpdates(userWalletId: UserWalletId, networks: Set<Network>): Flow<Set<NetworkStatus>>
/**
* Retrieves network statuses of specified blockchain networks for a specific user wallet.

View file

@ -17,7 +17,6 @@ internal class MockNetworksRepository(
override fun getNetworkStatusesUpdates(
userWalletId: UserWalletId,
networks: Set<Network>,
refresh: Boolean,
): Flow<Set<NetworkStatus>> {
return statuses.map { it.getOrElse { e -> throw e } }
}

View file

@ -35,6 +35,7 @@ import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.coroutines.JobHolder
import com.tangem.utils.coroutines.saveIn
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import timber.log.Timber
@ -71,6 +72,7 @@ internal class TokenDetailsViewModel @Inject constructor(
private val marketPriceJobHolder = JobHolder()
private val refreshStateJobHolder = JobHolder()
private val networkStatusAutoUpdateStateJobHolder = JobHolder()
private var cryptoCurrencyStatus: CryptoCurrencyStatus? = null
private var wallet by Delegates.notNull<UserWallet>()
@ -148,7 +150,6 @@ internal class TokenDetailsViewModel @Inject constructor(
getCurrencyStatusUpdatesUseCase(
userWalletId = selectedWallet.walletId,
currencyId = cryptoCurrency.id,
refresh = true,
)
.distinctUntilChanged()
.onEach { either ->
@ -161,6 +162,17 @@ internal class TokenDetailsViewModel @Inject constructor(
.flowOn(dispatchers.io)
.launchIn(viewModelScope)
.saveIn(marketPriceJobHolder)
viewModelScope.launch(dispatchers.io) {
// Wait for blockchain updates pending transactions.
// Immediate update doesn't receive any changes.
delay(NETWORK_STATUS_AUTO_UPDATE_DELAY)
fetchCurrencyStatusUseCase.invoke(
userWalletId = wallet.walletId,
id = cryptoCurrency.id,
refresh = true,
)
}.saveIn(networkStatusAutoUpdateStateJobHolder)
}
private fun updateTxHistory(refresh: Boolean = false) {
@ -377,4 +389,8 @@ internal class TokenDetailsViewModel @Inject constructor(
override fun onCloseRentInfoNotification() {
uiState = stateFactory.getStateWithRemovedRentNotification()
}
companion object {
private const val NETWORK_STATUS_AUTO_UPDATE_DELAY = 1000L
}
}