Updated on 2026-08-14
This commit is contained in:
parent
6901522cf7
commit
a61cb65789
13 changed files with 89 additions and 62 deletions
|
|
@ -231,7 +231,7 @@ class TokenItemStateConverter(
|
|||
useAccentColor = true,
|
||||
).let(::add)
|
||||
}
|
||||
if (status.value.getStatusSource() == StatusSource.ONLY_CACHE) {
|
||||
if (status.value.sources.total == StatusSource.ONLY_CACHE) {
|
||||
TokenItemState.FiatAmountState.Content.IconUM(
|
||||
iconRes = R.drawable.ic_error_sync_24,
|
||||
useAccentColor = false,
|
||||
|
|
@ -274,14 +274,6 @@ class TokenItemStateConverter(
|
|||
return PriceChangeConverter.fromBigDecimal(value = this)
|
||||
}
|
||||
|
||||
fun CryptoCurrencyStatus.Value.isFlickering(): Boolean = getStatusSource() == StatusSource.CACHE
|
||||
|
||||
private fun CryptoCurrencyStatus.Value.getStatusSource(): StatusSource? {
|
||||
return when (this) {
|
||||
is CryptoCurrencyStatus.Loaded -> source
|
||||
is CryptoCurrencyStatus.NoAccount -> source
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
fun CryptoCurrencyStatus.Value.isFlickering(): Boolean = sources.total == StatusSource.CACHE
|
||||
}
|
||||
}
|
||||
|
|
@ -21,6 +21,10 @@ enum class StatusSource {
|
|||
|
||||
/** Status is loaded from the cache and can't be updated with actual value */
|
||||
ONLY_CACHE,
|
||||
|
||||
;
|
||||
|
||||
fun isActual() = this == ACTUAL
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.domain.tokens.model
|
||||
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.getResultStatusSource
|
||||
import com.tangem.domain.staking.model.stakekit.YieldBalance
|
||||
import com.tangem.domain.txhistory.models.TxHistoryItem
|
||||
import java.math.BigDecimal
|
||||
|
|
@ -51,7 +52,19 @@ data class CryptoCurrencyStatus(
|
|||
/** Staking yield balance */
|
||||
open val yieldBalance: YieldBalance? = null
|
||||
|
||||
open val source: StatusSource = StatusSource.ACTUAL
|
||||
/** Sources */
|
||||
open val sources: Sources = Sources()
|
||||
}
|
||||
|
||||
data class Sources(
|
||||
val networkSource: StatusSource = StatusSource.ACTUAL,
|
||||
val quoteSource: StatusSource = StatusSource.ACTUAL,
|
||||
val yieldBalanceSource: StatusSource = StatusSource.ACTUAL,
|
||||
) {
|
||||
|
||||
val total: StatusSource by lazy {
|
||||
listOf(networkSource, quoteSource, yieldBalanceSource).getResultStatusSource()
|
||||
}
|
||||
}
|
||||
|
||||
/** Represents the Loading state of a cryptocurrency, typically while fetching its details. */
|
||||
|
|
@ -86,7 +99,7 @@ data class CryptoCurrencyStatus(
|
|||
* Represents a state where there is no account associated with the cryptocurrency
|
||||
*
|
||||
* @property amountToCreateAccount base reserve amount for account creation
|
||||
* @property source source of data
|
||||
* @property sources sources of data
|
||||
*/
|
||||
data class NoAccount(
|
||||
val amountToCreateAccount: BigDecimal,
|
||||
|
|
@ -94,7 +107,7 @@ data class CryptoCurrencyStatus(
|
|||
override val priceChange: BigDecimal?,
|
||||
override val fiatRate: BigDecimal?,
|
||||
override val networkAddress: NetworkAddress,
|
||||
override val source: StatusSource,
|
||||
override val sources: Sources,
|
||||
) : Value(isError = false) {
|
||||
|
||||
override val amount: BigDecimal = BigDecimal.ZERO
|
||||
|
|
@ -110,7 +123,7 @@ data class CryptoCurrencyStatus(
|
|||
* @property hasCurrentNetworkTransactions Indicates if there are any transactions in progress related to the
|
||||
* cryptocurrency network.
|
||||
* @property pendingTransactions The current cryptocurrency transactions.
|
||||
* @property source source of data
|
||||
* @property sources sources of data
|
||||
*/
|
||||
data class Loaded(
|
||||
override val amount: BigDecimal,
|
||||
|
|
@ -121,7 +134,7 @@ data class CryptoCurrencyStatus(
|
|||
override val hasCurrentNetworkTransactions: Boolean,
|
||||
override val pendingTransactions: Set<TxHistoryItem>,
|
||||
override val networkAddress: NetworkAddress,
|
||||
override val source: StatusSource,
|
||||
override val sources: Sources,
|
||||
) : Value(isError = false)
|
||||
|
||||
/**
|
||||
|
|
@ -144,7 +157,7 @@ data class CryptoCurrencyStatus(
|
|||
override val hasCurrentNetworkTransactions: Boolean,
|
||||
override val pendingTransactions: Set<TxHistoryItem>,
|
||||
override val networkAddress: NetworkAddress,
|
||||
override val source: StatusSource,
|
||||
override val sources: Sources,
|
||||
) : Value(isError = false)
|
||||
|
||||
/**
|
||||
|
|
@ -161,8 +174,6 @@ data class CryptoCurrencyStatus(
|
|||
override val hasCurrentNetworkTransactions: Boolean,
|
||||
override val pendingTransactions: Set<TxHistoryItem>,
|
||||
override val networkAddress: NetworkAddress,
|
||||
) : Value(isError = false) {
|
||||
|
||||
override val source: StatusSource = StatusSource.CACHE
|
||||
}
|
||||
override val sources: Sources,
|
||||
) : Value(isError = false)
|
||||
}
|
||||
|
|
@ -122,7 +122,7 @@ class GetCryptoCurrencyActionsUseCase(
|
|||
return getActionsForUnreachableCurrency(userWallet, cryptoCurrencyStatus, requirements)
|
||||
}
|
||||
|
||||
if (cryptoCurrencyStatus.value.source != StatusSource.ACTUAL) {
|
||||
if (cryptoCurrencyStatus.value.sources.total != StatusSource.ACTUAL) {
|
||||
return getActionsForOutdatedData(userWallet, cryptoCurrencyStatus, requirements)
|
||||
}
|
||||
|
||||
|
|
@ -289,9 +289,17 @@ class GetCryptoCurrencyActionsUseCase(
|
|||
}
|
||||
|
||||
// swap
|
||||
val isSwapAvailable = with(cryptoCurrencyStatus.value.sources) {
|
||||
quoteSource.isActual() && networkSource.isActual()
|
||||
}
|
||||
|
||||
activeList.add(
|
||||
TokenActionsState.ActionState.Swap(
|
||||
unavailabilityReason = ScenarioUnavailabilityReason.UsedOutdatedData,
|
||||
unavailabilityReason = if (isSwapAvailable) {
|
||||
ScenarioUnavailabilityReason.None
|
||||
} else {
|
||||
ScenarioUnavailabilityReason.UsedOutdatedData
|
||||
},
|
||||
showBadge = false,
|
||||
),
|
||||
)
|
||||
|
|
@ -313,7 +321,17 @@ class GetCryptoCurrencyActionsUseCase(
|
|||
activeList.add(TokenActionsState.ActionState.Stake(ScenarioUnavailabilityReason.UsedOutdatedData, null))
|
||||
|
||||
// send
|
||||
activeList.add(TokenActionsState.ActionState.Send(ScenarioUnavailabilityReason.UsedOutdatedData))
|
||||
val isSendAvailable = cryptoCurrencyStatus.value.sources.networkSource.isActual()
|
||||
|
||||
activeList.add(
|
||||
TokenActionsState.ActionState.Send(
|
||||
unavailabilityReason = if (isSendAvailable) {
|
||||
ScenarioUnavailabilityReason.None
|
||||
} else {
|
||||
ScenarioUnavailabilityReason.UsedOutdatedData
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
// region sell
|
||||
activeList.add(TokenActionsState.ActionState.Sell(ScenarioUnavailabilityReason.UsedOutdatedData))
|
||||
|
|
|
|||
|
|
@ -138,7 +138,9 @@ class GetCurrencyWarningsUseCase(
|
|||
}
|
||||
|
||||
private fun getUsedOutdatedDataWarning(status: CryptoCurrencyStatus): CryptoCurrencyWarning? {
|
||||
return CryptoCurrencyWarning.UsedOutdatedDataWarning.takeIf { status.value.source == StatusSource.ONLY_CACHE }
|
||||
return CryptoCurrencyWarning.UsedOutdatedDataWarning.takeIf {
|
||||
status.value.sources.total == StatusSource.ONLY_CACHE
|
||||
}
|
||||
}
|
||||
|
||||
private fun getIsBetaTokensWarning(currency: CryptoCurrency): CryptoCurrencyWarning? {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package com.tangem.domain.tokens.operations
|
||||
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.getResultStatusSource
|
||||
import com.tangem.domain.staking.model.stakekit.YieldBalance
|
||||
import com.tangem.domain.tokens.model.*
|
||||
import java.math.BigDecimal
|
||||
|
|
@ -56,14 +55,14 @@ internal class CurrencyStatusOperations(
|
|||
priceChange = quote?.priceChange,
|
||||
fiatRate = quote?.fiatRate,
|
||||
networkAddress = status.address,
|
||||
source = listOf(
|
||||
status.source,
|
||||
(quote as? Quote.Value)?.source ?: StatusSource.ACTUAL,
|
||||
).getResultStatusSource(),
|
||||
sources = CryptoCurrencyStatus.Sources(
|
||||
networkSource = status.source,
|
||||
quoteSource = (quote as? Quote.Value)?.source ?: StatusSource.ACTUAL,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("CyclomaticComplexMethod")
|
||||
@Suppress("CyclomaticComplexMethod", "LongMethod")
|
||||
private fun createStatus(
|
||||
networkStatusValue: NetworkStatus.Verified,
|
||||
yieldBalance: YieldBalance?,
|
||||
|
|
@ -105,11 +104,11 @@ internal class CurrencyStatusOperations(
|
|||
pendingTransactions = currentTransactions,
|
||||
networkAddress = networkStatusValue.address,
|
||||
yieldBalance = currentYieldBalance,
|
||||
source = listOfNotNull(
|
||||
networkStatusValue.source,
|
||||
currentYieldBalance?.source ?: StatusSource.ACTUAL,
|
||||
(quote as? Quote.Value)?.source ?: StatusSource.ACTUAL,
|
||||
).getResultStatusSource(),
|
||||
sources = CryptoCurrencyStatus.Sources(
|
||||
networkSource = networkStatusValue.source,
|
||||
quoteSource = (quote as? Quote.Value)?.source ?: StatusSource.ACTUAL,
|
||||
yieldBalanceSource = currentYieldBalance?.source ?: StatusSource.ACTUAL,
|
||||
),
|
||||
)
|
||||
quote is Quote.Empty || ignoreQuote -> CryptoCurrencyStatus.NoQuote(
|
||||
amount = amount,
|
||||
|
|
@ -117,6 +116,11 @@ internal class CurrencyStatusOperations(
|
|||
pendingTransactions = currentTransactions,
|
||||
networkAddress = networkStatusValue.address,
|
||||
yieldBalance = currentYieldBalance,
|
||||
sources = CryptoCurrencyStatus.Sources(
|
||||
networkSource = networkStatusValue.source,
|
||||
quoteSource = (quote as? Quote.Value)?.source ?: StatusSource.ACTUAL,
|
||||
yieldBalanceSource = currentYieldBalance?.source ?: StatusSource.ACTUAL,
|
||||
),
|
||||
)
|
||||
quote is Quote.Value -> CryptoCurrencyStatus.Loaded(
|
||||
amount = amount,
|
||||
|
|
@ -127,11 +131,11 @@ internal class CurrencyStatusOperations(
|
|||
pendingTransactions = currentTransactions,
|
||||
networkAddress = networkStatusValue.address,
|
||||
yieldBalance = currentYieldBalance,
|
||||
source = listOf(
|
||||
networkStatusValue.source,
|
||||
currentYieldBalance?.source ?: StatusSource.ACTUAL,
|
||||
quote.source,
|
||||
).getResultStatusSource(),
|
||||
sources = CryptoCurrencyStatus.Sources(
|
||||
networkSource = networkStatusValue.source,
|
||||
quoteSource = quote.source,
|
||||
yieldBalanceSource = currentYieldBalance?.source ?: StatusSource.ACTUAL,
|
||||
),
|
||||
)
|
||||
else -> CryptoCurrencyStatus.Loading
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ internal class TokenListFiatBalanceOperations(
|
|||
}
|
||||
|
||||
return (fiatBalance as? TotalFiatBalance.Loaded)?.copy(
|
||||
source = currencies.map { it.value.source }.getResultStatusSource(),
|
||||
source = currencies.map { it.value.sources.total }.getResultStatusSource(),
|
||||
) ?: fiatBalance
|
||||
}
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ internal class TokenListFiatBalanceOperations(
|
|||
?: TotalFiatBalance.Loaded(
|
||||
amount = BigDecimal.ZERO,
|
||||
isAllAmountsSummarized = false,
|
||||
source = (status as? CryptoCurrencyStatus.NoAccount)?.source ?: StatusSource.ACTUAL,
|
||||
source = (status as? CryptoCurrencyStatus.NoAccount)?.sources?.total ?: StatusSource.ACTUAL,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -85,7 +85,7 @@ internal class TokenListFiatBalanceOperations(
|
|||
) ?: TotalFiatBalance.Loaded(
|
||||
amount = status.fiatAmount + fiatStakingBalance,
|
||||
isAllAmountsSummarized = true,
|
||||
source = status.source,
|
||||
source = status.sources.total,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ internal class GetPrimaryCurrencyStatusUpdatesUseCaseTest {
|
|||
defaultAddress = NetworkAddress.Address(value = "mock", NetworkAddress.Address.Type.Primary),
|
||||
),
|
||||
yieldBalance = null,
|
||||
sources = CryptoCurrencyStatus.Sources(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package com.tangem.domain.tokens.mock
|
||||
|
||||
import arrow.core.nonEmptyListOf
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.tokens.model.*
|
||||
import java.math.BigDecimal
|
||||
|
||||
|
|
@ -75,7 +74,7 @@ internal object MockTokensStates {
|
|||
networkAddress = NetworkAddress.Single(
|
||||
defaultAddress = NetworkAddress.Address(value = "mock", NetworkAddress.Address.Type.Primary),
|
||||
),
|
||||
source = StatusSource.ACTUAL,
|
||||
sources = CryptoCurrencyStatus.Sources(),
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -89,7 +88,7 @@ internal object MockTokensStates {
|
|||
networkAddress = NetworkAddress.Single(
|
||||
defaultAddress = NetworkAddress.Address(value = "mock", NetworkAddress.Address.Type.Primary),
|
||||
),
|
||||
source = StatusSource.ACTUAL,
|
||||
sources = CryptoCurrencyStatus.Sources(),
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -103,7 +102,7 @@ internal object MockTokensStates {
|
|||
networkAddress = NetworkAddress.Single(
|
||||
defaultAddress = NetworkAddress.Address(value = "mock", NetworkAddress.Address.Type.Primary),
|
||||
),
|
||||
source = StatusSource.ACTUAL,
|
||||
sources = CryptoCurrencyStatus.Sources(),
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -117,7 +116,7 @@ internal object MockTokensStates {
|
|||
networkAddress = NetworkAddress.Single(
|
||||
defaultAddress = NetworkAddress.Address(value = "mock", NetworkAddress.Address.Type.Primary),
|
||||
),
|
||||
source = StatusSource.ACTUAL,
|
||||
sources = CryptoCurrencyStatus.Sources(),
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -152,6 +151,7 @@ internal object MockTokensStates {
|
|||
value = MockNetworks.verifiedNetworksStatuses.first { it.network == status.currency.network }.value as? NetworkStatus.Verified,
|
||||
).address,
|
||||
yieldBalance = null,
|
||||
sources = CryptoCurrencyStatus.Sources(),
|
||||
)
|
||||
is Quote.Value -> CryptoCurrencyStatus.Loaded(
|
||||
amount = amount,
|
||||
|
|
@ -162,7 +162,7 @@ internal object MockTokensStates {
|
|||
hasCurrentNetworkTransactions = false,
|
||||
networkAddress = requireNotNull(networkStatus.value as? NetworkStatus.Verified).address,
|
||||
yieldBalance = null,
|
||||
source = StatusSource.ACTUAL,
|
||||
sources = CryptoCurrencyStatus.Sources(),
|
||||
)
|
||||
}
|
||||
status.copy(value = value)
|
||||
|
|
@ -180,6 +180,7 @@ internal object MockTokensStates {
|
|||
.value as? NetworkStatus.Verified,
|
||||
).address,
|
||||
yieldBalance = null,
|
||||
sources = CryptoCurrencyStatus.Sources(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,9 @@ import com.tangem.domain.models.StatusSource
|
|||
import com.tangem.domain.staking.model.stakekit.YieldBalance
|
||||
import com.tangem.domain.tokens.error.CurrencyStatusError
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.*
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.BalanceType
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsBalanceBlockState
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsNotification
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.txhistory.TokenDetailsTxHistoryTransactionStateConverter
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.utils.getBalance
|
||||
|
|
@ -211,13 +213,5 @@ internal class TokenDetailsLoadedBalanceConverter(
|
|||
return totalAmount.format { crypto(status.currency) }
|
||||
}
|
||||
|
||||
private fun CryptoCurrencyStatus.Value.isFlickering(): Boolean = getStatusSource() == StatusSource.CACHE
|
||||
|
||||
private fun CryptoCurrencyStatus.Value.getStatusSource(): StatusSource? {
|
||||
return when (this) {
|
||||
is CryptoCurrencyStatus.Loaded -> source
|
||||
is CryptoCurrencyStatus.NoAccount -> source
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
private fun CryptoCurrencyStatus.Value.isFlickering(): Boolean = sources.total == StatusSource.CACHE
|
||||
}
|
||||
|
|
@ -78,7 +78,7 @@ internal class GetSingleWalletWarningsFactory @Inject constructor(
|
|||
element = WalletNotification.UsedOutdatedData,
|
||||
condition = maybePrimaryCurrencyStatus.fold(
|
||||
ifLeft = { false },
|
||||
ifRight = { it.value.source == StatusSource.ONLY_CACHE },
|
||||
ifRight = { it.value.sources.total == StatusSource.ONLY_CACHE },
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ internal class SingleWalletCardStateConverter(
|
|||
balance = formatFiatAmount(status = status, appCurrency = appCurrency),
|
||||
cardCount = selectedWallet.getCardsCount(),
|
||||
isZeroBalance = status.fiatAmount?.isZero(),
|
||||
isBalanceFlickering = (status as? CryptoCurrencyStatus.Loaded)?.source == StatusSource.CACHE,
|
||||
isBalanceFlickering = (status as? CryptoCurrencyStatus.Loaded)?.sources?.total == StatusSource.CACHE,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
[versions]
|
||||
tangemBlockchainSdk = "release-app_5.21-969"
|
||||
tangemBlockchainSdk = "release-app_5.21-976"
|
||||
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
|
||||
tangemCardSdk = "release-app_5.21-435"
|
||||
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue