diff --git a/app/build.gradle b/app/build.gradle index 446c060d9f..3dcd68f4e8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -170,6 +170,8 @@ dependencies { implementation 'androidx.compose.ui:ui-tooling:1.1.1' implementation "com.google.accompanist:accompanist-appcompat-theme:0.23.0" + implementation "com.github.skydoves:androidveil:1.1.2" + implementation("io.coil-kt:coil:2.0.0-rc01") implementation("io.coil-kt:coil-compose:2.0.0-rc01") @@ -180,4 +182,4 @@ dependencies { androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' -} \ No newline at end of file +} diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Specific.kt b/app/src/main/java/com/tangem/tap/common/extensions/Specific.kt index ea112781c3..b431b780ad 100644 --- a/app/src/main/java/com/tangem/tap/common/extensions/Specific.kt +++ b/app/src/main/java/com/tangem/tap/common/extensions/Specific.kt @@ -108,24 +108,22 @@ fun BigDecimal.isLessThanOrEqual(value: BigDecimal): Boolean { fun BigDecimal.formatAmountAsSpannedString( currencySymbol: String, - integerPartSizeProportion: Float = 1.4f + reminderPartSizeProportion: Float = 0.7f ): SpannedString { val amount = this .setScale(2, RoundingMode.HALF_UP) - .toString() + .formatWithSpaces() val integer = amount.substringBefore('.') val reminder = amount.substringAfter('.') return buildSpannedString { + append(integer) + append('.') append( - integer, - RelativeSizeSpan(integerPartSizeProportion), + "$reminder $currencySymbol", + RelativeSizeSpan(reminderPartSizeProportion), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE ) - append('.') - append(reminder) - append(' ') - append(currencySymbol) } } 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 8328274be6..6230fd27a3 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 @@ -2,6 +2,7 @@ package com.tangem.tap.features.wallet.ui.adapters import android.view.LayoutInflater import android.view.ViewGroup +import androidx.core.view.isVisible import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView @@ -10,6 +11,7 @@ import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.Token import com.tangem.domain.common.TapWorkarounds.derivationStyle import com.tangem.tap.common.extensions.getString +import com.tangem.tap.common.extensions.hide import com.tangem.tap.common.extensions.loadCurrenciesIcon import com.tangem.tap.common.extensions.show import com.tangem.tap.features.wallet.redux.Currency @@ -61,57 +63,63 @@ class WalletAdapter RecyclerView.ViewHolder(binding.root) { fun bind(wallet: WalletData) = with(binding) { - tvCurrency.text = wallet.currencyData.currency - tvAmount.text = wallet.currencyData.amountFormatted.orEmpty() - tvAmountFiat.text = wallet.currencyData.fiatAmountFormatted - tvExchangeRate.text = wallet.fiatRateString - cardWallet.setOnClickListener { - store.dispatch(WalletAction.MultiWallet.SelectWallet(wallet)) + val status = wallet.currencyData.status + val isCustomCurrency = wallet.currency.isCustomCurrency( + derivationStyle = store.state.globalState + .scanResponse + ?.card + ?.derivationStyle + ) + val statusMessage = when (status) { + BalanceStatus.TransactionInProgress -> { + root.getString(R.string.wallet_balance_tx_in_progress) + } + BalanceStatus.Unreachable -> { + root.getString(R.string.wallet_balance_blockchain_unreachable) + } + BalanceStatus.NoAccount -> { + root.getString(R.string.wallet_error_no_account) + } + BalanceStatus.VerifiedOnline, + BalanceStatus.SameCurrencyTransactionInProgress, + BalanceStatus.EmptyCard, + BalanceStatus.UnknownBlockchain, + BalanceStatus.Loading, + null -> null } - val blockchain = wallet.currency.blockchain - val token = (wallet.currency as? Currency.Token)?.token - val isCustom = wallet.currency - .isCustomCurrency(store.state.globalState.scanResponse?.card?.derivationStyle) - tvExchangeRate.show(!isCustom) - tvCustomCurrency.show(isCustom) + if (status == null || status == BalanceStatus.Loading) { + lContent.root.hide() + lShimmer.root.veil() + } else { + lShimmer.root.unVeil() + lContent.root.show() + } Picasso.get().loadCurrenciesIcon( imageView = ivCurrency, textView = tvTokenLetter, - token = token, blockchain = blockchain, + token = (wallet.currency as? Currency.Token)?.token, + blockchain = wallet.currency.blockchain, ) - when (wallet.currencyData.status) { - BalanceStatus.VerifiedOnline, - BalanceStatus.SameCurrencyTransactionInProgress -> hideMessage() - BalanceStatus.Loading -> if (wallet.currencyData.amountFormatted == null) { - showMessage(root.getString(R.string.wallet_balance_loading)) - } - BalanceStatus.TransactionInProgress -> - showMessage(root.getString(R.string.wallet_balance_tx_in_progress)) - BalanceStatus.Unreachable -> - showMessage(root.getString(R.string.wallet_balance_blockchain_unreachable)) + lContent.tvCurrency.text = wallet.currencyData.currency + lContent.tvAmountFiat.text = wallet.currencyData.fiatAmountFormatted ?: "—" + lContent.tvAmount.text = wallet.currencyData.amountFormatted ?: "—" - BalanceStatus.NoAccount -> - showMessage(root.getString(R.string.wallet_error_no_account)) - else -> { - } + lContent.tvStatus.isVisible = statusMessage != null + lContent.tvStatus.text = statusMessage + + lContent.tvExchangeRate.isVisible = statusMessage == null + lContent.tvExchangeRate.text = if (isCustomCurrency) { + root.getString(id = R.string.token_item_no_rate) + } else { + wallet.fiatRateString } - } - private fun showMessage(message: String) { - toggleMessage(true) - binding.tvStatus.text = message - } - - private fun hideMessage() { - toggleMessage(false) - } - - private fun toggleMessage(show: Boolean) { - binding.tvAmount.show(!show) - binding.tvStatus.show(show) + cardWallet.setOnClickListener { + store.dispatch(WalletAction.MultiWallet.SelectWallet(wallet)) + } } } } \ No newline at end of file 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 66b4a9e664..623f19e85d 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,7 +1,6 @@ package com.tangem.tap.features.wallet.ui.wallet import android.app.Dialog -import android.view.View import androidx.core.view.isVisible import androidx.recyclerview.widget.LinearLayoutManager import com.tangem.common.card.Card @@ -132,13 +131,11 @@ class MultiWalletView : WalletView { ) = with(binding.lCardTotalBalance) { root.isVisible = totalBalance != null if (totalBalance != null) { - tvBalance.animateVisibility( - show = totalBalance.state != TotalBalance.State.Loading, - hiddenVisibility = View.INVISIBLE - ) - pbLoading.animateVisibility( - show = totalBalance.state == TotalBalance.State.Loading - ) + if (totalBalance.state == TotalBalance.State.Loading) { + veilBalance.veil() + } else { + veilBalance.unVeil() + } tvProcessing.animateVisibility( show = totalBalance.state == TotalBalance.State.SomeTokensFailed ) diff --git a/app/src/main/res/layout/card_total_balance.xml b/app/src/main/res/layout/card_total_balance.xml index 0b0d382e71..196dc167e1 100644 --- a/app/src/main/res/layout/card_total_balance.xml +++ b/app/src/main/res/layout/card_total_balance.xml @@ -22,10 +22,10 @@ - + tools:veilLayout_veiled="false"> - + + + + + + + + diff --git a/app/src/main/res/layout/item_currency_wallet.xml b/app/src/main/res/layout/item_currency_wallet.xml index c2d664e182..ddb13e5666 100644 --- a/app/src/main/res/layout/item_currency_wallet.xml +++ b/app/src/main/res/layout/item_currency_wallet.xml @@ -21,7 +21,8 @@ android:layout_marginTop="12dp" android:layout_marginBottom="12dp" android:layout_marginStart="16dp" - android:layout_marginEnd="16dp"> + android:layout_marginEnd="16dp" + android:animateLayoutChanges="true"> - - - - - - - - - - - - + app:layout_constraintEnd_toEndOf="parent" + tools:visibility="visible" /> - - - + app:layout_constraintStart_toEndOf="@id/iv_currency" + app:layout_constraintEnd_toEndOf="parent" /> diff --git a/app/src/main/res/layout/item_currency_wallet_content.xml b/app/src/main/res/layout/item_currency_wallet_content.xml new file mode 100644 index 0000000000..18249f4c63 --- /dev/null +++ b/app/src/main/res/layout/item_currency_wallet_content.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/item_currency_wallet_shimmer.xml b/app/src/main/res/layout/item_currency_wallet_shimmer.xml new file mode 100644 index 0000000000..a37bd8c956 --- /dev/null +++ b/app/src/main/res/layout/item_currency_wallet_shimmer.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 0e8fe53b9d..75c6262e20 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -385,4 +385,5 @@ Баланс Обработка полной суммы… Управление токенами + Нет цены diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c87db69e49..65c053f776 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -207,6 +207,7 @@ Reduce by %s XTZ No, send all Total balance - Processing full amount… + Some networks are unreachable Manage tokens + No rate diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 49c8fefbbb..f36d1cd4bf 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -160,7 +160,6 @@ -