Updated on 2026-08-14

This commit is contained in:
Tangem 2021-05-21 10:27:46 +03:00
parent 33759c620c
commit 293c932422
21 changed files with 357 additions and 242 deletions

View file

@ -26,12 +26,21 @@ fun BigDecimal.toFormattedCurrencyString(decimals: Int, currency: String): Strin
return "${this.toFormattedString(decimals)} $currency"
}
fun BigDecimal.toFiatString(rateValue: BigDecimal, fiatCurrencyName: FiatCurrencyName): String? {
fun BigDecimal.toFiatString(rateValue: BigDecimal, fiatCurrencyName: FiatCurrencyName): String {
var fiatValue = rateValue.multiply(this)
fiatValue = fiatValue.setScale(2, RoundingMode.DOWN)
return "≈ ${fiatCurrencyName} $fiatValue"
}
fun BigDecimal.toFiatValue(rateValue: BigDecimal): BigDecimal {
val fiatValue = rateValue.multiply(this)
return fiatValue.setScale(2, RoundingMode.DOWN)
}
fun BigDecimal.toFormattedFiatValue(fiatCurrencyName: FiatCurrencyName): String {
return "≈ ${fiatCurrencyName} $this"
}
fun FiatCurrency.toFormattedString(): String = "${this.name} (${this.symbol}) - ${this.sign}"
fun BigDecimal.stripZeroPlainString(): String = this.stripTrailingZeros().toPlainString()

View file

@ -17,12 +17,14 @@ import com.tangem.tap.domain.tokens.CardCurrencies
import com.tangem.tap.domain.twins.TwinsHelper
import com.tangem.tap.domain.twins.isTwinCard
import com.tangem.tap.features.tokens.redux.TokensAction
import com.tangem.tap.features.wallet.redux.Currency
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.network.NetworkConnectivity
import com.tangem.tap.network.coinmarketcap.CoinMarketCapService
import com.tangem.tap.store
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import timber.log.Timber
import java.math.BigDecimal
@ -64,19 +66,23 @@ class TapWalletManager {
}
suspend fun loadFiatRate(fiatCurrency: FiatCurrencyName, wallet: Wallet) {
val currencyList = wallet.getTokens().map { it.symbol }.toMutableList()
currencyList.add(wallet.blockchain.currency)
loadFiatRate(fiatCurrency, currencyList)
Timber.d(wallet.getTokens().toString())
val currencies = wallet.getTokens()
.map { Currency.Token(it, wallet.blockchain) }
.plus(Currency.Blockchain(wallet.blockchain))
loadFiatRate(fiatCurrency, currencies)
}
suspend fun loadFiatRate(fiatCurrency: FiatCurrencyName, cryptoCurrencyName: CryptoCurrencyName) {
val currencyList = listOf(cryptoCurrencyName)
loadFiatRate(fiatCurrency, currencyList)
suspend fun loadFiatRate(fiatCurrency: FiatCurrencyName, currency: Currency) {
val currencies = listOf(currency)
loadFiatRate(fiatCurrency, currencies)
}
private suspend fun loadFiatRate(fiatCurrency: FiatCurrencyName, currencyList: List<CryptoCurrencyName>) {
val results = mutableListOf<Pair<CryptoCurrencyName, Result<BigDecimal>?>>()
currencyList.forEach { results.add(it to coinMarketCapService.getRate(it, fiatCurrency)) }
suspend fun loadFiatRate(fiatCurrency: FiatCurrencyName, currencies: List<Currency>) {
val results = mutableListOf<Pair<Currency, Result<BigDecimal>?>>()
currencies.forEach {
results.add(it to coinMarketCapService.getRate(it.currencySymbol, fiatCurrency))
}
handleFiatRatesResult(results)
}
@ -268,7 +274,7 @@ class TapWalletManager {
}
}
private suspend fun handleFiatRatesResult(results: List<Pair<CryptoCurrencyName, Result<BigDecimal>?>>) {
private suspend fun handleFiatRatesResult(results: List<Pair<Currency, Result<BigDecimal>?>>) {
withContext(Dispatchers.Main) {
results.map {
when (it.second) {

View file

@ -44,4 +44,7 @@ fun Card.signedHashesCount(): Int {
}
val Card.remainingSignatures: Int?
get() = this.getSingleWallet()?.remainingSignatures
get() = this.getSingleWallet()?.remainingSignatures
val Card.isWalletDataSupported: Boolean
get() = this.firmwareVersion.major >= 4

View file

@ -134,11 +134,11 @@ private fun sendTransaction(
dispatch(NavigationAction.PopBackTo())
scope.launch(Dispatchers.IO) {
withContext(Dispatchers.Main) {
dispatch(WalletAction.UpdateWallet(walletManager.wallet.blockchain.currency))
dispatch(WalletAction.UpdateWallet(walletManager.wallet.blockchain))
}
delay(10000)
withContext(Dispatchers.Main) {
dispatch(WalletAction.UpdateWallet(walletManager.wallet.blockchain.currency))
dispatch(WalletAction.UpdateWallet(walletManager.wallet.blockchain))
}
}
}

View file

@ -1,6 +1,9 @@
package com.tangem.tap.features.tokens.redux
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.domain.tokens.CardCurrencies
import com.tangem.tap.features.wallet.redux.Currency
import com.tangem.tap.features.wallet.redux.WalletData
import org.rekotlin.Action
class TokensReducer {
@ -18,13 +21,21 @@ private fun internalReduce(action: Action, state: AppState): TokensState {
tokensState.copy(currencies = action.currencies)
}
is TokensAction.SetAddedCurrencies -> {
tokensState.copy(addedCurrencies = action.wallets.mapNotNull { it.currencyData.currencySymbol })
tokensState.copy(addedCurrencies = action.wallets.toCardCurrencies())
}
is TokensAction.LoadCardTokens.Success -> {
tokensState.copy(addedTokens = LinkedHashSet(
action.tokens.map { TokenWithAmount(it, null) }
action.tokens.map { TokenWithAmount(it, null) }
))
}
else -> tokensState
}
}
private fun List<WalletData>.toCardCurrencies(): CardCurrencies {
val tokens = mapNotNull { (it.currency as? Currency.Token)?.token }
val blockchains = mapNotNull { (it.currency as? Currency.Blockchain)?.blockchain }
return CardCurrencies(tokens = tokens, blockchains = blockchains)
}

View file

@ -3,12 +3,13 @@ package com.tangem.tap.features.tokens.redux
import com.tangem.blockchain.common.Amount
import com.tangem.blockchain.common.Token
import com.tangem.tap.common.redux.global.CryptoCurrencyName
import com.tangem.tap.domain.tokens.CardCurrencies
import com.tangem.tap.features.tokens.ui.adapters.CurrencyListItem
import org.rekotlin.StateType
data class TokensState(
val addedTokens: LinkedHashSet<TokenWithAmount> = LinkedHashSet(),
val addedCurrencies: List<CryptoCurrencyName> = emptyList(),
val addedCurrencies: CardCurrencies? = null,
val currencies: List<CurrencyListItem> = emptyList(),
) : StateType

View file

@ -14,6 +14,7 @@ import com.tangem.blockchain.common.IconsUtil
import com.tangem.blockchain.common.Token
import com.tangem.tap.common.extensions.*
import com.tangem.tap.common.redux.global.CryptoCurrencyName
import com.tangem.tap.domain.tokens.CardCurrencies
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.store
import com.tangem.wallet.R
@ -24,7 +25,7 @@ import java.util.*
class CurrenciesAdapter : ListAdapter<CurrencyListItem, RecyclerView.ViewHolder>(DiffUtilCallback) {
var addedCurrencies: List<CryptoCurrencyName> = emptyList()
var addedCurrencies: CardCurrencies? = null
private var unfilteredList = listOf<CurrencyListItem>()
@ -42,12 +43,18 @@ class CurrenciesAdapter : ListAdapter<CurrencyListItem, RecyclerView.ViewHolder>
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
0 -> TitleViewHolder(LayoutInflater.from(parent.context)
.inflate(R.layout.item_currency_subtitle, parent, false))
1 -> CurrenciesViewHolder(LayoutInflater.from(parent.context)
.inflate(R.layout.item_popular_token, parent, false))
else -> CurrenciesViewHolder(LayoutInflater.from(parent.context)
.inflate(R.layout.item_popular_token, parent, false))
0 -> TitleViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.item_currency_subtitle, parent, false)
)
1 -> CurrenciesViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.item_popular_token, parent, false)
)
else -> CurrenciesViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.item_popular_token, parent, false)
)
}
}
@ -62,11 +69,11 @@ class CurrenciesAdapter : ListAdapter<CurrencyListItem, RecyclerView.ViewHolder>
object DiffUtilCallback : DiffUtil.ItemCallback<CurrencyListItem>() {
override fun areContentsTheSame(
oldItem: CurrencyListItem, newItem: CurrencyListItem
oldItem: CurrencyListItem, newItem: CurrencyListItem
) = oldItem == newItem
override fun areItemsTheSame(
oldItem: CurrencyListItem, newItem: CurrencyListItem
oldItem: CurrencyListItem, newItem: CurrencyListItem
) = oldItem == newItem
}
@ -76,20 +83,23 @@ class CurrenciesAdapter : ListAdapter<CurrencyListItem, RecyclerView.ViewHolder>
if (!query.isNullOrEmpty()) {
val queryNormalized = query.toString().toLowerCase(Locale.US)
list.addAll(
unfilteredList.filter { element ->
when (element) {
is CurrencyListItem.BlockchainListItem -> {
element.blockchain.currency.toLowerCase(Locale.US).contains(queryNormalized)
|| element.blockchain.fullName.toLowerCase(Locale.US).contains(queryNormalized)
unfilteredList.filter { element ->
when (element) {
is CurrencyListItem.BlockchainListItem -> {
element.blockchain.currency.toLowerCase(Locale.US)
.contains(queryNormalized)
|| element.blockchain.fullName.toLowerCase(Locale.US)
.contains(queryNormalized)
}
is CurrencyListItem.TokenListItem -> {
element.token.name.toLowerCase(Locale.US).contains(queryNormalized)
|| element.token.symbol.toLowerCase(Locale.US).contains(queryNormalized)
}
else -> false
}
})
is CurrencyListItem.TokenListItem -> {
element.token.name.toLowerCase(Locale.US).contains(queryNormalized)
|| element.token.symbol.toLowerCase(Locale.US)
.contains(queryNormalized)
}
else -> false
}
})
} else {
list.addAll(unfilteredList)
}
@ -97,14 +107,14 @@ class CurrenciesAdapter : ListAdapter<CurrencyListItem, RecyclerView.ViewHolder>
}
class CurrenciesViewHolder(val view: View) :
RecyclerView.ViewHolder(view) {
fun bind(currency: CurrencyListItem, addedCurrencies: List<CryptoCurrencyName>) {
RecyclerView.ViewHolder(view) {
fun bind(currency: CurrencyListItem, addedCurrencies: CardCurrencies?) {
when (currency) {
is CurrencyListItem.BlockchainListItem -> {
val blockchain = currency.blockchain
view.tv_currency_name.text = blockchain.fullName
view.tv_currency_symbol.text = blockchain.currency
val isAdded = addedCurrencies.any { it == blockchain.currency }
val isAdded = addedCurrencies?.blockchains?.contains(blockchain) == true
view.btn_add_token.show(!isAdded)
view.btn_token_added.show(isAdded)
@ -125,7 +135,11 @@ class CurrenciesAdapter : ListAdapter<CurrencyListItem, RecyclerView.ViewHolder>
view.tv_currency_name.text = token.name
view.tv_currency_symbol.text = token.symbol
val isAdded = addedCurrencies.any { it == token.symbol }
val isAdded = addedCurrencies?.tokens
?.any {
it.symbol == token.symbol && it.contractAddress == token.contractAddress
} == true
view.btn_add_token.show(!isAdded)
view.btn_token_added.show(isAdded)
@ -145,7 +159,7 @@ class CurrenciesAdapter : ListAdapter<CurrencyListItem, RecyclerView.ViewHolder>
}
class TitleViewHolder(val view: View) :
RecyclerView.ViewHolder(view) {
RecyclerView.ViewHolder(view) {
fun bind(title: CurrencyListItem.TitleListItem) {
view.tv_subtitle.text = view.getString(title.titleResId).toUpperCase(Locale.US)
}

View file

@ -24,7 +24,7 @@ sealed class WalletAction : Action {
}
data class LoadWallet(val allowTopUp: Boolean? = null, val currency: CryptoCurrencyName? = null) : WalletAction() {
data class LoadWallet(val allowTopUp: Boolean? = null, val blockchain: Blockchain? = null) : WalletAction() {
data class Success(val wallet: Wallet) : WalletAction()
data class NoAccount(val wallet: Wallet, val amountToCreateAccount: String) : WalletAction()
data class Failure(val wallet: Wallet, val errorMessage: String? = null) : WalletAction()
@ -45,7 +45,7 @@ sealed class WalletAction : Action {
data class SaveCurrencies(val cardCurrencies: CardCurrencies) : MultiWallet()
object FindTokensInUse : MultiWallet()
data class FindBlockchainsInUse(val card: Card, val factory: WalletManagerFactory) : MultiWallet()
data class TokenLoaded(val amount: Amount) : MultiWallet()
data class TokenLoaded(val amount: Amount, val token: Token) : MultiWallet()
data class SelectWallet(val walletData: WalletData?) : MultiWallet()
data class RemoveWallet(val walletData: WalletData) : MultiWallet()
data class SetPrimaryBlockchain(val blockchain: Blockchain) : MultiWallet()
@ -71,16 +71,16 @@ sealed class WalletAction : Action {
class CheckRemainingSignatures(val remainingSignatures: Int?) : Warnings()
}
data class UpdateWallet(val currency: CryptoCurrencyName? = null) : WalletAction() {
data class UpdateWallet(val blockchain: Blockchain? = null) : WalletAction() {
object ScheduleUpdatingWallet : WalletAction()
data class Success(val wallet: Wallet) : WalletAction()
data class Failure(val errorMessage: String? = null) : WalletAction()
}
data class LoadFiatRate(
val wallet: Wallet? = null, val currency: CryptoCurrencyName? = null
val wallet: Wallet? = null, val currency: Currency? = null
) : WalletAction() {
data class Success(val fiatRate: Pair<CryptoCurrencyName, BigDecimal?>) : WalletAction()
data class Success(val fiatRate: Pair<Currency, BigDecimal?>) : WalletAction()
object Failure : WalletAction()
}

View file

@ -30,13 +30,12 @@ data class WalletState(
val walletManagers: List<WalletManager> = emptyList(),
val isMultiwalletAllowed: Boolean = false,
val cardCurrency: CryptoCurrencyName? = null,
val selectedWallet: CryptoCurrencyName? = null,
val selectedWallet: Currency? = null,
val primaryBlockchain: Blockchain? = null,
val primaryToken: Token? = null
) : StateType {
val primaryWallet = if (wallets.isNotEmpty()) wallets[0] else null
// val primaryWalletManager = if (walletManagers.isNotEmpty()) walletManagers[0] else null
val shouldShowDetails: Boolean =
primaryWallet?.currencyData?.status != com.tangem.tap.features.wallet.ui.BalanceStatus.EmptyCard &&
@ -45,19 +44,14 @@ data class WalletState(
val blockchains: List<Blockchain>
get() = walletManagers.map { it.wallet.blockchain }
fun getWalletManager(currencyName: CryptoCurrencyName?): WalletManager? {
if (currencyName == null) return null
val walletManager = walletManagers.find { it.wallet.blockchain.currency == currencyName }
return walletManager ?: getWalletManagerForToken(currencyName)
}
fun getWalletManagerForToken(currencyName: CryptoCurrencyName?): WalletManager? {
fun getWalletManager(token: Token?): WalletManager? {
if (token == null) return null
val ethereumWalletManager = walletManagers.find { it.wallet.blockchain == Blockchain.Ethereum }
return if (ethereumWalletManager?.presetTokens?.find { it.symbol == currencyName } != null) {
return if (ethereumWalletManager?.presetTokens?.find { it == token } != null) {
ethereumWalletManager
} else {
val primaryWalletManager = walletManagers.find { it.wallet.blockchain == primaryBlockchain }
if (primaryWalletManager?.presetTokens?.find { it.symbol == currencyName } != null) {
if (primaryWalletManager?.presetTokens?.find { it == token } != null) {
primaryWalletManager
} else {
ethereumWalletManager
@ -65,38 +59,69 @@ data class WalletState(
}
}
fun getWalletData(currencyName: CryptoCurrencyName?): WalletData? {
if (currencyName == null) return null
return wallets.find { it.currencyData.currencySymbol == currencyName }
fun getWalletManager(currency: Currency?) : WalletManager? {
if (currency?.blockchain == null) return null
return walletManagers.find { it.wallet.blockchain == currency.blockchain }
}
fun getWalletManager(blockchain: Blockchain) : WalletManager? {
return walletManagers.find { it.wallet.blockchain == blockchain }
}
fun getWalletData(currency: Currency?) : WalletData? {
if (currency == null) return null
return wallets.find { it.currency == currency }
}
fun getWalletData(blockchain: Blockchain?): WalletData? {
if (blockchain == null) return null
return wallets.find { (it.currency as? Currency.Blockchain)?.blockchain == blockchain }
}
fun getWalletData(token: Token?): WalletData? {
if (token == null) return null
return wallets.find { (it.currency as? Currency.Token)?.token == token }
}
fun getSelectedWalletData(): WalletData? {
return wallets.find { it.currencyData.currencySymbol == selectedWallet }
return wallets.find { it.currency == selectedWallet }
}
fun canBeRemoved(walletData: WalletData?): Boolean {
if (walletData == null) return false
if (walletData.blockchain != store.state.walletState.primaryBlockchain
&& (walletData.token == null || walletData.token != store.state.walletState.primaryToken)) {
val walletManager = getWalletManager(walletData.currencyData.currencySymbol)
if (!isPrimaryCurrency(walletData)) {
val walletManager = getWalletManager(walletData.currency)
?: return true
if (walletData.token == null && walletManager.presetTokens.isNotEmpty()) return false
if (walletData.currency is Currency.Blockchain &&
walletManager.presetTokens.isNotEmpty()
) {
return false
}
val wallet = walletManager.wallet
if (walletData.blockchain != null) {
if (walletData.currency is Currency.Blockchain) {
return wallet.recentTransactions.toPendingTransactions(wallet.address).isEmpty() &&
wallet.amounts.toSendableAmounts().isEmpty()
} else if (walletData.token != null) (
} else if (walletData.currency is Currency.Token) (
return wallet.recentTransactions.toPendingTransactionsForToken(
walletData.token, wallet.address).isEmpty()
&& wallet.amounts[AmountType.Token(token = walletData.token)]?.isAboveZero() != true
walletData.currency.token, wallet.address).isEmpty()
&& wallet.amounts[AmountType.Token(token = walletData.currency.token)]
?.isAboveZero() != true
)
}
return false
}
private fun isPrimaryCurrency(walletData: WalletData): Boolean {
return (walletData.currency is Currency.Blockchain &&
walletData.currency.blockchain == store.state.walletState.primaryBlockchain)
|| (walletData.currency is Currency.Token &&
walletData.currency.token == store.state.walletState.primaryToken)
}
fun replaceWalletInWallets(walletData: WalletData?): List<WalletData> {
if (walletData == null) return wallets
return wallets.filter { it.currencyData.currency != walletData.currencyData.currency } + walletData
@ -180,14 +205,32 @@ data class WalletData(
val fiatRateString: String? = null,
val fiatRate: BigDecimal? = null,
val mainButton: WalletMainButton = WalletMainButton.SendButton(false),
val token: Token? = null,
val blockchain: Blockchain? = null,
val currency: Currency? = null
) {
fun shouldShowMultipleAddress(): Boolean {
val listOfAddresses = walletAddresses?.list ?: return false
return (currencyData.currencySymbol == Blockchain.Bitcoin.currency ||
currencyData.currencySymbol == Blockchain.BitcoinTestnet.currency ||
currencyData.currencySymbol == Blockchain.CardanoShelley.currency) &&
return (currency?.blockchain == Blockchain.Bitcoin ||
currency?.blockchain == Blockchain.BitcoinTestnet ||
currency?.blockchain == Blockchain.CardanoShelley) &&
listOfAddresses.size > 1
}
}
sealed interface Currency {
val blockchain: com.tangem.blockchain.common.Blockchain
val currencySymbol: CryptoCurrencyName
data class Token(
val token: com.tangem.blockchain.common.Token,
override val blockchain: com.tangem.blockchain.common.Blockchain
) : Currency {
override val currencySymbol: CryptoCurrencyName = token.symbol
}
data class Blockchain(
override val blockchain: com.tangem.blockchain.common.Blockchain
) : Currency {
override val currencySymbol: CryptoCurrencyName = blockchain.currency
}
}

View file

@ -12,6 +12,7 @@ import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.currenciesRepository
import com.tangem.tap.domain.extensions.makeWalletManagerForApp
import com.tangem.tap.domain.extensions.makeWalletManagersForApp
import com.tangem.tap.features.wallet.redux.Currency
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.features.wallet.redux.WalletState
import com.tangem.tap.scope
@ -52,8 +53,8 @@ class MultiWalletMiddleware {
store.dispatch(WalletAction.MultiWallet.AddWalletManagers(it))
}
}
store.dispatch(WalletAction.LoadFiatRate(currency = action.blockchain.currency))
store.dispatch(WalletAction.LoadWallet(currency = action.blockchain.currency))
store.dispatch(WalletAction.LoadFiatRate(currency = Currency.Blockchain(action.blockchain)))
store.dispatch(WalletAction.LoadWallet(blockchain = action.blockchain))
}
is WalletAction.MultiWallet.SaveCurrencies -> {
val cardId = globalState?.scanNoteResponse?.card?.cardId
@ -61,12 +62,15 @@ class MultiWalletMiddleware {
}
is WalletAction.MultiWallet.RemoveWallet -> {
val cardId = globalState?.scanNoteResponse?.card?.cardId
if (action.walletData.token != null) {
walletState?.getWalletManagerForToken(action.walletData.token.symbol)
?.removeToken(action.walletData.token)
cardId?.let { currenciesRepository.removeToken(it, action.walletData.token) }
} else if (action.walletData.blockchain != null) {
cardId?.let { currenciesRepository.removeBlockchain(it, action.walletData.blockchain) }
when (val currency = action.walletData.currency) {
is Currency.Blockchain -> {
cardId?.let { currenciesRepository.removeBlockchain(it, currency.blockchain) }
}
is Currency.Token -> {
walletState?.getWalletManager(currency.token)
?.removeToken(currency.token)
cardId?.let { currenciesRepository.removeToken(it, currency.token) }
}
}
}
is WalletAction.MultiWallet.FindBlockchainsInUse -> {
@ -83,7 +87,7 @@ class MultiWalletMiddleware {
val wallet = walletManager.wallet
val coinAmount = wallet.amounts[AmountType.Coin]?.value
if (coinAmount != null && !coinAmount.isZero()) {
if (walletState?.getWalletData(wallet.blockchain.currency) == null) {
if (walletState?.getWalletData(wallet.blockchain) == null) {
scope.launch(Dispatchers.Main) {
store.dispatch(WalletAction.MultiWallet.AddWalletManagers(
listOfNotNull(walletManager)))
@ -101,7 +105,7 @@ class MultiWalletMiddleware {
}
}
is WalletAction.MultiWallet.FindTokensInUse -> {
val walletManager = walletState?.getWalletManager(Blockchain.Ethereum.currency)
val walletManager = walletState?.getWalletManager(Blockchain.Ethereum)
?: return
val tokenFinder = walletManager as TokenFinder
scope.launch {
@ -124,21 +128,34 @@ class MultiWalletMiddleware {
private fun addToken(token: Token, walletState: WalletState?, globalState: GlobalState?) {
val card = globalState?.scanNoteResponse?.card ?: return
val walletManager = walletState?.getWalletManager(token.symbol) ?:
globalState.tapWalletManager.walletManagerFactory.makeWalletManagerForApp(
val walletManager = walletState?.getWalletManager(token)
?: globalState.tapWalletManager.walletManagerFactory.makeWalletManagerForApp(
card = card,
blockchain = Blockchain.Ethereum
)?.also { walletManager ->
)?.also { walletManager ->
store.dispatch(WalletAction.MultiWallet.AddWalletManagers(walletManager))
store.dispatch(WalletAction.MultiWallet.AddBlockchain(walletManager.wallet.blockchain))
}
store.dispatch(
WalletAction.LoadFiatRate(
currency = Currency.Token(
token = token,
blockchain = walletManager?.wallet?.blockchain ?: Blockchain.Ethereum
)
)
)
scope.launch {
val result = walletManager?.addToken(token)
withContext(Dispatchers.Main) {
when (result) {
is Result.Success -> {
store.dispatch(WalletAction.LoadFiatRate(currency = token.symbol))
store.dispatch(WalletAction.MultiWallet.TokenLoaded(result.data))
store.dispatch(
WalletAction.MultiWallet.TokenLoaded(
amount = result.data, token = token
)
)
}
}
}

View file

@ -19,10 +19,7 @@ import com.tangem.tap.domain.twins.TwinsHelper
import com.tangem.tap.features.details.redux.DetailsAction
import com.tangem.tap.features.details.redux.twins.CreateTwinWallet
import com.tangem.tap.features.send.redux.PrepareSendScreen
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.*
import com.tangem.tap.network.NetworkStateChanged
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@ -49,12 +46,12 @@ class WalletMiddleware {
is WalletAction.LoadWallet -> {
scope.launch {
if (action.currency == null) {
if (action.blockchain == null) {
walletState?.walletManagers?.map { walletManager ->
globalState?.tapWalletManager?.loadWalletData(walletManager)
}
} else {
val walletManager = walletState?.getWalletManager(action.currency)
val walletManager = walletState?.getWalletManager(action.blockchain)
walletManager?.let { globalState?.tapWalletManager?.loadWalletData(it) }
}
}
@ -62,7 +59,7 @@ class WalletMiddleware {
is WalletAction.LoadWallet.Success -> {
val coinAmount = action.wallet.amounts[AmountType.Coin]?.value
if (coinAmount != null && !coinAmount.isZero()) {
if (walletState?.getWalletData(action.wallet.blockchain.currency) == null) {
if (walletState?.getWalletData(action.wallet.blockchain) == null) {
store.dispatch(WalletAction.MultiWallet.AddBlockchain(action.wallet.blockchain))
store.dispatch(WalletAction.LoadWallet.Success(action.wallet))
}
@ -72,24 +69,24 @@ class WalletMiddleware {
}
is WalletAction.LoadFiatRate -> {
scope.launch {
if (action.wallet != null) {
globalState?.tapWalletManager?.loadFiatRate(
when {
action.wallet != null -> {
globalState?.tapWalletManager?.loadFiatRate(
globalState.appCurrency, action.wallet
)
} else if (action.currency != null) {
globalState?.tapWalletManager?.loadFiatRate(
)
}
action.currency != null -> {
globalState?.tapWalletManager?.loadFiatRate(
globalState.appCurrency, action.currency
)
} else {
walletState?.wallets?.filter { it.blockchain != null }
?.map { walletState.getWalletManager(it.blockchain?.currency) }
?.mapNotNull { walletManager ->
walletManager?.let {
globalState?.tapWalletManager?.loadFiatRate(
globalState.appCurrency, walletManager.wallet
)
}
}
)
}
else -> {
globalState?.tapWalletManager?.loadFiatRate(
fiatCurrency = globalState.appCurrency,
currencies = walletState?.wallets?.mapNotNull { it.currency }
?: emptyList()
)
}
}
}
}
@ -119,9 +116,9 @@ class WalletMiddleware {
}
}
is WalletAction.UpdateWallet -> {
if (action.currency != null) {
if (action.blockchain != null) {
scope.launch {
val walletManager = walletState?.getWalletManager(action.currency)
val walletManager = walletState?.getWalletManager(action.blockchain)
walletManager?.let { globalState?.tapWalletManager?.updateWallet(it) }
}
} else {
@ -195,7 +192,7 @@ class WalletMiddleware {
private fun prepareSendAction(amount: Amount?, state: WalletState?): Action {
val selectedWalletData = state?.getSelectedWalletData()
val currency = selectedWalletData?.currencyData?.currencySymbol
val currency = selectedWalletData?.currency
val walletManager = state?.getWalletManager(currency)
val wallet = walletManager?.wallet
@ -208,12 +205,17 @@ class WalletMiddleware {
} else {
val amounts = wallet?.amounts?.toSendableAmounts()
if (currency != null && state.isMultiwalletAllowed) {
val amountToSend = amounts?.find { it.currencySymbol == currency }
?: return WalletAction.Send.ChooseCurrency(amounts)
if (amountToSend.type is AmountType.Token) {
prepareSendActionForToken(amountToSend, state, selectedWalletData, wallet, walletManager)
} else {
PrepareSendScreen(amountToSend, selectedWalletData.fiatRate, walletManager)
when (currency) {
is Currency.Blockchain -> {
val amountToSend = amounts?.find { it.currencySymbol == currency.blockchain.currency }
?: return WalletAction.Send.ChooseCurrency(amounts)
PrepareSendScreen(amountToSend, selectedWalletData.fiatRate, walletManager)
}
is Currency.Token -> {
val amountToSend = amounts?.find { it.currencySymbol == currency.token.symbol }
?: return WalletAction.Send.ChooseCurrency(amounts)
prepareSendActionForToken(amountToSend, state, selectedWalletData, wallet, walletManager)
}
}
} else {
if (amounts?.size ?: 0 > 1) {
@ -230,7 +232,7 @@ class WalletMiddleware {
amount: Amount, state: WalletState?, selectedWalletData: WalletData?, wallet: Wallet?,
walletManager: WalletManager?
): PrepareSendScreen {
val coinRate = state?.getWalletData(wallet?.blockchain?.currency)?.fiatRate
val coinRate = state?.getWalletData(wallet?.blockchain)?.fiatRate
val tokenRate = if (state?.isMultiwalletAllowed == true) {
selectedWalletData?.fiatRate
} else {

View file

@ -1,6 +1,7 @@
package com.tangem.tap.features.wallet.redux.reducers
import com.tangem.blockchain.common.AmountType
import com.tangem.blockchain.common.Blockchain
import com.tangem.common.extensions.isZero
import com.tangem.tap.common.extensions.toFiatString
import com.tangem.tap.common.extensions.toFormattedCurrencyString
@ -18,12 +19,12 @@ class MultiWalletReducer {
return when (action) {
is WalletAction.MultiWallet.AddWalletManagers -> {
state.copy(
walletManagers = state.walletManagers + action.walletManagers
walletManagers = state.walletManagers + action.walletManagers
)
}
is WalletAction.MultiWallet.AddBlockchains -> {
val wallets = action.blockchains.map { blockchain ->
val wallet = state.getWalletManager(blockchain.currency)?.wallet
val wallet = state.getWalletManager(blockchain)?.wallet
val cardToken = if (!state.isMultiwalletAllowed) {
wallet?.getFirstToken()?.symbol?.let { TokenData("", tokenSymbol = it) }
} else {
@ -39,12 +40,12 @@ class MultiWalletReducer {
walletAddresses = createAddressList(wallet),
mainButton = WalletMainButton.SendButton(false),
topUpState = TopUpState(allowed = false),
blockchain = blockchain
currency = Currency.Blockchain(blockchain)
)
}
val selectedWallet = if (!state.isMultiwalletAllowed) {
wallets[0].currencyData.currencySymbol
wallets[0].currency
} else {
state.selectedWallet
}
@ -54,7 +55,7 @@ class MultiWalletReducer {
)
}
is WalletAction.MultiWallet.AddBlockchain -> {
val wallet = state.getWalletManager(action.blockchain.currency)?.wallet
val wallet = state.getWalletManager(action.blockchain)?.wallet
val walletData = WalletData(
currencyData = BalanceWidgetData(
BalanceStatus.Loading,
@ -64,7 +65,7 @@ class MultiWalletReducer {
walletAddresses = createAddressList(wallet),
mainButton = WalletMainButton.SendButton(false),
topUpState = TopUpState(allowed = false),
blockchain = action.blockchain
currency = Currency.Blockchain(action.blockchain)
)
val newState = state.copy(wallets = state.replaceWalletInWallets(walletData))
if (wallet != null && wallet.amounts[AmountType.Coin]?.value != null) {
@ -76,29 +77,29 @@ class MultiWalletReducer {
is WalletAction.MultiWallet.AddTokens -> {
if (!state.isMultiwalletAllowed) return state
val wallets = action.tokens.map { token ->
val walletManager = state.getWalletManager(token)?.wallet
WalletData(
currencyData = BalanceWidgetData(
BalanceStatus.Loading,
currency = token.name,
currencySymbol = token.symbol
),
walletAddresses = createAddressList(
state.getWalletManagerForToken(token.symbol)?.wallet
),
walletAddresses = createAddressList(walletManager),
mainButton = WalletMainButton.SendButton(false),
topUpState = TopUpState(allowed = false),
token = token
currency = Currency.Token(
token = token,
blockchain = walletManager?.blockchain ?: Blockchain.Ethereum
)
)
}
state.copy(wallets = state.replaceSomeWallets(wallets))
}
is WalletAction.MultiWallet.AddToken -> {
if (!state.isMultiwalletAllowed) return state
val walletManager = state.getWalletManager(action.token)?.wallet
val walletAddresses = createAddressList(walletManager)
val walletAddresses = createAddressList(
state.getWalletManagerForToken(action.token.symbol)?.wallet
)
val wallet = WalletData(
currencyData = BalanceWidgetData(
BalanceStatus.Loading,
@ -108,13 +109,16 @@ class MultiWalletReducer {
walletAddresses = walletAddresses,
mainButton = WalletMainButton.SendButton(false),
topUpState = TopUpState(allowed = false),
token = action.token
currency = Currency.Token(
token = action.token,
blockchain = walletManager?.blockchain ?: Blockchain.Ethereum
)
)
val wallets = state.replaceWalletInWallets(wallet)
state.copy(wallets = wallets)
}
is WalletAction.MultiWallet.TokenLoaded -> {
val pendingTransactions = state.getWalletManagerForToken(action.amount.currencySymbol)
val pendingTransactions = state.getWalletManager(action.token)
?.wallet?.let { wallet ->
wallet.recentTransactions.toPendingTransactions(wallet.address)
} ?: emptyList()
@ -127,14 +131,14 @@ class MultiWalletReducer {
pendingTransactions.isNotEmpty() -> BalanceStatus.SameCurrencyTransactionInProgress
else -> BalanceStatus.VerifiedOnline
}
val tokenWalletData = state.getWalletData(action.amount.currencySymbol)
val tokenWalletData = state.getWalletData(action.token)
val newTokenWalletData = tokenWalletData?.copy(
currencyData = tokenWalletData.currencyData.copy(
status = tokenBalanceStatus,
amount = action.amount.value?.toFormattedCurrencyString(
action.amount.decimals, action.amount.currencySymbol
),
fiatAmount = tokenWalletData.fiatRate?.let {
fiatAmountFormatted = tokenWalletData.fiatRate?.let {
action.amount.value
?.toFiatString(it, store.state.globalState.appCurrency)
}
@ -149,12 +153,24 @@ class MultiWalletReducer {
state.copy(isMultiwalletAllowed = action.isMultiwalletAllowed)
is WalletAction.MultiWallet.SelectWallet ->
state.copy(selectedWallet = action.walletData?.currencyData?.currencySymbol)
state.copy(selectedWallet = action.walletData?.currency)
is WalletAction.MultiWallet.RemoveWallet -> {
state.copy(wallets = state.wallets.filterNot {
it.currencyData.currencySymbol == action.walletData.currencyData.currencySymbol
})
val wallets = state.wallets.filterNot {
it.currency == action.walletData.currency
}
if (action.walletData.currency is Currency.Blockchain) {
state.copy(
wallets = wallets,
walletManagers = state.walletManagers.filterNot {
it.wallet.blockchain == action.walletData.currency.blockchain
}
)
} else {
state.copy(wallets = wallets)
}
}
is WalletAction.MultiWallet.SetPrimaryBlockchain ->
state.copy(primaryBlockchain = action.blockchain)

View file

@ -3,9 +3,7 @@ package com.tangem.tap.features.wallet.redux.reducers
import com.tangem.blockchain.common.AmountType
import com.tangem.blockchain.common.Wallet
import com.tangem.common.extensions.isZero
import com.tangem.tap.common.extensions.toFiatString
import com.tangem.tap.common.extensions.toFormattedCurrencyString
import com.tangem.tap.common.extensions.toFormattedString
import com.tangem.tap.common.extensions.*
import com.tangem.tap.domain.getFirstToken
import com.tangem.tap.features.wallet.models.removeUnknownTransactions
import com.tangem.tap.features.wallet.models.toPendingTransactions
@ -34,7 +32,7 @@ class OnWalletLoadedReducer {
): WalletState {
val fiatCurrencySymbol = store.state.globalState.appCurrency
val amount = wallet.amounts[AmountType.Coin]?.value
if (walletState.getWalletData(wallet.blockchain.currency) == null) {
if (walletState.getWalletData(wallet.blockchain) == null) {
return walletState
}
val formattedAmount = amount?.toFormattedCurrencyString(
@ -50,37 +48,40 @@ class OnWalletLoadedReducer {
} else {
BalanceStatus.VerifiedOnline
}
val walletData = walletState.getWalletData(wallet.blockchain.currency)
val walletData = walletState.getWalletData(wallet.blockchain)
?: WalletData()
val fiatAmount = walletData.fiatRate?.let { amount?.toFiatValue(it) }
val newWalletData = walletData.copy(
currencyData = walletData.currencyData.copy(
status = balanceStatus, currency = wallet.blockchain.fullName,
currencySymbol = wallet.blockchain.currency,
amount = formattedAmount,
fiatAmount = walletData.fiatRate?.let { amount?.toFiatString(it, fiatCurrencySymbol) }
fiatAmount = fiatAmount,
fiatAmountFormatted = fiatAmount?.toFormattedFiatValue(fiatCurrencySymbol)
),
pendingTransactions = pendingTransactions.removeUnknownTransactions(),
mainButton = WalletMainButton.SendButton(sendButtonEnabled)
)
val tokens = wallet.getTokens().mapNotNull { token ->
val tokenWalletData = walletState.getWalletData(token.symbol)
val tokenWalletData = walletState.getWalletData(token)
val tokenPendingTransactions = pendingTransactions.filter { it.currency == token.symbol }
val tokenBalanceStatus = when {
tokenPendingTransactions.isNotEmpty() -> BalanceStatus.TransactionInProgress
pendingTransactions.isNotEmpty() -> BalanceStatus.SameCurrencyTransactionInProgress
else -> BalanceStatus.VerifiedOnline
}
val tokenFiatAmount = tokenWalletData?.fiatRate?.let { rate ->
wallet.getTokenAmount(token)?.value?.toFiatValue(rate)
}
tokenWalletData?.copy(
currencyData = tokenWalletData.currencyData.copy(
status = tokenBalanceStatus,
amount = wallet.getTokenAmount(token)?.value?.toFormattedCurrencyString(
token.decimals, token.symbol
),
fiatAmount = tokenWalletData.fiatRate?.let {
wallet.getTokenAmount(token)?.value
?.toFiatString(it, fiatCurrencySymbol)
}
fiatAmount = tokenFiatAmount,
fiatAmountFormatted = tokenFiatAmount?.toFormattedFiatValue(fiatCurrencySymbol)
),
pendingTransactions = tokenPendingTransactions.removeUnknownTransactions(),
mainButton = WalletMainButton.SendButton(sendButtonEnabled)
@ -145,8 +146,8 @@ class OnWalletLoadedReducer {
currencySymbol = wallet.blockchain.currency,
formattedAmount,
token = tokenData,
fiatAmount = fiatAmount,
fiatAmountRaw = fiatAmountRaw
fiatAmountFormatted = fiatAmount,
fiatAmount = fiatAmountRaw
),
pendingTransactions = pendingTransactions.removeUnknownTransactions(),
mainButton = WalletMainButton.SendButton(sendButtonEnabled)

View file

@ -1,15 +1,11 @@
package com.tangem.tap.features.wallet.redux.reducers
import com.tangem.blockchain.common.AmountType
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.Wallet
import com.tangem.commands.common.network.TangemService
import com.tangem.common.extensions.toHexString
import com.tangem.tap.common.extensions.toFiatString
import com.tangem.tap.common.extensions.toFormattedCurrencyString
import com.tangem.tap.common.extensions.toQrCode
import com.tangem.tap.common.extensions.*
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.CryptoCurrencyName
import com.tangem.tap.common.redux.global.FiatCurrencyName
import com.tangem.tap.domain.TapError
import com.tangem.tap.domain.getFirstToken
@ -88,7 +84,7 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
)
}
is WalletAction.LoadWallet -> {
if (action.currency == null) {
if (action.blockchain == null) {
val wallets = newState.wallets.map { wallet ->
wallet.copy(
currencyData = wallet.currencyData.copy(
@ -106,9 +102,12 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
wallets = wallets
)
} else {
val walletManager = newState.getWalletManager(action.currency) ?: return newState
val currencies = listOf(walletManager.wallet.blockchain.currency) + walletManager.presetTokens.map { it.symbol }
val newWallets = newState.wallets.filter { currencies.contains(it.currencyData.currencySymbol) }
val walletManager = newState.getWalletManager(action.blockchain) ?: return newState
val blockchain = walletManager.wallet.blockchain
val currencies = listOf(Currency.Blockchain(blockchain)) + walletManager.presetTokens.map {
Currency.Token(token = it, blockchain = blockchain)
}
val newWallets = newState.wallets.filter { currencies.contains(it.currency) }
.map { wallet ->
wallet.copy(
currencyData = wallet.currencyData.copy(
@ -131,7 +130,7 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
newState = onWalletLoadedReducer.reduce(action.wallet, newState)
}
is WalletAction.LoadWallet.NoAccount -> {
val walletData = newState.getWalletData(action.wallet.blockchain.currency)?.copy(
val walletData = newState.getWalletData(action.wallet.blockchain)?.copy(
currencyData = BalanceWidgetData(
BalanceStatus.NoAccount, action.wallet.blockchain.fullName,
currencySymbol = action.wallet.blockchain.currency,
@ -155,7 +154,7 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
} else {
action.errorMessage
}
val walletData = newState.getWalletData(action.wallet.blockchain.currency)
val walletData = newState.getWalletData(action.wallet.blockchain)
val newWalletData = walletData?.copy(
currencyData = walletData.currencyData.copy(
status = BalanceStatus.Unreachable,
@ -164,7 +163,7 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
topUpState = TopUpState(false)
)
val tokenWallets = action.wallet.getTokens()
.mapNotNull { newState.getWalletData(it.symbol) }
.mapNotNull { newState.getWalletData(it) }
.map {
it.copy(currencyData = it.currencyData.copy(
status = BalanceStatus.Unreachable, errorMessage = message
@ -241,7 +240,7 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
is WalletAction.ChangeSelectedAddress -> {
val selectedWalletData = newState.getWalletData(newState.selectedWallet)
val walletAddresses = newState.getWalletData(selectedWalletData?.currencyData?.currencySymbol)?.walletAddresses
val walletAddresses = newState.getWalletData(selectedWalletData?.currency)?.walletAddresses
?: return newState
val address = walletAddresses.list.firstOrNull { it.type == action.type }
?: return newState
@ -288,64 +287,60 @@ private fun handleCheckSignedHashesActions(action: WalletAction.Warnings, state:
private fun setNewFiatRate(
fiatRate: Pair<CryptoCurrencyName, BigDecimal?>,
fiatRate: Pair<Currency, BigDecimal?>,
appCurrency: FiatCurrencyName, state: WalletState
): WalletState {
val rate = fiatRate.second ?: return state
val rateFormatted = rate.toFormattedCurrencyString(2, appCurrency)
val currency = fiatRate.first
if (!state.isMultiwalletAllowed) {
return setSingeWalletFiatRate(rate, rateFormatted, currency, appCurrency, state)
return if (!state.isMultiwalletAllowed) {
setSingeWalletFiatRate(rate, rateFormatted, currency, appCurrency, state)
} else {
return setMultiWalletFiatRate(rate, rateFormatted, currency, appCurrency, state)
setMultiWalletFiatRate(rate, rateFormatted, currency, appCurrency, state)
}
}
private fun setMultiWalletFiatRate(
rate: BigDecimal, rateFormatted: String, currency: CryptoCurrencyName,
appCurrency: FiatCurrencyName, state: WalletState
rate: BigDecimal, rateFormatted: String, currency: Currency,
appCurrency: FiatCurrencyName, state: WalletState
): WalletState {
val walletData = state.getWalletData(currency) ?: return state
val wallet = state.walletManagers.find { it.wallet.blockchain.currency == currency }?.wallet
if (wallet != null) {
val newWalletData = state.getWalletData(currency)?.copy(
currencyData = walletData.currencyData.copy(
fiatAmount = wallet.amounts[AmountType.Coin]?.value
?.toFiatString(rate, appCurrency)),
fiatRate = rate, fiatRateString = rateFormatted
)
return state.copy(wallets = state.replaceWalletInWallets(newWalletData))
} else {
val ethereumWallet = state.walletManagers.find { it.wallet.blockchain == Blockchain.Ethereum }?.wallet
val token = ethereumWallet?.getTokens()?.find { it.symbol == currency } ?: return state
val tokenFiatAmount = ethereumWallet.getTokenAmount(token)?.value?.toFiatString(rate, appCurrency)
val newWalletData = state.getWalletData(currency)?.copy(
currencyData = walletData.currencyData.copy(
fiatAmount = tokenFiatAmount),
fiatRate = rate, fiatRateString = rateFormatted
)
return state.copy(wallets = state.replaceWalletInWallets(newWalletData))
val wallet = state.getWalletManager(currency)?.wallet
val fiatAmount = when (currency) {
is Currency.Blockchain ->
wallet?.amounts?.get(AmountType.Coin)?.value?.toFiatValue(rate)
is Currency.Token ->
wallet?.getTokenAmount(currency.token)?.value?.toFiatValue(rate)
}
val fiatAmountFormatted = fiatAmount?.toFormattedFiatValue(appCurrency)
val newWalletData = state.getWalletData(currency)?.copy(
currencyData = walletData.currencyData.copy(
fiatAmountFormatted = fiatAmountFormatted,
fiatAmount = fiatAmount
),
fiatRate = rate, fiatRateString = rateFormatted
)
return state.copy(wallets = state.replaceWalletInWallets(newWalletData))
}
private fun setSingeWalletFiatRate(
rate: BigDecimal, rateFormatted: String, currency: CryptoCurrencyName,
rate: BigDecimal, rateFormatted: String, currency: Currency,
appCurrency: FiatCurrencyName, state: WalletState
): WalletState {
val wallet = state.walletManagers[0].wallet
val token = wallet.getFirstToken()
if (currency == state.primaryWallet?.currencyData?.currencySymbol) {
if (currency == state.primaryWallet?.currency) {
val fiatAmount = wallet.amounts[AmountType.Coin]?.value
?.toFiatString(rate, appCurrency)
val walletData = state.primaryWallet.copy(
currencyData = state.primaryWallet.currencyData.copy(fiatAmount = fiatAmount),
currencyData = state.primaryWallet.currencyData.copy(fiatAmountFormatted = fiatAmount),
fiatRate = rate,
fiatRateString = rateFormatted
)
return state.copy(wallets = listOf(walletData))
} else if (currency == token?.symbol) {
} else if (currency is Currency.Token && currency.token == token) {
val tokenFiatAmount = wallet.getTokenAmount(token)?.value?.toFiatString(rate, appCurrency)
val tokenData = state.primaryWallet?.currencyData?.token?.copy(
fiatAmount = tokenFiatAmount,

View file

@ -22,15 +22,15 @@ enum class BalanceStatus {
}
data class BalanceWidgetData(
val status: BalanceStatus? = null,
val currency: String? = null,
val currencySymbol: String? = null,
val amount: String? = null,
val fiatAmount: String? = null,
val fiatAmountRaw: BigDecimal? = null,
val token: TokenData? = null,
val amountToCreateAccount: String? = null,
val errorMessage: String? = null
val status: BalanceStatus? = null,
val currency: String? = null,
val currencySymbol: String? = null,
val amount: String? = null,
val fiatAmountFormatted: String? = null,
val fiatAmount: BigDecimal? = null,
val token: TokenData? = null,
val amountToCreateAccount: String? = null,
val errorMessage: String? = null
)
data class TokenData(
@ -158,7 +158,7 @@ class BalanceWidget(
fragment.tv_amount.text = if (showAmount) data.amount else ""
if (showAmount) {
fragment.tv_fiat_amount.show()
fragment.tv_fiat_amount.text = data.fiatAmount
fragment.tv_fiat_amount.text = data.fiatAmountFormatted
}
}
}

View file

@ -9,6 +9,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.transition.TransitionInflater
import com.squareup.picasso.Picasso
import com.tangem.blockchain.common.Blockchain
import com.tangem.tap.MainActivity
import com.tangem.tap.common.extensions.*
@ -24,6 +25,9 @@ import kotlinx.android.synthetic.main.fragment_details_twin_cards.*
import kotlinx.android.synthetic.main.fragment_wallet_details.*
import kotlinx.android.synthetic.main.fragment_wallet_details.toolbar
import kotlinx.android.synthetic.main.item_currency_wallet.view.*
import kotlinx.android.synthetic.main.item_currency_wallet.view.iv_currency
import kotlinx.android.synthetic.main.item_currency_wallet.view.tv_token_letter
import kotlinx.android.synthetic.main.item_popular_token.view.*
import kotlinx.android.synthetic.main.layout_balance_error.*
import kotlinx.android.synthetic.main.layout_balance_wallet_details.*
import kotlinx.android.synthetic.main.layout_wallet_details.*
@ -123,7 +127,7 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS
if (selectedWallet.currencyData.status != BalanceStatus.Loading) {
store.dispatch(WalletAction.LoadWallet(
selectedWallet.topUpState.allowed,
selectedWallet.currencyData.currencySymbol
selectedWallet.currency?.blockchain
))
}
}
@ -134,16 +138,12 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS
}
private fun handleCurrencyIcon(wallet: WalletData) {
val blockchain = wallet.currencyData.currencySymbol?.let { Blockchain.fromCurrency(it) }
if (blockchain != null && blockchain != Blockchain.Unknown) {
tv_token_letter.text = null
iv_currency.colorFilter = null
iv_currency.setImageResource(blockchain.getIconRes())
} else {
tv_token_letter.text = wallet.currencyData.currencySymbol?.take(1)
wallet.token?.getColor()?.let { iv_currency.setColorFilter(it) }
iv_currency.setImageResource(R.drawable.shape_circle)
}
Picasso.get().loadCurrenciesIcon(
imageView = iv_currency,
textView = tv_token_letter,
blockchain = wallet.currency?.blockchain,
token = (wallet.currency as? Currency.Token)?.token
)
}
@ -154,7 +154,7 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS
private fun setupAddressCard(state: WalletData) {
if (state.walletAddresses != null) {
if (state.shouldShowMultipleAddress() && state.blockchain != null) {
if (state.shouldShowMultipleAddress() && state.currency is Currency.Blockchain) {
(card_balance as? ViewGroup)?.beginDelayedTransition()
chip_group_address_type.show()
chip_group_address_type.fitChipsByGroupWidth()
@ -164,7 +164,7 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS
chip_group_address_type.setOnCheckedChangeListener { group, checkedId ->
if (checkedId == -1) return@setOnCheckedChangeListener
val type = MultipleAddressUiHelper.idToType(checkedId, state.blockchain)
val type = MultipleAddressUiHelper.idToType(checkedId, state.currency.blockchain)
type?.let { store.dispatch(WalletAction.ChangeSelectedAddress(type)) }
}
} else {
@ -260,7 +260,7 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS
tv_amount.text = if (showAmount) data.amount else ""
if (showAmount) {
tv_fiat_amount.show()
tv_fiat_amount.text = data.fiatAmount
tv_fiat_amount.text = data.fiatAmountFormatted
}
}

View file

@ -8,6 +8,7 @@ import android.view.MenuItem
import android.view.View
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.get
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView

View file

@ -6,15 +6,12 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.squareup.picasso.Callback
import com.squareup.picasso.Picasso
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.IconsUtil
import com.tangem.blockchain.common.Token
import com.tangem.tap.common.extensions.getColor
import com.tangem.tap.common.extensions.getIconRes
import com.tangem.tap.common.extensions.loadCurrenciesIcon
import com.tangem.tap.common.extensions.show
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.ui.BalanceStatus
@ -24,8 +21,6 @@ import kotlinx.android.synthetic.main.item_currency_wallet.view.*
import kotlinx.android.synthetic.main.item_currency_wallet.view.iv_currency
import kotlinx.android.synthetic.main.item_currency_wallet.view.tv_currency_symbol
import kotlinx.android.synthetic.main.item_currency_wallet.view.tv_token_letter
import kotlinx.android.synthetic.main.item_popular_token.view.*
import java.lang.Exception
import java.math.BigDecimal
class WalletAdapter
@ -38,7 +33,9 @@ class WalletAdapter
fun submitList(list: List<WalletData>, primaryBlockchain: Blockchain?, primaryToken: Token? = null) {
val listModified = list.toMutableList()
val primaryBlockchainWallet = when (
val index = listModified.indexOfFirst { it.blockchain == primaryBlockchain }
val index = listModified.indexOfFirst {
(it.currency as? Currency.Blockchain)?.blockchain == primaryBlockchain
}
) {
-1 -> null
else -> listModified.removeAt(index)
@ -46,20 +43,20 @@ class WalletAdapter
val primaryTokenWallet = if (primaryToken == null) null else when (
val index = listModified.indexOfFirst { it.token == primaryToken }
val index = listModified.indexOfFirst { (it.currency as? Currency.Token)?.token == primaryToken }
) {
-1 -> null
else -> listModified.removeAt(index)
}
if (list.all { it.currencyData.fiatAmount == null }) {
if (list.all { it.currencyData.fiatAmountFormatted == null }) {
val sortedList = listOfNotNull(primaryBlockchainWallet, primaryTokenWallet) + listModified
super.submitList(sortedList)
return
}
val sorted = listModified.sortedWith(
compareByDescending<WalletData> { it.currencyData.fiatAmountRaw ?: BigDecimal.ZERO }
compareByDescending<WalletData> { it.currencyData.fiatAmount ?: BigDecimal.ZERO }
.thenBy { it.currencyData.currencySymbol }
)
val sortedList = listOfNotNull(primaryBlockchainWallet, primaryTokenWallet) + sorted
@ -93,13 +90,13 @@ class WalletAdapter
view.tv_currency.text = wallet.currencyData.currency
view.tv_amount.text = wallet.currencyData.amount?.takeWhile { !it.isWhitespace() }
view.tv_currency_symbol.text = wallet.currencyData.amount?.takeLastWhile { !it.isWhitespace() }
view.tv_amount_fiat.text = wallet.currencyData.fiatAmount
view.tv_amount_fiat.text = wallet.currencyData.fiatAmountFormatted
view.tv_exchange_rate.text = wallet.fiatRateString
view.card_wallet.setOnClickListener {
store.dispatch(WalletAction.MultiWallet.SelectWallet(wallet))
}
val blockchain = wallet.blockchain
val token = wallet.token
val blockchain = wallet.currency?.blockchain
val token = (wallet.currency as? Currency.Token)?.token
Picasso.get().loadCurrenciesIcon(
imageView = view.iv_currency,

View file

@ -190,7 +190,7 @@ class SingleWalletView : WalletView {
private fun setupAddressCard(state: WalletData, fragment: WalletFragment) = with(fragment) {
if (state.walletAddresses != null && state.blockchain != null) {
if (state.walletAddresses != null && state.currency is Currency.Blockchain) {
l_address?.show()
if (state.shouldShowMultipleAddress()) {
(l_address as? ViewGroup)?.beginDelayedTransition()
@ -202,7 +202,7 @@ class SingleWalletView : WalletView {
chip_group_address_type.setOnCheckedChangeListener { group, checkedId ->
if (checkedId == -1) return@setOnCheckedChangeListener
val type = MultipleAddressUiHelper.idToType(checkedId, state.blockchain)
val type = MultipleAddressUiHelper.idToType(checkedId, state.currency.blockchain)
type?.let { store.dispatch(WalletAction.ChangeSelectedAddress(type)) }
}
} else {

View file

@ -19,7 +19,6 @@ buildscript {
allprojects {
repositories {
google()
jcenter()
maven { url 'https://jitpack.io' }
def nexusUser = "viewer"
def nexusPass = "smartcash124"

View file

@ -1,4 +1,4 @@
ext.versions = [
kotlin : '1.5.0',
build_gradle: '4.2.0',
build_gradle: '4.2.1',
]