diff --git a/app/build.gradle b/app/build.gradle index 3e16223f89..48f34abcb7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -93,10 +93,10 @@ dependencies { implementation 'com.google.android.play:core-ktx:1.8.1' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5' - implementation 'com.tangem:blockchain:develop-85' + implementation 'com.tangem:blockchain:develop-88' // implementation 'com.tangem:blockchain:0.0.1' - implementation 'com.tangem.tangem-sdk-kotlin:core:develop-142' - implementation 'com.tangem.tangem-sdk-kotlin:android:develop-142' + implementation 'com.tangem.tangem-sdk-kotlin:core:develop-154' + implementation 'com.tangem.tangem-sdk-kotlin:android:develop-154' // WebView implementation "androidx.browser:browser:1.3.0" diff --git a/app/src/main/assets/tangem-app-config b/app/src/main/assets/tangem-app-config index 7f058ec409..985642c135 160000 --- a/app/src/main/assets/tangem-app-config +++ b/app/src/main/assets/tangem-app-config @@ -1 +1 @@ -Subproject commit 7f058ec409b4eaaf8688ecd4bf944ef8d58d3564 +Subproject commit 985642c135606ba1f59fd739127aec03024da79b diff --git a/app/src/main/java/com/tangem/tap/common/compose/extensions/LazyListState.kt b/app/src/main/java/com/tangem/tap/common/compose/extensions/LazyListState.kt index a14477efca..f05044368f 100644 --- a/app/src/main/java/com/tangem/tap/common/compose/extensions/LazyListState.kt +++ b/app/src/main/java/com/tangem/tap/common/compose/extensions/LazyListState.kt @@ -2,6 +2,8 @@ package com.tangem.tap.common.compose.extensions import androidx.compose.foundation.lazy.LazyListState import androidx.compose.runtime.* +import androidx.compose.ui.platform.LocalView +import com.tangem.tap.common.extensions.hideKeyboard @Composable fun LazyListState.OnBottomReached(loadMoreThreshold: Int, loadMore: () -> Unit) { @@ -17,4 +19,11 @@ fun LazyListState.OnBottomReached(loadMoreThreshold: Int, loadMore: () -> Unit) LaunchedEffect(shouldLoadMore) { if (shouldLoadMore) loadMore() } +} + +@Composable +fun LazyListState.HideKeyboardOnScroll() { + if (isScrollInProgress) { + LocalView.current.hideKeyboard() + } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt b/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt index dcf89c160d..5cf9b2d3ad 100644 --- a/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt +++ b/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt @@ -8,6 +8,7 @@ import com.tangem.wallet.R @DrawableRes fun Blockchain.getRoundIconRes(): Int { return when (this) { + Blockchain.Arbitrum, Blockchain.ArbitrumTestnet -> R.drawable.ic_arbitrum_round Blockchain.Ducatus -> R.drawable.ic_ducatus Blockchain.Bitcoin, Blockchain.BitcoinTestnet,-> R.drawable.ic_bitcoin_round Blockchain.BitcoinCash -> R.drawable.ic_bitcoin_cash_round @@ -33,6 +34,7 @@ fun Blockchain.getRoundIconRes(): Int { @DrawableRes fun Blockchain.getGreyedOutIconRes(): Int { return when (this) { + Blockchain.Arbitrum, Blockchain.ArbitrumTestnet -> R.drawable.ic_arbitrum_no_color // Blockchain.Ducatus -> R.drawable.ic_ducatus Blockchain.Bitcoin, Blockchain.BitcoinTestnet,-> R.drawable.ic_bitcoin_no_color Blockchain.BitcoinCash -> R.drawable.ic_bitcoin_cash_no_color diff --git a/app/src/main/java/com/tangem/tap/domain/extensions/CurrencyExchangeManager.kt b/app/src/main/java/com/tangem/tap/domain/extensions/CurrencyExchangeManager.kt index d3f7730510..23be9f4aaf 100644 --- a/app/src/main/java/com/tangem/tap/domain/extensions/CurrencyExchangeManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/extensions/CurrencyExchangeManager.kt @@ -1,6 +1,7 @@ package com.tangem.tap.domain.extensions import com.tangem.blockchain.common.Blockchain +import com.tangem.blockchain.common.Blockchain.Arbitrum import com.tangem.tap.features.wallet.redux.Currency import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager import com.tangem.tap.network.exchangeServices.CurrencyExchangeStatus @@ -19,6 +20,7 @@ fun CurrencyExchangeManager.sellIsAllowed(currency: Currency): Boolean { fun CurrencyExchangeStatus.buyIsAllowed(currency: Currency): Boolean { if (store.state.globalState.configManager?.config?.isTopUpEnabled == false) return false + if (currency.blockchain == Arbitrum) return false if (!isBuyAllowed) return false //TODO: temporary, for the 3.32 release, unlock all buy button diff --git a/app/src/main/java/com/tangem/tap/domain/tokens/LoadAvailableCoinsService.kt b/app/src/main/java/com/tangem/tap/domain/tokens/LoadAvailableCoinsService.kt index b195457e4f..a0be7dc18a 100644 --- a/app/src/main/java/com/tangem/tap/domain/tokens/LoadAvailableCoinsService.kt +++ b/app/src/main/java/com/tangem/tap/domain/tokens/LoadAvailableCoinsService.kt @@ -21,7 +21,7 @@ class LoadAvailableCoinsService( if (isTestNet) { return Result.Success( LoadedCoins( - currencies = currenciesRepository.getTestnetCoins(), + currencies = currenciesRepository.getTestnetCoins().filter(searchInput), moreAvailable = false, ) ) @@ -59,6 +59,15 @@ class LoadAvailableCoinsService( ) } + private fun List.filter(searchInput: String?): List { + if (searchInput.isNullOrBlank()) return this + + return filter{ + it.symbol.contains(searchInput, ignoreCase = true) || + it.name.contains(searchInput, ignoreCase = true) + } + } + companion object { const val LOAD_PER_PAGE = 100 } diff --git a/app/src/main/java/com/tangem/tap/domain/twins/WriteProtectedIssuerDataTask.kt b/app/src/main/java/com/tangem/tap/domain/twins/WriteProtectedIssuerDataTask.kt index 37f9715e19..e4ae0109bd 100644 --- a/app/src/main/java/com/tangem/tap/domain/twins/WriteProtectedIssuerDataTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/twins/WriteProtectedIssuerDataTask.kt @@ -63,11 +63,17 @@ class WriteProtectedIssuerDataTask( val counter = (readResponse.issuerDataCounter ?: 0) + 1 val data = twinPublicKey + cardSignature val signedByIssuer = FileHashHelper.prepareHashes( - cardId, data, counter, issuerKeys.privateKey + cardId = cardId, + fileData = data, + fileCounter = counter, + fileName = null, + privateKey = issuerKeys.privateKey, ) WriteIssuerDataCommand( - data, signedByIssuer.finalizingSignature!!, - counter, issuerKeys.publicKey + issuerData = data, + issuerDataSignature = signedByIssuer.finalizingSignature!!, + issuerDataCounter = counter, + issuerPublicKey = issuerKeys.publicKey, ).run(session, callback) } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt index 0739effc65..c37a625c54 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt @@ -5,6 +5,7 @@ import com.tangem.common.card.Card import com.tangem.domain.common.ScanResponse import com.tangem.domain.common.TwinCardNumber import com.tangem.operations.pins.CheckUserCodesResponse +import com.tangem.tap.common.entities.FiatCurrency import com.tangem.tap.common.redux.NotificationAction import com.tangem.tap.domain.termsOfUse.CardTou import com.tangem.wallet.R @@ -58,4 +59,5 @@ sealed class DetailsAction : Action { } } + data class ChangeAppCurrency(val fiatCurrency: FiatCurrency) : DetailsAction() } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt index 45910f64c4..a095d46d7e 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt @@ -31,6 +31,9 @@ private fun internalReduce(action: Action, state: AppState): DetailsState { is DetailsAction.ManageSecurity -> { handleSecurityAction(action, detailsState) } + is DetailsAction.ChangeAppCurrency -> + detailsState.copy(appCurrency = action.fiatCurrency) + else -> detailsState } } diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsState.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsState.kt index eca730c5e2..ee6fd2bb7e 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsState.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsState.kt @@ -4,6 +4,7 @@ import android.net.Uri import com.tangem.blockchain.common.Wallet import com.tangem.domain.common.ScanResponse import com.tangem.tap.common.entities.Button +import com.tangem.tap.common.entities.FiatCurrency import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsState import com.tangem.tap.store import org.rekotlin.StateType @@ -19,6 +20,7 @@ data class DetailsState( val securityScreenState: SecurityScreenState? = null, val cardTermsOfUseUrl: Uri? = null, val createBackupAllowed: Boolean = false, + val appCurrency: FiatCurrency = FiatCurrency.Default ) : StateType { // if you do not delegate - the application crashes on startup, diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/DetailsFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/DetailsFragment.kt index d4ad890b8b..e8f3b56a62 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/DetailsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/DetailsFragment.kt @@ -17,6 +17,7 @@ import com.tangem.tap.features.details.redux.DetailsAction import com.tangem.tap.features.details.redux.DetailsState import com.tangem.tap.features.details.redux.SecurityOption import com.tangem.tap.features.feedback.FeedbackEmail +import com.tangem.tap.features.wallet.redux.WalletAction import com.tangem.tap.store import com.tangem.wallet.R import com.tangem.wallet.databinding.FragmentDetailsBinding @@ -114,6 +115,14 @@ class DetailsFragment : Fragment(R.layout.fragment_details), StoreSubscriber, val derivationStyle: DerivationStyle? ) : TokensAction() diff --git a/app/src/main/java/com/tangem/tap/features/tokens/redux/TokensMiddleware.kt b/app/src/main/java/com/tangem/tap/features/tokens/redux/TokensMiddleware.kt index 48f848e65a..aab99a3d58 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/redux/TokensMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/redux/TokensMiddleware.kt @@ -53,7 +53,13 @@ class TokensMiddleware { action.searchInput ) } - + is TokensAction.LoadMore -> { + if (store.state.tokensState.needToLoadMore + && store.state.tokensState.currencies.isNotEmpty() + ) { + handleLoadCurrencies(action.scanResponse) + } + } } next(action) } diff --git a/app/src/main/java/com/tangem/tap/features/tokens/ui/AddTokensFragment.kt b/app/src/main/java/com/tangem/tap/features/tokens/ui/AddTokensFragment.kt index fae99d7af4..8abbc33a2b 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/ui/AddTokensFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/ui/AddTokensFragment.kt @@ -84,7 +84,11 @@ class AddTokensFragment : Fragment(R.layout.fragment_add_tokens), } val onLoadMore = { - store.dispatch(TokensAction.LoadCurrencies(scanResponse = store.state.globalState.scanResponse)) + store.dispatch( + TokensAction.LoadMore( + scanResponse = store.state.globalState.scanResponse + ) + ) } cvCurrencies.setContent { diff --git a/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/ListOfCurrencies.kt b/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/ListOfCurrencies.kt index 75755a0e73..4892cf5e13 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/ListOfCurrencies.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/ListOfCurrencies.kt @@ -11,6 +11,7 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.tangem.blockchain.common.Blockchain +import com.tangem.tap.common.compose.extensions.HideKeyboardOnScroll import com.tangem.tap.common.compose.extensions.OnBottomReached import com.tangem.tap.domain.tokens.Currency import com.tangem.tap.features.tokens.redux.ContractAddress @@ -44,6 +45,8 @@ fun ListOfCurrencies( } val listState = rememberLazyListState() + listState.HideKeyboardOnScroll() + listState.OnBottomReached(loadMoreThreshold = 40) { onLoadMore() } LazyColumn( state = listState, @@ -67,7 +70,6 @@ fun ListOfCurrencies( ) } } - listState.OnBottomReached(loadMoreThreshold = 40) { onLoadMore() } } val Currency.fullName: String diff --git a/app/src/main/java/com/tangem/tap/features/wallet/models/PendingTransaction.kt b/app/src/main/java/com/tangem/tap/features/wallet/models/PendingTransaction.kt index d24a3ea480..b96f055f59 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/models/PendingTransaction.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/models/PendingTransaction.kt @@ -48,7 +48,7 @@ fun List.filterByCoin(): List { } fun List.filterByToken(token: Token): List { - return this.filter { it.currency == token.symbol } + return this.filter { it.transactionData.amount.currencySymbol == token.symbol } } fun TransactionData.toPendingTransactionForToken(token: Token, walletAddress: String): PendingTransaction? { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/models/TotalBalance.kt b/app/src/main/java/com/tangem/tap/features/wallet/models/TotalBalance.kt index fdabcb075d..5d63e8b816 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/models/TotalBalance.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/models/TotalBalance.kt @@ -1,16 +1,11 @@ package com.tangem.tap.features.wallet.models import com.tangem.tap.common.entities.FiatCurrency +import com.tangem.tap.features.wallet.redux.ProgressState import java.math.BigDecimal data class TotalBalance( - val state: State, + val state: ProgressState, val fiatAmount: BigDecimal, val fiatCurrency: FiatCurrency, -) { - enum class State { - Loading, - SomeTokensFailed, - Success, - } -} \ No newline at end of file +) \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt index 6ca5098dd8..769d28a8cd 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt @@ -1,7 +1,11 @@ package com.tangem.tap.features.wallet.redux import android.content.Context -import com.tangem.blockchain.common.* +import com.tangem.blockchain.common.Amount +import com.tangem.blockchain.common.Blockchain +import com.tangem.blockchain.common.Token +import com.tangem.blockchain.common.Wallet +import com.tangem.blockchain.common.WalletManager import com.tangem.blockchain.common.address.AddressType import com.tangem.common.card.Card import com.tangem.tap.common.entities.FiatCurrency @@ -11,8 +15,8 @@ import com.tangem.tap.domain.TapError import com.tangem.tap.domain.configurable.warningMessage.WarningMessage import com.tangem.tap.domain.tokens.models.BlockchainNetwork import com.tangem.wallet.R -import org.rekotlin.Action import java.math.BigDecimal +import org.rekotlin.Action sealed class WalletAction : Action { @@ -21,6 +25,7 @@ sealed class WalletAction : Action { data class SetIfTestnetCard(val isTestnet: Boolean) : WalletAction() object LoadData : WalletAction() { + object Refresh : WalletAction() data class Failure(val error: TapError) : WalletAction() } 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 aecdd574e8..b906784269 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 @@ -1,7 +1,12 @@ package com.tangem.tap.features.wallet.redux import android.graphics.Bitmap -import com.tangem.blockchain.common.* +import com.tangem.blockchain.common.Amount +import com.tangem.blockchain.common.Blockchain +import com.tangem.blockchain.common.DerivationStyle +import com.tangem.blockchain.common.Token +import com.tangem.blockchain.common.Wallet +import com.tangem.blockchain.common.WalletManager import com.tangem.blockchain.common.address.AddressType import com.tangem.common.extensions.isZero import com.tangem.domain.common.extensions.canHandleToken @@ -19,15 +24,21 @@ import com.tangem.tap.domain.extensions.sellIsAllowed import com.tangem.tap.domain.tokens.models.BlockchainNetwork import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsState import com.tangem.tap.features.tokens.redux.TokenWithBlockchain -import com.tangem.tap.features.wallet.models.* +import com.tangem.tap.features.wallet.models.PendingTransaction +import com.tangem.tap.features.wallet.models.TotalBalance +import com.tangem.tap.features.wallet.models.WalletRent +import com.tangem.tap.features.wallet.models.WalletWarning +import com.tangem.tap.features.wallet.models.hasPendingTransactions +import com.tangem.tap.features.wallet.models.hasSendableAmounts +import com.tangem.tap.features.wallet.models.isSendableAmount import com.tangem.tap.features.wallet.redux.reducers.calculateTotalFiatAmount -import com.tangem.tap.features.wallet.redux.reducers.findTotalBalanceState +import com.tangem.tap.features.wallet.redux.reducers.findProgressState import com.tangem.tap.features.wallet.ui.BalanceStatus import com.tangem.tap.features.wallet.ui.BalanceWidgetData import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager import com.tangem.tap.store -import org.rekotlin.StateType import java.math.BigDecimal +import org.rekotlin.StateType import kotlin.properties.ReadOnlyProperty data class WalletState( @@ -55,13 +66,14 @@ data class WalletState( val isTangemTwins: Boolean get() = store.state.globalState.scanResponse?.isTangemTwins() == true - val primaryWallet: WalletData? = if (wallets.isNotEmpty()) wallets[0].walletsData[0] else null + val primaryWallet: WalletData? = wallets.firstOrNull() + ?.walletsData?.firstOrNull() val primaryWalletManager: WalletManager? = if (wallets.isNotEmpty()) wallets[0].walletManager else null val shouldShowDetails: Boolean = primaryWallet?.currencyData?.status != BalanceStatus.EmptyCard && - primaryWallet?.currencyData?.status != BalanceStatus.UnknownBlockchain + primaryWallet?.currencyData?.status != BalanceStatus.UnknownBlockchain val blockchains: List get() = wallets.mapNotNull { it.walletManager?.wallet?.blockchain } @@ -191,6 +203,7 @@ data class WalletState( fun updateWalletStore(walletStore: WalletStore?): WalletState { return copy(wallets = replaceWalletInWallets(walletStore)) .updateTotalBalance() + .updateProgressState() } private fun updateWalletStores(walletStores: List): WalletState { @@ -208,6 +221,7 @@ data class WalletState( } return copy(wallets = updatedWallets + walletStoresMutable) .updateTotalBalance() + .updateProgressState() } fun removeWallet(walletData: WalletData?): WalletState { @@ -218,6 +232,8 @@ data class WalletState( && it.blockchainNetwork.derivationPath == walletData.currency.derivationPath } copy(wallets = walletStores) + .updateTotalBalance() + .updateProgressState() } else { val walletStore = getWalletStore(walletData.currency) val walletDataList = walletStore?.walletsData @@ -270,11 +286,13 @@ data class WalletState( } private fun updateTotalBalance(): WalletState { - return if (wallets.isNotEmpty()) { - val walletsData = wallets.flatMap(WalletStore::walletsData) + val walletsData = this.wallets + .flatMap(WalletStore::walletsData) + + return if (walletsData.isNotEmpty()) { this.copy( totalBalance = TotalBalance( - state = walletsData.findTotalBalanceState(), + state = walletsData.findProgressState(), fiatAmount = walletsData.calculateTotalFiatAmount(), fiatCurrency = store.state.globalState.appCurrency ) @@ -283,6 +301,20 @@ data class WalletState( totalBalance = null ) } + + private fun updateProgressState(): WalletState { + val walletsData = this.wallets + .flatMap(WalletStore::walletsData) + + return if (walletsData.isNotEmpty()) { + val newProgressState = walletsData.findProgressState() + + this.copy( + state = walletsData.findProgressState(), + error = this.error.takeIf { newProgressState == ProgressState.Error } + ) + } else this + } } sealed interface WalletDialog : StateDialog { @@ -295,7 +327,7 @@ sealed interface WalletDialog : StateDialog { ) : WalletDialog } -enum class ProgressState : WidgetState { Loading, Done, Error } +enum class ProgressState : WidgetState { Loading, Refreshing, Done, Error } enum class ErrorType { NoInternetConnection } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/AppCurrencyMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/AppCurrencyMiddleware.kt index 904aecab65..d339e49202 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/AppCurrencyMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/AppCurrencyMiddleware.kt @@ -7,6 +7,7 @@ import com.tangem.tap.common.entities.FiatCurrency import com.tangem.tap.common.extensions.dispatchDialogShow import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.domain.TapWalletManager +import com.tangem.tap.features.details.redux.DetailsAction import com.tangem.tap.features.wallet.redux.WalletAction import com.tangem.tap.features.wallet.redux.WalletDialog import com.tangem.tap.persistence.FiatCurrenciesPrefStorage @@ -63,6 +64,7 @@ class AppCurrencyMiddleware( tapWalletManager.rates.clear() fiatCurrenciesPrefStorage.saveAppCurrency(action.fiatCurrency) store.dispatch(GlobalAction.ChangeAppCurrency(action.fiatCurrency)) + store.dispatch(DetailsAction.ChangeAppCurrency(action.fiatCurrency)) store.dispatch(WalletAction.LoadFiatRate()) } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt index a4862b21b8..e4f7b6f659 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt @@ -15,7 +15,12 @@ import com.tangem.domain.common.extensions.withMainContext import com.tangem.operations.attestation.Attestation import com.tangem.operations.attestation.OnlineCardVerifier import com.tangem.tap.common.analytics.Analytics -import com.tangem.tap.common.extensions.* +import com.tangem.tap.common.extensions.copyToClipboard +import com.tangem.tap.common.extensions.dispatchDebugErrorNotification +import com.tangem.tap.common.extensions.dispatchOnMain +import com.tangem.tap.common.extensions.onCardScanned +import com.tangem.tap.common.extensions.shareText +import com.tangem.tap.common.extensions.stripZeroPlainString import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.common.redux.navigation.AppScreen @@ -28,12 +33,17 @@ import com.tangem.tap.features.send.redux.PrepareSendScreen import com.tangem.tap.features.wallet.models.PendingTransactionType import com.tangem.tap.features.wallet.models.getPendingTransactions import com.tangem.tap.features.wallet.models.getSendableAmounts -import com.tangem.tap.features.wallet.redux.* +import com.tangem.tap.features.wallet.redux.Currency +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.WalletStore import com.tangem.tap.network.NetworkStateChanged import com.tangem.tap.preferencesStorage import com.tangem.tap.scope import com.tangem.tap.store import com.tangem.tap.tangemSdkManager +import java.math.BigDecimal import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.launch @@ -41,7 +51,6 @@ import org.rekotlin.Action import org.rekotlin.DispatchFunction import org.rekotlin.Middleware import timber.log.Timber -import java.math.BigDecimal class WalletMiddleware { private val tradeCryptoMiddleware = TradeCryptoMiddleware() @@ -198,7 +207,8 @@ class WalletMiddleware { store.dispatchOnMain(WalletAction.Warnings.CheckIfNeeded) } } - is WalletAction.LoadData -> { + is WalletAction.LoadData, + is WalletAction.LoadData.Refresh -> { scope.launch { val scanNoteResponse = globalState.scanResponse ?: return@launch if (walletState.walletsData.isNotEmpty()) { 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 28a7675472..850f6b3b3b 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 @@ -2,7 +2,6 @@ package com.tangem.tap.features.wallet.redux.reducers import com.tangem.blockchain.common.AmountType import com.tangem.blockchain.common.Token -import com.tangem.blockchain.extensions.isAboveZero import com.tangem.common.extensions.guard import com.tangem.tap.common.extensions.toFiatString import com.tangem.tap.common.extensions.toFormattedCurrencyString @@ -11,13 +10,7 @@ import com.tangem.tap.domain.tokens.models.BlockchainNetwork import com.tangem.tap.features.wallet.models.filterByToken import com.tangem.tap.features.wallet.models.getPendingTransactions import com.tangem.tap.features.wallet.models.removeUnknownTransactions -import com.tangem.tap.features.wallet.models.toPendingTransactions -import com.tangem.tap.features.wallet.redux.Currency -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.redux.WalletStore +import com.tangem.tap.features.wallet.redux.* import com.tangem.tap.features.wallet.ui.BalanceStatus import com.tangem.tap.features.wallet.ui.BalanceWidgetData import com.tangem.tap.features.wallet.ui.TokenData @@ -41,8 +34,8 @@ class MultiWalletReducer { } val walletData = WalletData( currencyData = BalanceWidgetData( - BalanceStatus.Loading, - blockchain.blockchain.fullName, + status = BalanceStatus.Loading, + currency = blockchain.blockchain.fullName, currencySymbol = blockchain.blockchain.currency, token = cardToken ), @@ -77,8 +70,8 @@ class MultiWalletReducer { val walletData = WalletData( currencyData = BalanceWidgetData( - BalanceStatus.Loading, - action.blockchain.blockchain.fullName, + status = BalanceStatus.Loading, + currency = action.blockchain.blockchain.fullName, currencySymbol = action.blockchain.blockchain.currency, ), walletAddresses = createAddressList(wallet), @@ -121,7 +114,8 @@ class MultiWalletReducer { else -> BalanceStatus.VerifiedOnline } val tokenWalletData = state.getWalletData(currency) - val isTokenSendButtonEnabled = action.amount.isAboveZero() && pendingTransactions.isEmpty() + val isTokenSendButtonEnabled = tokenWalletData?.shouldEnableTokenSendButton() == true + && pendingTransactions.isEmpty() val newTokenWalletData = tokenWalletData?.copy( currencyData = tokenWalletData.currencyData.copy( @@ -184,7 +178,7 @@ fun Token.toWallet(state: WalletState, blockchain: BlockchainNetwork): WalletDat return WalletData( currencyData = BalanceWidgetData( - BalanceStatus.Loading, + status = BalanceStatus.Loading, currency = this.name, currencySymbol = this.symbol ), 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 442cbf46ec..ac3ede0818 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 @@ -12,12 +12,7 @@ import com.tangem.tap.domain.tokens.models.BlockchainNetwork import com.tangem.tap.features.wallet.models.filterByToken import com.tangem.tap.features.wallet.models.getPendingTransactions import com.tangem.tap.features.wallet.models.removeUnknownTransactions -import com.tangem.tap.features.wallet.models.toPendingTransactions -import com.tangem.tap.features.wallet.redux.Currency -import com.tangem.tap.features.wallet.redux.ProgressState -import com.tangem.tap.features.wallet.redux.TradeCryptoState -import com.tangem.tap.features.wallet.redux.WalletMainButton -import com.tangem.tap.features.wallet.redux.WalletState +import com.tangem.tap.features.wallet.redux.* import com.tangem.tap.features.wallet.ui.BalanceStatus import com.tangem.tap.features.wallet.ui.BalanceWidgetData import com.tangem.tap.features.wallet.ui.TokenData @@ -61,7 +56,8 @@ class OnWalletLoadedReducer { val fiatAmount = walletData.fiatRate?.let { coinAmountValue?.toFiatValue(it) } val newWalletData = walletData.copy( currencyData = walletData.currencyData.copy( - status = balanceStatus, currency = wallet.blockchain.fullName, + status = balanceStatus, + currency = wallet.blockchain.fullName, currencySymbol = wallet.blockchain.currency, blockchainAmount = coinAmountValue, amount = coinAmountValue, @@ -89,7 +85,7 @@ class OnWalletLoadedReducer { tokenWalletData?.fiatRate?.let { rate -> tokenAmountValue?.toFiatValue(rate) } val isTokenSendButtonEnabled = newWalletData.shouldEnableTokenSendButton() - && tokenPendingTransactions.isEmpty() + && pendingTransactions.isEmpty() tokenWalletData?.copy( currencyData = tokenWalletData.currencyData.copy( status = tokenBalanceStatus, @@ -110,17 +106,8 @@ class OnWalletLoadedReducer { val newWallets = tokens + newWalletData val wallets = walletState.replaceSomeWallets((newWallets)) - val state = if (wallets.any { it.currencyData.status == BalanceStatus.Loading }) { - ProgressState.Loading - } else { - ProgressState.Done - } return walletState .updateWalletsData(wallets) - .copy( - state = state, - error = null - ) } private fun onSingleWalletLoaded(wallet: Wallet, walletState: WalletState): WalletState { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/TotalBalanceOperations.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/TotalBalanceOperations.kt index 06d91d7db0..15e44ea361 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/TotalBalanceOperations.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/TotalBalanceOperations.kt @@ -1,48 +1,60 @@ package com.tangem.tap.features.wallet.redux.reducers -import com.tangem.tap.features.wallet.models.TotalBalance +import com.tangem.tap.features.wallet.redux.ProgressState import com.tangem.tap.features.wallet.redux.WalletData import com.tangem.tap.features.wallet.ui.BalanceStatus import java.math.BigDecimal -fun List.findTotalBalanceState(): TotalBalance.State { - return this.mapToTotalBalanceState() - .reduce(TotalBalance.State::or) +fun List.findProgressState(): ProgressState { + return this + .mapToProgressState() + .reduce(ProgressState::or) } fun List.calculateTotalFiatAmount(): BigDecimal { - return this.map { it.currencyData.fiatAmount ?: BigDecimal.ZERO } + return this + .map { it.currencyData.fiatAmount ?: BigDecimal.ZERO } .reduce(BigDecimal::plus) } -fun List.mapToTotalBalanceState(): List { - return this.map { - when (it.currencyData.status) { +private fun List.mapToProgressState(): List { + return this.map { wallet -> + if (wallet.fiatRate == null) ProgressState.Error + else when (wallet.currencyData.status) { + BalanceStatus.Refreshing -> ProgressState.Refreshing BalanceStatus.VerifiedOnline, BalanceStatus.SameCurrencyTransactionInProgress, - BalanceStatus.TransactionInProgress -> TotalBalance.State.Success + BalanceStatus.TransactionInProgress, + BalanceStatus.NoAccount -> ProgressState.Done BalanceStatus.Unreachable, - BalanceStatus.NoAccount, BalanceStatus.EmptyCard, - BalanceStatus.UnknownBlockchain -> TotalBalance.State.SomeTokensFailed + BalanceStatus.UnknownBlockchain -> ProgressState.Error BalanceStatus.Loading, - null -> TotalBalance.State.Loading + null -> ProgressState.Loading } } } -infix fun TotalBalance.State.or(newState: TotalBalance.State): TotalBalance.State { +private infix fun ProgressState.or(newState: ProgressState): ProgressState { return when (this) { - TotalBalance.State.Loading -> when (newState) { - TotalBalance.State.Loading, - TotalBalance.State.SomeTokensFailed, - TotalBalance.State.Success -> this + ProgressState.Loading -> when (newState) { + ProgressState.Loading, + ProgressState.Refreshing, + ProgressState.Error, + ProgressState.Done -> this } - TotalBalance.State.Success, - TotalBalance.State.SomeTokensFailed -> when (newState) { - TotalBalance.State.Loading, - TotalBalance.State.SomeTokensFailed -> newState - TotalBalance.State.Success -> this + ProgressState.Done, + ProgressState.Error -> when (newState) { + ProgressState.Loading, + ProgressState.Refreshing, + ProgressState.Error -> newState + ProgressState.Done -> this + } + ProgressState.Refreshing -> when (newState) { + ProgressState.Loading -> this + ProgressState.Refreshing, + ProgressState.Error, + ProgressState.Done -> newState } } } \ 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 11ea7236c0..fe7213d361 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 @@ -9,6 +9,7 @@ import com.tangem.tap.common.entities.FiatCurrency import com.tangem.tap.common.extensions.toFiatRateString import com.tangem.tap.common.extensions.toFiatString 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.common.redux.AppState import com.tangem.tap.domain.TapError @@ -25,7 +26,6 @@ import com.tangem.tap.features.wallet.redux.TradeCryptoState import com.tangem.tap.features.wallet.redux.WalletAction import com.tangem.tap.features.wallet.redux.WalletAddresses import com.tangem.tap.features.wallet.redux.WalletData -import com.tangem.tap.features.wallet.redux.WalletDialog import com.tangem.tap.features.wallet.redux.WalletMainButton import com.tangem.tap.features.wallet.redux.WalletState import com.tangem.tap.features.wallet.redux.WalletStore @@ -135,14 +135,25 @@ private fun internalReduce(action: Action, state: AppState): WalletState { error = null, ) } + is WalletAction.LoadData.Refresh -> { + newState = newState.copy( + state = ProgressState.Refreshing, + error = null, + ) + } is WalletAction.LoadWallet -> { + val balanceStatus = if (newState.state == ProgressState.Refreshing) { + BalanceStatus.Refreshing + } else { + BalanceStatus.Loading + } if (action.blockchain == null) { val wallets = newState.wallets.map { it.copy( walletsData = it.walletsData.map { walletData -> walletData.copy( currencyData = walletData.currencyData.copy( - status = BalanceStatus.Loading, + status = balanceStatus, currency = walletData.currencyData.currency, currencySymbol = walletData.currencyData.currencySymbol, ), @@ -169,7 +180,7 @@ private fun internalReduce(action: Action, state: AppState): WalletState { .map { wallet -> wallet.copy( currencyData = wallet.currencyData.copy( - status = BalanceStatus.Loading, + status = balanceStatus, currency = wallet.currencyData.currency, currencySymbol = wallet.currencyData.currencySymbol, ), @@ -191,31 +202,37 @@ private fun internalReduce(action: Action, state: AppState): WalletState { walletState = newState ) is WalletAction.LoadWallet.NoAccount -> { - val walletData = newState.getWalletData(action.blockchain)?.copy( - currencyData = BalanceWidgetData( - BalanceStatus.NoAccount, action.wallet.blockchain.fullName, - currencySymbol = action.wallet.blockchain.currency, - amountToCreateAccount = action.amountToCreateAccount + val amount = BigDecimal.ZERO + val fiatAmount = BigDecimal.ZERO + val walletData = newState.getWalletData(action.blockchain)?.let { walletData -> + val walletBlockchain = walletData.currency.blockchain + walletData.copy( + currencyData = BalanceWidgetData( + status = BalanceStatus.NoAccount, + currency = action.wallet.blockchain.fullName, + currencySymbol = action.wallet.blockchain.currency, + amount = amount, + amountFormatted = amount.toFormattedCurrencyString( + decimals = walletBlockchain.decimals(), + currency = walletBlockchain.currency, + ), + fiatAmount = fiatAmount, + fiatAmountFormatted = fiatAmount.toFiatRateString( + fiatCurrencyName = store.state.globalState.appCurrency.symbol + ), + amountToCreateAccount = action.amountToCreateAccount, + ) ) - ) + } var updatedWalletStore = newState.getWalletStore(action.blockchain) ?.updateWallets(listOfNotNull(walletData)) - val progressState = - if (updatedWalletStore?.walletsData?.any { it.currencyData.status == BalanceStatus.Loading } == true) { - ProgressState.Loading - } else { - ProgressState.Done - } updatedWalletStore = updatedWalletStore?.updateWallets( newState.updateTradeCryptoState(exchangeManager, updatedWalletStore.walletsData) ) newState = newState.updateWalletStore(updatedWalletStore) - .copy( - state = progressState - ) } is WalletAction.LoadWallet.Failure -> { @@ -410,19 +427,24 @@ private fun setMultiWalletFiatRate( state: WalletState ): WalletState { val newWalletsData = fiatRates.mapNotNull { (currency, rate) -> - val walletStore = state.getWalletStore(currency) ?: return state + val walletStore = state.getWalletStore(currency) ?: return@mapNotNull null val wallet = walletStore.walletManager?.wallet - val walletData = state.getWalletData(currency) ?: return state + val walletData = state.getWalletData(currency) ?: return@mapNotNull null + val currencyData = walletData.currencyData - val fiatAmount = when (currency) { + var fiatAmount = when (currency) { is Currency.Blockchain -> wallet?.amounts?.get(AmountType.Coin)?.value?.toFiatValue(rate) is Currency.Token -> wallet?.getTokenAmount(currency.token)?.value?.toFiatValue(rate) } + if (currencyData.status == BalanceStatus.NoAccount && fiatAmount == null) { + fiatAmount = BigDecimal.ZERO + } val fiatAmountFormatted = fiatAmount?.toFormattedFiatValue(appCurrency.symbol) - state.getWalletData(currency)?.copy( - currencyData = walletData.currencyData.copy( + + walletData.copy( + currencyData = currencyData.copy( fiatAmountFormatted = fiatAmountFormatted, fiatAmount = fiatAmount ), 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 6f666e8601..2be2f19145 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 @@ -13,6 +13,7 @@ enum class BalanceStatus { SameCurrencyTransactionInProgress, Unreachable, Loading, + Refreshing, NoAccount, EmptyCard, UnknownBlockchain 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 24473568ef..6a113fb7a8 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 @@ -135,15 +135,14 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber) { 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 6230fd27a3..afcb72f78e 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 @@ -64,6 +64,9 @@ class WalletAdapter fun bind(wallet: WalletData) = with(binding) { val status = wallet.currencyData.status + // Skip changes when on refreshing status + if (status == BalanceStatus.Refreshing) return@with + val isCustomCurrency = wallet.currency.isCustomCurrency( derivationStyle = store.state.globalState .scanResponse @@ -77,14 +80,13 @@ class WalletAdapter BalanceStatus.Unreachable -> { root.getString(R.string.wallet_balance_blockchain_unreachable) } - BalanceStatus.NoAccount -> { - root.getString(R.string.wallet_error_no_account) - } + BalanceStatus.NoAccount, BalanceStatus.VerifiedOnline, BalanceStatus.SameCurrencyTransactionInProgress, BalanceStatus.EmptyCard, BalanceStatus.UnknownBlockchain, BalanceStatus.Loading, + BalanceStatus.Refreshing, null -> null } @@ -111,11 +113,10 @@ class WalletAdapter 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 - } + lContent.tvExchangeRate.text = wallet.fiatRateString + ?: root.getString(id = R.string.token_item_no_rate) + + badgeCustomBalance.isVisible = isCustomCurrency cardWallet.setOnClickListener { store.dispatch(WalletAction.MultiWallet.SelectWallet(wallet)) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/CurrencySelectionDialog.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/CurrencySelectionDialog.kt index 78b665cde6..f47a0b3ea1 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/CurrencySelectionDialog.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/CurrencySelectionDialog.kt @@ -2,7 +2,6 @@ package com.tangem.tap.features.wallet.ui.wallet import android.content.Context import androidx.appcompat.app.AlertDialog -import com.tangem.tap.common.extensions.dispatchDialogHide import com.tangem.tap.features.wallet.redux.WalletAction import com.tangem.tap.features.wallet.redux.WalletDialog import com.tangem.tap.store @@ -16,27 +15,25 @@ object CurrencySelectionDialog { val currenciesToShow = dialog.currenciesList .map { it.displayName } .toTypedArray() - var currentSelection = dialog.currenciesList + val currentSelection = dialog.currenciesList .indexOfFirst { it.code == dialog.currentAppCurrency.code } return AlertDialog.Builder(context) .setTitle(context.getString(R.string.details_row_title_currency)) .setNegativeButton(context.getString(R.string.common_cancel)) { _, _ -> /* no-op */ } - .setPositiveButton(context.getString(R.string.common_done)) { _, _ -> - dialog.currenciesList.getOrNull(currentSelection)?.let { selectedCurrency -> + .setOnDismissListener { + store.dispatch(WalletAction.DialogAction.Hide) + } + .setSingleChoiceItems(currenciesToShow, currentSelection) { _, which -> + dialog.currenciesList.getOrNull(which)?.let { selectedCurrency -> store.dispatch( WalletAction.AppCurrencyAction.SelectAppCurrency( fiatCurrency = selectedCurrency ) ) + store.dispatch(WalletAction.DialogAction.Hide) } } - .setOnDismissListener { - store.dispatchDialogHide() - } - .setSingleChoiceItems(currenciesToShow, currentSelection) { _, which -> - currentSelection = which - } .create() } } \ 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 b777d3ef00..5646b437f0 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 @@ -14,6 +14,7 @@ import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.currenciesRepository import com.tangem.tap.features.tokens.redux.TokensAction import com.tangem.tap.features.wallet.models.TotalBalance +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.BalanceStatus @@ -125,17 +126,19 @@ class MultiWalletView : WalletView { ) = with(binding.lCardTotalBalance) { root.isVisible = totalBalance != null if (totalBalance != null) { - if (totalBalance.state == TotalBalance.State.Loading) { + // Skip changes when on refreshing state + if (totalBalance.state == ProgressState.Refreshing) return@with + + if (totalBalance.state == ProgressState.Loading) { veilBalance.veil() } else { veilBalance.unVeil() } tvProcessing.animateVisibility( - show = totalBalance.state == TotalBalance.State.SomeTokensFailed + show = totalBalance.state == ProgressState.Error ) - tvBalance.text = if (totalBalance.state == TotalBalance.State.SomeTokensFailed) "—" - else totalBalance.fiatAmount.formatAmountAsSpannedString( + tvBalance.text = totalBalance.fiatAmount.formatAmountAsSpannedString( currencySymbol = totalBalance.fiatCurrency.symbol ) tvCurrencyName.text = totalBalance.fiatCurrency.code @@ -189,7 +192,6 @@ class MultiWalletView : WalletView { private fun configureButtonsForEmptyWalletState(binding: FragmentWalletBinding) = with(binding) { lButtonsLong.root.show() - lButtonsLong.btnScanLong.setOnClickListener { store.dispatch(WalletAction.Scan) } lButtonsLong.btnConfirmLong.setOnClickListener { store.dispatch(WalletAction.CreateWallet) } lButtonsLong.btnConfirmLong.text = fragment?.getText(R.string.wallet_button_create_wallet) 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 4fb9b0ca0b..b7e0a307a5 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 @@ -130,20 +130,8 @@ class SingleWalletView : WalletView { lButtonsLong.btnConfirmLong } - val btnScan = if (state.tradeCryptoState.sellingAllowed || - state.tradeCryptoState.buyingAllowed - ) { - lButtonsShort.btnScan - } else { - lButtonsLong.btnScanLong - } - setupConfirmButton(state, btnConfirm, isTwinsWallet) - btnScan.setOnClickListener { - store.dispatch(WalletAction.Scan) - } - lAddress.btnCopy.setOnClickListener { state.walletAddresses?.selectedAddress?.address?.let { addressString -> store.dispatch(WalletAction.CopyAddress(addressString, fragment!!.requireContext())) diff --git a/app/src/main/res/drawable/shape_badge_custom_currency.xml b/app/src/main/res/drawable/shape_badge_custom_currency.xml new file mode 100644 index 0000000000..2c3b7f7bd4 --- /dev/null +++ b/app/src/main/res/drawable/shape_badge_custom_currency.xml @@ -0,0 +1,15 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/card_total_balance.xml b/app/src/main/res/layout/card_total_balance.xml index 196dc167e1..1f97649e18 100644 --- a/app/src/main/res/layout/card_total_balance.xml +++ b/app/src/main/res/layout/card_total_balance.xml @@ -52,7 +52,7 @@ app:veilLayout_veiled="true" app:veilLayout_radius="4dp" app:layout_constraintTop_toBottomOf="@id/tv_title" - app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintBottom_toTopOf="@id/tv_processing" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" tools:veilLayout_veiled="false"> @@ -80,7 +80,8 @@ android:textSize="12sp" android:text="@string/main_processing_full_amount" app:layout_constraintTop_toBottomOf="@id/veil_balance" - app:layout_constraintStart_toStartOf="parent" /> + app:layout_constraintStart_toStartOf="parent" + tools:visibility="visible" /> + + + + + + android:layout_height="wrap_content" + android:drawablePadding="15dp" + android:paddingTop="7dp" + android:paddingBottom="7dp" + android:text="@string/disclaimer_title" + android:textColor="@color/darkGray6" + android:textSize="16sp" + app:drawableEndCompat="@drawable/ic_angle_bracket_right" + app:drawableTint="@color/darkGray1" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/tv_app_currency_title" /> - + \ No newline at end of file diff --git a/app/src/main/res/layout/item_currency_wallet.xml b/app/src/main/res/layout/item_currency_wallet.xml index ddb13e5666..de692cfa83 100644 --- a/app/src/main/res/layout/item_currency_wallet.xml +++ b/app/src/main/res/layout/item_currency_wallet.xml @@ -47,6 +47,15 @@ app:layout_constraintTop_toTopOf="@id/iv_currency" tools:text="J" /> + + - - - \ No newline at end of file + diff --git a/app/src/main/res/layout/layout_wallet_short_buttons.xml b/app/src/main/res/layout/layout_wallet_short_buttons.xml index 08bdfeef5a..ed60601395 100644 --- a/app/src/main/res/layout/layout_wallet_short_buttons.xml +++ b/app/src/main/res/layout/layout_wallet_short_buttons.xml @@ -14,8 +14,8 @@ android:layout_marginBottom="8dp" android:text="@string/wallet_button_trade" app:icon="@drawable/ic_arrows_up_down" - app:layout_constraintBottom_toTopOf="@id/btn_scan" - app:layout_constraintEnd_toStartOf="@id/btn_confirm" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toStartOf="@id/btn_confirm" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintHorizontal_chainStyle="packed" app:layout_constraintStart_toStartOf="parent" @@ -34,29 +34,10 @@ android:text="@string/wallet_button_send" app:icon="@drawable/ic_send" app:iconGravity="textEnd" - android:textAlignment="center" - app:layout_constraintBottom_toTopOf="@id/btn_scan" - app:layout_constraintEnd_toEndOf="parent" + android:textAlignment="center" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@id/btn_trade" app:layout_constraintVertical_bias="1" /> - - - - - \ No newline at end of file + diff --git a/app/src/main/res/values-ru/strings_final.xml b/app/src/main/res/values-ru/strings_final.xml index ea424b57b6..201a1684ae 100644 --- a/app/src/main/res/values-ru/strings_final.xml +++ b/app/src/main/res/values-ru/strings_final.xml @@ -47,7 +47,7 @@ Пользовательский Баланс - Обработка полной суммы… + В сумме учтены не все монеты Управление токенами Нет цены diff --git a/app/src/main/res/values/strings_final.xml b/app/src/main/res/values/strings_final.xml index 2478dee488..d59d31ff0e 100644 --- a/app/src/main/res/values/strings_final.xml +++ b/app/src/main/res/values/strings_final.xml @@ -47,7 +47,7 @@ Custom Total balance - Some networks are unreachable + The amount does not include some of your funds Manage tokens No rate diff --git a/domain/build.gradle b/domain/build.gradle index ea723c1e44..169aea23f3 100644 --- a/domain/build.gradle +++ b/domain/build.gradle @@ -59,10 +59,10 @@ dependencies { implementation implementation(project(path: ':network')) implementation implementation(project(path: ':common')) - implementation 'com.tangem:blockchain:develop-85' + implementation 'com.tangem:blockchain:develop-88' // implementation 'com.tangem:blockchain:0.0.1' - implementation 'com.tangem.tangem-sdk-kotlin:core:develop-142' - implementation 'com.tangem.tangem-sdk-kotlin:android:develop-142' + implementation 'com.tangem.tangem-sdk-kotlin:core:develop-154' + implementation 'com.tangem.tangem-sdk-kotlin:android:develop-154' // Kotlin coroutines implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2' diff --git a/domain/src/main/java/com/tangem/domain/common/TapWorkarounds.kt b/domain/src/main/java/com/tangem/domain/common/TapWorkarounds.kt index a5ce7922c8..644cc7525e 100644 --- a/domain/src/main/java/com/tangem/domain/common/TapWorkarounds.kt +++ b/domain/src/main/java/com/tangem/domain/common/TapWorkarounds.kt @@ -75,6 +75,10 @@ object TapWorkarounds { "AB06" to Blockchain.XRP, "AB07" to Blockchain.Bitcoin, "AB08" to Blockchain.Ethereum, + "AB09" to Blockchain.Bitcoin, // new batches for 3.34 + "AB10" to Blockchain.Ethereum, + "AB11" to Blockchain.Bitcoin, + "AB12" to Blockchain.Ethereum, ) private val tangemWalletBatchesWithStandardDerivationType = listOf(