diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt index 299cc99014..d3f607e439 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt @@ -4,6 +4,7 @@ import android.graphics.Bitmap import com.tangem.blockchain.common.* import com.tangem.blockchain.common.address.AddressType import com.tangem.blockchain.extensions.isAboveZero +import com.tangem.common.extensions.isZero import com.tangem.tap.common.entities.Button import com.tangem.tap.common.extensions.toQrCode import com.tangem.tap.common.redux.StateDialog @@ -248,17 +249,27 @@ data class WalletData( val currencyData: BalanceWidgetData = BalanceWidgetData(), val updatingWallet: Boolean = false, val tradeCryptoState: TradeCryptoState = TradeCryptoState(), - val allowToSend: Boolean = true, val fiatRateString: String? = null, val fiatRate: BigDecimal? = null, val mainButton: WalletMainButton = WalletMainButton.SendButton(false), val currency: Currency, - val walletRent: WalletRent? = null, + val warningRent: WalletRent? = null, + val blockchainAmount: BigDecimal? = BigDecimal.ZERO ) { fun shouldShowMultipleAddress(): Boolean { val listOfAddresses = walletAddresses?.list ?: return false return listOfAddresses.size > 1 } + + fun shouldShowCoinAmountWarning(): Boolean = when (currency) { + is Currency.Blockchain -> false + is Currency.Token -> blockchainAmountIsEmpty() && !tokenAmountIsEmpty() + } + + fun shouldEnableTokenSendButton(): Boolean = !blockchainAmountIsEmpty() || !tokenAmountIsEmpty() + + private fun blockchainAmountIsEmpty(): Boolean = blockchainAmount?.isZero() ?: false + private fun tokenAmountIsEmpty(): Boolean = currencyData.amount?.isZero() == true } data class WalletRent( diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt index d684e1da6d..e64d5a82cf 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt @@ -29,15 +29,15 @@ class MultiWalletReducer { null } WalletData( - currencyData = BalanceWidgetData( - BalanceStatus.Loading, - blockchain.fullName, - currencySymbol = blockchain.currency, - token = cardToken - ), - walletAddresses = createAddressList(wallet), - mainButton = WalletMainButton.SendButton(false), - currency = Currency.Blockchain(blockchain), + currencyData = BalanceWidgetData( + BalanceStatus.Loading, + blockchain.fullName, + currencySymbol = blockchain.currency, + token = cardToken + ), + walletAddresses = createAddressList(wallet), + mainButton = WalletMainButton.SendButton(false), + currency = Currency.Blockchain(blockchain), ) } @@ -47,21 +47,21 @@ class MultiWalletReducer { state.selectedCurrency } state.copy( - walletsData = walletsData, - selectedCurrency = selectedCurrency + walletsData = walletsData, + selectedCurrency = selectedCurrency ) } is WalletAction.MultiWallet.AddBlockchain -> { val wallet = state.getWalletManager(action.blockchain)?.wallet val walletData = WalletData( - currencyData = BalanceWidgetData( - BalanceStatus.Loading, - action.blockchain.fullName, - currencySymbol = action.blockchain.currency, - ), - walletAddresses = createAddressList(wallet), - mainButton = WalletMainButton.SendButton(false), - currency = Currency.Blockchain(action.blockchain), + currencyData = BalanceWidgetData( + BalanceStatus.Loading, + action.blockchain.fullName, + currencySymbol = action.blockchain.currency, + ), + walletAddresses = createAddressList(wallet), + mainButton = WalletMainButton.SendButton(false), + currency = Currency.Blockchain(action.blockchain), ) val newState = state.copy(walletsData = state.replaceWalletInWallets(walletData)) if (wallet != null && wallet.amounts[AmountType.Coin]?.value != null) { @@ -80,13 +80,13 @@ class MultiWalletReducer { } is WalletAction.MultiWallet.TokenLoaded -> { val pendingTransactions = state.getWalletManager(action.token) - ?.wallet?.let { wallet -> - wallet.recentTransactions.toPendingTransactions(wallet.address) - } ?: emptyList() + ?.wallet?.let { wallet -> + wallet.recentTransactions.toPendingTransactions(wallet.address) + } ?: emptyList() val sendButtonEnabled = action.amount.value?.isZero() == false && pendingTransactions.isEmpty() val tokenPendingTransactions = pendingTransactions - .filter { it.currency == action.amount.currencySymbol } + .filter { it.currency == action.amount.currencySymbol } val tokenBalanceStatus = when { tokenPendingTransactions.isNotEmpty() -> BalanceStatus.TransactionInProgress pendingTransactions.isNotEmpty() -> BalanceStatus.SameCurrencyTransactionInProgress @@ -94,19 +94,20 @@ class MultiWalletReducer { } val tokenWalletData = state.getWalletData(action.token) val newTokenWalletData = tokenWalletData?.copy( - currencyData = tokenWalletData.currencyData.copy( - status = tokenBalanceStatus, - amount = action.amount.value?.toFormattedCurrencyString( - action.amount.decimals, action.amount.currencySymbol - ), - fiatAmountFormatted = tokenWalletData.fiatRate?.let { - action.amount.value - ?.toFiatString(it, store.state.globalState.appCurrency) - } + currencyData = tokenWalletData.currencyData.copy( + status = tokenBalanceStatus, + amount = action.amount.value, + amountFormatted = action.amount.value?.toFormattedCurrencyString( + action.amount.decimals, action.amount.currencySymbol ), - pendingTransactions = pendingTransactions.removeUnknownTransactions(), - mainButton = WalletMainButton.SendButton(sendButtonEnabled), - currency = Currency.Token(action.token) + fiatAmountFormatted = tokenWalletData.fiatRate?.let { + action.amount.value + ?.toFiatString(it, store.state.globalState.appCurrency) + } + ), + pendingTransactions = pendingTransactions.removeUnknownTransactions(), + mainButton = WalletMainButton.SendButton(sendButtonEnabled), + currency = Currency.Token(action.token) ) val wallets = state.replaceWalletInWallets(newTokenWalletData) state.copy(walletsData = wallets) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/OnWalletLoadedReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/OnWalletLoadedReducer.kt index 6bc4b389d1..e654ad24ea 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/OnWalletLoadedReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/OnWalletLoadedReducer.kt @@ -36,11 +36,11 @@ class OnWalletLoadedReducer { return walletState } val formattedAmount = coinAmountValue?.toFormattedCurrencyString( - wallet.blockchain.decimals(), - wallet.blockchain.currency) + wallet.blockchain.decimals(), + wallet.blockchain.currency) val pendingTransactions = wallet.recentTransactions - .toPendingTransactions(wallet.address) + .toPendingTransactions(wallet.address) val coinSendButton = coinAmountValue?.isZero() == false && pendingTransactions.isEmpty() val balanceStatus = if (pendingTransactions.isNotEmpty()) { @@ -52,17 +52,19 @@ class OnWalletLoadedReducer { val fiatAmount = walletData?.fiatRate?.let { coinAmountValue?.toFiatValue(it) } val newWalletData = walletData?.copy( - currencyData = walletData.currencyData.copy( - status = balanceStatus, currency = wallet.blockchain.fullName, - currencySymbol = wallet.blockchain.currency, - amount = formattedAmount, - fiatAmount = fiatAmount, - fiatAmountFormatted = fiatAmount?.toFormattedFiatValue(fiatCurrencySymbol) - ), - pendingTransactions = pendingTransactions.removeUnknownTransactions(), - mainButton = WalletMainButton.SendButton(coinSendButton), - currency = Currency.Blockchain(wallet.blockchain), - tradeCryptoState = TradeCryptoState.from(exchangeManager, walletData) + currencyData = walletData.currencyData.copy( + status = balanceStatus, currency = wallet.blockchain.fullName, + currencySymbol = wallet.blockchain.currency, + amount = coinAmountValue, + amountFormatted = formattedAmount, + fiatAmount = fiatAmount, + fiatAmountFormatted = fiatAmount?.toFormattedFiatValue(fiatCurrencySymbol) + ), + pendingTransactions = pendingTransactions.removeUnknownTransactions(), + mainButton = WalletMainButton.SendButton(coinSendButton), + currency = Currency.Blockchain(wallet.blockchain), + tradeCryptoState = TradeCryptoState.from(exchangeManager, walletData), + blockchainAmount = coinAmountValue ) val tokens = wallet.getTokens().mapNotNull { token -> @@ -73,20 +75,23 @@ class OnWalletLoadedReducer { pendingTransactions.isNotEmpty() -> BalanceStatus.SameCurrencyTransactionInProgress else -> BalanceStatus.VerifiedOnline } - val tokenAmountValue = wallet.getTokenAmount(token)?.value - val tokenFiatAmount = tokenWalletData?.fiatRate?.let { rate -> tokenAmountValue?.toFiatValue(rate)} + val tokenAmountValue = wallet.getTokenAmount(token)?.value + val tokenFiatAmount = tokenWalletData?.fiatRate?.let { rate -> tokenAmountValue?.toFiatValue(rate) } - val tokenSendButton = tokenAmountValue?.isZero() == false && tokenPendingTransactions.isEmpty() + val tokenSendButton = newWalletData?.shouldEnableTokenSendButton() == true + && tokenPendingTransactions.isEmpty() tokenWalletData?.copy( - currencyData = tokenWalletData.currencyData.copy( - status = tokenBalanceStatus, - amount = tokenAmountValue?.toFormattedCurrencyString(token.decimals, token.symbol), - fiatAmount = tokenFiatAmount, - fiatAmountFormatted = tokenFiatAmount?.toFormattedFiatValue(fiatCurrencySymbol) - ), - pendingTransactions = tokenPendingTransactions.removeUnknownTransactions(), - mainButton = WalletMainButton.SendButton(tokenSendButton), - tradeCryptoState = TradeCryptoState.from(exchangeManager, tokenWalletData) + currencyData = tokenWalletData.currencyData.copy( + status = tokenBalanceStatus, + amount = tokenAmountValue, + amountFormatted = tokenAmountValue?.toFormattedCurrencyString(token.decimals, token.symbol), + fiatAmount = tokenFiatAmount, + fiatAmountFormatted = tokenFiatAmount?.toFormattedFiatValue(fiatCurrencySymbol) + ), + pendingTransactions = tokenPendingTransactions.removeUnknownTransactions(), + mainButton = WalletMainButton.SendButton(tokenSendButton), + tradeCryptoState = TradeCryptoState.from(exchangeManager, tokenWalletData), + blockchainAmount = coinAmountValue ) } val newWallets = (tokens + newWalletData).mapNotNull { it } @@ -98,7 +103,7 @@ class OnWalletLoadedReducer { ProgressState.Done } return walletState.copy( - state = state, walletsData = wallets, error = null + state = state, walletsData = wallets, error = null ) } @@ -128,16 +133,13 @@ class OnWalletLoadedReducer { } val amount = wallet.amounts[AmountType.Coin]?.value val formattedAmount = amount?.toFormattedCurrencyString( - wallet.blockchain.decimals(), - wallet.blockchain.currency) + wallet.blockchain.decimals(), + wallet.blockchain.currency) val fiatRate = walletState.primaryWallet?.fiatRate val fiatAmountRaw = fiatRate?.multiply(amount)?.setScale(2, RoundingMode.DOWN) val fiatAmount = fiatRate?.let { amount?.toFiatString(it, fiatCurrencySymbol) } - val pendingTransactions = wallet.recentTransactions - .toPendingTransactions(wallet.address) - - //TO: + val pendingTransactions = wallet.recentTransactions.toPendingTransactions(wallet.address) val sendButtonEnabled = amount?.isZero() == false && pendingTransactions.isEmpty() val balanceStatus = if (pendingTransactions.isNotEmpty()) { BalanceStatus.TransactionInProgress @@ -145,21 +147,23 @@ class OnWalletLoadedReducer { BalanceStatus.VerifiedOnline } val walletData = walletState.primaryWallet?.copy( - currencyData = BalanceWidgetData( - balanceStatus, wallet.blockchain.fullName, - currencySymbol = wallet.blockchain.currency, - formattedAmount, - token = tokenData, - fiatAmountFormatted = fiatAmount, - fiatAmount = fiatAmountRaw - ), - pendingTransactions = pendingTransactions.removeUnknownTransactions(), - mainButton = WalletMainButton.SendButton(sendButtonEnabled), - tradeCryptoState = TradeCryptoState.from(exchangeManager, walletState.primaryWallet) + currencyData = BalanceWidgetData( + balanceStatus, wallet.blockchain.fullName, + currencySymbol = wallet.blockchain.currency, + token = tokenData, + amount = amount, + amountFormatted = formattedAmount, + fiatAmountFormatted = fiatAmount, + fiatAmount = fiatAmountRaw + ), + pendingTransactions = pendingTransactions.removeUnknownTransactions(), + mainButton = WalletMainButton.SendButton(sendButtonEnabled), + tradeCryptoState = TradeCryptoState.from(exchangeManager, walletState.primaryWallet), + blockchainAmount = amount ) val wallets = walletData?.let { listOf(walletData) } ?: emptyList() return walletState.copy( - state = ProgressState.Done, walletsData = wallets, error = null + state = ProgressState.Done, walletsData = wallets, error = null ) } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt index 7defb905f2..ec2ca28027 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/WalletReducer.kt @@ -246,7 +246,7 @@ private fun internalReduce(action: Action, state: AppState): WalletState { if (walletData == null) { newState } else { - walletData = walletData.copy(walletRent = WalletRent(action.minRent, action.rentExempt)) + walletData = walletData.copy(warningRent = WalletRent(action.minRent, action.rentExempt)) newState = newState.copy( walletsData = newState.replaceSomeWallets(listOf(walletData)) ) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/BalanceWidget.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/BalanceWidget.kt index 42527e8528..f67d9411cb 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/BalanceWidget.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/BalanceWidget.kt @@ -22,7 +22,8 @@ data class BalanceWidgetData( val status: BalanceStatus? = null, val currency: String? = null, val currencySymbol: String? = null, - val amount: String? = null, + val amount: BigDecimal? = null, + val amountFormatted: String? = null, val fiatAmountFormatted: String? = null, val fiatAmount: BigDecimal? = null, val token: TokenData? = null, @@ -149,7 +150,7 @@ class BalanceWidget( tvCurrency.text = data.token?.tokenSymbol tvBaseCurrency.text = data.currency tvAmount.text = if (showAmount) data.token?.amount else "" - tvBaseAmount.text = if (showAmount) data.amount else "" + tvBaseAmount.text = if (showAmount) data.amountFormatted else "" if (showAmount) { tvFiatAmount.show() tvFiatAmount.text = data.token?.fiatAmount @@ -160,7 +161,7 @@ class BalanceWidget( with(binding.lBalance) { groupBaseCurrency.hide() tvCurrency.text = data.currency - tvAmount.text = if (showAmount) data.amount else "" + tvAmount.text = if (showAmount) data.amountFormatted else "" if (showAmount) { tvFiatAmount.show() tvFiatAmount.text = data.fiatAmountFormatted diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt index 3644f38988..6342b8f813 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletDetailsFragment.kt @@ -107,8 +107,8 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), handleDialogs(state.walletDialog) handleCurrencyIcon(selectedWallet) - handleWalletRent(selectedWallet.walletRent) - + handleWalletRent(selectedWallet.warningRent) + handleNotEnoughFundsOnMainCurrency(selectedWallet) binding.srlWalletDetails.setOnRefreshListener { if (selectedWallet.currencyData.status != BalanceStatus.Loading) { @@ -153,14 +153,27 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), private fun handleWalletRent(rent: WalletRent?) = with(binding) { val rent = rent.guard { - lRentWarning.root.hide() + lWarning.root.hide() return } val warningMessage = requireContext().getString( R.string.solana_rent_warning, rent.minRentValue, rent.rentExemptValue ) - lRentWarning.tvRentWarningMessage.text = warningMessage - lRentWarning.root.show() + lWarning.tvWarningMessage.text = warningMessage + lWarning.root.show() + } + + private fun handleNotEnoughFundsOnMainCurrency(selectedWalletData: WalletData) = with(binding) { + if (selectedWalletData.shouldShowCoinAmountWarning()) { + val blockchainName = selectedWalletData.currency.blockchain.fullName + val warningMessage = requireContext().getString( + R.string.token_details_send_blocked_fee_format, blockchainName, blockchainName + ) + lWarning.tvWarningMessage.text = warningMessage + lWarning.root.show() + } else { + lWarning.root.hide() + } } private fun handleCurrencyIcon(wallet: WalletData) = with(binding.lWalletDetails.lBalance) { @@ -234,7 +247,7 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), lBalance.root.show() lBalance.groupBalance.show() lBalance.tvError.hide() - lBalance.tvAmount.text = data.amount + lBalance.tvAmount.text = data.amountFormatted lBalance.tvFiatAmount.text = data.fiatAmountFormatted lBalance.tvStatus.setLoadingStatus(R.string.wallet_balance_loading) } @@ -244,7 +257,7 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), lBalance.root.show() lBalance.groupBalance.show() lBalance.tvError.hide() - lBalance.tvAmount.text = data.amount + lBalance.tvAmount.text = data.amountFormatted lBalance.tvFiatAmount.text = data.fiatAmountFormatted when (data.status) { BalanceStatus.VerifiedOnline, BalanceStatus.SameCurrencyTransactionInProgress -> { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt index 074d4a882b..968485c440 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt @@ -57,8 +57,8 @@ class WalletAdapter fun bind(wallet: WalletData) = with(binding) { tvCurrency.text = wallet.currencyData.currency - tvAmount.text = wallet.currencyData.amount?.takeWhile { !it.isWhitespace() } - tvCurrencySymbol.text = wallet.currencyData.amount?.takeLastWhile { !it.isWhitespace() } + tvAmount.text = wallet.currencyData.amountFormatted?.takeWhile { !it.isWhitespace() } + tvCurrencySymbol.text = wallet.currencyData.amountFormatted?.takeLastWhile { !it.isWhitespace() } tvAmountFiat.text = wallet.currencyData.fiatAmountFormatted tvExchangeRate.text = wallet.fiatRateString cardWallet.setOnClickListener { @@ -77,7 +77,7 @@ class WalletAdapter BalanceStatus.VerifiedOnline, BalanceStatus.SameCurrencyTransactionInProgress -> hideWarning() BalanceStatus.Loading -> { hideWarning() - if (wallet.currencyData.amount == null) { + if (wallet.currencyData.amountFormatted == null) { tvExchangeRate.text = root.getString(R.string.wallet_balance_loading) } } diff --git a/app/src/main/res/layout/fragment_wallet_details.xml b/app/src/main/res/layout/fragment_wallet_details.xml index 0f6ef2b42d..a2d946a3ca 100644 --- a/app/src/main/res/layout/fragment_wallet_details.xml +++ b/app/src/main/res/layout/fragment_wallet_details.xml @@ -99,8 +99,8 @@ app:layout_constraintTop_toBottomOf="@id/rv_pending_transaction" /> diff --git a/app/src/main/res/layout/layout_wallet_details_rent.xml b/app/src/main/res/layout/layout_wallet_details_warning.xml similarity index 91% rename from app/src/main/res/layout/layout_wallet_details_rent.xml rename to app/src/main/res/layout/layout_wallet_details_warning.xml index 1f44d10ea7..43eeed159a 100644 --- a/app/src/main/res/layout/layout_wallet_details_rent.xml +++ b/app/src/main/res/layout/layout_wallet_details_warning.xml @@ -13,7 +13,7 @@ android:layout_height="wrap_content">