From 64e6a7609fba79c3a304a0d21b014604848ed481 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 11 Apr 2023 12:49:04 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../tap/features/wallet/ui/BalanceWidget.kt | 110 ++++++------- .../wallet/ui/WalletDetailsFragment.kt | 125 ++++++++------- .../tap/features/wallet/ui/WalletFragment.kt | 5 +- .../tap/features/wallet/ui/WalletViewModel.kt | 4 +- .../wallet/ui/WalletWarningConverter.kt | 4 +- .../wallet/ui/adapters/WalletAdapter.kt | 53 ++++--- .../analytics/WalletAnalyticsEventsMapper.kt | 27 ++-- .../wallet/ui/utils/WalletDataOperations.kt | 144 ++++++++++++++++++ .../wallet/ui/view/TotalBalanceCard.kt | 40 ++--- .../wallet/ui/view/WalletDetailsButtonsRow.kt | 2 +- .../wallet/ui/wallet/MultiWalletView.kt | 59 ++----- .../wallet/ui/wallet/SingleWalletView.kt | 27 ++-- .../ui/wallet/saltPay/SaltPayWalletView.kt | 12 +- .../tap/features/walletSelector/ui/Mapper.kt | 2 +- 14 files changed, 380 insertions(+), 234 deletions(-) create mode 100644 app/src/main/java/com/tangem/tap/features/wallet/ui/utils/WalletDataOperations.kt 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 0afeb7e3b0..3b8cac1392 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 @@ -3,6 +3,10 @@ package com.tangem.tap.features.wallet.ui import androidx.annotation.IdRes import com.tangem.tap.common.extensions.hide import com.tangem.tap.common.extensions.show +import com.tangem.tap.domain.model.WalletDataModel +import com.tangem.tap.features.wallet.ui.utils.getFormattedAmount +import com.tangem.tap.features.wallet.ui.utils.getFormattedFiatAmount +import com.tangem.tap.store import com.tangem.wallet.R import com.tangem.wallet.databinding.CardBalanceBinding import java.math.BigDecimal @@ -36,36 +40,37 @@ data class BalanceWidgetData( class BalanceWidget( private val binding: CardBalanceBinding, private val fragment: WalletFragment, - private val data: BalanceWidgetData, - private val token: BalanceWidgetData?, - private val isTwinCard: Boolean, + private val blockchainWalletData: WalletDataModel, + private val tokenWalletData: WalletDataModel?, ) { @Suppress("LongMethod", "ComplexMethod") fun setup() { - when (data.status) { - BalanceStatus.Loading -> { + when (blockchainWalletData.status) { + is WalletDataModel.Loading -> { with(binding) { lBalance.root.show() lBalanceError.root.hide() lBalance.tvFiatAmount.hide() - lBalance.tvCurrency.text = data.currency + lBalance.tvCurrency.text = blockchainWalletData.currency.currencyName lBalance.tvAmount.text = "" } showStatus(R.id.tv_status_loading) - if (token != null) { - showBalanceWithToken(data, false) + if (tokenWalletData != null) { + showBalanceWithToken(blockchainWalletData, false) } else { - showBalanceWithoutToken(data, false) + showBalanceWithoutToken(blockchainWalletData, false) } } - BalanceStatus.VerifiedOnline, BalanceStatus.TransactionInProgress -> with(binding.lBalance) { + is WalletDataModel.VerifiedOnline, + is WalletDataModel.TransactionInProgress, + -> with(binding.lBalance) { root.show() binding.lBalanceError.root.hide() - val statusView = if (data.status == BalanceStatus.VerifiedOnline) { + val statusView = if (blockchainWalletData.status is WalletDataModel.VerifiedOnline) { R.id.tv_status_verified } else { tvStatusError.text = @@ -75,61 +80,62 @@ class BalanceWidget( showStatus(statusView) tvStatusErrorMessage.hide() - if (token != null) { - showBalanceWithToken(data, true) + if (tokenWalletData != null) { + showBalanceWithToken(blockchainWalletData, true) } else { - showBalanceWithoutToken(data, true) + showBalanceWithoutToken(blockchainWalletData, true) } } - BalanceStatus.Unreachable -> with(binding.lBalance) { + is WalletDataModel.Unreachable -> with(binding.lBalance) { root.show() binding.lBalanceError.root.hide() tvFiatAmount.hide() groupBaseCurrency.hide() - val currency = if (token != null) token.currencySymbol else data.currency + val currency = tokenWalletData?.currency?.currencySymbol + ?: blockchainWalletData.currency.currencyName tvCurrency.text = currency tvAmount.text = "" - tvStatusErrorMessage.text = data.errorMessage + tvStatusErrorMessage.text = blockchainWalletData.status.errorMessage tvStatusError.text = fragment.getString(R.string.wallet_balance_blockchain_unreachable) showStatus(R.id.group_error) - tvStatusErrorMessage.show(!data.errorMessage.isNullOrBlank()) + tvStatusErrorMessage.show(!blockchainWalletData.status.errorMessage.isNullOrBlank()) } - BalanceStatus.EmptyCard -> with(binding.lBalanceError) { - binding.lBalance.root.hide() - binding.lBalanceError.root.show() - if (isTwinCard) { - tvErrorTitle.text = fragment.getText(R.string.wallet_error_empty_twin_card) - tvErrorDescriptions.text = - fragment.getText(R.string.wallet_error_empty_twin_card_subtitle) - } else { - tvErrorTitle.text = fragment.getText(R.string.wallet_error_empty_card) - tvErrorDescriptions.text = - fragment.getText(R.string.wallet_error_empty_card_subtitle) - } - } - BalanceStatus.NoAccount -> with(binding.lBalanceError) { + // BalanceStatus.EmptyCard -> with(binding.lBalanceError) { + // binding.lBalance.root.hide() + // binding.lBalanceError.root.show() + // if (isTwinCard) { + // tvErrorTitle.text = fragment.getText(R.string.wallet_error_empty_twin_card) + // tvErrorDescriptions.text = + // fragment.getText(R.string.wallet_error_empty_twin_card_subtitle) + // } else { + // tvErrorTitle.text = fragment.getText(R.string.wallet_error_empty_card) + // tvErrorDescriptions.text = + // fragment.getText(R.string.wallet_error_empty_card_subtitle) + // } + // } + is WalletDataModel.NoAccount -> with(binding.lBalanceError) { binding.lBalance.root.hide() binding.lBalanceError.root.show() tvErrorTitle.text = fragment.getText(R.string.wallet_error_no_account) tvErrorDescriptions.text = fragment.getString( R.string.no_account_generic, - data.amountToCreateAccount, - data.currencySymbol, + blockchainWalletData.status.amountToCreateAccount, + blockchainWalletData.currency.currencySymbol, ) } - BalanceStatus.UnknownBlockchain -> with(binding.lBalanceError) { - binding.lBalance.root.hide() - binding.lBalanceError.root.show() - tvErrorTitle.text = - fragment.getText(R.string.wallet_error_unsupported_blockchain) - tvErrorDescriptions.text = - fragment.getString(R.string.wallet_error_unsupported_blockchain_subtitle) - } + // BalanceStatus.UnknownBlockchain -> with(binding.lBalanceError) { + // binding.lBalance.root.hide() + // binding.lBalanceError.root.show() + // tvErrorTitle.text = + // fragment.getText(R.string.wallet_error_unsupported_blockchain) + // tvErrorDescriptions.text = + // fragment.getString(R.string.wallet_error_unsupported_blockchain_subtitle) + // } else -> {} } } @@ -140,25 +146,25 @@ class BalanceWidget( tvStatusVerified.show(viewRes == R.id.tv_status_verified) } - private fun showBalanceWithToken(data: BalanceWidgetData, showAmount: Boolean) = with(binding.lBalance) { + private fun showBalanceWithToken(data: WalletDataModel, showAmount: Boolean) = with(binding.lBalance) { groupBaseCurrency.show() - tvCurrency.text = token?.currencySymbol - tvBaseCurrency.text = data.currency - tvAmount.text = if (showAmount) token?.amountFormatted else "" - tvBaseAmount.text = if (showAmount) data.amountFormatted else "" + tvCurrency.text = tokenWalletData?.currency?.currencySymbol + tvBaseCurrency.text = data.currency.currencyName + tvAmount.text = if (showAmount) tokenWalletData?.getFormattedAmount() else "" + tvBaseAmount.text = if (showAmount) data.getFormattedAmount() else "" if (showAmount) { tvFiatAmount.show() - tvFiatAmount.text = token?.fiatAmountFormatted + tvFiatAmount.text = tokenWalletData?.getFormattedFiatAmount(store.state.globalState.appCurrency) } } - private fun showBalanceWithoutToken(data: BalanceWidgetData, showAmount: Boolean) = with(binding.lBalance) { + private fun showBalanceWithoutToken(data: WalletDataModel, showAmount: Boolean) = with(binding.lBalance) { groupBaseCurrency.hide() - tvCurrency.text = data.currency - tvAmount.text = if (showAmount) data.amountFormatted else "" + tvCurrency.text = data.currency.currencyName + tvAmount.text = if (showAmount) data.getFormattedAmount() else "" if (showAmount) { tvFiatAmount.show() - tvFiatAmount.text = data.fiatAmountFormatted + tvFiatAmount.text = data.getFormattedFiatAmount(store.state.globalState.appCurrency) } } } \ No newline at end of file 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 e070d1e5da..9952836ff9 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 @@ -41,21 +41,29 @@ import com.tangem.tap.common.extensions.show import com.tangem.tap.common.extensions.toQrCode import com.tangem.tap.common.recyclerView.SpaceItemDecoration import com.tangem.tap.common.redux.navigation.NavigationAction +import com.tangem.tap.domain.model.WalletDataModel import com.tangem.tap.features.wallet.models.Currency import com.tangem.tap.features.wallet.models.PendingTransaction import com.tangem.tap.features.wallet.models.PendingTransactionType import com.tangem.tap.features.wallet.models.WalletWarning -import com.tangem.tap.features.wallet.redux.AddressData import com.tangem.tap.features.wallet.redux.ErrorType import com.tangem.tap.features.wallet.redux.ProgressState import com.tangem.tap.features.wallet.redux.WalletAction -import com.tangem.tap.features.wallet.redux.WalletData import com.tangem.tap.features.wallet.redux.WalletState -import com.tangem.tap.features.wallet.redux.WalletState.Companion.UNKNOWN_AMOUNT_SIGN +import com.tangem.tap.features.wallet.redux.utils.UNKNOWN_AMOUNT_SIGN import com.tangem.tap.features.wallet.ui.adapters.PendingTransactionsAdapter import com.tangem.tap.features.wallet.ui.adapters.WalletDetailWarningMessagesAdapter import com.tangem.tap.features.wallet.ui.images.load import com.tangem.tap.features.wallet.ui.test.TestWallet +import com.tangem.tap.features.wallet.ui.utils.assembleWarnings +import com.tangem.tap.features.wallet.ui.utils.getAvailableActions +import com.tangem.tap.features.wallet.ui.utils.getFormattedAmount +import com.tangem.tap.features.wallet.ui.utils.getFormattedFiatAmount +import com.tangem.tap.features.wallet.ui.utils.isAvailableToBuy +import com.tangem.tap.features.wallet.ui.utils.isAvailableToSell +import com.tangem.tap.features.wallet.ui.utils.isAvailableToSwap +import com.tangem.tap.features.wallet.ui.utils.mainButton +import com.tangem.tap.features.wallet.ui.utils.shouldShowMultipleAddress import com.tangem.tap.store import com.tangem.tap.userWalletsListManagerSafe import com.tangem.tap.walletCurrenciesManager @@ -85,31 +93,19 @@ class WalletDetailsFragment : private val binding: FragmentWalletDetailsBinding by viewBinding(FragmentWalletDetailsBinding::bind) - private val walletDataWatcher: ModelWatcher = modelWatcher { - val addressCardStrategy: DiffStrategy = { old, new -> - old.currency != new.currency || - old.walletAddresses?.selectedAddress != new.walletAddresses?.selectedAddress || - old.shouldShowMultipleAddress() != new.shouldShowMultipleAddress() + private val walletDataWatcher: ModelWatcher = modelWatcher { + val addressCardStrategy: DiffStrategy = { old, new -> + old.currency != new.currency || old.walletAddresses != new.walletAddresses } - WalletData::pendingTransactions { - showPendingTransactionsIfPresent(it) - } - WalletData::currency { + WalletDataModel::currency { handleCurrencyIcon(it) } - WalletData::currencyData { - setupBalanceData(it) - } - WalletData::walletAddresses { walletAddresses -> + WalletDataModel::walletAddresses { walletAddresses -> setupCopyAndShareButtons(walletAddresses?.selectedAddress?.address) } - WalletData::assembleWarnings { warnings -> - handleWarnings(warnings) - } - (WalletData::currencyData or WalletData::currency) { walletData -> - setupCurrency(walletData.currencyData, walletData.currency) - setupSwipeRefresh(walletData.currencyData, walletData.currency) + WalletDataModel::currency { currency -> + setupCurrency(currency) } watch({ it }, addressCardStrategy) { walletData -> setupAddressCard( @@ -121,9 +117,28 @@ class WalletDetailsFragment : } private val walletStateWatcher: ModelWatcher = modelWatcher { - WalletState::selectedWalletData { selectedWallet -> + val walletDataStrategy: DiffStrategy = { old, new -> + new.walletsStores.isNotEmpty() && + new.selectedCurrency != null && + (old.selectedCurrency != new.selectedCurrency || old.walletsStores != new.walletsStores) + } + + watch({ it }, walletDataStrategy) { state -> + val selectedWallet = state.selectedWalletData if (selectedWallet != null) { + setupBalanceData(selectedWallet) + setupSwipeRefresh(selectedWallet) walletDataWatcher.invoke(selectedWallet) + + val walletStore = state.getWalletStore(state.selectedCurrency) + if (walletStore != null) { + handleWarnings( + selectedWallet.assembleWarnings( + blockchainAmount = walletStore.blockchainWalletData.status.amount, + blockchainWalletRent = walletStore.walletRent, + ), + ) + } } } (WalletState::selectedWalletData or WalletState::isExchangeServiceFeatureOn) { state -> @@ -234,8 +249,8 @@ class WalletDetailsFragment : ) } - private fun setupCurrency(currencyData: BalanceWidgetData, currency: Currency) = with(binding) { - tvCurrencyTitle.text = currencyData.currency + private fun setupCurrency(currency: Currency) = with(binding) { + tvCurrencyTitle.text = currency.currencyName if (currency is Currency.Token) { tvCurrencySubtitle.text = tvCurrencySubtitle.getString( @@ -248,16 +263,17 @@ class WalletDetailsFragment : } } - private fun setupSwipeRefresh(currencyData: BalanceWidgetData, currency: Currency) { + private fun setupSwipeRefresh(walletData: WalletDataModel) { binding.srlWalletDetails.setOnRefreshListener { - if (currencyData.status != BalanceStatus.Loading && currencyData.status != BalanceStatus.Refreshing) { + if (walletData.status !is WalletDataModel.Loading) { Analytics.send(Token.Refreshed()) + val selectedUserWallet = userWalletsListManagerSafe?.selectedUserWalletSync.guard { + Timber.e("Unable to refresh wallet details screen, no user wallet selected") + return@setOnRefreshListener + } + binding.srlWalletDetails.isRefreshing = true lifecycleScope.launch(Dispatchers.Default) { - val selectedUserWallet = userWalletsListManagerSafe?.selectedUserWalletSync.guard { - Timber.e("Unable to refresh wallet details screen, no user wallet selected") - return@launch - } - walletCurrenciesManager.update(selectedUserWallet, currency) + walletCurrenciesManager.update(selectedUserWallet, walletData.currency) .doOnResult { withMainContext { binding.srlWalletDetails.isRefreshing = false @@ -266,9 +282,6 @@ class WalletDetailsFragment : } } } - - binding.srlWalletDetails.isRefreshing = currencyData.status == BalanceStatus.Loading || - currencyData.status == BalanceStatus.Refreshing } private fun setupCopyAndShareButtons(walletAddress: String?) { @@ -284,7 +297,7 @@ class WalletDetailsFragment : } } - private fun setupButtonsRow(selectedWallet: WalletData, isExchangeServiceFeatureOn: Boolean) { + private fun setupButtonsRow(selectedWallet: WalletDataModel, isExchangeServiceFeatureOn: Boolean) { val exchangeManager = store.state.globalState.exchangeManager binding.rowButtons.apply { onBuyClick = { store.dispatch(WalletAction.TradeCryptoAction.Buy()) } @@ -340,7 +353,7 @@ class WalletDetailsFragment : private fun setupAddressCard( shouldShowMultipleAddress: Boolean, - selectedAddress: AddressData?, + selectedAddress: WalletDataModel.AddressData?, currency: Currency, ) = with(binding.lWalletDetails) { if (selectedAddress == null) return@with @@ -371,7 +384,7 @@ class WalletDetailsFragment : private fun setupAddressTypeChips( shouldShowMultipleAddress: Boolean, - selectedAddress: AddressData, + selectedAddress: WalletDataModel.AddressData, currency: Currency, ) = with(binding.lWalletDetails) { if (shouldShowMultipleAddress && currency is Currency.Blockchain) { @@ -408,54 +421,58 @@ class WalletDetailsFragment : } } - private fun setupBalanceData(data: BalanceWidgetData) = with(binding.lWalletDetails) { - when (data.status) { - BalanceStatus.Loading -> { + private fun setupBalanceData(walletData: WalletDataModel) = with(binding.lWalletDetails) { + when (val status = walletData.status) { + is WalletDataModel.Loading -> { lBalanceError.root.hide() lBalance.root.show() lBalance.groupBalance.show() lBalance.tvError.hide() - lBalance.tvAmount.text = data.amountFormatted - lBalance.tvFiatAmount.text = data.fiatAmountFormatted ?: UNKNOWN_AMOUNT_SIGN + lBalance.tvAmount.text = walletData.getFormattedAmount() + lBalance.tvFiatAmount.text = walletData.getFormattedFiatAmount(store.state.globalState.appCurrency) lBalance.tvStatus.setLoadingStatus(R.string.wallet_balance_loading) } - BalanceStatus.VerifiedOnline, BalanceStatus.SameCurrencyTransactionInProgress, - BalanceStatus.TransactionInProgress, + is WalletDataModel.VerifiedOnline, + is WalletDataModel.SameCurrencyTransactionInProgress, + is WalletDataModel.TransactionInProgress, -> { lBalanceError.root.hide() lBalance.root.show() lBalance.groupBalance.show() lBalance.tvError.hide() - lBalance.tvAmount.text = data.amountFormatted - lBalance.tvFiatAmount.text = data.fiatAmountFormatted ?: UNKNOWN_AMOUNT_SIGN - when (data.status) { - BalanceStatus.VerifiedOnline, BalanceStatus.SameCurrencyTransactionInProgress -> { + lBalance.tvAmount.text = walletData.getFormattedAmount() + lBalance.tvFiatAmount.text = walletData.getFormattedFiatAmount(store.state.globalState.appCurrency) + when (status) { + is WalletDataModel.VerifiedOnline, + is WalletDataModel.SameCurrencyTransactionInProgress, + -> { lBalance.tvStatus.setVerifiedBalanceStatus(R.string.wallet_balance_verified) } else -> { lBalance.tvStatus.setWarningStatus(R.string.wallet_balance_tx_in_progress) } } + showPendingTransactionsIfPresent(status.pendingTransactions) } - BalanceStatus.Unreachable -> { + is WalletDataModel.Unreachable -> { lBalanceError.root.hide() lBalance.root.show() lBalance.groupBalance.hide() lBalance.tvError.show() lBalance.tvError.setWarningStatus( R.string.wallet_balance_blockchain_unreachable, - data.errorMessage, + status.errorMessage, ) } - BalanceStatus.NoAccount -> { + is WalletDataModel.NoAccount -> { lBalance.root.hide() lBalanceError.root.show() lBalanceError.tvErrorTitle.text = getText(R.string.wallet_error_no_account) lBalanceError.tvErrorDescriptions.text = getString( R.string.no_account_generic, - data.amountToCreateAccount, - data.currencySymbol, + status.amountToCreateAccount, + walletData.currency.currencySymbol, ) } else -> {} diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt index 571653ff77..ca1149d987 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt @@ -68,7 +68,7 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber - totalBalance?.state?.let { + totalBalance?.let { viewModel.onBalanceLoaded(totalBalance) store.state.globalState.topUpController?.totalBalanceStateChanged(it) } @@ -159,8 +159,7 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber { + state.isMultiwalletAllowed && walletView !is MultiWalletView -> { walletView.onViewDestroy() walletView = MultiWalletView() walletView.changeWalletView(this, binding) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletViewModel.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletViewModel.kt index 2be9db11ee..bba9814685 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletViewModel.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletViewModel.kt @@ -9,8 +9,8 @@ import com.tangem.tap.common.analytics.converters.ParamCardCurrencyConverter import com.tangem.tap.common.analytics.events.Basic import com.tangem.tap.common.analytics.events.MainScreen import com.tangem.tap.common.extensions.dispatchOnMain +import com.tangem.tap.domain.model.TotalFiatBalance import com.tangem.tap.domain.userWalletList.UserWalletsListManager -import com.tangem.tap.features.wallet.models.TotalBalance import com.tangem.tap.features.wallet.redux.WalletAction import com.tangem.tap.features.wallet.ui.analytics.WalletAnalyticsEventsMapper import com.tangem.tap.store @@ -88,7 +88,7 @@ internal class WalletViewModel @Inject constructor( bootstrapShowSaveWalletIfNeeded() } - fun onBalanceLoaded(totalBalance: TotalBalance?) { + fun onBalanceLoaded(totalBalance: TotalFiatBalance?) { if (totalBalance != null) { walletAnalyticsEventsMapper.convert(totalBalance)?.let { balanceParam -> analyticsEventHandler.send( diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletWarningConverter.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletWarningConverter.kt index 8e9e9c6219..afbf3bff5a 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletWarningConverter.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletWarningConverter.kt @@ -41,8 +41,8 @@ class WalletWarningConverter( is WalletWarning.Rent -> { context.getString( R.string.solana_rent_warning, - message.walletRent.minRentValue, - message.walletRent.rentExemptValue, + message.walletRent.rent, + message.walletRent.exemptionAmount, ) } } 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 98f4fbecee..cbb32572e7 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 @@ -12,18 +12,20 @@ import com.tangem.tap.common.analytics.events.Portfolio import com.tangem.tap.common.extensions.getString import com.tangem.tap.common.extensions.hide import com.tangem.tap.common.extensions.show +import com.tangem.tap.domain.model.WalletDataModel import com.tangem.tap.features.wallet.redux.WalletAction -import com.tangem.tap.features.wallet.redux.WalletData -import com.tangem.tap.features.wallet.ui.BalanceStatus +import com.tangem.tap.features.wallet.ui.utils.getFormattedAmount +import com.tangem.tap.features.wallet.ui.utils.getFormattedFiatAmount +import com.tangem.tap.features.wallet.ui.utils.getFormattedFiatRate import com.tangem.tap.features.wallet.ui.images.load import com.tangem.tap.store import com.tangem.wallet.R import com.tangem.wallet.databinding.ItemCurrencyWalletBinding -class WalletAdapter : ListAdapter(DiffUtilCallback) { +class WalletAdapter : ListAdapter(DiffUtilCallback) { override fun getItemId(position: Int): Long { - return currentList[position].currencyData.currencySymbol?.hashCode()?.toLong() ?: 0 + return currentList[position].currency.currencySymbol.hashCode().toLong() } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WalletsViewHolder { @@ -39,34 +41,33 @@ class WalletAdapter : ListAdapter(D holder.bind(currentList[position]) } - object DiffUtilCallback : DiffUtil.ItemCallback() { - override fun areContentsTheSame(oldItem: WalletData, newItem: WalletData) = oldItem == newItem + object DiffUtilCallback : DiffUtil.ItemCallback() { + override fun areContentsTheSame(oldItem: WalletDataModel, newItem: WalletDataModel) = oldItem == newItem - override fun areItemsTheSame(oldItem: WalletData, newItem: WalletData) = oldItem == newItem + override fun areItemsTheSame(oldItem: WalletDataModel, newItem: WalletDataModel) = oldItem == newItem } class WalletsViewHolder(val binding: ItemCurrencyWalletBinding) : RecyclerView.ViewHolder(binding.root) { - fun bind(wallet: WalletData) = with(binding) { - val status = wallet.currencyData.status - // Skip changes when on refreshing status - if (status == BalanceStatus.Refreshing) return@with + fun bind(wallet: WalletDataModel) = with(binding) { + val status = wallet.status + val fiatCurrency = store.state.globalState.appCurrency val statusMessage = when (status) { - BalanceStatus.TransactionInProgress -> { + is WalletDataModel.TransactionInProgress -> { root.getString(R.string.wallet_balance_tx_in_progress) } - BalanceStatus.Unreachable -> { + is WalletDataModel.Unreachable -> { root.getString(R.string.wallet_balance_blockchain_unreachable) } - BalanceStatus.MissedDerivation -> { + is WalletDataModel.MissedDerivation -> { root.getString(R.string.wallet_balance_missing_derivation) } else -> null } - if (status == null || status == BalanceStatus.Loading) { + if (status is WalletDataModel.Loading) { lContent.root.hide() lShimmer.root.veil() } else { @@ -82,24 +83,22 @@ class WalletAdapter : ListAdapter(D ?.derivationStyle, ) - lContent.tvCurrency.text = wallet.currencyData.currency - lContent.tvAmountFiat.text = wallet.currencyData.fiatAmountFormatted ?: "—" - lContent.tvAmount.text = wallet.currencyData.amountFormatted ?: "—" + lContent.tvCurrency.text = wallet.currency.currencyName + lContent.tvAmountFiat.text = wallet.getFormattedFiatAmount(fiatCurrency) + lContent.tvAmount.text = wallet.getFormattedAmount() lContent.tvStatus.isVisible = statusMessage != null lContent.tvStatus.text = statusMessage lContent.tvExchangeRate.isVisible = statusMessage == null - lContent.tvExchangeRate.text = wallet.fiatRateString - ?: root.getString(id = R.string.token_item_no_rate) + lContent.tvExchangeRate.text = wallet.getFormattedFiatRate( + fiatCurrency = fiatCurrency, + noRateValue = root.getString(id = R.string.token_item_no_rate), + ) - if (wallet.walletAddresses != null) { - cardWallet.setOnClickListener { - Analytics.send(Portfolio.TokenTapped()) - store.dispatch(WalletAction.MultiWallet.SelectWallet(wallet.currency)) - } - } else { - cardWallet.setOnClickListener(null) + cardWallet.setOnClickListener { + Analytics.send(Portfolio.TokenTapped()) + store.dispatch(WalletAction.MultiWallet.SelectWallet(wallet.currency)) } } } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/analytics/WalletAnalyticsEventsMapper.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/analytics/WalletAnalyticsEventsMapper.kt index 6c750a5368..277ce8471c 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/analytics/WalletAnalyticsEventsMapper.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/analytics/WalletAnalyticsEventsMapper.kt @@ -2,22 +2,16 @@ package com.tangem.tap.features.wallet.ui.analytics import com.tangem.tap.common.analytics.events.AnalyticsParam import com.tangem.tap.common.extensions.isGreaterThan -import com.tangem.tap.features.wallet.models.TotalBalance -import com.tangem.tap.features.wallet.redux.ProgressState +import com.tangem.tap.domain.model.TotalFiatBalance import com.tangem.utils.converter.Converter import java.math.BigDecimal -class WalletAnalyticsEventsMapper : Converter { +class WalletAnalyticsEventsMapper : Converter { - override fun convert(value: TotalBalance): AnalyticsParam.CardBalanceState? { - return when (value.state) { - ProgressState.Done -> if (value.fiatAmount?.isGreaterThan(BigDecimal.ZERO) == true) { - AnalyticsParam.CardBalanceState.Full - } else { - AnalyticsParam.CardBalanceState.Empty - } - ProgressState.Error -> { - if (value.fiatAmount == null) { + override fun convert(value: TotalFiatBalance): AnalyticsParam.CardBalanceState? { + return when (value) { + is TotalFiatBalance.Error -> { + if (value.amount == null) { // if fiatAmount is null while ProgressState.Error it means error occurs when loading blockchain AnalyticsParam.CardBalanceState.BlockchainError } else { @@ -25,7 +19,14 @@ class WalletAnalyticsEventsMapper : Converter null + is TotalFiatBalance.Loaded -> { + if (value.amount.isGreaterThan(BigDecimal.ZERO)) { + AnalyticsParam.CardBalanceState.Full + } else { + AnalyticsParam.CardBalanceState.Empty + } + } + is TotalFiatBalance.Loading -> null } } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/utils/WalletDataOperations.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/utils/WalletDataOperations.kt new file mode 100644 index 0000000000..6b08921a5d --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/utils/WalletDataOperations.kt @@ -0,0 +1,144 @@ +package com.tangem.tap.features.wallet.ui.utils + +import com.tangem.blockchain.common.Blockchain +import com.tangem.common.extensions.isZero +import com.tangem.domain.common.extensions.toNetworkId +import com.tangem.feature.swap.api.SwapFeatureToggleManager +import com.tangem.feature.swap.domain.SwapInteractor +import com.tangem.tap.common.entities.FiatCurrency +import com.tangem.tap.common.extensions.toFiatRateString +import com.tangem.tap.common.extensions.toFiatValue +import com.tangem.tap.common.extensions.toFormattedCurrencyString +import com.tangem.tap.common.extensions.toFormattedFiatValue +import com.tangem.tap.domain.model.WalletDataModel +import com.tangem.tap.domain.model.WalletStoreModel +import com.tangem.tap.features.wallet.models.WalletWarning +import com.tangem.tap.features.wallet.redux.WalletMainButton +import com.tangem.tap.features.wallet.redux.utils.UNKNOWN_AMOUNT_SIGN +import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager +import java.math.BigDecimal + +internal val WalletDataModel.mainButton: WalletMainButton + get() = WalletMainButton.SendButton( + enabled = !status.amount.isZero() && status.pendingTransactions.isEmpty(), + ) + +internal fun WalletDataModel.getFormattedAmount(): String { + return status.amount.toFormattedCurrencyString( + decimals = currency.decimals, + currency = currency.currencySymbol, + ) +} + +internal fun WalletDataModel.getFormattedFiatAmount( + fiatCurrency: FiatCurrency, + unknownAmountSign: String = UNKNOWN_AMOUNT_SIGN, +): String { + return this.fiatRate?.let { status.amount.toFiatValue(it) } + ?.takeIf { !status.isErrorStatus } + ?.toFormattedFiatValue(fiatCurrency.symbol) + ?: unknownAmountSign +} + +internal fun WalletDataModel.getFormattedFiatRate(fiatCurrency: FiatCurrency, noRateValue: String): String { + return fiatRate?.toFiatRateString(fiatCurrency.symbol) + ?: noRateValue +} + +internal fun WalletDataModel.isAvailableToBuy(exchangeManager: CurrencyExchangeManager): Boolean { + return exchangeManager.availableForBuy(currency) +} + +internal fun WalletDataModel.isAvailableToSell(exchangeManager: CurrencyExchangeManager): Boolean { + return exchangeManager.availableForSell(currency) +} + +internal fun WalletDataModel.isAvailableToSwap( + swapFeatureToggleManager: SwapFeatureToggleManager, + swapInteractor: SwapInteractor, +): Boolean { + if (currency.blockchain.id == Blockchain.Optimism.id && !swapFeatureToggleManager.isOptimismSwapEnabled) { + return false + } + return swapInteractor.isAvailableToSwap(currency.blockchain.toNetworkId()) && + !currency.isCustomCurrency(null) +} + +internal fun WalletDataModel.getAvailableActions( + swapInteractor: SwapInteractor, + exchangeManager: CurrencyExchangeManager, + swapFeatureToggleManager: SwapFeatureToggleManager, +): Set { + return setOfNotNull( + if (isAvailableToBuy(exchangeManager)) CurrencyAction.Buy else null, + if (isAvailableToSell(exchangeManager)) CurrencyAction.Sell else null, + if (isAvailableToSwap(swapFeatureToggleManager, swapInteractor)) CurrencyAction.Swap else null, + ) +} + +internal fun WalletDataModel.shouldShowMultipleAddress(): Boolean { + val listOfAddresses = walletAddresses?.list.orEmpty() + return listOfAddresses.size > 1 +} + +internal fun WalletDataModel.assembleWarnings( + blockchainAmount: BigDecimal, + blockchainWalletRent: WalletStoreModel.WalletRent?, +): List { + val walletWarnings = mutableListOf() + assembleNonTypedWarnings(walletWarnings, blockchainWalletRent) + assembleBlockchainWarnings(walletWarnings) + assembleTokenWarnings(walletWarnings, blockchainAmount) + + return walletWarnings.sortedBy { it.showingPosition } +} + +private fun WalletDataModel.assembleNonTypedWarnings( + walletWarnings: MutableList, + walletRent: WalletStoreModel.WalletRent?, +) { + if (this.status is WalletDataModel.SameCurrencyTransactionInProgress) { + walletWarnings.add(WalletWarning.TransactionInProgress(currency.currencyName)) + } + if (walletRent != null) { + walletWarnings.add(WalletWarning.Rent(walletRent)) + } +} + +private fun WalletDataModel.assembleBlockchainWarnings(walletWarnings: MutableList) { + with(currency) { + if (!isBlockchain()) return + + if (existentialDeposit != null) { + val warning = WalletWarning.ExistentialDeposit( + currencyName = currencyName, + edStringValueWithSymbol = "${existentialDeposit.toPlainString()} $currencySymbol", + ) + walletWarnings.add(warning) + } + } +} + +private fun WalletDataModel.assembleTokenWarnings( + walletWarnings: MutableList, + blockchainAmount: BigDecimal, +) { + if (!currency.isToken()) return + + if (!this.isEmptyAmount && blockchainAmount.isZero()) { + walletWarnings.add( + WalletWarning.BalanceNotEnoughForFee( + currencyName = currency.currencyName, + blockchainFullName = currency.blockchain.fullName, + blockchainSymbol = currency.blockchain.currency, + ), + ) + } +} + +private val WalletDataModel.isEmptyAmount: Boolean + get() = this.status.amount.isZero() + +enum class CurrencyAction { + Buy, Sell, Swap +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/view/TotalBalanceCard.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/view/TotalBalanceCard.kt index 4efe5659b4..4eab1313a5 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/view/TotalBalanceCard.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/view/TotalBalanceCard.kt @@ -35,9 +35,8 @@ import com.tangem.core.ui.components.SpacerW4 import com.tangem.core.ui.res.TangemTheme import com.tangem.tap.common.entities.FiatCurrency import com.tangem.tap.common.extensions.formatWithSpaces -import com.tangem.tap.features.wallet.models.TotalBalance -import com.tangem.tap.features.wallet.redux.ProgressState -import com.tangem.tap.features.wallet.redux.WalletState.Companion.UNKNOWN_AMOUNT_SIGN +import com.tangem.tap.domain.model.TotalFiatBalance +import com.tangem.tap.features.wallet.redux.utils.UNKNOWN_AMOUNT_SIGN import com.tangem.wallet.R import com.valentinilk.shimmer.shimmer import java.math.BigDecimal @@ -52,18 +51,25 @@ internal class TotalBalanceCard @JvmOverloads constructor( ) : AbstractComposeView(context, attrs, defStyleAttr) { private var state by mutableStateOf(TotalBalanceCardState.Empty) - var status: TotalBalance? = null + var status: TotalFiatBalance? = null set(value) { if (field == value) return field = value - updateState(value, onChangeFiatCurrencyClick) + updateState(value, fiatCurrency, onChangeFiatCurrencyClick) } var onChangeFiatCurrencyClick: () -> Unit = { /* no-op */ } set(value) { if (field == value) return field = value - updateState(status, value) + updateState(status, fiatCurrency, value) + } + + var fiatCurrency: FiatCurrency = FiatCurrency.Default + set(value) { + if (field == value) return + field = value + updateState(status, value, onChangeFiatCurrencyClick) } @Composable @@ -77,23 +83,21 @@ internal class TotalBalanceCard @JvmOverloads constructor( return javaClass.name } - private fun updateState(status: TotalBalance?, onChangeCurrencyClick: () -> Unit) { - state = when (status?.state) { + private fun updateState(status: TotalFiatBalance?, fiatCurrency: FiatCurrency, onChangeCurrencyClick: () -> Unit) { + state = when (status) { null -> TotalBalanceCardState.Empty - ProgressState.Loading -> TotalBalanceCardState.Loading( - fiatCurrency = status.fiatCurrency, + is TotalFiatBalance.Error -> TotalBalanceCardState.Failure( + amount = status.amount, + fiatCurrency = fiatCurrency, onChangeFiatCurrencyClick = onChangeCurrencyClick, ) - ProgressState.Error -> TotalBalanceCardState.Failure( - amount = status.fiatAmount, - fiatCurrency = status.fiatCurrency, + is TotalFiatBalance.Loading -> TotalBalanceCardState.Loading( + fiatCurrency = fiatCurrency, onChangeFiatCurrencyClick = onChangeCurrencyClick, ) - ProgressState.Refreshing, - ProgressState.Done, - -> TotalBalanceCardState.Success( - amount = status.fiatAmount ?: BigDecimal.ZERO, - fiatCurrency = status.fiatCurrency, + is TotalFiatBalance.Loaded -> TotalBalanceCardState.Success( + amount = status.amount, + fiatCurrency = fiatCurrency, onChangeFiatCurrencyClick = onChangeCurrencyClick, ) } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/view/WalletDetailsButtonsRow.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/view/WalletDetailsButtonsRow.kt index c7457f1158..d9bf31f00c 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/view/WalletDetailsButtonsRow.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/view/WalletDetailsButtonsRow.kt @@ -9,7 +9,7 @@ import androidx.core.view.isVisible import com.google.android.material.button.MaterialButton import com.tangem.tap.common.extensions.hide import com.tangem.tap.common.extensions.show -import com.tangem.tap.features.wallet.redux.CurrencyAction +import com.tangem.tap.features.wallet.ui.utils.CurrencyAction import com.tangem.wallet.databinding.ViewWalletDetailsButtonsRowBinding internal class WalletDetailsButtonsRow @JvmOverloads constructor( diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/MultiWalletView.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/MultiWalletView.kt index d735ef9615..f981a8beca 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/MultiWalletView.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/MultiWalletView.kt @@ -1,6 +1,5 @@ package com.tangem.tap.features.wallet.ui.wallet -import android.widget.Button import androidx.core.view.isVisible import androidx.recyclerview.widget.LinearLayoutManager import com.badoo.mvicore.modelWatcher @@ -14,14 +13,13 @@ import com.tangem.tap.common.extensions.hide import com.tangem.tap.common.extensions.show import com.tangem.tap.common.redux.navigation.AppScreen import com.tangem.tap.common.redux.navigation.NavigationAction +import com.tangem.tap.domain.model.TotalFiatBalance import com.tangem.tap.features.tokens.redux.TokensAction -import com.tangem.tap.features.wallet.models.TotalBalance +import com.tangem.tap.features.wallet.redux.ErrorType import com.tangem.tap.features.wallet.redux.WalletAction import com.tangem.tap.features.wallet.redux.WalletState -import com.tangem.tap.features.wallet.ui.BalanceStatus import com.tangem.tap.features.wallet.ui.WalletFragment import com.tangem.tap.features.wallet.ui.adapters.WalletAdapter -import com.tangem.tap.features.wallet.ui.view.WalletDetailsButtonsRow import com.tangem.tap.store import com.tangem.wallet.R import com.tangem.wallet.databinding.FragmentWalletBinding @@ -151,35 +149,29 @@ class MultiWalletView : WalletView() { } } - private fun handleTotalBalance(binding: FragmentWalletBinding, totalBalance: TotalBalance?, walletsCount: Int) = - with(binding.lCardTotalBalance) { - isVisible = walletsCount > 0 + private fun handleTotalBalance( + binding: FragmentWalletBinding, + totalBalance: TotalFiatBalance?, + walletsCount: Int, + ) = with(binding.lCardTotalBalance) { + isVisible = walletsCount > 0 - onChangeFiatCurrencyClick = { - store.dispatch(WalletAction.AppCurrencyAction.ChooseAppCurrency) - } - status = totalBalance + onChangeFiatCurrencyClick = { + store.dispatch(WalletAction.AppCurrencyAction.ChooseAppCurrency) } + status = totalBalance + } private fun handleErrorStates(state: WalletState, binding: FragmentWalletBinding, fragment: WalletFragment) { - when (state.primaryWalletData?.currencyData?.status) { - BalanceStatus.EmptyCard -> { - showErrorState( - binding, - fragment.getText(R.string.wallet_error_empty_card), - fragment.getString(R.string.wallet_error_empty_card_subtitle), - ) - configureButtonsForEmptyWalletState(binding) - } - BalanceStatus.UnknownBlockchain -> { + when (state.error) { + ErrorType.UnknownBlockchain -> { showErrorState( binding, fragment.getText(R.string.wallet_error_unsupported_blockchain), fragment.getString(R.string.wallet_error_unsupported_blockchain_subtitle), ) } - else -> { /* no-op */ - } + else -> { /* no-op */ } } } @@ -199,27 +191,8 @@ class MultiWalletView : WalletView() { } } - private fun configureButtonsForEmptyWalletState(binding: FragmentWalletBinding) = with(binding) { - rowButtons.btnBuy.hide() - rowButtons.btnSell.hide() - rowButtons.btnTrade.hide() - rowButtons.show() - - rowButtons.btnSend.text = fragment?.getText(R.string.wallet_button_create_wallet) - rowButtons.onSendClick = { store.dispatch(WalletAction.CreateWallet) } - } - override fun onDestroyFragment() { super.onDestroyFragment() watcher.clear() } -} - -private val WalletDetailsButtonsRow.btnBuy: Button - get() = this.findViewById(R.id.btn_buy) -private val WalletDetailsButtonsRow.btnSell: Button - get() = this.findViewById(R.id.btn_sell) -private val WalletDetailsButtonsRow.btnTrade: Button - get() = this.findViewById(R.id.btn_trade) -private val WalletDetailsButtonsRow.btnSend: Button - get() = this.findViewById(R.id.btn_send) \ No newline at end of file +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt index f29df37ca0..744fc34601 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/SingleWalletView.kt @@ -11,14 +11,19 @@ import com.tangem.tap.common.extensions.getQuantityString import com.tangem.tap.common.extensions.getString import com.tangem.tap.common.extensions.hide import com.tangem.tap.common.extensions.show +import com.tangem.tap.domain.model.WalletDataModel import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsState import com.tangem.tap.features.wallet.models.Currency import com.tangem.tap.features.wallet.models.PendingTransaction import com.tangem.tap.features.wallet.models.PendingTransactionType import com.tangem.tap.features.wallet.redux.WalletAction -import com.tangem.tap.features.wallet.redux.WalletData import com.tangem.tap.features.wallet.redux.WalletMainButton import com.tangem.tap.features.wallet.redux.WalletState +import com.tangem.tap.features.wallet.ui.utils.getAvailableActions +import com.tangem.tap.features.wallet.ui.utils.isAvailableToBuy +import com.tangem.tap.features.wallet.ui.utils.isAvailableToSell +import com.tangem.tap.features.wallet.ui.utils.mainButton +import com.tangem.tap.features.wallet.ui.utils.shouldShowMultipleAddress import com.tangem.tap.features.wallet.ui.BalanceWidget import com.tangem.tap.features.wallet.ui.MultipleAddressUiHelper import com.tangem.tap.features.wallet.ui.WalletFragment @@ -71,7 +76,7 @@ class SingleWalletView : WalletView() { setupTwinCards(state.twinCardsState, binding) setupButtons(primaryWalletData, binding, state.isExchangeServiceFeatureOn) setupAddressCard(state, binding) - showPendingTransactionsIfPresent(primaryWalletData.pendingTransactions) + showPendingTransactionsIfPresent(primaryWalletData.status.pendingTransactions) setupBalance(state, primaryWalletData) } @@ -83,32 +88,30 @@ class SingleWalletView : WalletView() { binding?.rvPendingTransaction?.show(knownTransactions.isNotEmpty()) } - private fun setupBalance(state: WalletState, primaryWallet: WalletData) { + private fun setupBalance(state: WalletState, primaryWallet: WalletDataModel) { val fragment = fragment ?: return binding?.apply { lCardBalance.lBalance.root.show() BalanceWidget( binding = this.lCardBalance, fragment = fragment, - data = primaryWallet.currencyData, - token = state.primaryTokenData?.currencyData, - isTwinCard = state.isTangemTwins, + blockchainWalletData = primaryWallet, + tokenWalletData = state.primaryTokenData, ).setup() } } private fun setupTwinCards(twinCardsState: TwinCardsState?, binding: FragmentWalletBinding) = with(binding) { - twinCardsState?.cardNumber?.let { cardNumber -> - tvTwinCardNumber.show() - tvTwinCardNumber.text = tvTwinCardNumber.getQuantityString(R.plurals.card_label_card_count, 2) - } if (twinCardsState?.cardNumber == null) { tvTwinCardNumber.hide() + } else { + tvTwinCardNumber.show() + tvTwinCardNumber.text = tvTwinCardNumber.getQuantityString(R.plurals.card_label_card_count, 2) } } private fun setupButtons( - walletData: WalletData, + walletData: WalletDataModel, binding: FragmentWalletBinding, isExchangeServiceFeatureEnabled: Boolean, ) = with(binding) { @@ -134,7 +137,7 @@ class SingleWalletView : WalletView() { } private fun setupRowButtons( - walletData: WalletData, + walletData: WalletDataModel, rowButtons: WalletDetailsButtonsRow, isExchangeServiceFeatureEnabled: Boolean, ) { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/saltPay/SaltPayWalletView.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/saltPay/SaltPayWalletView.kt index e999ee383a..ef9bf43ffa 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/saltPay/SaltPayWalletView.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/saltPay/SaltPayWalletView.kt @@ -8,13 +8,15 @@ import com.tangem.tap.common.ShimmerData import com.tangem.tap.common.ShimmerRecyclerAdapter import com.tangem.tap.common.analytics.events.MainScreen import com.tangem.tap.common.extensions.animateVisibility -import com.tangem.tap.common.extensions.formatAmountAsSpannedString import com.tangem.tap.common.extensions.hide import com.tangem.tap.common.extensions.show import com.tangem.tap.common.recyclerView.SpaceItemDecoration import com.tangem.tap.features.wallet.redux.ProgressState import com.tangem.tap.features.wallet.redux.WalletAction import com.tangem.tap.features.wallet.redux.WalletState +import com.tangem.tap.features.wallet.ui.utils.getFormattedAmount +import com.tangem.tap.features.wallet.ui.utils.getFormattedFiatAmount +import com.tangem.tap.features.wallet.ui.utils.isAvailableToBuy import com.tangem.tap.features.wallet.ui.WalletFragment import com.tangem.tap.features.wallet.ui.wallet.WalletView import com.tangem.tap.features.wallet.ui.wallet.saltPay.rv.HistoryItemData @@ -124,16 +126,14 @@ class SaltPayWalletView : WalletView() { tvUnreachable.animateVisibility(show = mainProgressState == ProgressState.Error) veilBalanceCrypto.animateVisibility(show = mainProgressState != ProgressState.Error) - if (tokenData.currencyData.fiatAmount == null) { + if (tokenData.fiatRate == null) { veilBalance.veil() } else { veilBalance.unVeil() - tvBalance.text = tokenData.currencyData.fiatAmount.formatAmountAsSpannedString( - currencySymbol = appCurrency.symbol, - ) + tvBalance.text = tokenData.getFormattedFiatAmount(appCurrency) } - tvBalanceCrypto.text = tokenData.currencyData.amountFormatted + tvBalanceCrypto.text = tokenData.getFormattedAmount() tvCurrencyName.text = appCurrency.code tvCurrencyName.setOnClickListener { diff --git a/app/src/main/java/com/tangem/tap/features/walletSelector/ui/Mapper.kt b/app/src/main/java/com/tangem/tap/features/walletSelector/ui/Mapper.kt index a00447b139..400c4e026e 100644 --- a/app/src/main/java/com/tangem/tap/features/walletSelector/ui/Mapper.kt +++ b/app/src/main/java/com/tangem/tap/features/walletSelector/ui/Mapper.kt @@ -3,7 +3,7 @@ package com.tangem.tap.features.walletSelector.ui import com.tangem.tap.common.entities.FiatCurrency import com.tangem.tap.common.extensions.toFormattedFiatValue import com.tangem.tap.domain.model.TotalFiatBalance -import com.tangem.tap.features.wallet.redux.WalletState.Companion.UNKNOWN_AMOUNT_SIGN +import com.tangem.tap.features.wallet.redux.utils.UNKNOWN_AMOUNT_SIGN import com.tangem.tap.features.walletSelector.redux.UserWalletModel import com.tangem.tap.features.walletSelector.ui.model.MultiCurrencyUserWalletItem import com.tangem.tap.features.walletSelector.ui.model.SingleCurrencyUserWalletItem