diff --git a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/warnings/CryptoCurrencyWarning.kt b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/warnings/CryptoCurrencyWarning.kt index 6c8ec13eb1..2149361962 100644 --- a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/warnings/CryptoCurrencyWarning.kt +++ b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/warnings/CryptoCurrencyWarning.kt @@ -30,4 +30,6 @@ sealed class CryptoCurrencyWarning { * @param exemptionAmount Amount that should be on the blockchain balance not to pay rent */ data class Rent(val rent: BigDecimal, val exemptionAmount: BigDecimal) : CryptoCurrencyWarning() + + data class HasPendingTransactions(val blockchainSymbol: String) : CryptoCurrencyWarning() } \ No newline at end of file diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCurrencyWarningsUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCurrencyWarningsUseCase.kt index b35a730d3a..f1b1b4c948 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCurrencyWarningsUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCurrencyWarningsUseCase.kt @@ -30,7 +30,7 @@ class GetCurrencyWarningsUseCase( ): Flow> { val currency = currencyStatus.currency return combine( - getFeeWarningFlow( + getCoinRelatedWarnings( userWalletId = userWalletId, networkId = currency.network.id, currencyId = currency.id, @@ -41,7 +41,7 @@ class GetCurrencyWarningsUseCase( flowOf(walletManagersFacade.getExistentialDeposit(userWalletId, currency.network)), flowOf(getNetworkUnavailableWarning(currencyStatus)), flowOf(getNetworkNoAccountWarning(currencyStatus)), - ) { maybeFeeWarning, maybeRentWarning, maybeEdWarning, maybeNetworkUnavailable, maybeNetworkNoAccount -> + ) { coinRelatedWarnings, maybeRentWarning, maybeEdWarning, maybeNetworkUnavailable, maybeNetworkNoAccount -> setOfNotNull( maybeRentWarning, maybeEdWarning?.let { @@ -50,20 +50,20 @@ class GetCurrencyWarningsUseCase( edStringValueWithSymbol = "${it.toPlainString()} ${currency.symbol}", ) }, - maybeFeeWarning, + *coinRelatedWarnings.toTypedArray(), maybeNetworkUnavailable, maybeNetworkNoAccount, ) }.flowOn(dispatchers.io) } - private suspend fun getFeeWarningFlow( + private suspend fun getCoinRelatedWarnings( userWalletId: UserWalletId, networkId: Network.ID, currencyId: CryptoCurrency.ID, derivationPath: Network.DerivationPath, isSingleWalletWithTokens: Boolean, - ): Flow { + ): Flow> { val operations = CurrenciesStatusesOperations( currenciesRepository = currenciesRepository, quotesRepository = quotesRepository, @@ -87,17 +87,22 @@ class GetCurrencyWarningsUseCase( ) { tokenStatus, coinStatus -> when { tokenStatus != null && coinStatus != null -> { - if (!tokenStatus.value.amount.isZero() && coinStatus.value.amount.isZero()) { - CryptoCurrencyWarning.BalanceNotEnoughForFee( - currency = tokenStatus.currency, - blockchainFullName = coinStatus.currency.name, - blockchainSymbol = coinStatus.currency.symbol, - ) - } else { - null + buildList { + if (tokenStatus.value.hasCurrentNetworkTransactions) { + add(CryptoCurrencyWarning.HasPendingTransactions(coinStatus.currency.symbol)) + } + if (!tokenStatus.value.amount.isZero() && coinStatus.value.amount.isZero()) { + add( + CryptoCurrencyWarning.BalanceNotEnoughForFee( + currency = tokenStatus.currency, + blockchainFullName = coinStatus.currency.name, + blockchainSymbol = coinStatus.currency.symbol, + ), + ) + } } } - else -> CryptoCurrencyWarning.SomeNetworksUnreachable + else -> listOf(CryptoCurrencyWarning.SomeNetworksUnreachable) } } } diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/components/TokenDetailsNotification.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/components/TokenDetailsNotification.kt index d664dfe47a..c832472ce0 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/components/TokenDetailsNotification.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/components/TokenDetailsNotification.kt @@ -24,41 +24,7 @@ internal sealed class TokenDetailsNotification(val config: NotificationConfig) { iconResId = iconResId, buttonsState = buttonsState, ), - ) { - - object NetworksUnreachable : Warning( - title = resourceReference(R.string.warning_network_unreachable_title), - subtitle = resourceReference(R.string.warning_network_unreachable_message), - ) - - data class NetworkFee( - private val feeInfo: CryptoCurrencyWarning.BalanceNotEnoughForFee, - private val onBuyClick: () -> Unit, - ) : Warning( - title = TextReference.Res( - id = R.string.warning_send_blocked_funds_for_fee_title, - formatArgs = wrappedList(feeInfo.blockchainFullName), - ), - subtitle = TextReference.Res( - id = R.string.warning_send_blocked_funds_for_fee_message, - formatArgs = wrappedList( - feeInfo.currency.name, - feeInfo.blockchainFullName, - feeInfo.currency.name, - feeInfo.blockchainFullName, - feeInfo.blockchainSymbol, - ), - ), - iconResId = feeInfo.currency.networkIconResId, - buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig( - text = resourceReference( - id = R.string.common_buy_currency, - formatArgs = wrappedList(feeInfo.blockchainSymbol), - ), - onClick = onBuyClick, - ), - ) - } + ) sealed class Informational( title: TextReference, @@ -71,35 +37,76 @@ internal sealed class TokenDetailsNotification(val config: NotificationConfig) { iconResId = R.drawable.ic_alert_circle_24, onCloseClick = onCloseClick, ), - ) { - data class RentInfo( - private val rentInfo: CryptoCurrencyWarning.Rent, - private val onCloseClick: () -> Unit, - ) : Informational( - title = TextReference.Res(R.string.warning_rent_fee_title), - subtitle = TextReference.Res( - id = R.string.warning_solana_rent_fee_message, - formatArgs = wrappedList(rentInfo.rent, rentInfo.exemptionAmount), - ), - onCloseClick = onCloseClick, - ) + ) - data class ExistentialDeposit( - private val existentialInfo: CryptoCurrencyWarning.ExistentialDeposit, - ) : Informational( - title = resourceReference(R.string.warning_existential_deposit_title), - subtitle = TextReference.Res( - id = R.string.warning_existential_deposit_message, - formatArgs = wrappedList(existentialInfo.currencyName, existentialInfo.edStringValueWithSymbol), - ), - ) + object NetworksUnreachable : Warning( + title = resourceReference(R.string.warning_network_unreachable_title), + subtitle = resourceReference(R.string.warning_network_unreachable_message), + ) - class NetworksNoAccount(val network: String, val symbol: String, val amount: String) : Informational( - title = resourceReference(R.string.warning_no_account_title), - subtitle = resourceReference( - R.string.no_account_generic, - wrappedList(network, amount, symbol), + data class NetworkFee( + private val feeInfo: CryptoCurrencyWarning.BalanceNotEnoughForFee, + private val onBuyClick: () -> Unit, + ) : Warning( + title = TextReference.Res( + id = R.string.warning_send_blocked_funds_for_fee_title, + formatArgs = wrappedList(feeInfo.blockchainFullName), + ), + subtitle = TextReference.Res( + id = R.string.warning_send_blocked_funds_for_fee_message, + formatArgs = wrappedList( + feeInfo.currency.name, + feeInfo.blockchainFullName, + feeInfo.currency.name, + feeInfo.blockchainFullName, + feeInfo.blockchainSymbol, ), - ) - } + ), + iconResId = feeInfo.currency.networkIconResId, + buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig( + text = resourceReference( + id = R.string.common_buy_currency, + formatArgs = wrappedList(feeInfo.blockchainSymbol), + ), + onClick = onBuyClick, + ), + ) + + data class RentInfo( + private val rentInfo: CryptoCurrencyWarning.Rent, + private val onCloseClick: () -> Unit, + ) : Informational( + title = TextReference.Res(R.string.warning_rent_fee_title), + subtitle = TextReference.Res( + id = R.string.warning_solana_rent_fee_message, + formatArgs = wrappedList(rentInfo.rent, rentInfo.exemptionAmount), + ), + onCloseClick = onCloseClick, + ) + + data class ExistentialDeposit( + private val existentialInfo: CryptoCurrencyWarning.ExistentialDeposit, + ) : Informational( + title = resourceReference(R.string.warning_existential_deposit_title), + subtitle = TextReference.Res( + id = R.string.warning_existential_deposit_message, + formatArgs = wrappedList(existentialInfo.currencyName, existentialInfo.edStringValueWithSymbol), + ), + ) + + class NetworksNoAccount(val network: String, val symbol: String, val amount: String) : Informational( + title = resourceReference(R.string.warning_no_account_title), + subtitle = resourceReference( + id = R.string.no_account_generic, + formatArgs = wrappedList(network, amount, symbol), + ), + ) + + class HasPendingTransactions(val coinSymbol: String) : Informational( + title = resourceReference(R.string.warning_send_blocked_pending_transactions_title), + subtitle = resourceReference( + id = R.string.warning_send_blocked_pending_transactions_message, + formatArgs = wrappedList(coinSymbol), + ), + ) } \ No newline at end of file diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsLoadedBalanceConverter.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsLoadedBalanceConverter.kt index a8ac0b4f70..5fefb9e7d5 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsLoadedBalanceConverter.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsLoadedBalanceConverter.kt @@ -40,7 +40,7 @@ internal class TokenDetailsLoadedBalanceConverter( return state.copy( tokenBalanceBlockState = TokenDetailsBalanceBlockState.Error(state.tokenBalanceBlockState.actionButtons), marketPriceBlockState = MarketPriceBlockState.Error(state.marketPriceBlockState.currencySymbol), - notifications = persistentListOf(TokenDetailsNotification.Warning.NetworksUnreachable), + notifications = persistentListOf(TokenDetailsNotification.NetworksUnreachable), ) } diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsNotificationConverter.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsNotificationConverter.kt index b4dbfbb290..0f34733f00 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsNotificationConverter.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsNotificationConverter.kt @@ -19,29 +19,32 @@ internal class TokenDetailsNotificationConverter( fun removeRentInfo(currentState: TokenDetailsState): ImmutableList { val newNotifications = currentState.notifications.toMutableList() - newNotifications.removeBy { it is TokenDetailsNotification.Informational.RentInfo } + newNotifications.removeBy { it is TokenDetailsNotification.RentInfo } return newNotifications.toImmutableList() } private fun mapToNotification(warning: CryptoCurrencyWarning): TokenDetailsNotification { return when (warning) { - is CryptoCurrencyWarning.BalanceNotEnoughForFee -> TokenDetailsNotification.Warning.NetworkFee( + is CryptoCurrencyWarning.BalanceNotEnoughForFee -> TokenDetailsNotification.NetworkFee( feeInfo = warning, onBuyClick = clickIntents::onBuyClick, ) - is CryptoCurrencyWarning.ExistentialDeposit -> TokenDetailsNotification.Informational.ExistentialDeposit( + is CryptoCurrencyWarning.ExistentialDeposit -> TokenDetailsNotification.ExistentialDeposit( existentialInfo = warning, ) - is CryptoCurrencyWarning.Rent -> TokenDetailsNotification.Informational.RentInfo( + is CryptoCurrencyWarning.Rent -> TokenDetailsNotification.RentInfo( rentInfo = warning, onCloseClick = clickIntents::onCloseRentInfoNotification, ) - CryptoCurrencyWarning.SomeNetworksUnreachable -> TokenDetailsNotification.Warning.NetworksUnreachable - is CryptoCurrencyWarning.SomeNetworksNoAccount -> TokenDetailsNotification.Informational.NetworksNoAccount( + CryptoCurrencyWarning.SomeNetworksUnreachable -> TokenDetailsNotification.NetworksUnreachable + is CryptoCurrencyWarning.SomeNetworksNoAccount -> TokenDetailsNotification.NetworksNoAccount( network = warning.amountCurrency.name, amount = warning.amountToCreateAccount.toString(), symbol = warning.amountCurrency.symbol, ) + is CryptoCurrencyWarning.HasPendingTransactions -> TokenDetailsNotification.HasPendingTransactions( + coinSymbol = warning.blockchainSymbol, + ) } } } \ No newline at end of file