Updated on 2026-08-14

This commit is contained in:
Tangem 2022-06-06 17:53:14 +03:00
commit 6079bd5f68
11 changed files with 90 additions and 73 deletions

@ -1 +1 @@
Subproject commit 7f058ec409b4eaaf8688ecd4bf944ef8d58d3564
Subproject commit 64ae04d2086e5a605dd4da3cba4af32a60d46c79

View file

@ -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

View file

@ -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,11 @@ class DetailsFragment : Fragment(R.layout.fragment_details), StoreSubscriber<Det
store.dispatch(DetailsAction.CreateBackup)
}
tvAppCurrency.show(state.scanResponse?.card?.isMultiwalletAllowed != true)
tvAppCurrency.setOnClickListener {
store.dispatch(WalletAction.AppCurrencyAction.ChooseAppCurrency)
}
tvSendFeedback.setOnClickListener {
store.dispatch(GlobalAction.SendFeedback(FeedbackEmail()))
}

View file

@ -48,7 +48,7 @@ fun List<PendingTransaction>.filterByCoin(): List<PendingTransaction> {
}
fun List<PendingTransaction>.filterByToken(token: Token): List<PendingTransaction> {
return this.filter { it.currency == token.symbol }
return this.filter { it.transactionData.amount.currencySymbol == token.symbol }
}
fun TransactionData.toPendingTransactionForToken(token: Token, walletAddress: String): PendingTransaction? {

View file

@ -9,7 +9,6 @@ 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.TapWorkarounds.derivationStyle
import com.tangem.domain.common.extensions.canHandleToken
import com.tangem.domain.common.extensions.toCoinId
import com.tangem.domain.features.addCustomToken.CustomCurrency
@ -67,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<Blockchain>
get() = wallets.mapNotNull { it.walletManager?.wallet?.blockchain }
@ -232,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
@ -284,24 +286,16 @@ data class WalletState(
}
private fun updateTotalBalance(): WalletState {
return if (this.wallets.isNotEmpty()) {
val globalState = store.state.globalState
val walletsData = this.wallets
.flatMap(WalletStore::walletsData)
.filterNot { wallet ->
wallet.currency.isCustomCurrency(
derivationStyle = globalState
.scanResponse
?.card
?.derivationStyle
)
}
val walletsData = this.wallets
.flatMap(WalletStore::walletsData)
.filter { it.fiatRate != null }
return if (walletsData.isNotEmpty()) {
this.copy(
totalBalance = TotalBalance(
state = walletsData.findProgressState(),
fiatAmount = walletsData.calculateTotalFiatAmount(),
fiatCurrency = globalState.appCurrency
fiatCurrency = store.state.globalState.appCurrency
)
)
} else this.copy(
@ -310,9 +304,10 @@ data class WalletState(
}
private fun updateProgressState(): WalletState {
return if (this.wallets.isNotEmpty()) {
val walletsData = this.wallets
.flatMap(WalletStore::walletsData)
val walletsData = this.wallets
.flatMap(WalletStore::walletsData)
return if (walletsData.isNotEmpty()) {
val newProgressState = walletsData.findProgressState()
this.copy(

View file

@ -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,12 +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.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
@ -120,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(

View file

@ -12,11 +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.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
@ -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,

View file

@ -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
@ -201,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 -> {
@ -420,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
),

View file

@ -113,11 +113,8 @@ 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

View file

@ -216,20 +216,34 @@
android:background="@color/separatorGrey2"
app:layout_constraintTop_toBottomOf="@id/tv_settings_title" />
<TextView
android:id="@+id/tv_app_currency"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="7dp"
android:paddingBottom="7dp"
android:text="@string/details_row_title_currency"
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_settings_title" />
<TextView
android:id="@+id/tv_disclaimer"
android:layout_width="match_parent"
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_settings_title" />
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" />
<TextView
android:id="@+id/tv_card_tou"
@ -279,4 +293,4 @@
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -47,7 +47,7 @@
<string name="common_custom">Пользовательский</string>
<string name="main_page_balance">Баланс</string>
<string name="main_processing_full_amount">Обработка полной суммы…</string>
<string name="main_processing_full_amount">Некоторые сети недоступны</string>
<string name="main_manage_tokens">Управление токенами</string>
<string name="token_item_no_rate">Нет цены</string>
</resources>